About mcpresso-oauth-server
mcpresso-oauth-server is an MCP server published by git+granular-software in the Security category: production-ready OAuth 2.1 server for Model Context Protocol (MCP) with mcpresso integration.
The repository has 1 stars and 0 forks.
Install
npx mcpresso-oauth-serverclaude mcp add mcpresso-oauth-server -- npx -y mcpresso-oauth-servernpx -y mcpresso-oauth-serverThis server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.
Ask AI
Ask AI about mcpresso-oauth-server
Powered by Claude · Grounded in docs
Security checks
- ✓README presentThe repository ships documentation.
- !Scoped permissionsDoesn't declare a permission scope. Assume it can do anything its process can.
4 checks have not been run yet.
README
mcpresso-oauth-server
A production-ready OAuth 2.1 server implementation designed specifically for Model Context Protocol (MCP) servers. Provides seamless authentication integration with mcpresso servers.
Features
- ✅ OAuth 2.1 Compliant - Full implementation of OAuth 2.1 draft specification
- ✅ MCP Integration - Designed specifically for Model Context Protocol
- ✅ PKCE Support - Proof Key for Code Exchange (required for MCP)
- ✅ Custom User Authentication - Pluggable login logic and UI customization
- ✅ Production Ready - Security headers, rate limiting, compression, CORS
- ✅ Flexible Deployment - Run standalone or integrated with MCP servers
- ✅ Dynamic Client Registration - RFC 7591 compliant
- ✅ Multiple Grant Types - Authorization code, refresh token, client credentials
- ✅ Token Introspection - RFC 7662 compliant
- ✅ Discovery Endpoints - RFC 8414 and RFC 9728 compliant
Quick Start
Installation
npm install mcpresso-oauth-server
# or
bun add mcpresso-oauth-server
Basic Usage
import {
MCPOAuthServer,
MemoryStorage
} from 'mcpresso-oauth-server'
// Initialize storage with demo data
const storage = new MemoryStorage()
await storage.createClient({
id: 'demo-client',
secret: 'demo-secret',
name: 'Demo Client',
type: 'confidential',
redirectUris: ['http://localhost:4000/callback'],
scopes: ['read', 'write'],
grantTypes: ['authorization_code']
})
// Create OAuth server with custom authentication
const oauthServer = new MCPOAuthServer({
issuer: 'http://localhost:4000',
serverUrl: 'http://localhost:4000',
jwtSecret: 'your-secret-key',
auth: {
authenticateUser: async (credentials, context) => {
// Your login logic here
const user = users.find(u => u.username === credentials.username)
return user && validatePassword(credentials.password, user.password) ? user : null
},
getCurrentUser: async (sessionData, context) => {
// Check if user is already logged in via session/cookies
return null // Force login for this example
},
renderLoginPage: async (context, error) => {
// Optional: Customize login page
return `<html>...custom login form...</html>`
}
}
}, storage)
MCP Integration
Two Deployment Modes
Mode 1: Integrated (Same Port)
Run OAuth and MCP server together:
import { createMCPServer } from 'mcpresso'
import { MCPOAuthServer } from 'mcpresso-oauth-server'
// Create OAuth server
const oauthServer = new MCPOAuthServer({...}, storage)
// Create MCP server with integrated OAuth
const app = createMCPServer({
name: "integrated_server",
resources: [userResource],
auth: {
oauth: oauthServer, // Integrate OAuth server
userLookup: async (jwtPayload) => {
// Fetch full user profiles from your database
return await db.users.findById(jwtPayload.sub)
}
}
})
app.listen(4000) // Both OAuth and MCP on port 4000
Architecture:
┌─────────────────────────────────┐
│ Integrated Server │
│ (Port 4000) │
│ │
│ ┌─────────────┐ ┌─────────────┐ │
│ │OAuth Service│ │ MCP Service │ │
│ │• /authorize │ │• MCP API │ │
│ │• /token │ │• Resources │ │
│ │• Login UI │ │• Tools │ │
│ └─────────────┘ └─────────────┘ │
└─────────────────────────────────┘
Mode 2: Separate Servers
Run OAuth and MCP on different ports:
// OAuth Server (Port 4001)
const oauthApp = express()
oauthApp.use(cors()) // Important for cross-origin requests
registerOAuthEndpoints(oauthApp, oauthServer)
oauthApp.listen(4001)
// MCP Server (Port 4000)
const mcpApp = createMCPServer({
name: "api_server",
resources: [userResource],
auth: {
issuer: "http://localhost:4001", // OAuth server URL
serverUrl: "http://localhost:4000", // This MCP server URL
jwtSecret: "shared-secret", // Same secret as OAuth server
userLookup: async (jwtPayload) => {
return await db.users.findById(jwtPayload.sub)
}
}
})
mcpApp.listen(4000)
Architecture:
┌─────────────────┐ ┌──────────────────┐
│ OAuth Server │ │ MCP Server │
│ (Port 4001) │ │ (Port 4000) │
│ │ │ │
│ • /authorize │ │ • MCP API │
│ • /token │ │ • Token Validation│
│ • Login UI │ │ • Resources │
└─────────────────┘ └──────────────────┘
Custom Authentication
User Authentication Callbacks
Implement your own user authentication logic:
const oauthServer = new MCPOAuthServer({
// ... other config
auth: {
// Required: Validate user credentials
authenticateUser: async (credentials, context) => {
const { username, password } = credentials
// Example with database lookup
const user = await db.users.findByEmail(username)
if (!user) return null
// Verify password (use bcrypt in production)
const isValid = await bcrypt.compare(password, user.hashedPassword)
if (!isValid) return null
// Return user object
return {
id: user.id,
username: user.email,
email: user.email,
scopes: user.permissions // e.g., ['read', 'write', 'admin']
}
},
// Optional: Check existing sessions
getCurrentUser: async (sessionData, context) => {
if (sessionData?.userId) {
return await db.users.findById(sessionData.userId)
}
return null
},
// Optional: Custom login page
renderLoginPage: async (context, error) => {
return `
<!DOCTYPE html>
<html>
<head><title>Login - ${context.clientId}</title></head>
<body>
<h2>Login to ${context.clientId}</h2>
${error ? `<p style="color:red">${error}</p>` : ''}
<form method="POST" action="/authorize">
<!-- Hidden OAuth parameters -->
<input type="hidden" name="response_type" value="code">
<input type="hidden" name="client_id" value="${context.clientId}">
<input type="hidden" name="redirect_uri" value="${context.redirectUri}">
<input type="hidden" name="scope" value="${context.scope || ''}">
<!-- Login form -->
<div>
<label>Email:</label>
<input type="email" name="username" required>
</div>
<div>
<label>Password:</label>
<input type="password" name="password" required>
</div>
<button type="submit">Login</button>
</form>
</body>
</html>
`
}
}
}, storage)
Integration Examples
With Supabase
import { createClient } from '@supabase/supabase-js'
const supabase = createClient(url, key)
const oauthServer = new MCPOAuthServer({
auth: {
authenticateUser: async ({ username, password }) => {
const { data, error } = await supabase.auth.signInWithPassword({
email: username,
password: password
})
if (error || !data.user) return null
return {
id: data.user.id,
username: data.user.email,
email: data.user.email,
scopes: data.user.user_metadata?.scopes || ['read']
}
}
}
})
With Firebase
import { signInWithEmailAndPassword } from 'firebase/auth'
const oauthServer = new MCPOAuthServer({
auth: {
authenticateUser: async ({ username, password }) => {
try {
const userCredential = await signInWithEmailAndPassword(auth, username, password)
const user = userCredential.user
return {
id: user.uid,
username: user.email,
email: user.email,
scopes: user.customClaims?.scopes || ['read']
}
} catch (error) {
return null
}
}
}
})
Configuration
Environment Variables
Configure the server using environment variables:
# Server configuration
OAUTH_ISSUER=https://auth.yourdomain.com
OAUTH_SERVER_URL=https://auth.yourdomain.com
OAUTH_JWT_SECRET=your-super-secret-jwt-key
# CORS configuration (for separate server deployment)
CORS_ORIGIN=https://yourdomain.com,https://api.yourdomain.com
TRUST_PROXY=true
# Server port
PORT=4001
Security Configuration
The server includes production-ready security features:
const oauthServer = new MCPOAuthServer({
// ... OAuth config
http: {
cors: {
origin: ['https://yourdomain.com'],
credentials: true,
methods: ['GET', 'POST', 'OPTIONS']
},
enableHelmet: true,
enableRateLimit: true,
rateLimitConfig: {
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100 // requests per window
}
}
})
API Endpoints
OAuth 2.1 Endpoints
GET /authorize- Authorization endpoint (shows login page)POST /authorize- Authorization endpoint (processes login)POST /token- Token endpointPOST /introspect- Token introspectionPOST /revoke- Token revocationGET /userinfo- User info endpointPOST /register- Dynamic client registration
Discovery Endpoints
GET /.well-known/oauth-authorization-server- OAuth metadata (RFC 8414)GET /.well-known/jwks.json- JSON Web Key SetGET /.well-known/oauth-protected-resource- MCP protected resource metadata
Admin Endpoints
GET /health- Health checkGET /admin/clients- List clientsGET /admin/users- List usersGET /admin/stats- Server statistics
Storage
The package includes an in-memory storage implementation for development. For production, implement the MCPOAuthStorage interface:
import type { MCPOAuthStorage } from 'mcpresso-oauth-server'
class DatabaseStorage implements MCPOAuthStorage {
async createClient(client: OAuthClient): Promise<void> {
// Store client in your database
}
async getClient(clientId: string): Promise<OAuthClient | null> {
// Fetch client from your database
}
// ... implement all required methods
}
Examples
See complete working examples:
- Integrated OAuth:
mcpresso/examples/oauth2-simple-demo.ts - Separate Servers:
mcpresso/examples/separate-servers-demo.ts
Testing
Manual OAuth Flow Testing
- Get Authorization Code:
# Open in browser or use curl
curl "http://localhost:4001/authorize?response_type=code&client_id=demo-client&redirect_uri=http://localhost:4001/callback&scope=read&resource=http://localhost:4000"
- Exchange for Token:
curl -X POST "http://localhost:4001/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code&client_id=demo-client&client_secret=demo-secret&code=YOUR_CODE&redirect_uri=http://localhost:4001/callback&resource=http://localhost:4000"
- Use Token with MCP API:
curl -X POST "http://localhost:4000" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"whoami_user","arguments":{}}}'
Development
Build & Test
# Install dependencies
bun install
# Build the package
bun run build
# Run tests
bun test
# Start development server
bun run dev
Security Best Practices
For production deployments:
- Use Strong JWT Secrets - Generate cryptographically secure secrets
- Configure CORS Properly - Only allow trusted origins
- Enable HTTPS - Always use HTTPS in production
- Implement Proper Storage - Use a production database, not memory storage
- Monitor & Log - Set up proper logging and monitoring
- Keep Dependencies Updated - Regularly update packages
- Rate Limiting - Configure appropriate rate limits
- Input Validation - Validate all user inputs
Support
- Documentation: mcpresso documentation
- Issues: GitHub Issues
- Examples: Working examples
License
MIT - See LICENSE file for details.
README copy captured when this server was indexed; it may lag the repository. The original is authoritative.