BlueprintLabIO/mcp-switch
If you are the rightful owner of mcp-switch and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.
MCP-Switch is a lightweight Model Context Protocol (MCP) server designed to connect with other MCP servers, manage OAUTH authentication, and provide clients with the appropriate tools.
MCP Switch (OAuth Supported!)
A lightweight MCP router that connects AI tools (Claude Desktop, Cursor, VS Code) to other MCP servers. It handles OAuth locally and forwards requests to downstream MCPs. It does NOT implement API-specific MCP tool wrappers itself.
Scope clarification: This projectβs responsibility is routing and auth. If you need API-specific tools (e.g., Gmail, Calendar, GitHub issues), run those as separate MCP servers and point mcp-switch at them. Avoid adding direct API wrappers here to prevent duplication and scope creep.
π Quick Start
# 1. Clone and install
git clone https://github.com/BlueprintDesignLab/mcp-switch
cd mcp-switch
npm install
# 2. Authenticate with providers (opens browser)
npm run auth:google
npm run auth:github
npm run auth:slack
# 3. Start the gateway
npm start
# Server running on http://localhost:8042
# 4. Configure your AI client (see below)
That's it! No OAuth app creation, no credential downloads, no complex configuration.
π What This Does
- Single Gateway: Route requests from clients to one or more downstream MCP servers
- OAuth Automation: Handles token refresh, PKCE flows, provider quirks (for MCPs that require OAuth)
- Local & Private: All tokens stored encrypted on your machine
- Multi-Client: Multiple AI clients share the same server instance
- Out of scope: Implementing API-specific MCP tools; build or reuse dedicated MCP servers for that purpose
Claude Desktop βββ
βββ HTTP βββΆ MCP Switch (this repo) βββΆ Downstream MCP servers
VS Code βββββ€ (localhost:8042) (e.g., Gmail MCP, GitHub MCP)
β
Cursor βββββ
π¦ Dependencies
Core Dependencies
{
"@modelcontextprotocol/sdk": "^1.0.0",
"express": "^4.18.0",
"googleapis": "^131.0.0",
"@octokit/rest": "^20.0.0",
"@slack/web-api": "^7.0.0",
"@notionhq/client": "^2.2.0",
"open": "^10.0.0"
}
Pre-registered OAuth Apps
- Google: Calendar, Gmail, Drive APIs (read-only by default)
- GitHub: Repositories, Issues, Profile (public data + authorized private)
- Slack: Channels, Messages, Files (workspace you authorize)
- Notion: Databases, Pages (pages you share with the integration)
System Requirements
- Node.js 18+ (for ES modules and native fetch)
- macOS/Linux/Windows (cross-platform)
- Port 8042 available (configurable)
π§ Installation
1. Provider Authentication (if a downstream MCP needs OAuth)
Use the included auth scripts only to obtain local tokens required to reach downstream MCP servers that rely on OAuth. Do not add direct API functionality here.
npm run auth:google
# Opens browser β Sign in β Allow permissions β Done!
GitHub
npm run auth:github
# Opens browser β Sign in β Allow permissions β Done!
If a providerβs functionality is desired, run or install its dedicated MCP server and configure mcp-switch to route to it.
2. Client Configuration
Claude Desktop
// ~/.config/claude-desktop/config.json
{
"mcpServers": {
"oauth-gateway": {
"url": "http://localhost:8042"
}
}
}
VS Code / Cursor
// settings.json
{
"mcp.servers": {
"oauth-gateway": {
"url": "http://localhost:8042"
}
}
}
π Security Architecture
Threat Model
- Asset: OAuth access/refresh tokens for your connected services
- Boundary: Your local machine (trusted environment)
- Risks: Token theft via malware, accidental exposure, token replay
Security Controls
1. Token Encryption (AES-256-GCM)
// tokens.json is encrypted at rest
{
"google": {
"encrypted": "a1b2c3d4...",
"iv": "random_iv",
"authTag": "auth_tag"
}
}
2. PKCE for All OAuth Flows
// RFC 7636 - prevents authorization code interception
const codeChallenge = crypto
.createHash('sha256')
.update(randomCodeVerifier)
.digest('base64url');
3. Minimal Scopes
// Request only necessary permissions
const googleScopes = [
'https://www.googleapis.com/auth/calendar.readonly',
'https://www.googleapis.com/auth/drive.readonly'
// NO write permissions by default
];
4. Token Auto-Refresh
// Refresh tokens before expiry
if (token.expires_at - Date.now() < 5 * 60 * 1000) {
await refreshToken();
}
Security Best Practices
File Permissions
chmod 600 tokens.json # Owner read/write only
chmod 700 config/ # Owner access only
Environment Variables
# Never commit secrets to git
echo "tokens.json" >> .gitignore
echo ".env" >> .gitignore
π¨ Common Issues
Server Issues
# Port 8042 already in use
# Fix: Use different port
PORT=8043 npm start
# Server won't start
# Check: Node.js version
node --version # Should be 18+
OAuth Errors
# "Browser didn't open"
# Fix: Manual browser navigation
npm run auth:google --manual
# "Token expired"
# Fix: Re-authenticate with provider
npm run auth:google
MCP Connection Issues
# Claude can't connect
# Check: Server is running
curl http://localhost:8042/health
# Should return: {"status": "ok"}
π How It Works
Architecture
MCP Client ββHTTP/SSEβββΆ MCP Switch (router) ββHTTP/SSEβββΆ Downstream MCP servers
(Claude/Cursor/VS Code) (Express) (e.g., Gmail MCP, GitHub MCP)
Request Flow
- MCP Client calls tool via HTTP POST to
/message
- Gateway validates request and checks tokens
- OAuth Logic refreshes expired tokens automatically
- Provider API called with valid Bearer token
- Response streamed back via Server-Sent Events
Token Flow
- Initial Auth: User runs
npm run auth:google
β browser OAuth flow - Token Storage: Access/refresh tokens encrypted locally
- Auto-Refresh: Tokens refreshed automatically before expiry
- Shared Instance: All MCP clients use same server and tokens
π Development
Project Structure
src/
βββ server.js # Express server + MCP SSE transport
βββ providers/
β βββ google.js # Google OAuth + API integration
β βββ github.js # GitHub OAuth + API integration
β βββ base.js # Shared provider interface
βββ oauth/
β βββ manager.js # OAuth flow orchestration
β βββ storage.js # Encrypted token storage
β βββ pkce.js # PKCE implementation
βββ tools/
βββ registry.js # MCP tool registration
Development Commands
npm start # Start server (production)
npm run dev # Start with hot reload
npm run test # Run test suite
Adding New Destinations
- Add routing targets for downstream MCP servers; do not add direct API wrappers.
- Expose configuration to map tool namespaces to external MCP endpoints.
- Keep OAuth handling limited to whatβs required to reach those MCPs.
π License
MIT License - see for details.
π€ Contributing
- Fork the repository
- Create feature branch:
git checkout -b feature/new-provider
- Add tests:
npm run test
- Submit pull request
β οΈ Disclaimer
This is a development tool for personal use. Review the code before using with sensitive data. Each OAuth provider has its own terms of service that you must follow.