Address PR feedback:
- Remove session store and session management
- Use stateless mode (sessionIdGenerator: undefined)
- Each request creates a fresh server instance
- Remove user-controlled format string in error message
- Simplify handler logic significantly
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Wire up 13 MCP Apps servers from the @modelcontextprotocol/server-* packages:
- budget-allocator: Interactive budget allocation UI
- cohort-heatmap: Customer retention heatmap
- customer-segmentation: Scatter chart with clustering
- map: Interactive 3D globe viewer (CesiumJS)
- pdf: Interactive PDF viewer
- scenario-modeler: SaaS business projections dashboard
- shadertoy: Real-time GLSL shader renderer
- sheet-music: ABC notation to sheet music visualizer
- system-monitor: Real-time OS metrics display
- threejs: 3D scene renderer
- transcript: Live speech transcription
- video-resource: Binary video streaming via MCP resources
- wiki-explorer: Wikipedia link graph visualization
Each server is mounted at /{slug}/mcp and shares the same OAuth
authentication as the main MCP server.
Also updates the splash page to dynamically list all available
example servers.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update @modelcontextprotocol/ext-apps to 0.4.0
- Use new nested format `_meta.ui.resourceUri` in tool definition
- Remove resourceUri from tool result (only needed in tool definition)
- Add example structuredContent and _meta in tool result for demo
Include the MCP Apps UI resource in the resources list so clients
can discover it via resources/list.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implements a simple MCP Apps tool that returns an interactive React UI:
- Add `mcp_apps_hello_world` tool with `_meta.ui/resourceUri` metadata
- Add resource handler for `ui://hello-world/app.html` returning HTML
- Create React app using `@modelcontextprotocol/ext-apps/react` hooks
- Add Vite build tooling to bundle React apps into single HTML files
The tool demonstrates the MCP Apps extension (SEP-1865) which allows
MCP servers to return interactive UI that runs in the client.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add dev-with-mitm.sh for TUI-based traffic inspection
- Add dev-with-mitmweb.sh for web UI-based traffic inspection
- Fix missing 'id' field in JSON-RPC error responses (required by spec)
- Migrate from zod-to-json-schema to Zod v4's native z.toJSONSchema()
The mitmproxy scripts help developers debug MCP traffic by running
the server through a reverse proxy that intercepts all client requests.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Updated demo tools count from 7 to 8 and added elicitations to the feature list
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add rate limiting to prevent DoS attacks on vulnerable routes
- Update package-lock.json to use public npm registry
- Document intentionally permissive CORS for public test server
- Remove health endpoints to match original codebase (no health checks)
- Fix auth server splash page to list all OAuth endpoints
- Update test scripts to check server availability via splash page
- Merge auth-server and mcp-server into unified architecture under src/modules/
- Add configurable auth modes: internal (single process) and external (separate processes)
- Update example scripts to support OAuth discovery and both auth modes
- Consolidate OAuth documentation into comprehensive implementation guide
- Add configuration options for development vs production deployments
- Support both Redis-backed and in-memory session storage
Enhance token validation in separate mode to fully comply with MCP specification:
- Validate audience (aud) claim to ensure tokens are issued for this specific MCP server
- Validate temporal claims (nbf, iat) with appropriate clock skew tolerance
- Add configurable canonical URI for audience validation
- Improve logging for validation failures
These changes prevent token passthrough attacks and ensure tokens are
properly scoped to the intended resource server, as required by the
MCP OAuth 2.0 specification.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Remove incorrect mcpAuthMetadataRouter call when running in separate mode.
The resource server should not serve OAuth metadata endpoints - only the
auth server should provide these endpoints.
- Add express-rate-limit to custom endpoints for security:
- /introspect: 100 requests per 5 minutes
- /fakeupstreamauth/*: 20 requests per minute
- Static files: 25 requests per 10 minutes
- Add automated e2e testing npm scripts using concurrently:
- npm run test:e2e:integrated: Auto-starts server and runs test
- npm run test:e2e:separate: Auto-starts both servers and runs test
- Update README with automated testing approach documentation
- Update docs/streamable-http-design.md with current file structure
- Remove redundancy in README e2e testing documentation
- Verified: All tests, linting, and e2e scripts pass with rate limiting
- Remove /oauth prefix from introspect endpoint to match SDK pattern
- Fix auth-server endpoints: /introspect not /oauth/introspect
- Update external-verifier to call correct introspect endpoint
- Add 30-day expiry to client registration (REDIS_EXPIRY_TIMES.CLIENT_REGISTRATION)
- Remove inaccurate scratch/ directory references from README
- Add backlinks from auth-server/README.md to main README sections
- Verified all implementation details against running servers and Redis data
- Implemented retry logic (5 attempts, 3 second delay) for auth server connection
- Added token validation caching with 60-second default TTL
- Cache respects token expiration time if provided
- Cache invalidation on 401/403 responses
- Automatic cache cleanup every minute
- Debug logging for cache hits and misses
- Created ExternalAuthVerifier for token validation with external auth server
- Added mode switching logic to src/index.ts
- Integrated mode uses mcpAuthRouter (current behavior)
- Separate mode uses mcpAuthMetadataRouter and external verifier
- Fake upstream auth routes only available in integrated mode
- Added auth server metadata fetching with error handling
- Created shared/types.ts with well-documented type definitions
- Created shared/auth-core.ts with core auth functions (PKCE, tokens, encryption)
- Created shared/redis-auth.ts with Redis operations for auth data
- Updated src/services/auth.ts to use shared modules
- Added TokenIntrospectionResponse interface for Mode 2
- Updated config.ts with AUTH_MODE, AUTH_SERVER_URL, AUTH_SERVER_PORT
- Added validation for port consistency between URL and PORT variables
- Added comprehensive JSDoc comments for all config variables
- Created .env.integrated and .env.separate config files
- Updated redis.ts to use REDIS_URL from config
- Added .claude/ to .gitignore
- Moved inline CSS to external stylesheet to comply with CSP
- Added black background to logo area for visibility of white MCP logo
- Updated specification link to point to dated version (2025-06-18)
- Changed "MCP Everything Server" to "MCP Example Server"
- Added route to serve styles.css file
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implemented a clean, informative splash page at the root endpoint that showcases:
- Server features and capabilities
- API endpoints documentation
- Links to GitHub repository and MCP documentation
- Black and white theme matching MCP branding
- Responsive design for mobile and desktop
The splash page provides users with an immediate overview of the server's functionality
and serves as a landing page for the MCP Everything Server.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace getRawBody with direct req.body usage since express.json() middleware already parses it
- Add debugging support with --inspect flag for dev scripts
- Add VS Code launch configurations for debugging
The issue was that getRawBody tried to read an already-consumed stream. Since express.json()
middleware is applied globally, we can directly use req.body instead.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add MCPInitResponse interface for test responses
- Replace 'any' types with proper interface
- Remove unused JSONRPCResponse import
- Maintain type safety while fixing build errors
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove unused imports and variables
- Replace 'any' types with proper type guards
- Add comments to empty catch blocks
- Fix Response/Request type imports in logger
- Use 'unknown' instead of 'any' for generic types
- Remove unused createMcpServer and setSessionOwner imports
All ESLint checks now pass.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove sensitive data (auth tokens, cookies) from request logging
- Add detailed logging throughout streamable HTTP request lifecycle:
- Session creation/reuse
- Session ownership validation
- Transport initialization
- Message flow through Redis channels
- Session shutdown and cleanup
- Add logging for inactivity timeouts and control messages
- Use appropriate log levels (info for lifecycle, debug for details, error for failures)
All logs now include contextual information like sessionId, userId, and channel names
for easier debugging and monitoring.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add structured logger utility with Cloud Run trace context support
- Uses AsyncLocalStorage for request context propagation
- Replace all console.log/error/warn statements with structured logger
- Add logging middleware to capture request/response metadata
- Support Google Cloud Logging severity levels and trace correlation
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add afterEach hook to properly close transport instances
- Prevents hanging tests due to uncleaned inactivity timers
- All 85 tests now pass successfully
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add 5-minute inactivity timeout to prevent memory leaks
- Reset timer on each message received from client
- Clear timer on transport close
- Add comprehensive tests for timeout behavior
- Fix async/await in redisRelayToMcpServer calls
Sessions will now automatically shutdown after 5 minutes of no client activity.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add Accept header to mock requests per MCP spec requirement
- Fix TypeScript build errors in integration tests
- Add shutdownSession calls to properly clean up MCP server intervals
- Update afterEach to ensure proper test cleanup
- Add debug configurations for Jest in VS Code launch.json
All tests now pass without hanging processes.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Update tests to handle async session initialization
- Fix session ID retrieval from SSE/JSON responses
- Update DELETE request tests to match new behavior
- Remove references to deprecated startServerListeningToRedis
- Add proper waits for async operations
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add cleanup function to mcp server creation
- Export new Redis transport functions from index
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
**MCP Server Auth Page (src/auth/provider.ts):**
- Black background with white card design
- Official MCP logo and branding
- Clear client information display
- Elegant "Continue to Authentication" flow
- Professional MCP server identification
**Upstream Fake Auth Page (src/handlers/fakeauth.ts):**
- Updated branding to distinguish from MCP server
- Lock icon and "Upstream Authentication" title
- Clear user ID management with localStorage
- Generate/edit user ID functionality for testing
- Multi-user testing instructions
**Technical Updates:**
- Permissive CSP headers for both auth pages
- Logo serving route at /mcp-logo.png
- Responsive design with modern CSS
- Clear visual distinction between MCP server auth vs upstream auth
- Enhanced userId integration in OAuth authorization flow
Both pages now provide professional user experience while maintaining
clear distinction between the MCP server's auth and the fake upstream
provider auth for testing purposes.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add userId: string field to distinguish individual users from OAuth clients
- Prepares for user session isolation implementation
- clientId represents OAuth application, userId represents individual user
This separation allows multiple users to use the same OAuth client while
maintaining session isolation for security.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Test Redis subscription cleanup after response completion
- Test DELETE request session termination with control messages
- Test error handling for invalid session IDs
- Test user session isolation scenarios (documents expected behavior)
- Use MockRedisClient directly instead of mocking the mock
- Verify actual Redis channel creation and cleanup behavior
- Add proper Express Response mock with all required methods
Tests cover the three key areas:
1. Redis subscription cleanup after shttp responses
2. MCP server shutdown on DELETE requests
3. Session isolation between authenticated users
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>