gdrive-mcp-server
by devinxiong97
README.md
# Personal Google Drive — Remote MCP Server
A production-style **remote [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server** that connects an MCP-compatible AI assistant to a **Google Drive** account. It runs serverlessly on **Cloudflare Workers**, authenticates users with **Google OAuth 2.0**, and exposes Drive as a small set of safe, well-typed tools the assistant can call.
The interesting part is the auth: this single Worker is **both an OAuth server and an OAuth client at the same time**. It issues tokens to the AI client *and* logs the user into Google — a pattern that shows up in almost every real "connect my app to a third-party API on the user's behalf" integration.
> **New here?** Read the two guides in [`docs/`](docs/):
> - [`docs/SETUP_GUIDE.md`](docs/SETUP_GUIDE.md) — build and deploy it yourself, step by step.
> - [`docs/HOW_IT_WORKS.md`](docs/HOW_IT_WORKS.md) — the concepts (MCP, OAuth, serverless) explained from scratch.
---
## What it does
Once connected, the assistant gains these tools:
| Tool | What it does |
|------|--------------|
| `whoami` | Reports which Google account is connected (a quick sanity check). |
| `list_files` | Lists the most recently modified files. |
| `search_files` | Searches by file name or full-text content. |
| `read_file` | Reads a file by id. Google Docs/Sheets/Slides are exported to text/CSV. |
| `create_file` | Creates a new file from text — including native Google Docs. |
| `update_file` | Replaces a file's contents and/or renames it. |
| `delete_file` | Moves a file to the Drive trash (recoverable, not a hard delete). |
Each tool is a thin, validated wrapper over the Google Drive REST API, called with the signed-in user's access token.
## Architecture at a glance
```
OAuth server OAuth client
┌───────────┐ (issues tokens) ┌──────────────┐ (logs you in) ┌─────────┐
│ AI client │ ◀────────────────▶ │ This Worker │ ◀───────────────▶ │ Google │
└───────────┘ MCP over /sse └──────────────┘ Drive API └─────────┘
│
┌──────┴───────┐
│ Durable Obj │ holds the live MCP session
│ + KV (grants)│ stores OAuth grants/tokens
└──────────────┘
```
1. The AI client connects to `/sse`, finds it protected, and runs an OAuth flow **against this Worker**.
2. The Worker shows a one-time approval screen, then redirects the user to **Google** to sign in and consent.
3. Google redirects back to `/callback`; the Worker exchanges the code for a Google access token and stores it (with the user's name/email) as **encrypted session state**.
4. The MCP tools call the Google Drive API using that token, on the user's behalf.
## Tech stack
- **[Cloudflare Workers](https://developers.cloudflare.com/workers/)** — serverless runtime (deploys globally, scales to zero, free tier).
- **[Durable Objects](https://developers.cloudflare.com/durable-objects/)** — host the stateful MCP session.
- **[Workers KV](https://developers.cloudflare.com/kv/)** — stores OAuth grants.
- **[`@cloudflare/workers-oauth-provider`](https://github.com/cloudflare/workers-oauth-provider)** — turns the Worker into a spec-compliant OAuth server.
- **[`agents` / `McpAgent`](https://www.npmjs.com/package/agents)** — the MCP server framework.
- **[`@modelcontextprotocol/sdk`](https://github.com/modelcontextprotocol)** — the MCP types and server.
- **[Hono](https://hono.dev/)** — tiny router for the `/authorize` and `/callback` endpoints.
- **[Zod](https://zod.dev/)** — runtime validation of every tool's inputs.
- **TypeScript** throughout.
## Repository map
| File | Responsibility |
|------|----------------|
| `src/index.ts` | The MCP server, all Drive tools, and the `OAuthProvider` wiring. |
| `src/google-handler.ts` | The `/authorize` + `/callback` routes that talk to Google. |
| `src/utils.ts` | Google authorize-URL builder and authorization-code → token exchange. |
| `src/workers-oauth-utils.ts` | Signed-cookie approval dialog (reference helper). |
| `wrangler.jsonc` | Worker config: bindings, Durable Object, KV namespace. |
## Quick start
Full instructions live in [`docs/SETUP_GUIDE.md`](docs/SETUP_GUIDE.md). The short version:
```bash
npm install
npx wrangler login
npx wrangler kv namespace create OAUTH_KV # paste the id into wrangler.jsonc
npx wrangler secret put GOOGLE_CLIENT_ID
npx wrangler secret put GOOGLE_CLIENT_SECRET
npx wrangler secret put COOKIE_ENCRYPTION_KEY # value: openssl rand -hex 32
npm run deploy
```
Then add the printed `https://<your-worker>.workers.dev/sse` URL as a custom connector in any MCP-compatible client and sign in with Google.
## Local development
```bash
cp .dev.vars.example .dev.vars # fill in the three values
npm run dev # http://localhost:8788
npx @modelcontextprotocol/inspector@latest # point it at http://localhost:8788/sse
```
## Design notes & limitations
- **Scope is configurable.** The default requests the full `drive` scope so the write tools work. Narrow it to `drive.file` (only files this app creates) or `drive.readonly` in `src/google-handler.ts` to reduce risk.
- **Token lifetime.** Uses Google's short-lived access token (no refresh token yet), so a periodic re-connect is needed. Adding offline/refresh-token support is the natural next enhancement.
- **`read_file` handles text.** Plain-text files and exportable Google formats (Docs/Sheets/Slides) work; arbitrary binary files are out of scope.
- **`delete_file` trashes, it doesn't purge.** Files go to Drive trash and remain recoverable.
## License
MIT
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues