Skip to content

feat: remote deployment mode (Streamable HTTP + MCP OAuth 2.1)#97

Merged
a-bonus merged 4 commits intoa-bonus:mainfrom
Mawox:feat/remote-mode
Mar 27, 2026
Merged

feat: remote deployment mode (Streamable HTTP + MCP OAuth 2.1)#97
a-bonus merged 4 commits intoa-bonus:mainfrom
Mawox:feat/remote-mode

Conversation

@Mawox
Copy link
Copy Markdown

@Mawox Mawox commented Mar 27, 2026

Summary

Adds a remote deployment mode so the server can run centrally on Cloud Run (or any container host) instead of locally via npx. Uses FastMCP's built-in GoogleProvider for MCP OAuth 2.1 authentication -- Cursor handles the entire auth flow automatically.

  • Zero changes to any tool file -- uses AsyncLocalStorage to provide per-request Google API clients transparently
  • Fully backward compatible -- default behavior (stdio + local tokens) is unchanged
  • 3 files changed/added: src/index.ts, src/clients.ts, src/remoteWrapper.ts (new)
  • Landing page at / with English/Czech support (auto-detected from Accept-Language)
  • README refreshed: all 67 tools documented with correct names, remote deployment section added
  • Dockerfile for Cloud Run deployment
  • Updated fastmcp to v3.34.0

New env vars (only for remote mode)

Variable Description
MCP_TRANSPORT=httpStream Enables remote mode (default: stdio)
BASE_URL Public URL for OAuth redirects
ALLOWED_DOMAINS Comma-separated allowed Google Workspace domains

How it works

  1. MCP_TRANSPORT=httpStream activates GoogleProvider + httpStream transport
  2. wrapServerForRemote() monkey-patches server.addTool() to wrap every tool's execute with auth enforcement, domain checking, and per-request client injection via AsyncLocalStorage
  3. Existing getDocsClient() / getSheetsClient() / getDriveClient() check AsyncLocalStorage first, falling back to the singleton for stdio mode
  4. Server is completely stateless -- no token storage, no database

User experience

Users just add a URL to Cursor:

{
  "mcpServers": {
    "google-docs": {
      "type": "streamableHttp",
      "url": "https://your-service.run.app/mcp"
    }
  }
}

Cursor prompts for Google sign-in on first connection. No npx, no Node.js, no local tokens.

Test plan

  • npm run build -- clean TypeScript compilation
  • npm test -- all 172 tests pass
  • Deployed to Cloud Run (europe-west3), tested end-to-end from Cursor
  • OAuth flow works (GoogleProvider + Cursor's MCP OAuth 2.1)
  • readDocument tool successfully reads Google Docs via remote server
  • 67 tools visible in Cursor
  • Landing page serves English/Czech based on Accept-Language
  • stdio mode still works as before (no regression)

@a-bonus a-bonus merged commit 975186e into a-bonus:main Mar 27, 2026
4 checks passed
@a-bonus
Copy link
Copy Markdown
Owner

a-bonus commented Mar 27, 2026

awesome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants