* feat(examples): add SSE transport support to all example servers
Add backwards-compatible SSE transport support alongside the current
Streamable HTTP transport. Each server now exposes:
- /mcp (GET, POST, DELETE) - Streamable HTTP transport (current spec)
- /sse (GET) - Legacy SSE transport stream endpoint
- /messages (POST) - Legacy SSE transport message endpoint
This enables older clients using the deprecated HTTP+SSE protocol
(version 2024-11-05) to connect to the example servers.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* refactor(examples): migrate 6 servers to use shared server utility
Refactored the following example servers to use the shared startServer utility from examples/shared/server-utils.ts:
- threejs-server
- system-monitor-server
- cohort-heatmap-server
- budget-allocator-server
- customer-segmentation-server
- scenario-modeler-server
Changes for each server:
- Removed direct imports: SSEServerTransport, StdioServerTransport, StreamableHTTPServerTransport, cors, express
- Removed PORT constant (now handled by shared utility)
- Added import for startServer from ../shared/server-utils.js
- Replaced entire async main() function with single startServer() call
- Preserved all business logic (tool registration, resource registration, helper functions)
This reduces code duplication by ~700 lines and ensures consistent transport handling across all example servers.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* refactor(examples): migrate remaining servers to shared utility
Complete the migration of example servers to use the shared
server-utils.ts module for transport setup:
- basic-server-react
- basic-server-vanillajs
- wiki-explorer-server
- Add shared/server-utils.ts
This centralizes all transport handling (stdio, Streamable HTTP, SSE)
in one place, reducing code duplication across ~500 lines.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(examples): improve server-utils with stateful sessions and security
Address critical issues in the shared server utility:
1. Stateful sessions: Use sessionIdGenerator + onsessioninitialized
to persist StreamableHTTPServerTransport across requests
2. Unified session store: Single Map for both transport types with
proper type discrimination
3. Error handling: Try/catch on all endpoints with JSON-RPC errors
4. DNS rebinding protection: Use SDK's createMcpExpressApp helper
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(examples): allow connections from any host for development
Use host: "0.0.0.0" in createMcpExpressApp to disable DNS rebinding
protection, allowing connections from Android emulators and other
devices on the network. Also re-add CORS middleware.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* refactor(examples): use getPort() helper for transport selection
- Add getPort() helper that returns undefined for --stdio, else port
- Caller now explicitly passes port to startServer()
- port: undefined → stdio mode, port: number → HTTP mode
This makes the transport selection explicit at the call site.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(examples): startServer returns promise that resolves/rejects on listen
Use httpServer.on('listening') and httpServer.on('error') events
to properly resolve or reject the returned promise.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(examples): add error handling to startServer calls
Exit with code 1 if server fails to start (e.g., port in use).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* refactor(examples): update server files to use main() pattern with stdio support
Update all example server files to use the new main() pattern that supports both HTTP and stdio transports:
- Add StdioServerTransport import
- Remove getPort import (replaced with direct env var parsing)
- Replace direct startServer call with async main() function
- Add --stdio flag detection to choose between transports
- Use PORT env var with default 3001 for HTTP mode
Updated servers:
- basic-server-vanillajs
- wiki-explorer-server
- threejs-server
- system-monitor-server
- cohort-heatmap-server
- budget-allocator-server
- customer-segmentation-server
- scenario-modeler-server
Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(examples): use correct default ports matching run-all.ts
Each server now defaults to its assigned port from run-all.ts:
- basic-server-react: 3101
- basic-server-vanillajs: 3102
- budget-allocator-server: 3103
- cohort-heatmap-server: 3104
- customer-segmentation-server: 3105
- scenario-modeler-server: 3106
- system-monitor-server: 3107
- threejs-server: 3108
- wiki-explorer-server: 3109
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix(examples): expose mcp-session-id header for CORS requests
Without exposedHeaders in the CORS config, browsers block JavaScript
from reading the mcp-session-id response header. This caused the SDK's
StreamableHTTPClientTransport to never capture the session ID, breaking
all subsequent requests with "Bad request: not initialized" errors.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* pretty:fix
---------
Co-authored-by: Claude <noreply@anthropic.com>
Replace hardcoded port assignments and npm scripts with run-all.ts that:
- Auto-discovers example directories and assigns ports
- Passes server URLs to basic-host via SERVERS env var
- Supports start, dev, and build commands
Update basic-host to fetch server list from /api/servers endpoint
and display server names from MCP server metadata.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Not all MCP clients support structuredContent in MCP tool results, so
examples now return data as JSON in content and parse it client-side.
Pattern used:
- Server: content: [{ type: "text", text: JSON.stringify(data) }]
- Client: JSON.parse(result.content!.filter(...).map(...).join(""))
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Apply MIME type change from commit 0af1532 to all examples and docs.
The profile parameter follows RFC 6838 recommendations for custom
media types, as MCP Apps is a profile of HTML rather than a new syntax.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Introduce new example implementations to replace simple-host and
simple-server:
- basic-host: Reference host implementation with double-iframe sandbox
pattern for secure UI isolation (outer iframe validates and relays
messages, inner iframe renders untrusted tool UI via srcdoc)
- basic-server-react: MCP server example demonstrating tool registration
with linked UI resources and React UI using the useApp() hook
Build infrastructure updates:
- Add build:all script and simplify CI/pre-commit to use it
- Add examples:dev for watch-mode development workflow
Also change PostMessageTransport logging from info to debug level.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>