Skip to main content
Glama

MCP ChatGPT Multi-Server Suite

by bobhuff0
OAUTH_SETUP.md8.03 kB
# 🔐 OAuth Security Setup for MCP Server ## Overview Adding OAuth security protects your MCP server from unauthorized access. Here are several approaches: --- ## 🎯 Option 1: ngrok OAuth (Recommended) ngrok has built-in OAuth protection that's easy to set up. ### Step 1: Enable OAuth in ngrok ```bash # Stop current ngrok # Then restart with OAuth ngrok http 3000 --oauth=google --oauth-allow-email=your@email.com ``` ### Step 2: Configure OAuth Providers **For Google OAuth:** ```bash ngrok http 3000 --oauth=google --oauth-allow-email=your@email.com ``` **For GitHub OAuth:** ```bash ngrok http 3000 --oauth=github --oauth-allow-email=your@email.com ``` **For Multiple Providers:** ```bash ngrok http 3000 --oauth=google --oauth=github --oauth-allow-email=your@email.com ``` ### Step 3: Update ChatGPT Connector After setting up OAuth, you'll need to: 1. **Get the new ngrok URL** (it may change) 2. **Configure OAuth in ChatGPT connector** 3. **Provide OAuth credentials** --- ## 🎯 Option 2: Custom OAuth Middleware Add OAuth protection directly to your Express server. ### Install OAuth Dependencies ```bash npm install passport passport-google-oauth20 express-session npm install --save-dev @types/passport @types/passport-google-oauth20 @types/express-session ``` ### Update Your Server (src/server.ts) ```typescript import express from 'express'; import passport from 'passport'; import { Strategy as GoogleStrategy } from 'passport-google-oauth20'; import session from 'express-session'; // OAuth Configuration const GOOGLE_CLIENT_ID = process.env.GOOGLE_CLIENT_ID || ''; const GOOGLE_CLIENT_SECRET = process.env.GOOGLE_CLIENT_SECRET || ''; // Configure Passport passport.use(new GoogleStrategy({ clientID: GOOGLE_CLIENT_ID, clientSecret: GOOGLE_CLIENT_SECRET, callbackURL: "/auth/google/callback" }, (accessToken, refreshToken, profile, done) => { // Verify user is allowed const allowedEmails = [ 'your@email.com', 'admin@yourdomain.com' ]; if (allowedEmails.includes(profile.emails?.[0]?.value)) { return done(null, profile); } else { return done(null, false); } })); // Add OAuth middleware to your Express app app.use(session({ secret: process.env.SESSION_SECRET || 'your-secret-key', resave: false, saveUninitialized: false })); app.use(passport.initialize()); app.use(passport.session()); // OAuth routes app.get('/auth/google', passport.authenticate('google', { scope: ['profile', 'email'] }) ); app.get('/auth/google/callback', passport.authenticate('google', { failureRedirect: '/login' }), (req, res) => { res.redirect('/'); } ); // Protect MCP endpoints const requireAuth = (req: any, res: any, next: any) => { if (req.isAuthenticated()) { return next(); } res.status(401).json({ error: 'Authentication required' }); }; // Apply auth to MCP endpoints app.post('/mcp/tools/call', requireAuth, async (req, res) => { // Your existing MCP logic }); app.get('/mcp/tools/list', requireAuth, (req, res) => { // Your existing list logic }); ``` --- ## 🎯 Option 3: API Key Authentication Simpler approach using API keys. ### Update Your Server ```typescript // Add API key middleware const requireApiKey = (req: any, res: any, next: any) => { const apiKey = req.headers['x-api-key'] || req.query.api_key; const validApiKeys = process.env.VALID_API_KEYS?.split(',') || []; if (validApiKeys.includes(apiKey)) { return next(); } res.status(401).json({ error: 'Invalid API key' }); }; // Apply to MCP endpoints app.post('/mcp/tools/call', requireApiKey, async (req, res) => { // Your existing logic }); app.get('/mcp/tools/list', requireApiKey, (req, res) => { // Your existing logic }); ``` ### Environment Variables Add to your `.env`: ```bash VALID_API_KEYS=your-secret-key-1,your-secret-key-2 ``` --- ## 🎯 Option 4: JWT Token Authentication Most flexible for programmatic access. ### Install JWT Dependencies ```bash npm install jsonwebtoken npm install --save-dev @types/jsonwebtoken ``` ### JWT Middleware ```typescript import jwt from 'jsonwebtoken'; const JWT_SECRET = process.env.JWT_SECRET || 'your-jwt-secret'; const requireJWT = (req: any, res: any, next: any) => { const token = req.headers.authorization?.replace('Bearer ', ''); if (!token) { return res.status(401).json({ error: 'No token provided' }); } try { const decoded = jwt.verify(token, JWT_SECRET); req.user = decoded; next(); } catch (error) { res.status(401).json({ error: 'Invalid token' }); } }; // Apply to MCP endpoints app.post('/mcp/tools/call', requireJWT, async (req, res) => { // Your existing logic }); ``` --- ## 🔧 Implementation Steps ### For ngrok OAuth (Easiest) 1. **Restart ngrok with OAuth:** ```bash ./stop-ngrok.sh ngrok http 3000 --oauth=google --oauth-allow-email=your@email.com ``` 2. **Get new URL:** ```bash ./get-ngrok-url.sh ``` 3. **Update ChatGPT connector** with new URL 4. **Configure OAuth in ChatGPT** (it will prompt for Google login) ### For Custom OAuth 1. **Get Google OAuth credentials:** - Go to [Google Cloud Console](https://console.cloud.google.com/) - Create OAuth 2.0 credentials - Add redirect URI: `https://your-ngrok-url.ngrok-free.app/auth/google/callback` 2. **Set environment variables:** ```bash export GOOGLE_CLIENT_ID=your_client_id export GOOGLE_CLIENT_SECRET=your_client_secret export SESSION_SECRET=your_session_secret ``` 3. **Update your server code** with OAuth middleware 4. **Rebuild and restart:** ```bash npm run build ./start.sh ``` --- ## 🎯 ChatGPT Integration with OAuth ### For ngrok OAuth: 1. **Use the ngrok URL** (no changes needed) 2. **ChatGPT will handle OAuth flow** automatically 3. **User will be prompted to login** on first access ### For Custom OAuth: 1. **Add OAuth configuration** to ChatGPT connector 2. **Provide OAuth endpoints** in your API schema 3. **Handle authentication flow** in your frontend --- ## 📋 Security Best Practices ### 1. Environment Variables ```bash # Add to .env GOOGLE_CLIENT_ID=your_client_id GOOGLE_CLIENT_SECRET=your_client_secret SESSION_SECRET=your_random_session_secret JWT_SECRET=your_random_jwt_secret VALID_API_KEYS=key1,key2,key3 ``` ### 2. Rate Limiting ```bash npm install express-rate-limit ``` ```typescript import rateLimit from 'express-rate-limit'; const limiter = rateLimit({ windowMs: 15 * 60 * 1000, // 15 minutes max: 100 // limit each IP to 100 requests per windowMs }); app.use('/mcp', limiter); ``` ### 3. HTTPS Only ```typescript app.use((req, res, next) => { if (process.env.NODE_ENV === 'production' && !req.secure) { return res.redirect(`https://${req.headers.host}${req.url}`); } next(); }); ``` --- ## 🚀 Quick Start (Recommended) **Use ngrok OAuth - it's the easiest:** ```bash # 1. Stop current ngrok ./stop-ngrok.sh # 2. Start with OAuth ngrok http 3000 --oauth=google --oauth-allow-email=your@email.com # 3. Get new URL ./get-ngrok-url.sh # 4. Use new URL in ChatGPT connector ``` **Benefits:** - ✅ No code changes needed - ✅ Built-in OAuth flow - ✅ Works with ChatGPT automatically - ✅ Easy to manage --- ## 🔍 Testing OAuth ### Test ngrok OAuth: ```bash curl -I https://your-ngrok-url.ngrok-free.app/mcp/tools/list # Should redirect to OAuth login ``` ### Test Custom OAuth: ```bash # Should return 401 without auth curl https://your-ngrok-url.ngrok-free.app/mcp/tools/list # Should work with valid token curl -H "Authorization: Bearer your-jwt-token" \ https://your-ngrok-url.ngrok-free.app/mcp/tools/list ``` --- ## 💡 Recommendation **Start with ngrok OAuth** - it's the simplest and works perfectly with ChatGPT: ```bash ngrok http 3000 --oauth=google --oauth-allow-email=your@email.com ``` This gives you: - ✅ Immediate security - ✅ No code changes - ✅ ChatGPT compatibility - ✅ Easy management **Want to implement this?** I can help you set it up! 🔐

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/bobhuff0/MCPAddIn'

If you have feedback or need assistance with the MCP directory API, please join our Discord server