Remove bearer auth middleware from all /:slug/mcp routes (pdf, map, etc.)
so they are publicly accessible without an OAuth token. The root /mcp
endpoint retains its existing bearer auth requirement.
https://claude.ai/code/session_019bG1wzY84JA7LbpkybddP9
Add INFO-level logging to both the stateful SHTTP handler and the
stateless example-apps handler to show the full client capabilities
sent during MCP initialization, including any extensions like
io.modelcontextprotocol/ui.
This helps verify that clients are correctly sending UI extension
capabilities during the initialization handshake.
Remove trailing slash from baseUri before constructing example server
URLs to avoid URLs like "example.com//budget-allocator/mcp".
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Each MCP App example server now has a copy button that copies the
full URL (including domain) to clipboard for easy pasting into Claude.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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>