- TypeScript 87.3%
- Shell 8.7%
- HTML 2.3%
- CSS 1.4%
- JavaScript 0.3%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
* fix: add /mcp to endpoints in misc README.mds * improve architecture interaction diagrams in README.md * add "OAuth Flow Analysis" section in README.md |
||
| .devcontainer | ||
| .github | ||
| .vscode | ||
| auth-server | ||
| docs | ||
| shared | ||
| src | ||
| .env.integrated | ||
| .env.separate | ||
| .git-blame-ignore-revs | ||
| .gitignore | ||
| CLAUDE.md | ||
| docker-compose.yml | ||
| eslint.config.mjs | ||
| jest.config.js | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
MCP Everything Server
Note: these docs were AI generated based on a claude code transcript, and then edited manually for accuracy
A comprehensive example implementation of a scalable Model Context Protocol (MCP) server that demonstrates all MCP functionality with full authentication support and horizontal scalability.
Overview
The Everything Server is an open-source reference implementation that showcases:
- Complete MCP Protocol Support: All MCP features including tools, resources, prompts, sampling, completions, and logging
- Multiple Transport Methods: Streamable HTTP (SHTTP) and Server-Sent Events (SSE)
- Comprehensive Auth: OAuth 2.0 with fake upstream provider for testing
- Horizontal Scalability: Redis-backed session management for multi-instance deployments
This server serves as both primarily as a learning resource, and an example implementation of a scalable remote MCP server.
Features
MCP Protocol Features
- Tools: 7 demonstration tools including echo, add, long-running operations, LLM sampling, image handling, annotations, and resource references
- Resources: 100 example resources with pagination, templates, and subscription support
- Prompts: Simple and complex prompts with argument support and resource embedding
- Sampling: Integration with MCP sampling for LLM interactions
- Completions: Auto-completion support for prompt arguments
- Logging: Multi-level logging with configurable verbosity
- Notifications: Progress updates, resource updates, and stderr messages
Transport & Infrastructure
- Streamable HTTP: Full implementation with GET/POST/DELETE support
- SSE Transport: Backwards-compatible Server-Sent Events
- Redis Integration: Pub/sub message routing and session state management
- Session Management: 5-minute TTL with automatic cleanup
- Horizontal Scaling: Any instance can handle any request
Authentication & Security
- Dual Mode Support: Run with integrated or separate authorization server
- OAuth 2.0: Complete authorization flow with PKCE support
- External Auth Ready: Demonstrates integration with external OAuth providers
- Session Ownership: User isolation and access control
- Security Headers: CSP, HSTS, X-Frame-Options, and more
- Bearer Token Auth: Middleware for protected endpoints
Authentication Modes
The Everything Server supports two authentication modes to demonstrate different MCP deployment patterns:
Integrated Mode (Default)
The MCP server acts as its own OAuth 2.0 authorization server. This is simpler to deploy and suitable for standalone MCP servers.
npm run dev:integrated
Separate Mode
The MCP server delegates authentication to a standalone authorization server. This demonstrates how MCP servers can integrate with existing OAuth infrastructure. See auth-server/README.md for more details about the standalone auth server.
# Start both the auth server and MCP server
npm run dev:with-separate-auth
# Or run them separately:
# Terminal 1: Start the authorization server
npm run dev:auth-server
# Terminal 2: Start the MCP server in separate mode
npm run dev:separate
In production, the separate authorization server would typically be replaced with:
- Corporate SSO (Auth0, Okta)
- Cloud providers (AWS Cognito, Azure AD)
- Social providers (Google, GitHub)
Testing with MCP Inspector
The MCP Inspector is a web-based tool for testing MCP servers. You can run it locally:
npx -y @modelcontextprotocol/inspector
Integrated Mode
# 1. Start Redis
docker compose up -d
# 2. Start the server
npm run dev:integrated
# 3. Open MCP Inspector
npx -y @modelcontextprotocol/inspector
# 4. Connect and test:
# - Connect to http://localhost:3232/mcp
# - Navigate to the Auth tab
# - Complete the OAuth flow
# - All auth endpoints will be served from :3232
Separate Mode
# 1. Start Redis
docker compose up -d
# 2. Start both servers
npm run dev:with-separate-auth
# 3. Open MCP Inspector
npx -y @modelcontextprotocol/inspector
# 4. Connect and test:
# - Connect to http://localhost:3232/mcp
# - Navigate to the Auth tab
# - The auth flow will redirect to :3001 for authentication
# - After auth, tokens from :3001 will be used on :3232
Architecture Diagrams
Integrated Mode
graph TD
Client["MCP Client<br/>(Inspector)"]
MCP["MCP Server<br/>(port 3232)<br/>• OAuth Server<br/>• Resource Server"]
Client <-->|"OAuth flow & MCP resources"| MCP
Separate Mode
graph TD
Client["MCP Client<br/>(Inspector)"]
MCP["MCP Server<br/>(port 3232)<br/>Resource Server"]
Auth["Auth Server<br/>(port 3001)<br/>OAuth Server"]
Client <-->|"1. Discover metadata"| MCP
Client <-->|"2. OAuth flow<br/>(register, authorize, token)"| Auth
Client <-->|"3. Use tokens for MCP resources"| MCP
MCP <-->|"Token validation<br/>(introspect)"| Auth
OAuth Flow Analysis
OAuth 2.0 + PKCE Flow Sequence
The server implements a complete OAuth 2.0 authorization code flow with PKCE. Here's how each step maps to data storage and expiry:
1. Client Registration (app setup - happens once)
App → Auth Server: "I want to use OAuth, here's my info"
Auth Server → App: "OK, your client_id is XYZ, client_secret is ABC"
- Storage: Client credentials for future OAuth flows
- Expiry: 30 days (long-lived app credentials)
2. Authorization Request (starts each OAuth flow)
User → App: "I want to connect to MCP server"
App → Auth Server: "User wants access, here's my PKCE challenge"
Auth Server: Stores pending authorization, shows auth page
- Storage:
PENDING_AUTHORIZATION- temporary state during flow - Expiry: 10 minutes (short-lived temporary state)
3. Authorization Code Exchange (completes OAuth flow)
User → Auth Server: "I approve this app"
Auth Server → App: "Here's your authorization code"
App → Auth Server: "Exchange code + PKCE verifier for tokens"
Auth Server → App: "Here are your access/refresh tokens"
- Storage:
TOKEN_EXCHANGE- prevents replay attacks - Expiry: 10 minutes (single-use, consumed immediately)
4. Token Storage (long-term user session)
Auth Server: Issues access_token + refresh_token
Server: Stores user installation with tokens
- Storage:
UPSTREAM_INSTALLATION- the actual user session - Expiry: 7 days (balances security vs usability)
5. Token Refresh (extends user session)
App → Auth Server: "My access token expired, here's my refresh token"
Auth Server → App: "Here's a new access token"
- Storage:
REFRESH_TOKEN- mapping for token rotation - Expiry: 7 days (matches installation lifetime)
Data Lifecycle Hierarchy
Timeline (shortest to longest expiry):
- OAuth flow state (10 minutes) - very temporary
- User sessions (7 days) - medium-term
- Client credentials (30 days) - long-term
This creates a logical hierarchy where each layer outlives the layers it supports.
Installation
Prerequisites
- Node.js >= 16
- Redis server (see Redis setup below)
- npm or yarn
Redis Setup
The server requires Redis for session management and message routing.
Option 1: Docker Compose (Recommended)
Install a Docker runtime:
- macOS: OrbStack - Fast, lightweight, and free
brew install orbstack # Or download from https://orbstack.dev/download - Windows/Linux: Docker Desktop
Start Redis:
# see docker-compose.yml
docker compose up -d
Option 2: Local Installation
# macOS
brew install redis && brew services start redis
# Ubuntu/Debian
sudo apt-get install redis-server && sudo systemctl start redis
Setup
# Clone the repository
git clone https://github.com/modelcontextprotocol/example-remote-server.git
cd example-remote-server
# Install dependencies
npm install
# Configure environment (optional)
cp .env.example .env
# Edit .env with your settings
Configuration
Environment variables (.env file):
# Server Configuration
PORT=3232 # MCP server port
BASE_URI=http://localhost:3232 # Base URI for OAuth redirects
# Redis Configuration
REDIS_URL=redis://localhost:6379 # Redis connection URL
# Authentication Mode (integrated | separate)
AUTH_MODE=integrated # Default: integrated mode
# Separate Mode Configuration (only used when AUTH_MODE=separate)
AUTH_SERVER_URL=http://localhost:3001 # External auth server URL
AUTH_SERVER_PORT=3001 # Auth server port (for standalone server)
Pre-configured environment files:
.env.integrated- Configuration for integrated mode.env.separate- Configuration for separate mode
# Use integrated mode
cp .env.integrated .env
# Use separate mode
cp .env.separate .env
Development
Commands
Development
# Start development server with hot reload
npm run dev
# Start in integrated mode (MCP server as OAuth server)
npm run dev:integrated
# Start in separate mode (external auth server)
npm run dev:separate
# Start standalone authorization server
npm run dev:auth-server
# Start both auth server and MCP server in separate mode
npm run dev:with-separate-auth
# Start development server with debugging
npm run dev:break
Build & Production
# Build TypeScript to JavaScript
npm run build
# Build authorization server
npm run build:auth-server
# Build everything
npm run build:all
# Run production server
npm start
# Run production auth server
npm run start:auth-server
Testing & Quality
# Run linting
npm run lint
# Run tests
npm test
Project Structure
├── src/
│ ├── index.ts # Express app setup and routes
│ ├── config.ts # Configuration management
│ ├── redis.ts # Redis client setup
│ ├── auth/
│ │ └── provider.ts # OAuth auth provider implementation
│ ├── handlers/
│ │ ├── shttp.ts # Streamable HTTP handler
│ │ ├── sse.ts # SSE transport handler
│ │ ├── fakeauth.ts # Fake upstream auth handler
│ │ └── common.ts # Shared middleware
│ ├── services/
│ │ ├── mcp.ts # MCP server implementation
│ │ ├── auth.ts # Session ownership management
│ │ └── redisTransport.ts # Redis-backed transport
│ └── utils/
│ └── logger.ts # Structured logging
├── docs/
│ ├── streamable-http-design.md # SHTTP implementation details
│ └── user-id-system.md # Authentication flow documentation
├── scratch/ # Development scripts and tests
└── dist/ # Compiled JavaScript output
API Endpoints
MCP Endpoints
GET/POST/DELETE /mcp- Streamable HTTP transport endpointPOST: Initialize sessions or send messagesGET: Establish SSE streamsDELETE: Terminate sessions
GET /sse- Legacy SSE transport endpointPOST /message- Legacy message endpoint for SSE transport
Authentication Endpoints
GET /fakeupstreamauth/authorize- Fake OAuth authorization pageGET /fakeupstreamauth/redirect- OAuth redirect handler- OAuth 2.0 endpoints provided by MCP SDK auth router
Headers
Mcp-Session-Id: Session identifier for Streamable HTTPAuthorization: Bearer <token>: OAuth access token- Standard MCP headers as per protocol specification
Authentication Flow
The server implements a complete OAuth 2.0 flow with a fake upstream provider for testing:
- Client Registration: Clients register to obtain client_id and client_secret
- Authorization: Users authenticate through
/fakeupstreamauth/authorize - User Management: localStorage-based user ID system for testing
- Token Exchange: Authorization codes exchanged for access tokens
- Session Creation: Authenticated tokens create owned sessions
- Access Control: Sessions are isolated by user ownership
See docs/user-id-system.md for detailed authentication documentation.
Transport Methods
Streamable HTTP (Recommended)
Modern transport supporting bidirectional communication over HTTP:
- Single endpoint for all operations
- Session management via headers
- Efficient message buffering
- Automatic reconnection support
See docs/streamable-http-design.md for implementation details.
Server-Sent Events (Legacy)
Backwards-compatible transport using SSE:
- Separate endpoints for SSE streams and messages
- Session management via URL parameters
- Redis-backed message routing
- Real-time event delivery
Scalability Architecture
The server is designed for horizontal scaling using Redis as the backbone:
Session State Management
- Redis Storage: All session state stored in Redis
- 5-minute TTL: Automatic session cleanup
- Session Ownership: User isolation via Redis keys
- Stateless Servers: Any instance can handle any request
Message Routing
- Pub/Sub Channels: Redis channels for message distribution
- Message Buffering: Reliable delivery for disconnected clients
- Connection State: Tracked via pub/sub subscription counts
- Automatic Cleanup: No explicit cleanup required
Redis Key Structure
session:{sessionId}:owner # Session ownership
mcp:shttp:toserver:{sessionId} # Client→Server messages
mcp:shttp:toclient:{sessionId}:{requestId} # Server→Client responses
mcp:control:{sessionId} # Control messages
Testing
Running Tests
# Run all tests
npm test
# Run specific test suites
npm test -- --testNamePattern="User Session Isolation"
npm test -- --testNamePattern="session ownership"
# Run with coverage
npm test -- --coverage
Test Categories
- Unit Tests: Individual component testing
- Integration Tests: Transport and Redis integration
- Auth Tests: OAuth flow and session ownership
- Multi-user Tests: User isolation and access control
Manual Testing
The scratch/ directory contains utility scripts for testing:
oauth.sh- Test OAuth flowssimple-test-client.js- Basic client implementationtest-shttp-client.ts- Streamable HTTP testingdebug-mcp-flow.sh- Debug MCP message flows
Security
Implemented Security Measures
- Authentication: OAuth 2.0 with bearer tokens
- Authorization: User-based session ownership
- Session Isolation: Users can only access their own sessions
- Security Headers:
- Content Security Policy (CSP)
- Strict Transport Security (HSTS)
- X-Frame-Options
- X-Content-Type-Options
- Input Validation: Zod schemas for all inputs
- Error Handling: Sanitized error responses
Security Best Practices
- Always use HTTPS in production
- Configure proper CORS origins
- Use strong client secrets
- Enable all security headers
- Monitor session lifetimes
- Implement rate limiting
- Use structured logging
Monitoring & Debugging
Logging
Structured JSON logging with sanitized outputs:
- HTTP request/response logging
- Authentication events
- Session lifecycle events
- Redis operations
- Error tracking
Redis Monitoring
# Monitor session ownership
redis-cli KEYS "session:*:owner"
# Watch real-time operations
redis-cli MONITOR | grep "session:"
# Check active sessions
redis-cli PUBSUB CHANNELS "mcp:shttp:toserver:*"
# Debug specific session
redis-cli GET "session:{sessionId}:owner"
Debug Tools
- Development scripts in
scratch/directory - Comprehensive test suite
- Hot-reload development mode
- Source maps for debugging
Contributing
We welcome contributions! Please see our Contributing Guidelines for details.
Development Workflow
- Fork the repository
- Create a feature branch
- Implement your changes
- Add tests for new functionality
- Ensure all tests pass
- Run linting and fix issues
- Submit a pull request
Code Style
- TypeScript with strict mode
- ESLint configuration included
- Prettier formatting recommended
- Comprehensive type definitions
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
Built by the Model Context Protocol team as a reference implementation for the MCP ecosystem.