mcp-oauth-bridge
v1.0.2
Published
A stdio MCP server that proxies requests to remote MCP servers with OAuth 2.0 authentication (Authorization Code + PKCE)
Downloads
311
Maintainers
Readme
mcp-oauth-bridge
A stdio MCP (Model Context Protocol) server that proxies requests to remote MCP servers with OAuth 2.0 authentication using Authorization Code flow with PKCE.
Features
- OAuth 2.0 Authorization Code + PKCE: Secure authentication flow
- Automatic token management: Tokens are cached and refreshed automatically
- Fully configurable: All OAuth endpoints and settings via environment variables
- Zero dependencies: Pure Node.js implementation
- Cross-platform: Works on macOS, Linux, and Windows
Installation
npx mcp-oauth-bridgeOr install globally:
npm install -g mcp-oauth-bridgeConfiguration
Environment Variables
Required
| Variable | Description |
|----------|-------------|
| MCP_SERVER_URL | Remote MCP server URL |
| MCP_AUTH_URL | OAuth 2.0 authorization endpoint |
| MCP_TOKEN_URL | OAuth 2.0 token endpoint |
| MCP_CLIENT_ID | OAuth 2.0 client ID |
| MCP_CLIENT_SECRET | OAuth 2.0 client secret |
Optional
| Variable | Default | Description |
|----------|---------|-------------|
| MCP_SCOPES | openid offline_access | Space-separated OAuth scopes |
| MCP_CALLBACK_PORT | 3333 | Local port for OAuth callback |
| MCP_TOKEN_PATH | ~/.mcp-oauth-bridge-tokens.json | Path to store tokens |
Usage with Claude Code
Create a .mcp.json file in your project root:
{
"mcpServers": {
"my-server": {
"type": "stdio",
"command": "npx",
"args": ["mcp-oauth-bridge"],
"env": {
"MCP_SERVER_URL": "https://mcp.example.com/mcp",
"MCP_AUTH_URL": "https://auth.example.com/oauth2/authorize",
"MCP_TOKEN_URL": "https://auth.example.com/oauth2/token",
"MCP_CLIENT_ID": "your-client-id",
"MCP_CLIENT_SECRET": "your-client-secret",
"MCP_SCOPES": "openid offline_access profile email"
}
}
}
}Then enable the server in .claude/settings.local.json:
{
"enabledMcpjsonServers": ["my-server"]
}How It Works
- First run: Opens your browser for OAuth authorization
- Token storage: Saves tokens to the configured path (mode 600)
- Automatic refresh: Refreshes expired tokens using the refresh token
- Request proxying: Forwards all MCP requests to the remote server with the access token
┌─────────────┐ stdio ┌──────────────────┐ HTTPS ┌────────────────┐
│ Claude Code │ ◄────────────► │ mcp-oauth-bridge │ ◄────────────► │ Remote MCP │
└─────────────┘ └──────────────────┘ │ Server │
│ └────────────────┘
│
▼
┌──────────────────┐
│ OAuth Provider │
│ (Authorization) │
└──────────────────┘Token Storage
Tokens are stored at the configured path (default: ~/.mcp-oauth-bridge-tokens.json) with restricted permissions (600). The file contains:
access_token: Current access tokenrefresh_token: Token used to obtain new access tokensexpires_in: Token lifetime in secondsobtained_at: Timestamp when token was obtained
Security Considerations
- Client credentials are passed via environment variables (not stored in code)
- Tokens are stored with restricted file permissions (600)
- PKCE is used to prevent authorization code interception attacks
- State parameter prevents CSRF attacks
Troubleshooting
"Missing required environment variables: ..."
Ensure all required environment variables are set in your .mcp.json configuration:
MCP_SERVER_URLMCP_AUTH_URLMCP_TOKEN_URLMCP_CLIENT_IDMCP_CLIENT_SECRET
OAuth flow times out
The OAuth flow has a 5-minute timeout. Ensure:
- Your browser can open automatically
- The configured callback port (default 3333) is available
- You complete the authorization within the timeout
Token refresh fails
Delete the token file to force a new authorization flow:
rm ~/.mcp-oauth-bridge-tokens.jsonPort already in use
Change the callback port using MCP_CALLBACK_PORT:
"env": {
"MCP_CALLBACK_PORT": "8888",
...
}License
MIT
