- Create docs/customization-guide.md with guidance on replacing demo functionality - Add customization section to main README - Fix all references to renamed oauth-architecture-patterns.md - Update repository structure comments to clarify what to replace vs keep
4.3 KiB
MCP Server - Resource Server with External OAuth
MCP resource server demonstrating token validation with external OAuth providers.
Purpose
This server shows how to build an MCP server that delegates all OAuth operations to external providers:
- No OAuth authorization code in the MCP server
- Token validation via introspection API (RFC 7662)
- Focus on serving MCP resources
- Authentication handled by external provider (Auth0, Okta, etc.)
Quick Start
# This server requires the auth server to be running!
# Option 1: Start both servers from repo root
cd .. && npm run dev
# Option 2: Start servers individually
# Terminal 1:
cd ../auth-server && npm run dev
# Terminal 2:
cd ../mcp-server && npm run dev
# Server starts on http://localhost:3232
Architecture
This server:
- Advertises the external OAuth server in its metadata
- Receives MCP requests with Bearer tokens
- Validates tokens via the OAuth server's
/introspectendpoint - Serves MCP resources after token validation
- Manages MCP sessions tied to validated users
The server does not issue tokens or handle user authentication.
Key Components
src/index.ts
Main entry point. Notable aspects for external auth:
- No OAuth endpoints (handled by auth server)
- Uses
ExternalAuthVerifierto validate tokens - Fetches auth metadata from external server on startup
- Serves MCP endpoints only
src/auth/external-verifier.ts
ExternalAuthVerifier - Validates tokens with external auth server:
async verifyAccessToken(token: string): Promise<AuthInfo> {
// Calls POST /introspect on auth server
// Validates token is active and intended for this MCP server
// Returns user info and scopes
}
src/services/mcp.ts
MCP server implementation with all features:
- 7 demonstration tools
- 100 paginated resources
- 3 prompts with argument support
- Sampling, completions, logging
src/services/redisTransport.ts
Redis-backed transport enabling:
- Horizontal scaling
- Session state management
- Message routing across instances
MCP Endpoints
# Streamable HTTP (recommended)
GET/POST/DELETE /mcp
# SSE (legacy)
GET /sse
POST /message
All endpoints require Authorization: Bearer <token> header.
Configuration
Environment variables in .env:
BASE_URI=http://localhost:3232 # This MCP server's URL
PORT=3232 # MCP server port
AUTH_SERVER_URL=http://localhost:3001 # External auth server URL
REDIS_URL=redis://localhost:6379
Token Validation Flow
- Client sends request with
Authorization: Bearer <token> - MCP server extracts token from header
- MCP server calls
POST AUTH_SERVER_URL/introspectwith token - Auth server returns token info (active, user_id, scopes, expiry)
- MCP server validates:
- Token is active
- Token audience matches this server (BASE_URI)
- Token hasn't expired
- Request proceeds with user context
Testing
npm test # 67 unit tests
npm run lint # Lint code
npm run typecheck # Type checking
npm run build # Build to dist/
Production Usage
To use a commercial OAuth provider instead of the demo auth server, see OAuth Architecture Patterns for detailed integration guidance.
Summary: Update AUTH_SERVER_URL in .env to point to your provider. You may need to adjust src/auth/external-verifier.ts for provider-specific introspection formats, but the MCP server code otherwise remains unchanged.
References
Related Documentation
- Main README - Complete project documentation
- Customization Guide - How to adapt this for your use case
- Auth Server README - The demo OAuth provider
- OAuth Architecture Patterns - OAuth integration options
- OAuth Flow - Detailed OAuth flow analysis
- Session Ownership - Session management details