A fully local bridge between your AI agent and your documents — wherever they live. Google Drive, Sheets, Docs, BigQuery, Gmail, Notion, Slack, Telegram, Cloudflare, GitLab.
Tells Claude Code where to find your data and how to access it, without exposing anything to the network. No hosted service, no open ports, no HTTP server. Just a local process talking to Claude over stdio, with credentials locked in macOS Keychain.
Claude Code can't see your private data — Drive files, Notion pages, Slack messages, BigQuery tables. Existing solutions often involve hosted proxies or browser extensions. This is different:
- Fully local — stdio transport, no listening ports, no server to expose
- Credentials in Keychain — encrypted at rest, locked when your Mac is locked, never in config files or env vars
- Direct API calls — your machine talks to Google/Notion/Slack directly, no middleman
- Read-only by default — service accounts and tokens use minimal permissions
What it does:
- Search across all connected sources with one tool call
- Read any document, spreadsheet, page, or chat by ID
- Query BigQuery and Cloudflare D1 with SQL
- Check & send email via Gmail
| Source | Auth method | What you get |
|---|---|---|
| Google Drive | Service Account | Search files, read Docs & Sheets |
| Google Sheets | Service Account | All tabs with headers and data |
| BigQuery | Service Account | SQL queries, explore datasets/tables/schemas |
| Gmail | OAuth2 refresh tokens | Search inbox, read emails, send emails |
| Notion | Integration token | Search pages, read page content |
| Slack | Bot/User token | Search messages, read channel history |
| Telegram | Client API (MTProto) | Search messages, read chats |
| Cloudflare | API token | Zones, Workers, Pages, D1, KV, R2 |
| GitLab | Personal Access Token | Projects, merge requests, issues, diffs |
git clone https://github.com/Chill-AI-Space/gated-docs.git
cd gated-docs
npm installRequires Node.js 22+ (uses native TypeScript via --experimental-strip-types).
node --experimental-strip-types bin/gated-docs.ts setupThis writes the MCP config to ~/.claude.json. Restart Claude Code to pick it up.
Pick any source below and run the auth command. You can connect as many as you need.
node --experimental-strip-types bin/gated-docs.ts scanBuilds structure.json — an index of all your documents, tables, and channels. This powers the dynamic tool descriptions so Claude knows what data is available.
The server also auto-scans on startup if the structure is stale.
Restart Claude Code. The MCP tools are now available — Claude will call them automatically when you ask about your data.
What you need: A Google Cloud service account key (JSON file).
Step-by-step setup
- Create a Google Cloud project (free)
- Enable APIs: Drive, Sheets, Docs — via API Library
- Create a Service Account → Keys tab → Create new key → JSON
- Share your Google Drive folders with the service account email (Viewer access)
Detailed walkthrough: docs/google-setup.md
node --experimental-strip-types bin/gated-docs.ts auth google --service-account ~/Downloads/key.jsonAfter auth, you can delete the key file — it's stored in Keychain.
Uses the same Google service account. Grant it IAM roles:
gcloud projects add-iam-policy-binding YOUR_PROJECT \
--member="serviceAccount:SA_EMAIL" \
--role="roles/bigquery.user"
gcloud projects add-iam-policy-binding YOUR_PROJECT \
--member="serviceAccount:SA_EMAIL" \
--role="roles/bigquery.dataViewer"Enable the API: BigQuery API
Gmail uses OAuth2 with refresh tokens — one-time browser consent, then permanent access. No admin needed, works with personal Gmail and Workspace.
Two separate tokens for least privilege: read-only and send.
- Enable Gmail API
- Create OAuth Client ID → Desktop app → download JSON
- Connect read access:
node --experimental-strip-types bin/gated-docs.ts auth gmail --client-secret-file ~/Downloads/client_secret_*.json- (Optional) Connect send access — reuses the same client credentials:
node --experimental-strip-types bin/gated-docs.ts auth gmail --sendEach step opens a browser for one-time consent. Refresh tokens stored permanently in Keychain.
- Create an integration → copy the token (
ntn_...) - In Notion, share databases/pages with the integration
node --experimental-strip-types bin/gated-docs.ts auth notion --token ntn_xxxx- Create a Slack app → From scratch
- OAuth & Permissions → add scopes:
- Bot:
channels:read,channels:history - User (for search):
search:read
- Bot:
- Install to workspace → copy the token
node --experimental-strip-types bin/gated-docs.ts auth slack --token xoxb-xxxx- Get
api_idandapi_hashfrom my.telegram.org → API development tools - Run auth (interactive — you'll receive a code via Telegram):
node --experimental-strip-types bin/gated-docs.ts auth telegram --api-id 12345 --api-hash abc123- Create an API token with Custom template
- Permissions (all Read): Zone, DNS, Workers Scripts, Pages, D1, Workers KV Storage, R2
node --experimental-strip-types bin/gated-docs.ts auth cloudflare --token cf-xxxxWorks with gitlab.com and self-hosted GitLab instances.
- Go to your GitLab → User Settings → Access Tokens (or
/-/user_settings/personal_access_tokens) - Create a token with scopes:
read_api,read_repository
# gitlab.com
node --experimental-strip-types bin/gated-docs.ts auth gitlab --token glpat-xxxx
# Self-hosted
node --experimental-strip-types bin/gated-docs.ts auth gitlab --token glpat-xxxx --url https://gitlab.example.comClaude can then search and read your projects, merge requests (with full diffs and comments), and issues.
Once connected, Claude Code gets these 8 tools:
| Tool | Description |
|---|---|
search |
Full-text search across all sources, or filter by source |
read_document |
Read a document, spreadsheet, page, channel, or resource by ID |
list_sources |
Show connected sources and all indexed documents |
bigquery_query |
Run SQL against BigQuery, get tab-separated results |
bigquery_explore |
List datasets, tables, schemas, or running jobs |
d1_query |
Run SQL against Cloudflare D1 (SQLite syntax) |
check_email |
Search Gmail inbox, read full emails, find verification codes |
send_email |
Send an email via Gmail (requires auth gmail --send) |
Tool descriptions are dynamically generated from your scan data — Claude sees exactly what documents, tables, and schemas are available.
Once the MCP is connected, just ask Claude in natural language:
"Find the Q1 marketing report in Drive and summarize it"
"What tables do we have in BigQuery? Show me the schema for the events table"
"Check my email for the verification code from GitHub"
"Search Slack for messages about the deploy issue yesterday"
"Read the project roadmap from Notion"
"Show me the DNS records for example.com on Cloudflare"
"Read my last merge request on GitLab and prepare responses to the review comments"
"Send an email to john@example.com about the meeting tomorrow"
Claude will call the right MCP tools automatically.
All commands:
gated-docs setup # Register MCP in ~/.claude.json
gated-docs auth google --service-account <key.json> # Connect Google Drive/Sheets/Docs
gated-docs auth notion --token <ntn_xxx> # Connect Notion
gated-docs auth slack --token <xoxb-xxx> # Connect Slack
gated-docs auth telegram --api-id <N> --api-hash <hash> # Connect Telegram
gated-docs auth cloudflare --token <cf-token> # Connect Cloudflare
gated-docs auth gitlab --token <pat> [--url <url>] # Connect GitLab (self-hosted or gitlab.com)
gated-docs auth gmail --client-secret-file <json> # Connect Gmail read (OAuth2)
gated-docs auth gmail --send # Connect Gmail send (reuses client creds)
gated-docs scan # Rebuild document index
gated-docs status # Show connections & stats
gated-docs search "query" # Test search from terminal
gated-docs check-email [query] # Test email from terminal
gated-docs deauth <source> # Remove credentialsRun via:
node --experimental-strip-types bin/gated-docs.ts <command>┌─────────────────────────────────────────────────────────┐
│ Your machine (everything runs here) │
│ │
│ Claude Code ──stdio──> gated-docs (local process) │
│ │ │
│ structure.json (doc index) │
│ macOS Keychain (credentials) │
│ │ │
└──────────────────────────────┼──────────────────────────┘
│ HTTPS (outbound only)
▼
Google · Notion · Slack · Telegram · Cloudflare · GitLab
- Auth stores credentials in macOS Keychain (base64-encoded for JSON values)
- Scan calls each connector to index documents → saves
structure.json - MCP server loads the structure at startup, generates dynamic tool descriptions
- Search uses native APIs per source (Drive fulltext, Notion search, Slack search, Telegram global search)
- Read fetches full content via the appropriate API
- Connectors are lazy-imported on first call — fast startup even with many sources
No inbound connections. The only network traffic is outbound HTTPS to the services you've connected.
| Path | Purpose |
|---|---|
~/.config/gated-docs/config.json |
Enabled sources and settings |
~/.config/gated-docs/structure.json |
Scan output (document index, schemas) |
macOS Keychain (gated-docs-*) |
All credentials |
~/.claude.json |
MCP server registration |
The entire security story is: local process + OS-level credential storage.
- stdio transport — the server is a child process of Claude Code, communicating over stdin/stdout. There is no HTTP server, no open port, nothing reachable from the network
- macOS Keychain — all credentials (service account keys, OAuth tokens, API tokens) are stored encrypted in Keychain. They're locked when your Mac is locked and never written to config files, env vars, or disk
- Minimal permissions — service accounts use read-only access, Gmail uses separate tokens for read vs. send (least privilege)
- No intermediaries — API calls go directly from your machine to Google/Notion/Slack/etc. No proxy, no hosted backend, no telemetry
- No vector DB, no embeddings — search uses native APIs per service (Drive fulltext, Notion search, Slack search). Nothing is indexed locally beyond a lightweight
structure.jsonwith document names and schemas
- macOS (uses Keychain for credential storage)
- Node.js 22+ (native TypeScript support)
- Claude Code (MCP client)
"403 Forbidden" — API not enabled or SA doesn't have access:
- Check API is enabled: APIs & Services
- Check file/folder is shared with the service account email
- For BigQuery: check IAM roles are granted
"Key creation is not allowed" — Org policy blocks SA key creation:
gcloud resource-manager org-policies delete iam.disableServiceAccountKeyCreation --project=YOUR_PROJECT"Token expired" for Gmail — Re-auth with OAuth2:
node --experimental-strip-types bin/gated-docs.ts auth gmail --client-secret-file ~/Downloads/client_secret_*.jsonBigQuery "Access Denied" — SA needs project-level roles. See BigQuery setup.
More details: docs/google-setup.md
MIT