Google Drive via gogcli for Claude — search, upload, download, permissions
Runs on your machine from its package; the steps are below.
At most: moves money, runs code or commands, deletes data, or sends messages for you.
Odel charges nothing per call. The publisher may charge for its own service.
Runs locally over stdio
This server isn't hosted — your MCP client launches it from a package registry. Use one of the commands below, or drop the config into your client (e.g. Claude Desktop).
Run
npx -y gogcli-mcp-drive
MCP client config
{
"mcpServers": {
"gogcli-drive": {
"command": "npx",
"args": [
"-y",
"gogcli-mcp-drive"
]
}
}
}A monorepo of Model Context Protocol servers that give Claude natural-language access to Google Workspace via gogcli.
Warning
AI-developed project. This codebase was built and is actively maintained by Claude. Review all code and tool permissions before use.
| Package | Tools | Description |
|---|---|---|
| gogcli-mcp | 52 | All services — Sheets, Docs, Gmail, Calendar, Drive, Tasks, Contacts, Auth |
| gogcli-mcp-sheets | 35 | Auth + full Sheets (base + 22 extra: tabs, formatting, named ranges, etc.) |
| gogcli-mcp-docs | 26 | Auth + full Docs (base + 14 extra: insert, export, sed, comments, etc.) |
Each package is a standalone MCP server. Install whichever one fits your needs — you don't need to install more than one.
By using this MCP server, you acknowledge and agree to the following:
1. This server accesses your own Google Workspace data via Google's official APIs (Gmail, Calendar, Drive, Sheets, Docs, Contacts). Auth happens via OAuth, with your explicit consent at each scope. It does not — and cannot — access anyone else's Google account or shared content you don't have permission to read.
2. Google's APIs Terms of Service govern your use of this server, in addition to any Google Workspace Acceptable Use Policy your domain admin enforces. The clauses most relevant here:
Google sets and enforces limits on your use of the APIs (e.g. limiting the number of API requests that you may make or the number of users you may serve), in our sole discretion.
And on credentials, which is the most-tripped-on clause for open-source projects:
You will keep your credentials confidential and make reasonable efforts to prevent and discourage other API Clients from using your credentials. Developer credentials may not be embedded in open source projects.
You are agreeing to those terms — read by the maintainer 2026-05-23 — every time you invoke a tool in this server.
3. You must configure your own OAuth client. This MCP does not ship an embedded client_secret.json. You register your own OAuth client at https://console.cloud.google.com/, scope it to your own user/project, and authorize it for the Workspace APIs you want to use. Do not check client_secret.json, credentials.json, or any refresh tokens into git — these are credentials and Google's ToS explicitly prohibits embedding them in OSS.
4. Personal, single-user use only. This project is not affiliated with, endorsed by, sponsored by, or in partnership with Google LLC. It is a personal automation tool for one Google account holder to read and write their own Workspace content. Do not use it to bulk-extract Workspace data from your org, automate against other users' accounts, or build a multi-tenant SaaS on top of it. If you want to do those things, you need a verified app, a domain-wide-delegation service account, and a Workspace admin's blessing — none of which this MCP provides.
5. Your domain admin's policy may add restrictions. If you're using a corporate Google Workspace account, your admin may restrict third-party OAuth apps, prohibit data exfiltration, or require app verification. Check with your IT admin before authorizing this MCP against a corporate domain.
6. You accept full responsibility for any consequences of using this server in connection with your Google account — quota exhaustion (Gmail and Drive APIs have aggressive per-user quotas), token revocation, account warnings, your domain admin emailing you, or any enforcement action. If Google or your domain admin objects to your use, stop using this server.
This section is the maintainer's good-faith summary of the terms — it is not legal advice and does not modify or supersede Google's actual APIs ToS or your domain's policies.
gogcli is the CLI that these MCP servers wrap. Install it for your platform:
macOS (Homebrew):
brew install steipete/tap/gogcli
macOS / Linux (binary):
curl -fsSL https://github.com/openclaw/gogcli/releases/latest/download/gog-$(uname -s | tr '[:upper:]' '[:lower:]')-$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/') -o /usr/local/bin/gog
chmod +x /usr/local/bin/gog
Windows (Scoop):
scoop bucket add steipete https://github.com/steipete/scoop-bucket
scoop install gogcli
Windows (manual):
Download gog-windows-amd64.exe from the latest release, rename to gog.exe, and add to your PATH.
gog auth add your@gmail.com
This opens a browser for Google OAuth. For specific services only:
gog auth add your@gmail.com --services sheets,docs,drive
Node.js 22 or later is required. Install via nodejs.org or:
brew install node # macOS
# Install the package you want
npm install -g gogcli-mcp # base
npm install -g gogcli-mcp-sheets # extended sheets
npm install -g gogcli-mcp-docs # extended docs
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"gogcli": {
"command": "gogcli-mcp",
"env": {
"GOG_ACCOUNT": "you@gmail.com"
}
}
}
}
Replace gogcli-mcp with gogcli-mcp-sheets or gogcli-mcp-docs for extended packages.
claude mcp add gogcli -- gogcli-mcp
Ask Claude things like:
All tools accept an optional account parameter:
Read Sheet1!A1:D10 from spreadsheet abc123 using my work account work@company.com
Tools that read or write files on the machine gog runs on (attach, localPath, file, out, export and
download paths) only accept paths inside the directories listed in GOG_FILE_ROOTS — a :-separated list
(; on Windows). Unset, it defaults to ~/gogcli-mcp-files: put files you want to attach or upload there, and
point exports and downloads there. Widen it deliberately (for example to your home directory) if you need to:
"env": { "GOG_ACCOUNT": "you@gmail.com", "GOG_FILE_ROOTS": "/Users/you/Documents:/Users/you/Downloads" }
attachInline / content carry file bytes with the request and are not affected.
The escape hatches are bound by the same roots: a path flag passed through gog_<service>_run (--out,
--out-dir, --attach, --file, any --*-file, an @file JSON input) must be inside GOG_FILE_ROOTS, and
gog_api_call's @file body likewise. Subcommands that take a local path positionally (drive upload,
drive sync, gmail import, appscript pull, slides add-slide / insert-image / replace-slide) are refused
there — use their dedicated tools.
Tools that reach another person, grant access, run code, bill a project or delete for good ask the user to confirm a preview first, through an MCP elicitation prompt. The preview names what is acted on — the file, event, class, student, spreadsheet or messages — rather than an opaque id:
| Service | Tools | Asks when |
|---|---|---|
| Gmail | gog_gmail_send, _reply, _reply_all, _forward, _autoreply, _drafts_send | always |
| Chat | gog_chat_messages_send, gog_chat_dm_send | always |
| Drive | gog_drive_share | always (granting access is the risk; gog sends no share email by default) |
| Classroom | gog_classroom_announcements_create | unless state is DRAFT with no scheduled time (students cannot see drafts; a scheduled one publishes itself) |
| Classroom | gog_classroom_invitations_create | always |
| Calendar | gog_calendar_create | only with attendees (the event lands on their calendars; no invitation email is sent) |
| Calendar | gog_calendar_update | only for a change guests can see, on an event that has or gains guests (reminder-only changes never ask) |
| Calendar | gog_calendar_respond | always (the organizer sees it) |
| Calendar | gog_calendar_delete | only when the event has guests or recurs (gog deletes the whole series by default) |
| Calendar | gog_calendar_move | only with sendUpdates all or externalOnly (Google emails the guests) |
| Calendar | gog_calendar_out_of_office | unless autoDecline is none (gog's default declines every conflicting meeting and notifies its organizer) |
| Calendar | gog_calendar_delete_calendar | always (the calendar and every event on it) |
| Chat | gog_chat_spaces_create | only with members (they are added and notified) |
| Classroom | gog_classroom_students_add | unless userId is me |
| Classroom | gog_classroom_teachers_add | always (a co-teacher sees every student's work) |
| Classroom | gog_classroom_coursework_create | unless state is DRAFT with no scheduled time |
| Classroom | gog_classroom_submissions_return | always (the student is notified and sees the grade) |
| Classroom | gog_classroom_courses_delete, gog_classroom_coursework_delete | always (submissions go with them) |
| Drive / Docs | gog_drive_comments_add, _reply, gog_docs_comments_add, _reply | always (the owner, the thread and anyone +mentioned are notified) |
| Drive | gog_drive_delete | only with permanent: true (moving to trash never asks) |
| Gmail | gog_gmail_batch_delete | only with force: true (the messages bypass Trash) |
| Gmail | gog_gmail_vacation_update | only with enable (the auto-reply goes to every sender in scope) |
| Gmail | gog_gmail_sendas_create | always (Google emails the address; the account gains a sending identity) |
| Sheets | gog_sheets_datasource_add, _update, _refresh | always (each starts a BigQuery job billed to the billing project) |
| Apps Script | gog_appscript_run_function | always (arbitrary code with the account's authority) |
| Classroom | gog_classroom_announcements_update, gog_classroom_coursework_update | only when publishing: state PUBLISHED or a scheduled time |
| API | gog_api_call | every write that is sent (allowWrite without dryRun); the prompt shows the exact api/version/method/params/body |
A Gmail forwarding filter (gog_gmail_filters_create with forward) asks too, but never takes the fallback below.
Some clients, claude.ai chat and Claude Desktop among them, cannot show the prompt. There, by default, these
tools use a two-step flow instead. MCP_CONFIRM_MODE (the same setting every chrischall MCP server uses) decides
what happens:
MCP_CONFIRM_MODE | On a client that cannot show a prompt |
|---|---|
ask-user (default) | Two steps (below). The first call returns the preview and a token, and tells the model to show it to you and continue only after you approve in chat. |
auto | The same two steps, but the model may use the token after reviewing the preview itself. |
refuse | Refused ("reason": "confirmation-unsupported"). |
A client that can show prompts (Claude Code) always gets the real prompt, whatever the mode, unless
MCP_CONFIRM_ELICITATION=off (below). An unrecognised
value is treated as refuse.
confirmToken. Nothing is sent or changed. It returns
"status": "confirmation-required", the full preview, a confirmToken, and the instruction to show the preview
to the user verbatim and go ahead only after they approve in chat. For mail the preview has from, to, cc, bcc,
subject, the complete body, attachment names and sizes, threadId and In-Reply-To (a draft also shows its draftId
and messageId). A share names the file, grantee and role. An announcement or invitation names the class. A
calendar change shows the event as it stands and what changes.confirmToken. It re-reads the draft,
message, file, course or event, and acts only if that still matches what the token was issued for.A token is an HMAC-SHA256 over the tool, account, target, the target's version (a draft's messageId, an event's etag) and a SHA-256 of the payload. For mail the payload is the recipients, subject, text and HTML body, attachment names and sizes (plus a content hash for files you pass in), and In-Reply-To/References. The token is single-use and expires after 10 minutes. Anything else sends nothing and returns an error:
| error | meaning |
|---|---|
DRAFT_CHANGED | what would happen changed: a draft was edited or re-saved (its messageId rotated, which mail clients such as Apple Mail do on every save), an event was edited elsewhere (its etag rotated), or the payload differs. The result carries the new preview and a fresh token for the user to re-approve. |
TOKEN_EXPIRED | older than the TTL |
TOKEN_REUSED | already used: one approval acts once |
TOKEN_INVALID | tampered, issued for a different tool, account or target, or issued before a server restart |
| variable | default | |
|---|---|---|
MCP_CONFIRM_MODE | ask-user | see the table above |
MCP_CONFIRM_ELICITATION | on | off never sends a confirmation prompt, so every client gets the MCP_CONFIRM_MODE path. Set it for a client that declares it can show prompts but never does (the gated call hangs — opencode 2.0.x). A gate with no token fallback (such as a Gmail forwarding filter) is refused instead. Any other value stays on, with a stderr warning. |
MCP_CONFIRM_TTL_SECONDS | 600 | token lifetime |
MCP_CONFIRM_SECRET | random per process | HMAC key; set it only if tokens must survive a server restart. Used tokens are remembered in memory, per process, so with a fixed secret a token that was already used is accepted again after a restart (or by another instance with the same secret) until it expires. Leave it unset unless you need that. |
What this does not do. With elicitation, the host asks the user and the model never sees the approval. With the fallback, the approval is a tool argument, so the check that the user really approved is the model following the instruction. The token makes sure what happens is exactly what was previewed, and that it happens once, for that one tool, account and target. It cannot prove a human said yes. That is why the fallback is opt-in.
npm install # install all workspace dependencies
npm run build # build all packages
npm test # test all packages (100% coverage gate)
npm run typecheck # typecheck all packages
--no-input to prevent interactive promptschild_process.spawn — no shell injection riskGOG_ACCESS_TOKEN is stripped from the child process environment to prevent stale token authGOG_FILE_ROOTS (resolved through symlinks), in the structured tools and the escape hatches alike, so a prompt-injected agent cannot attach ~/.ssh or gog's own credentials to an email, or write attachment bytes over ~/.zshrc; escape-hatch flags that make gog run a local command (--on-change, --on-new, --mmdc) are refusedgog_<service>_run, gog_api_call) refuse args that would override safety flags (--readonly=false, --disable-commands=, --account, a bare --, …); gog_auth_run cannot export tokens or remove an accountgog_<service>_run under each of gog's aliases and flag spellings for it — gog_docs_run, gog_sheets_run and gog_appscript_run included — and the ones that notify, grant access or run code are refused by gog_api_call as the raw API method. gog_<service>_run also refuses changes it cannot preview (drive bulk permission rewrites, drive unshare, calendar decline via propose-time, auto-declining focus time, guardian invitations, publishing Classroom materials, widening assignees), and every other gog_api_call write asks the user to confirm the exact method and payload firstgog_api_call write (the full list). On a client without elicitation, a two-step preview and a single-use token take the place of that prompt (MCP_CONFIRM_MODE: ask-user by default, auto or refuse) (details). A forwarding filter never takes that pathMIT