loading…
Search for a command to run...
loading…
MCP server with built-in Google OAuth 2.0 authentication, enabling secure tool access via Google sign-in with automatic token lifecycle management and optional
MCP server with built-in Google OAuth 2.0 authentication, enabling secure tool access via Google sign-in with automatic token lifecycle management and optional domain restriction for Google Workspace organizations.
Building an MCP server is straightforward — but adding proper authentication is not. The MCP spec requires OAuth 2.0 with discovery endpoints, dynamic client registration, PKCE, and token lifecycle management. That's a lot of boilerplate before you can write your first tool.
This project gives you all of that out of the box. You focus on your tools, authentication is handled.
pip install mcp-google-oauth
Prerequisite: This implementation uses Google OAuth 2.0 and is designed for organizations with Google Workspace. Your company domain (e.g.
yourcompany.com) must be managed by Google Workspace to restrict access to internal users. Other identity providers (Microsoft Entra ID, Okta, etc.) can be implemented following the same OAuth 2.0 methodology used here.
For developers building MCP servers:
create_mcp_app()) sets up the full OAuth 2.0 stack@mcp.tool() functions — everything else is providedFor end users connecting to your MCP server:
@yourcompany.com)/health# main.py
from dotenv import load_dotenv
load_dotenv()
from mcp_auth import create_mcp_app, MCPAuthConfig
config = MCPAuthConfig.from_env()
config.mcp_name = "my-connector"
app, mcp = create_mcp_app(config)
@mcp.tool()
def hello(name: str = "world") -> str:
"""Say hello."""
return f"Hello, {name}!"
graph LR
subgraph Claude
C[Claude Desktop<br/>or claude.ai]
MR[mcp-remote]
C <--> MR
end
subgraph Server ["Your Server"]
AUTH[mcp_auth/<br/>OAuth + token mgmt]
TOOLS["main.py<br/>@mcp.tool()"]
DB[(Database<br/>OAuth tokens only)]
AUTH <--> DB
end
subgraph Auth ["Authentication Provider"]
G[Google OAuth 2.0]
end
MR <-->|HTTPS| AUTH
MR <-->|tool calls| TOOLS
AUTH <-->|verify identity| G
sequenceDiagram
participant C as Claude
participant S as Your Server
participant G as Google
C->>S: POST /mcp/
S-->>C: 401 Unauthorized
C->>S: Discover OAuth endpoints
S-->>C: OAuth metadata
C->>S: Register client
S-->>C: client_id + secret
C->>S: Authorize
S-->>C: Redirect to Google
C->>G: User signs in
G-->>S: Callback + code
Note over S: Validate domain
S-->>C: Auth code
C->>S: Exchange code
S-->>C: Access + refresh tokens
C->>S: POST /mcp/ + Bearer token
S-->>C: Tool result
/google/callbackSee docs/architecture.md for detailed diagrams.
Requires Python 3.11+. Check with
python3 --version. If needed:brew install [email protected](macOS) or see python.org.
pip install mcp-google-oauth
Or install from source:
git clone https://github.com/hungvietdo/mcp-google-oauth.git
cd mcp-google-oauth
python3 -m venv .venv && source .venv/bin/activate
pip install -e .
Create a main.py in a new directory with your tools:
# main.py
from dotenv import load_dotenv
load_dotenv()
from mcp_auth import create_mcp_app, MCPAuthConfig
config = MCPAuthConfig.from_env()
config.mcp_name = "my-connector"
config.mcp_instructions = "A custom MCP connector."
app, mcp = create_mcp_app(config)
@mcp.tool()
def hello(name: str = "world") -> str:
"""Say hello. Use this to verify the connection is working."""
return f"Hello, {name}!"
# Add your own tools below...
https://YOUR_DOMAIN/google/callbackCreate a .env file in the same directory as main.py:
SESSION_SECRET=<run: python3 -c "import secrets; print(secrets.token_hex(32))">
GOOGLE_CLIENT_ID=your-client-id
GOOGLE_CLIENT_SECRET=your-client-secret
ALLOWED_DOMAIN=yourcompany.com
DATABASE_URL=sqlite:///./local.db
MCP_ISSUER_URL=https://your-domain.ngrok.app/mcp
GOOGLE_MCP_CALLBACK_URL=https://your-domain.ngrok.app/google/callback
mcp-google-oauth
Options:
mcp-google-oauth --port 9000 # custom port (default: 8080)
mcp-google-oauth --reload # auto-reload on file changes (dev mode)
mcp-google-oauth --app mymodule:app # custom app module (default: main:app)
Exposing to the internet: Claude.ai requires a public HTTPS URL. Use ngrok to tunnel your local server:
ngrok http 8080 --domain=your-domain.ngrok.appUpdate
MCP_ISSUER_URLandGOOGLE_MCP_CALLBACK_URLin.envto match the ngrok URL, then restart.
Claude.ai (Pro/Max/Team/Enterprise) — go to Customize → Connectors → Add custom connector and paste your MCP server URL. Either format works:
https://your-domain.ngrok.app/mcp/https://your-domain.ngrok.app/First use opens your browser for Google sign-in. No tokens or config files needed on the client side.
Claude Desktop / Claude Code: Add the server to your MCP config. See Claude MCP docs for details.
├── pyproject.toml # Package definition — pip install mcp-google-oauth
├── main.py # Your MCP server — define tools here
├── .env.example # Template for credentials
│
├── mcp_auth/ # Installable auth package
│ ├── __init__.py # create_mcp_app() + MCPAuthConfig
│ ├── cli.py # mcp-google-oauth CLI entrypoint
│ ├── database.py # SQLAlchemy engine + session
│ ├── models.py # OAuth token tables (auto-created)
│ ├── oauth_provider.py # Google OAuth 2.0 provider
│ ├── middleware.py # Path rewrite fix for mcp-remote
│ ├── routes.py # /google/callback, /health
│ └── example_main.py # Starter template
│
└── docs/
└── architecture.md # Detailed diagrams (OAuth flow, data model, security)
| Variable | Required | Description |
|---|---|---|
GOOGLE_CLIENT_ID |
Yes | From Google Cloud Console |
GOOGLE_CLIENT_SECRET |
Yes | From Google Cloud Console |
GOOGLE_MCP_CALLBACK_URL |
Yes | https://your-domain/google/callback |
MCP_ISSUER_URL |
Yes | https://your-domain/mcp |
SESSION_SECRET |
Yes | Random hex string for signing sessions |
ALLOWED_DOMAIN |
No | Restrict to a Google Workspace domain (e.g. yourcompany.com) |
DATABASE_URL |
No | Default: sqlite:///./local.db |
Why a database? The database only stores OAuth access and refresh tokens. It does not store any application data. Tables are auto-created on startup. If the database is deleted, users simply re-authenticate with Google on their next request — no data is lost.
Set in code after MCPAuthConfig.from_env():
| Property | Default | Description |
|---|---|---|
mcp_name |
"mcp-server" |
MCP server name shown in Claude |
mcp_instructions |
"" |
Instructions for Claude about available tools |
pip: command not foundUse pip3 or python3 -m pip instead:
pip3 install mcp-google-oauth
# or
python3 -m pip install mcp-google-oauth
mcp-google-oauth: command not found after installThe CLI is installed into your Python's bin directory. If it's not on your PATH, run it directly:
python3 -m mcp_auth.cli
Or find where pip installs scripts:
python3 -m site --user-base # add /bin to your PATH
No main.py found in the current directoryRun mcp-google-oauth from the directory that contains your main.py, or pass the app explicitly:
mcp-google-oauth --app mymodule:app
The redirect URI in Google Cloud Console must exactly match GOOGLE_MCP_CALLBACK_URL in your .env. Check for trailing slashes or http vs https mismatches.
Access blocked: domain not allowedYour Google account's email domain doesn't match ALLOWED_DOMAIN. Either:
ALLOWED_DOMAIN from .env to allow any Google accountcurl https://your-domain/health should return {"status":"ok"}MCP_ISSUER_URL matches the URL you give Claude (including /mcp suffix)Access tokens auto-refresh. If re-auth is needed (e.g. after deleting the database), just reconnect the server in Claude — it will open the browser again.
ImportError or missing dependenciesMake sure you installed into the right Python environment:
python3 -m pip install mcp-google-oauth
If using a virtual environment, activate it first before installing and running.
MIT
Выполни в терминале:
claude mcp add mcp-google-oauth -- npx Безопасность
Низкий рискАвтоматическая эвристика по публичным данным — не гарантия безопасности.