Skip to main content

GoogleDriveFilesystem

Stores files in a single Google Drive folder. Each directory maps to a Drive folder under the configured root, and paths use POSIX semantics (for example /notes/todo.txt).

info

For interface details, see WorkspaceFilesystem Interface.

Installation
Direct link to Installation

npm install @mastra/google-drive

Usage
Direct link to Usage

Add a GoogleDriveFilesystem to a workspace and assign it to an agent:

import { Agent } from '@mastra/core/agent'
import { Workspace } from '@mastra/core/workspace'
import { GoogleDriveFilesystem } from '@mastra/google-drive'

const workspace = new Workspace({
filesystem: new GoogleDriveFilesystem({
folderId: process.env.GOOGLE_DRIVE_FOLDER_ID!,
accessToken: process.env.GOOGLE_DRIVE_ACCESS_TOKEN!,
}),
})

const agent = new Agent({
id: 'drive-agent',
name: 'Drive Agent',
model: 'openai/gpt-4o-mini',
workspace,
})

Authentication
Direct link to Authentication

Supply one of the following authentication options:

  • accessToken: A pre-obtained OAuth access token. Use the https://www.googleapis.com/auth/drive scope so the token can see folders shared with the authenticated identity.
  • getAccessToken: A callback that returns a token. Useful when tokens are refreshed externally.
  • serviceAccount: A Google service account. Share the target folder with the service account email.

Service account
Direct link to Service account

Service account auth is the recommended option for backend agents. There is no user consent flow and no token refresh handling. You only need two values from the service account JSON key file: client_email and private_key.

Set up the service account
Direct link to Set up the service account
  1. Open the Google Cloud Console and select or create a project.
  2. Go to APIs & Services > Library, search for Google Drive API, and select Enable.
  3. Go to APIs & Services > Credentials, select Create credentials > Service account, and complete the form. The role can be left blank — Drive permissions are granted by sharing folders, not by IAM roles.
  4. Open the new service account, go to the Keys tab, and select Add key > Create new key > JSON. The browser downloads a JSON key file.
  5. Copy the client_email value from the JSON file. This is the address you share Drive folders with.
Share the Drive folder with the service account
Direct link to Share the Drive folder with the service account

The service account is its own Google identity. It cannot see anything in Drive until you share with it explicitly.

  1. Open the target folder in Google Drive.
  2. Select Share.
  3. Paste the service account's client_email address.
  4. Set the role to Editor (for read and write) or Viewer (for read-only access). Select Send.
  5. Copy the folder ID from the URL. It is the segment after /folders/ in https://drive.google.com/drive/folders/<folderId>.
warning

Service accounts cannot create files in standard "My Drive" folders. A service account has no personal Drive storage quota, so any file it creates needs to be owned by a quota-bearing entity. If you only share a personal Drive folder, read operations work but writes fail with a quota error.

For write access, place the folder inside a shared drive (formerly Team Drive) and add the service account as a member of that shared drive. Shared drives provide the storage quota that service-account-created files need.

Read-only workloads against a personal Drive folder do not have this restriction.

Configure the filesystem
Direct link to Configure the filesystem

Copy client_email and private_key from the JSON file into your environment:

GOOGLE_DRIVE_FOLDER_ID=1AbCdEfGhIjKlMnOpQrStUvWxYz
GOOGLE_DRIVE_CLIENT_EMAIL=my-bot@my-project.iam.gserviceaccount.com
# Wrap the value in quotes — the key contains newlines that must be preserved.
GOOGLE_DRIVE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkq...\n-----END PRIVATE KEY-----\n"
import { GoogleDriveFilesystem } from '@mastra/google-drive'

const filesystem = new GoogleDriveFilesystem({
folderId: process.env.GOOGLE_DRIVE_FOLDER_ID!,
serviceAccount: {
clientEmail: process.env.GOOGLE_DRIVE_CLIENT_EMAIL!,
privateKey: process.env.GOOGLE_DRIVE_PRIVATE_KEY!,
},
})

