Crossdrive
Free, self-hosted MCP server: one AI connection onto all your Google Drive and Gmail accounts.
Documentation
Every drive you own. One safe connection for your AI.
Crossdrive is a guarded file-and-mail layer between an AI client and your Google Drive and Gmail accounts (OneDrive
and Dropbox in beta), run as a remote MCP server you host yourself. Every account
sits under a label you choose, so a request always names work:/Contracts or personal:/Taxes and nothing is ever
done "in whichever account". The rules are enforced by the server, not by the chat app: each account can be read-only,
each Gmail account has its own mail mode (off, draft or send), delete means trash, writes can be dry-run first and
undone, every write is audited, and unknown arguments are refused. It also works between accounts: copy files and
folder trees from one account to another, or move them with the source trashed only after the copy is verified; find
duplicates across accounts; and search every account at once, with any account that failed named in the result. It
speaks plain MCP rather than belonging to one AI vendor, and your tokens stay in your own Vercel storage. So far only
the Claude desktop app has been verified as a client.
Do you need this?
Perhaps not. As of mid-November 2026 there are user reports (one Reddit thread) that Claude's built-in Gmail and Drive connectors are gaining support for several accounts in a gradual rollout. We could not confirm this from Anthropic's documentation, which describes one connected account (checked 12 November 2026), or test it ourselves. If you have it, and you only need to read and draft across a few Google accounts inside Claude, use it: it needs no setup.
Crossdrive is for when you want one or more of these:
- Rules per account, enforced on the server: read-only accounts, mail off, draft or send per account, trash-only delete, dry run, undo and an audit log.
- Work between accounts: copy or move files and folder trees, find duplicates across accounts, one search that names any account that failed.
- Your own hosting, not tied to one AI vendor: tokens in your own storage, and any MCP client can connect (only the Claude desktop app has been verified so far).
- OneDrive or Dropbox beside Google (beta, not yet tested on live accounts).
If you do not have it yet, Several Google accounts with an AI assistant: the built-in options, and when you still need more compares the other ways, including ones that need no new software.
What you should know before you connect anything
| Scopes requested | Drive (drive) and Gmail (gmail.modify, gmail.compose, gmail.send), per account, from your own Google Cloud project. No scope that permits permanent deletion is requested. |
| Where tokens live | Refresh tokens are encrypted with AES-256-GCM and stored in a private Vercel Blob store in your own Vercel account. The key is an environment variable only you hold. |
| What is logged | Every completed write: tool, account, affected item, actor. Mail entries also record the recipients, the subject and attachment file names. Never file contents, mail bodies or tokens. The log is append-only and readable through the audit tool. |
| Defaults | No permanent delete (trash only). Mail is draft-only for new accounts, and new accounts start read + write: switch a work account to read-only on its card right after connecting it. A "disconnect everything" button revokes every token. |
What has been tested
As of 12 November 2026, version 1.0.1 has been tested live against real Google accounts: two consumer Gmail accounts and one Google Workspace account, the Workspace one in read-only mode, through four rounds on one Vercel deployment. The client was a scripted OAuth client that went through the real consent screen in an unmodified Chrome. The fixes in 1.0.1 come from those rounds (changelog).
Verified live:
- Setup and connecting:
/setupand/healthchecks, client registration, the consent screen (Approve with full or read-only access, Deny, single-use authorization codes, token refresh, a clear error for a bad token), connecting three Google accounts under labels, and switching an account's mode and mail mode on/connect(in effect on the next call, about one second later). - Reading:
accounts,status,list,findacross all three accounts with paging,readof a Google Doc, PDF, xlsx and docx,tree,changes,shared,drives,duplicateswithin and across accounts, andaudit. - Writing within an account:
mkdir,put(text and binary files),rename,move,trash,untrash,undo, andbatch, including one batch across two accounts. - Across accounts:
copyof single files and folder trees with the resume cursor, andtransfer(copy and move) with hash verification. From a writable source, each file got a temporary reader grant that was audited and removed within seconds; folders were never shared; an abandoned folder copy left nothing shared. From a read-only source (consumer and Workspace), files were streamed and the source's permissions andmodifiedTimestayed unchanged. - Read-only accounts: every write tool, dry runs included, was refused before Google was called, and so was any copy or transfer into a read-only account or a move out of one.
- Gmail: search, read, labels, reading an attachment and saving it to Drive, drafts, labelling and trashing, sending
and replying in mode
send, and the refusals in modesdraftandoff. - Paging of large
readresults, security headers, and the signed-out pages at phone width. - Claude desktop app: on 12 November 2026 the Claude desktop app connected to a live instance through a custom
connector. Observed working: the OAuth consent flow,
status,findacross three accounts,mkdir(dry run, then real), refusal of a write on a read-only account, andtrash.
Not yet verified live:
- OneDrive and Dropbox. Never run against live accounts; beta, tested against in-memory fakes of their APIs only.
- Other AI client apps. ChatGPT, claude.ai on the web and the Claude mobile apps: not yet tested. Claude Code was not used in the live tests either. Apart from the Claude desktop check above, the live tests used a scripted OAuth client through real Chrome; the other client setup steps below follow those clients' documentation.
- Google-native files on the streamed path. Docs/Sheets/Slides export and re-import from a read-only source, Docs/Sheets/Slides staying native on the server-side path, and Forms and Drawings being skipped are covered by automated tests only.
- Disconnect, reconnect and "Disconnect everything" (the kill switch).
- The recipient allowlist (
CROSSDRIVE_MAIL_ALLOWED_RECIPIENTS). - The Deploy to Vercel button from an account other than the repository owner's.
- Also not exercised live beyond their read-only refusal: the sharing tools (
share,unshare,transfer_ownership,shortcut), large uploads (upload_begin,scripts/bulk-upload.mjs,putwithsourceUrl), Shared Drive contents (none of the test accounts had one), static bearer tokens, a writable Workspace account as a copy source, and the signed-in/connectpage at phone width.
Deploy to Vercel
Do the Google Cloud part first (docs/setup-google.md), because the button asks for the client
id and secret. You do not need to set CROSSDRIVE_BASE_URL on Vercel: Crossdrive uses the project's production domain
automatically. Set it only for a custom domain. Full walkthrough: docs/setup-vercel.md.
If you are deploying from the account that owns this repository, use Vercel's Import flow instead of the button; the button creates a copy of the repo and needs a new name.
Quickstart
- Create a Google OAuth client in your own Google Cloud project, with the Drive and Gmail APIs enabled and the consent screen set to Internal (Workspace) or published to Production (personal Gmail). Step by step.
- Deploy to Vercel with the button above, attach a Blob store, and paste the client id (it ends in
.apps.googleusercontent.com) and secret. Generate the two secrets withopenssl rand -base64 32(run it twice). The base URL is taken from Vercel's production domain; setCROSSDRIVE_BASE_URLonly for a custom domain, and then to the deployment's own address, never the GitHub repository URL. - Open
<your URL>/setup. It checks every variable (including placeholder text left in the Google client id or secret) and lists the two redirect URIs to add to the Google client:<your URL>/api/google/callbackand<your URL>/oauth/google-callback. - Connect your accounts at
<your URL>/connect, in two steps. First sign in with an e-mail fromCROSSDRIVE_ALLOWED_EMAILS; this only opens the admin page and connects nothing. Then, in Connect a cloud account, pick a label (for examplework,personal,clientco), click Connect Google and choose that Google account. The page confirms each connection by e-mail and label. New accounts start as read + write with mail as drafts only; switch an account to read-only (do it right away for a work account) or change its mail mode on its card. Repeat for each account. Google signs you in with the browser's own Google session: to connect several accounts, sign each of them in to the browser first (or be ready for Google to ask for that account's password). - Add the connector to your AI client using
<your URL>/api/mcp(details below), then ask: "search all my drives for the 2026 lease".
How it compares
Facts below are drawn from public issue trackers, documentation and user reports, and were last checked on 13 November 2026. Things move quickly; please open an issue if a row is out of date. "Not known" means we could not find it documented and have not tested it.
| Claude's built-in Drive/Gmail connector | Google's official Drive and Gmail MCP servers | taylorwilsdon/google_workspace_mcp | Crossdrive | |
|---|---|---|---|---|
| Several Google accounts | One account per connector per Anthropic's help page (12 Nov 2026); user reports of a multi-account rollout, unconfirmed. For custom connectors, a request to attach two with the same URL is open | Not documented as a feature | A documented weak spot: OAuth 2.1 mode binds one identity per session, and a per-account client pull request was closed unmerged in November 2026 | Yes: user-chosen labels, label:/path addressing |
| Search across accounts in one request | Not known | Not documented | Not in OAuth 2.1 mode (one identity per session) | find fans out and reports per-account errors and partial |
| Cross-account copy or move of files and folder trees | Not known | Not offered, to our knowledge | Not offered, to our knowledge | Yes, resumable; Drive's server-side copy from a writable source, streamed through your deployment from a read-only one; transfer moves only after verifying |
| Permission controls | Per tool (always allow, needs approval, blocked), per the same user report; whether they can differ per account is not known | Not assessed here | Not assessed here | Per account, on the server: read-only or read + write, and mail off, draft or send; plus read-only consent per client |
| Clients | Claude's own apps | Not assessed here | Not assessed here | Any MCP client with OAuth or a bearer token; only the Claude desktop app verified so far |
| Shared Drive items | Silent empty results in an open issue | The hosted Drive connector omits the same flags, per the same issue | Not assessed here | Supported; unreachable ones return an explicit error |
| Gmail | Drafts, send, reply and labels are documented; an open issue reports the label and archive tools not working for some users | Draft only, no send | Send supported; a recipient allowlist is an open proposal | Per account: off, draft or send; draft is the default; optional recipient allowlist |
| Delete | Not assessed here | Not assessed here | Not assessed here | Trash only; no permanent delete tool exists |
| Dynamic client registration | Not applicable | Not supported | Not assessed here | Yes, stateless OAuth 2.1 with PKCE |
| Setup effort | None | Programme enrolment and an OAuth client flagged for AI agents (enforced from 11 November 2026) | Your own Google project plus a local or hosted install | Your own Google project plus a Vercel deploy |
| Breadth of Google products | Drive and Gmail | Drive and Gmail | Better: 120+ tools across twelve Google products | Drive and Gmail only, by design |
| Hosting | Anthropic | Local or self-hosted | Self-hosted (Vercel) |
If you need Docs editing, Sheets formulas or Calendar, use google_workspace_mcp, and consider running both. If you want Claude to read and draft in one Google account, the built-in connectors are the least work, and if the reported multi-account rollout reaches you, the same may soon be true for a few accounts. Crossdrive is for people who want per-account rules enforced on a server they run, operations between accounts, or a connection that is not tied to one AI app.
Features
Every account under a label. Label each account yourself (^[a-z][a-z0-9-]{0,23}$) and connect as many as you like.
Paths are label:/path for My Drive, label:~shared/Folder/... for folders shared with the account, and
label:drive/<Shared Drive name>/... for Shared Drives. Every result carries owner, shared and canEdit; shared
means "owned by someone else and reached through sharing", not "this file has collaborators". Unknown arguments are
rejected with a "did you mean" hint, and tools that create or place something need an explicit destination.
Search and organise. find searches every Google account in parallel with timeouts and paging; an account that fails shows
up as an error entry and the response is marked partial rather than returning less without saying so. Also list,
tree, duplicates (including across accounts), changes (what changed in the last 24 hours or 7 days) and inbox.
Move things between accounts. copy copies files and whole folder trees between accounts in resumable slices:
with Drive's server-side copy when the source account is writable, and by streaming through your deployment when it is
read-only, so a read-only account is never modified. batch applies up to 100 moves, renames, trashes and copies with a dry-run preview and a
single batch id. undo reverses a move, rename, trash or untrash using the audit log.
Gmail. Search, read (bodies as plain text, never raw HTML), label, archive, trash, draft, reply, and save attachments straight into Drive. Sending is off by default and can be limited to an allowlist of recipients.
Large files. upload_begin returns a pre-authorised Drive upload URL so the bytes go from your computer straight to
Google. scripts/bulk-upload.mjs mirrors a local folder into a drive with skip-if-exists and resume.
Control from any browser. The connect page lets you flip an account between read-only and write, change its mail mode, reconnect it, disconnect it (which revokes the token at Google) or disconnect everything.
Per-client consent. Each MCP client that connects sees a consent screen naming the client and its redirect host, and can be downgraded to read-only. This is the MCP specification's answer to the confused-deputy problem. The approval is bound to the browser that was shown the screen (a short-lived cookie), so approve in the same browser, with cookies enabled for your Crossdrive site. (In 1.0.0 the Approve button failed in Chrome with "Consent must be given from this site"; fixed in 1.0.1.)
BETA: OneDrive and Dropbox. Microsoft Graph and Dropbox accounts can sit under the same labels. transfer copies or
moves files and folder trees between any two accounts across providers, resumable and verified by size or hash, with the
source trashed only after verification. This part has not yet been tested against live Microsoft or Dropbox accounts;
it is tested against in-memory fakes of their APIs only. Treat it as beta, run it on copies first and read
docs/providers.md.
Tools
44 tools. Full reference with arguments: docs/tools.md. Most write tools accept dryRun; tools.md lists
which do not. The Drive, Gmail and sharing tools work on Google accounts; the cloud_* tools and transfer are BETA,
not yet tested against live OneDrive or Dropbox accounts.
| Tool | Access | What it does |
|---|---|---|
accounts | read | Connected accounts with provider, email, storage (Google), mode and mail mode |
status | read | Token health per account: whether the refresh token still works, granted scopes, mode, mail mode |
drives | read | Shared Drives an account belongs to, with their label:drive/<name> paths |
find | read | Search all Google accounts or one; per-account errors, partial, timeouts, paging |
list | read | One level of a folder |
tree | read | A folder tree to a given depth with counts and sizes |
shared | read | Items other people have shared with an account |
read | read | File content as text, wrapped as untrusted data |
inbox | read | Loose files in the root and in the configured inbox folder |
permissions | read | Who has access to a file |
duplicates | read | Duplicate groups within or across accounts, with a suggested keeper |
changes | read | Files modified since a time, across accounts |
audit | read | Recent write-log entries |
mkdir | write | Create a folder (idempotent) |
put | write | Upload small content, or stream a web file into Drive |
upload_begin, upload_finish | write | Pre-authorised large upload from the client's machine |
move, rename | write | Move or rename within an account |
trash, untrash | write | Trash is the only delete |
undo | write | Reverse a move, rename, trash or untrash from the audit log |
copy | write | Copy files or folder trees, within or across accounts, resumable |
batch | write | Up to 100 operations with dry-run and one batch id |
share, unshare, transfer_ownership | write | Sharing changes, each audited with email and role |
shortcut | write | Create a Drive shortcut |
mail_search, mail_read, mail_labels, mail_attachment | read | Gmail search, read, label list, attachment text |
mail_draft | write | Create a draft; nothing is sent |
mail_send, mail_reply | write | Send or reply; only for accounts whose mail mode is send |
mail_label | write | Label, archive, trash, mark read; no permanent delete |
transfer (beta) | write | Copy or move files and trees between any two accounts, across providers |
cloud_list, cloud_find, cloud_read (beta) | read | List, search and read on OneDrive and Dropbox accounts |
cloud_mkdir, cloud_move, cloud_rename, cloud_trash (beta) | write | Write operations on OneDrive and Dropbox accounts |
Safety model
Safety is enforced by the server, not requested of the model. Annotations such as readOnlyHint are set honestly but
are never relied on.
- No permanent delete. No tool exists for it and no Gmail scope that allows it is requested. Trash is recoverable.
- Read-only accounts cannot reach a write tool at all: the tool is refused in code before Google is called. Every
write reads the account's mode and mail mode fresh from storage, so a switch on the connect page (or a disconnect)
applies to the very next call on every server instance. A read-only account can still be the source of a
cross-account copy, and it is only read: the file is streamed through the server, and no permission is added to it.
Before 1.0.1 it was not: the source got a temporary writer share. Writable sources share one file at a time, as
reader, and every grant and removal is audited. An expiry is set on that grant only where Google allows it (Google
Workspace); consumer Gmail accounts refuse one, so there the protection is the immediate removal plus the leftover
listing in
status(details). - Unknown arguments are rejected. A misnamed argument is an error that names it and suggests the right one, never
silently ignored, and
mkdir,move,copyandupload_beginneed an explicit destination. (In 1.0.0mkdirwithpathinstead ofparentPathcreated the folder at the My Drive root.) - Mail modes per account:
off,draftorsend. New accounts start atdraft. Send can be restricted withCROSSDRIVE_MAIL_ALLOWED_RECIPIENTS. The sender is never inferred. - Untrusted content. File and mail content is returned wrapped and labelled as data, URLs found inside documents are never fetched, and no forwarding filters can be created.
- Dry run and undo. Most write tools accept
dryRun(which ones);batchandtransferpreview by default;undoreverses moves, renames, trashes and untrashes. - Audit. Append-only, actions only, never bodies or tokens (mail entries carry recipients and subject).
- Revocation. Disconnect an account (token revoked at Google or Dropbox; Microsoft offers no per-token revoke) or everything, from the connect page.
- Tokens. Encrypted at rest; read-only static tokens for scripts; OAuth artefacts are signed JWTs, so rotating
CROSSDRIVE_JWT_SECRETinvalidates every issued token.
The threat model and what is deliberately not built: docs/security.md.
About the Google "unverified app" screen
Because you create the OAuth client in your own Google Cloud project, Google treats it as your own app.
- Google Workspace users: set the OAuth consent screen user type to Internal. Members of your organisation never see a warning. Workspace admins can still block third-party apps, in which case see the troubleshooting section of the setup guide.
- Personal Gmail users: the consent screen type has to be External. You will see "Google hasn't verified this app" once per account, for your own app. Click Advanced, then Go to (your app name) (unsafe). Nothing is wrong; you are the developer.
- Publish to Production. While an External app is in Testing mode Google expires its refresh tokens after 7 days, so your connections would silently die weekly. Publishing to Production removes that. You do not need to submit for verification for your own use.
- Why there is no shared, verified Crossdrive client yet. Drive and Gmail are restricted scopes. A public app using them needs Google's verification and an annual third-party security assessment (CASA), and until then is capped at 100 users. Self-hosting avoids all of that and keeps your tokens in your own account. A verified hosted option is on the roadmap; the groundwork is in docs/google-verification/.
Connecting clients
Your MCP endpoint is <your URL>/api/mcp.
These steps follow each client's documentation. Of these apps, only the Claude desktop app has been used against a live Crossdrive instance so far (see What has been tested); if one does not work, please open an issue.
-
Claude on the web and desktop: Settings, Connectors, Add custom connector, paste the URL. Claude discovers the OAuth server, signs you in with an allowed email and shows you Crossdrive's consent screen; click Approve. Claude's mobile apps use connectors added on the web or desktop.
-
Claude Code:
claude mcp add --transport http crossdrive https://YOUR-DEPLOYMENT.vercel.app/api/mcpthen run
/mcpinside Claude Code to finish the browser login. -
ChatGPT: add a custom MCP connector (developer mode) with the same URL and OAuth. Connector availability depends on your ChatGPT plan.
-
Other clients: send
Authorization: Bearer <token>with a value fromCROSSDRIVE_STATIC_TOKENS(full access) orCROSSDRIVE_READONLY_TOKENS(read tools only). For stdio-only clients usemcp-remote:{ "crossdrive": { "command": "npx", "args": ["-y", "mcp-remote", "https://YOUR-DEPLOYMENT.vercel.app/api/mcp", "--header", "Authorization: Bearer ${CROSSDRIVE_TOKEN}"] } }
Configuration
Copy .env.example. The legacy VAULT_ prefix is still accepted for every CROSSDRIVE_ variable.
| Variable | Purpose |
|---|---|
GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET | Your Google OAuth client |
CROSSDRIVE_JWT_SECRET | Signs OAuth artefacts; rotating it revokes every issued token |
CROSSDRIVE_ENC_KEY | 32 random bytes, base64; encrypts stored refresh tokens |
CROSSDRIVE_ALLOWED_EMAILS | Comma-separated emails allowed to sign in and administer |
CROSSDRIVE_BASE_URL | Public URL of the deployment. Optional on Vercel, where it defaults to the production domain; set it for a custom domain or when hosting elsewhere |
CROSSDRIVE_STATIC_TOKENS, CROSSDRIVE_READONLY_TOKENS | Optional bearer tokens for scripts and other clients |
CROSSDRIVE_MAIL_ALLOWED_RECIPIENTS | Optional allowlist of recipients for mail_send and mail_reply |
CROSSDRIVE_NAMING_RULE | date-entity enforces YYYY-MM-DD_Company_WhatItIs.ext on uploads and renames; default off |
CROSSDRIVE_INBOX_FOLDER | Name of the inbox folder put defaults to and inbox reports |
CROSSDRIVE_OPERATOR, CROSSDRIVE_CONTACT | Name and contact shown on the privacy and terms pages |
MS_CLIENT_ID, MS_CLIENT_SECRET, MS_TENANT | OneDrive (BETA, not yet tested against live accounts); MS_TENANT is optional, default common |
DROPBOX_CLIENT_ID, DROPBOX_CLIENT_SECRET | Dropbox (BETA, not yet tested against live accounts) |
BLOB_READ_WRITE_TOKEN | Set by the Vercel Blob store |
Limits and non-goals
- Copy method. Cross-account copies from a read-only account are streamed through your Vercel function: the bytes pass through it and count against its run time and bandwidth.
- Google-native files from a read-only account. Docs, Sheets and Slides are exported to docx, xlsx or pptx and imported back; comments, revision history and some formatting are lost. Forms, Sites, Drawings and Maps are not copied, and shortcuts are skipped. (Not yet observed live except for shortcuts.)
- Writable sources. Cross-account copies from a writable account briefly add a reader permission for your other
account on each file, which changes the file's
modifiedTime. On consumer Gmail accounts Drive refuses an expiry on that permission, so if its removal failed it would have no time limit. Removal failures are reported and listed bystatus. - Speed. A cross-account copy from a writable source takes about 3 to 4 seconds per file. Large folders need many
calls: a client must keep following the
resume(orcursor) value untildoneis true. - Comments and history. Drive's server-side copy never copies comments or revision history, with either method.
- Fresh paths. For a few minutes after a folder is moved, results from other server instances can still show the old path, and path lookups of just-moved items can briefly fail. Use ids for follow-up calls right after moving folders.
- Argument names differ between tools.
mkdirtakesparentPath,putandlisttakepath,moveandcopytaketoPath. An unknown argument is rejected with the accepted names, so a client can correct itself. - New accounts start read + write with mail as drafts. Set a work account read-only on its card immediately after connecting it.
- Admin session. The
/connectsign-in lasts one hour. Each additional Google account must be signed in to the same browser to connect it. sharedflag.sharedon a result means "owned by someone else and visible through sharing", not "this file has collaborators".- Drive and Gmail only on Google. No Docs editing, Sheets formulas, Calendar or Chat; use another server for those.
- One owner per deployment. It is not a multi-tenant hosted service.
- Folder copy runs in slices (the client follows a resume cursor) because serverless requests are time-limited.
putwith inline content is for small files because Vercel limits request bodies to about 4.5 MB; useupload_beginorsourceUrlfor anything bigger.- Scanned PDFs without a text layer are not read; there is no OCR and none is planned.
- Never built: permanent delete, forwarding filters, fetching URLs found inside documents.
- OneDrive and Dropbox support is BETA and not yet tested against live accounts.
- Crossdrive is not a backup tool or a bulk migration service; rclone and similar tools are better at that.
Roadmap
Not promises, in rough order of interest:
- A rules engine on the changes feed ("anything landing in the inbox that matches X goes to Y with name Z").
- Local stdio and Docker mode for people who do not want remote hosting.
- Folder-scoped tokens (a token confined to one subtree).
- A verified hosted option, if there is demand and the verification work is worth it.
- Promote OneDrive and Dropbox out of beta once they have been tested against live accounts.
- OCR is not planned.
Contributing
Issues and pull requests are welcome. Read CONTRIBUTING.md first; CLAUDE.md describes the architecture and the invariants a change must not break. Report security problems privately as described in SECURITY.md. Release notes: docs/CHANGELOG.md.
Licence
MIT, copyright Crossdrive contributors.