You do not need to copy the entire JSON file or pass other fields like project_id, client_id, private_key_id, or token_uri. They are not used. Only clientEmail and privateKey are required. privateKeyId, scopes, and subject are optional. scopes defaults to ['https://www.googleapis.com/auth/drive'], which is the scope required for the service account to see folders shared with it. The narrower drive.file scope only grants access to files the application created itself, so a folder shared with the service account would return 404 Not Found.

GoogleDriveFilesystem automatically normalizes the privateKey string before signing. It strips surrounding quotes (including escaped quotes from JSON-wrapped values), converts literal \n sequences to real newlines, normalizes \r\n line endings, and removes a trailing comma. The key works regardless of how your .env loader handles the value.

Troubleshoot
Direct link to Troubleshoot
  • 404 File not found: <folderId>: The service account does not have access to the folder. Confirm the folder is shared with the exact client_email address and that the folder ID matches the URL.
  • storageQuotaExceeded on write: The folder is in a personal "My Drive". Move the folder to a shared drive and add the service account as a member.
  • error:1E08010C:DECODER routines::unsupported: The privateKey value is malformed. Confirm the value contains the full PEM block and that newlines are preserved (literal \n is fine).

Read-only mode
Direct link to Read-only mode

Pass readOnly: true to block write operations (writeFile, appendFile, deleteFile, copyFile, moveFile, mkdir, rmdir).

const filesystem = new GoogleDriveFilesystem({
folderId,
accessToken,
readOnly: true,
})

Constructor parameters
Direct link to Constructor parameters

folderId:

string
ID of the Google Drive folder that acts as the workspace root. All paths are resolved inside this folder.

accessToken?:

string
OAuth access token with access to the folder.

getAccessToken?:

() => string | Promise<string>
Callback that returns a fresh OAuth access token. Called on every request that needs authorization.

serviceAccount?:

{ clientEmail: string; privateKey: string; privateKeyId?: string; scopes?: string[]; subject?: string }
Service account credentials used to mint access tokens via the OAuth 2.0 JWT flow.

id?:

string
= `google-drive:${folderId}`
Unique identifier for this filesystem instance

readOnly?:

boolean
= false
When true, all write operations are blocked.

instructions?:

InstructionsOption
Override the default instructions returned to tool descriptions.

Properties
Direct link to Properties

id:

string
Filesystem instance identifier

name:

string
Provider name ('GoogleDriveFilesystem')

provider:

string
Provider identifier ('google-drive')

readOnly:

boolean | undefined
Whether the filesystem is in read-only mode

Methods
Direct link to Methods

GoogleDriveFilesystem implements the WorkspaceFilesystem interface, providing all standard filesystem methods:

  • readFile(path, options?) - Download file contents
  • writeFile(path, content, options?) - Upload or overwrite a file
  • appendFile(path, content) - Append content by reading and re-uploading the file
  • deleteFile(path, options?) - Delete a file
  • copyFile(src, dest, options?) - Copy a file using the Drive files.copy API
  • moveFile(src, dest, options?) - Move a file between folders by swapping parents
  • mkdir(path, options?) - Create a folder
  • rmdir(path, options?) - Remove a folder
  • readdir(path, options?) - List folder contents (supports recursive and extension filtering)
  • stat(path) - Return Drive metadata for a file or folder
  • exists(path) - Check if a file or folder exists

Notes
Direct link to Notes

  • Google Drive allows multiple files with the same name in a folder. GoogleDriveFilesystem resolves paths by picking the first match, so keep names unique within each folder when you rely on path-based lookup.
  • writeFile creates parent folders automatically when recursive is unset (the default) or true. Set recursive: false to require the parent folder to already exist.
  • expectedMtime on WriteOptions is honored — when the stored modifiedTime differs, the write is rejected with StaleFileError to support optimistic concurrency.
  • The provider only exercises Drive REST endpoints (https://www.googleapis.com/drive/v3 and https://www.googleapis.com/upload/drive/v3) through the built-in fetch; no additional dependencies are required.