### Clone and Start MCP Server Source: https://github.com/modelcontextprotocol/example-remote-server/blob/main/README.md Clone the repository, install dependencies, and start the server with internal authentication and in-memory session management for quick exploration. ```bash git clone https://github.com/modelcontextprotocol/example-remote-server.git cd example-remote-server npm install npm run dev:internal ``` -------------------------------- ### Okta Provider Configuration Example Source: https://github.com/modelcontextprotocol/example-remote-server/blob/main/docs/oauth-implementation.md Example environment variable for Okta, specifying the base URL and the introspection endpoint. ```bash AUTH_SERVER_URL=https://your-domain.okta.com/oauth2/default # Introspection endpoint: /v1/introspect ``` -------------------------------- ### Initialize MCP Session with Example App Server (curl) Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt Initialize an MCP session with an example app server using a POST request. Ensure you include the correct Authorization header and Content-Type. The example app endpoints are listed on server startup. ```bash # Available example app endpoints (shown on server startup): # http://localhost:3232/budget-allocator/mcp # http://localhost:3232/cohort-heatmap/mcp # http://localhost:3232/customer-segmentation/mcp # http://localhost:3232/debug/mcp # http://localhost:3232/map/mcp # http://localhost:3232/pdf/mcp # ... (one per @modelcontextprotocol/server-* package) # Initialize a session against an example app server: curl -X POST http://localhost:3232/budget-allocator/mcp \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{ "jsonrpc": "2.0", "id": "init", "method": "initialize", "params": { "protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": { "name": "my-client", "version": "1.0" } } }' ``` -------------------------------- ### Auth0 Provider Configuration Example Source: https://github.com/modelcontextprotocol/example-remote-server/blob/main/docs/oauth-implementation.md Example environment variable for Auth0, specifying the base URL and the introspection endpoint. ```bash AUTH_SERVER_URL=https://your-tenant.auth0.com # Introspection endpoint: /oauth/token_info ``` -------------------------------- ### Bootstrap Express Application Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt Initializes and starts the Express server, wiring together authentication, MCP, and example app modules. The mounted modules depend on the configured authentication mode. ```typescript // npm run dev:internal → AUTH_MODE=internal (single process, all-in-one) // npm run dev:external → AUTH_MODE=external (MCP server only, separate auth) // AUTH_MODE=auth_server → standalone OAuth server, no MCP endpoints // Startup sequence: // 1. Load config // 2. Connect Redis (if REDIS_URL set) // 3. Mount AuthModule (internal / auth_server modes) // 4. Mount MCPModule (internal / external modes) // 5. Mount ExampleAppsModule // 6. Register /.well-known/oauth-authorization-server metadata endpoint // 7. app.listen(config.port) // After startup, logged endpoints: // Auth Endpoints: // Register Client : POST http://localhost:3232/register // Authorize : GET http://localhost:3232/authorize // Get Token : POST http://localhost:3232/token // Introspect : POST http://localhost:3232/introspect // Revoke : POST http://localhost:3232/revoke // MCP Endpoints: // Streamable HTTP : POST/GET/DELETE http://localhost:3232/mcp // SSE (legacy) : GET http://localhost:3232/sse // OAuth Metadata : GET http://localhost:3232/.well-known/oauth-authorization-server ``` -------------------------------- ### Start Redis with Docker Compose Source: https://github.com/modelcontextprotocol/example-remote-server/blob/main/README.md Use this command to start a Redis instance in the background for session management. Run `docker compose down` to stop it. ```bash docker compose up -d ``` -------------------------------- ### Azure AD Provider Configuration Example Source: https://github.com/modelcontextprotocol/example-remote-server/blob/main/docs/oauth-implementation.md Example environment variable for Azure AD, specifying the base URL. Note that introspection may require additional configuration. ```bash AUTH_SERVER_URL=https://login.microsoftonline.com/your-tenant-id # May require additional configuration for introspection ``` -------------------------------- ### Server Entry Point Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt The `main()` function bootstraps the Express application, wiring modules together, connecting Redis if configured, and starting the server. It handles different authentication modes and mounts relevant modules. ```APIDOC ## `main()` — Bootstrap the Express application Wires all modules together, connects Redis if configured, and starts listening. Auth mode determines which modules are mounted. ```typescript // npm run dev:internal → AUTH_MODE=internal (single process, all-in-one) // npm run dev:external → AUTH_MODE=external (MCP server only, separate auth) // AUTH_MODE=auth_server → standalone OAuth server, no MCP endpoints // Startup sequence: // 1. Load config // 2. Connect Redis (if REDIS_URL set) // 3. Mount AuthModule (internal / auth_server modes) // 4. Mount MCPModule (internal / external modes) // 5. Mount ExampleAppsModule // 6. Register /.well-known/oauth-authorization-server metadata endpoint // 7. app.listen(config.port) // After startup, logged endpoints: // Auth Endpoints: // Register Client : POST http://localhost:3232/register // Authorize : GET http://localhost:3232/authorize // Get Token : POST http://localhost:3232/token // Introspect : POST http://localhost:3232/introspect // Revoke : POST http://localhost:3232/revoke // MCP Endpoints: // Streamable HTTP : POST/GET/DELETE http://localhost:3232/mcp // SSE (legacy) : GET http://localhost:3232/sse // OAuth Metadata : GET http://localhost:3232/.well-known/oauth-authorization-server ``` ``` -------------------------------- ### Run MCP Inspector Source: https://github.com/modelcontextprotocol/example-remote-server/blob/main/README.md After starting the server, use the MCP Inspector to connect, authenticate, and explore the server's features in a browser. ```bash npx -y @modelcontextprotocol/inspector ``` -------------------------------- ### Initiate OAuth 2.0 Authorization Request with PKCE Source: https://github.com/modelcontextprotocol/example-remote-server/blob/main/docs/oauth-implementation.md Use this GET request to start the OAuth 2.0 flow. Ensure `code_challenge` is generated from a `code_verifier` using SHA256 and base64url encoding. ```http GET /authorize? client_id=abc123& redirect_uri=http://localhost:3000/callback& code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM& code_challenge_method=S256& state=xyz789 ``` -------------------------------- ### Client Registration Source: https://github.com/modelcontextprotocol/example-remote-server/blob/main/docs/oauth-implementation.md Register a new client application with the OAuth server. This is a one-time setup process. ```APIDOC ## POST /register ### Description Register a new client application with the OAuth server. ### Method POST ### Endpoint /register ### Parameters #### Request Body - **client_name** (string) - Required - The name of the client application. - **redirect_uris** (array of strings) - Required - A list of valid redirect URIs for the client. ### Request Example ```json { "client_name": "My MCP Client", "redirect_uris": ["http://localhost:3000/callback"] } ``` ### Response #### Success Response (200) - **client_id** (string) - The unique identifier for the registered client. - **client_secret** (string) - The secret for the registered client. - **client_id_issued_at** (integer) - Timestamp when the client ID was issued. - **client_secret_expires_at** (integer) - Timestamp when the client secret expires (0 indicates no expiry). ### Response Example ```json { "client_id": "abc123", "client_secret": "secret456", "client_id_issued_at": 1234567890, "client_secret_expires_at": 0 } ``` ### Storage Data is stored in Redis with a 30-day expiry under the key `auth:client:{clientId}`. ``` -------------------------------- ### Run MCP Server in External Auth Mode Source: https://github.com/modelcontextprotocol/example-remote-server/blob/main/README.md This command starts the MCP server with an external authentication server. The demo authorization server will also be started. ```bash npm run dev:external ``` -------------------------------- ### Redis CLI Commands for Session Monitoring Source: https://github.com/modelcontextprotocol/example-remote-server/blob/main/docs/session-ownership.md Provides command-line examples for monitoring session ownership and liveness using redis-cli. Useful for debugging and understanding session state. ```bash # List all session owners redis-cli KEYS "session:*:owner" # Check specific session ownership redis-cli GET "session:{sessionId}:owner" # Check if session is live (actively being handled) redis-cli PUBSUB NUMSUB "mcp:shttp:toserver:{sessionId}" # Monitor session operations redis-cli MONITOR | grep "session:" ``` -------------------------------- ### Autocomplete Temperature Argument using MCP Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt Use this to get suggestions for the 'temperature' argument. Provide the prompt reference and the partial temperature value. ```bash # Complete temperature argument # argument: { "name": "temperature", "value": "0." } # result.completion: { "values": ["0.5", "0.7"], "hasMore": false, "total": 2 } ``` -------------------------------- ### Configure Redis for Sessions Source: https://github.com/modelcontextprotocol/example-remote-server/blob/main/README.md Start Redis using Docker Compose and configure the server to use Redis for session storage, enabling persistence across restarts. Verify Redis connection with a grep command. ```bash # Redis-backed sessions docker compose up -d # Start Redis first # configure REDIS_URL or pass on command line - see Session Management Config below - e.g. REDIS_URL=redis://localhost:6379 npm run dev:internal # Sessions will now persist across restarts # Verify Redis is being used npm run dev:internal 2>&1 | grep -i redis # Should show: "Redis client connected successfully" or similar ``` -------------------------------- ### Autocomplete Resource URI Argument using MCP Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt Use this to get suggestions for resource URI arguments. Provide the resource reference and the partial resource ID value. ```bash # Complete a resource URI argument # ref: { "type": "ref/resource", "uri": "test://static/resource/{id}" } # argument: { "name": "resourceId", "value": "1" } # result.completion: { "values": ["1", "2", "3", "4", "5"], "hasMore": false, "total": 5 } # (filters EXAMPLE_COMPLETIONS.resourceId ["1","2","3","4","5"] starting with "1") ``` -------------------------------- ### Autocomplete Prompt Argument using MCP Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt Use this to get suggestions for prompt arguments. Provide the prompt reference and the partial argument value. ```bash # Complete a prompt argument curl -X POST http://localhost:3232/mcp \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Mcp-Session-Id: ${SESSION_ID}" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{ "jsonrpc": "2.0", "id": "c1", "method": "completion/complete", "params": { "ref": { "type": "ref/prompt", "name": "complex_prompt" }, "argument": { "name": "style", "value": "f" } } }' ``` -------------------------------- ### GET /authorize - OAuth 2.0 Authorization Endpoint Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt Initiates the OAuth 2.0 authorization code flow with PKCE support. ```APIDOC ## GET /authorize ### Description This endpoint initiates the OAuth 2.0 authorization code grant flow, incorporating Proof Key for Code Exchange (PKCE) for enhanced security. Clients should redirect users to this endpoint with appropriate parameters. ### Method `GET` ### Endpoint `/authorize` ### Parameters #### Path Parameters None #### Query Parameters - **client_id** (string) - Required - The client ID of the application. - **redirect_uri** (string) - Required - The URI to redirect the user to after authorization. - **response_type** (string) - Required - Must be set to `code` for authorization code grant. - **code_challenge** (string) - Required - The challenge generated from the code verifier using a specified method. - **code_challenge_method** (string) - Required - The method used to generate the `code_challenge`. Typically `S256`. - **state** (string) - Optional - An opaque value used to maintain state between the request and callback. ### Request Example ```bash # 1. Client generates PKCE pair CODE_VERIFIER=$(openssl rand -base64 32 | tr -d '=+/' | cut -c1-43) CODE_CHALLENGE=$(echo -n "$CODE_VERIFIER" | openssl dgst -sha256 -binary | openssl base64 | tr -d '=' | tr '+/' '-_') # 2. Open in browser open "http://localhost:3232/authorize?\ client_id=a1b2c3d4&\ redirect_uri=http://localhost:3000/callback&\ response_type=code&\ code_challenge=${CODE_CHALLENGE}&\ code_challenge_method=S256&\ state=random-state-xyz" ``` ### Response #### Success Response Upon successful user authorization, the server redirects the user's browser to the `redirect_uri` with an authorization `code` and the `state` parameter. Example Redirect URL: `http://localhost:3000/callback?code=AUTH_CODE&state=random-state-xyz` *Note: The authorization code has a 10-minute TTL and is stored temporarily, often in Redis under the key `auth:pending:{AUTH_CODE}`.* #### Error Response Standard OAuth 2.0 error responses will be returned if parameters are invalid or authorization fails. ``` -------------------------------- ### Call MCP Tool with cURL Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt Calls a specific tool within an active MCP session. This example demonstrates calling the 'add' tool with arguments 'a' and 'b', then processing the JSON output to extract the content. ```shell curl -s -X POST "${BASE}/mcp" \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Mcp-Session-Id: ${SESSION_ID}" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{"jsonrpc":"2.0","id":"1","method":"tools/call","params":{"name":"add","arguments":{"a":10,"b":32}}}' \ | grep '^data:' | cut -c7- | jq .result.content ``` -------------------------------- ### Run MCP Server in Internal Auth Mode Source: https://github.com/modelcontextprotocol/example-remote-server/blob/main/README.md This command starts the MCP server with an internal authentication mode, where auth endpoints run in-process. ```bash npm run dev:internal ``` -------------------------------- ### Call MCP App Tool `mcp_apps_hello_world` Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt Use this to call the `mcp_apps_hello_world` tool. For clients supporting MCP Apps, this renders an interactive HTML UI. ```bash curl -X POST http://localhost:3232/mcp \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Mcp-Session-Id: ${SESSION_ID}" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{ "jsonrpc": "2.0", "id": "t9", "method": "tools/call", "params": { "name": "mcp_apps_hello_world", "arguments": {} } }' ``` -------------------------------- ### Token Exchange Response Source: https://github.com/modelcontextprotocol/example-remote-server/blob/main/docs/oauth-implementation.md Example JSON response received after a successful token exchange, containing access and refresh tokens. ```json { "access_token": "eyJhbGc...", "refresh_token": "refresh_xyz", "token_type": "Bearer", "expires_in": 604800 } ``` -------------------------------- ### mcp_apps_hello_world tool Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt Calls the 'mcp_apps_hello_world' tool, which renders an interactive HTML UI for clients that support MCP Apps. ```APIDOC ## `mcp_apps_hello_world` tool — Interactive MCP App UI ### Description Calls the `mcp_apps_hello_world` tool to render an interactive HTML UI. ### Method POST ### Endpoint `http://localhost:3232/mcp` ### Headers - `Authorization`: Bearer ${ACCESS_TOKEN} - `Mcp-Session-Id`: ${SESSION_ID} - `Content-Type`: application/json - `Accept`: application/json, text/event-stream ### Request Body ```json { "jsonrpc": "2.0", "id": "t9", "method": "tools/call", "params": { "name": "mcp_apps_hello_world", "arguments": {} } } ``` ### Response Example (Success) ```json { "result": { "structuredContent": { "greeting": "Hello from MCP Apps!", "timestamp": "2024-04-05T10:30:00.000Z", "features": ["interactive UI","bidirectional communication","theme support"], "stats": { "version": "1.0.0", "requestCount": 427 } }, "_meta": { "exampleKey": "exampleValue", "processed": true } } } ``` ``` -------------------------------- ### List MCP Resources (Paginated) Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt Use this to list resources. The first request retrieves the initial page of 10 items. Subsequent requests use the `cursor` from the previous response to fetch the next page. ```bash # First page (10 items) curl -X POST http://localhost:3232/mcp \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Mcp-Session-Id: ${SESSION_ID}" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{"jsonrpc":"2.0","id":"r1","method":"resources/list"}' ``` ```bash # Next page using cursor: curl -X POST http://localhost:3232/mcp \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Mcp-Session-Id: ${SESSION_ID}" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{"jsonrpc":"2.0","id":"r2","method":"resources/list","params":{"cursor":"MTA="}}' ``` -------------------------------- ### List MCP Prompts Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt Use this to list all available prompts. Each prompt may have a name, description, and a list of arguments. ```bash curl -X POST http://localhost:3232/mcp \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Mcp-Session-Id: ${SESSION_ID}" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{"jsonrpc":"2.0","id":"p1","method":"prompts/list"}' ``` -------------------------------- ### List MCP Resource URI Templates Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt Use this to list available resource URI templates, which describe how resource URIs are structured. ```bash curl -X POST http://localhost:3232/mcp \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Mcp-Session-Id: ${SESSION_ID}" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{"jsonrpc":"2.0","id":"rt1","method":"resources/templates/list"}' ``` -------------------------------- ### Call 'add' Tool Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt Demonstrates calling the 'add' tool via a POST request to the /mcp endpoint, including session ID and numeric arguments. The result contains the sum. ```bash curl -X POST http://localhost:3232/mcp \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Mcp-Session-Id: ${SESSION_ID}" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{ "jsonrpc": "2.0", "id": "t2", "method": "tools/call", "params": { "name": "add", "arguments": { "a": 42, "b": 58 } } }' # result.content: [{ "type": "text", "text": "The sum of 42 and 58 is 100." }] ``` -------------------------------- ### Get Resource Reference with getResourceReference Tool Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt Returns an embedded resource reference, including its URI. This allows clients to access specific resources. ```bash curl -X POST http://localhost:3232/mcp \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Mcp-Session-Id: ${SESSION_ID}" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{ "jsonrpc": "2.0", "id": "t7", "method": "tools/call", "params": { "name": "getResourceReference", "arguments": { "resourceId": 5 } } }' ``` -------------------------------- ### Initialize MCP Module Server Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt Sets up the MCPModule with a base URI and token validator. The router is then used as middleware. ```typescript import { MCPModule } from './modules/mcp/index.js'; const mcpModule = new MCPModule( { baseUri: 'http://localhost:3232', redisUrl: process.env.REDIS_URL }, tokenValidator // any ITokenValidator implementation ); app.use('/', mcpModule.getRouter()); // Exposes: // GET/POST/DELETE /mcp — Streamable HTTP transport (recommended) // GET /sse — SSE connection (legacy) // POST /message — SSE message posting (legacy) ``` -------------------------------- ### NPM Test Commands for Session Isolation and Ownership Source: https://github.com/modelcontextprotocol/example-remote-server/blob/main/docs/session-ownership.md Demonstrates how to run specific test suites using npm test to verify session isolation and ownership functionalities. ```bash # Test session isolation npm test -- --testNamePattern="User Session Isolation" # Test session ownership npm test -- --testNamePattern="Session Ownership" ``` -------------------------------- ### OAuth Metadata Discovery Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt The `GET /.well-known/oauth-authorization-server` endpoint provides RFC 8414 OAuth server metadata, allowing MCP clients to discover available OAuth endpoints. ```APIDOC ## `GET /.well-known/oauth-authorization-server` — RFC 8414 OAuth server metadata MCP clients call this endpoint first to discover all OAuth endpoints. In internal mode it points to the same host; in external mode it points to `AUTH_SERVER_URL`. ```bash curl http://localhost:3232/.well-known/oauth-authorization-server # Response: # { # "issuer": "http://localhost:3232", # "authorization_endpoint": "http://localhost:3232/authorize", # "token_endpoint": "http://localhost:3232/token", # "registration_endpoint": "http://localhost:3232/register", # "introspection_endpoint": "http://localhost:3232/introspect", # "revocation_endpoint": "http://localhost:3232/revoke", # "token_endpoint_auth_methods_supported": ["none"], # "response_types_supported": ["code"], # "grant_types_supported": ["authorization_code", "refresh_token"], # "code_challenge_methods_supported": ["S256"], # "service_documentation": "https://modelcontextprotocol.io" # } ``` ``` -------------------------------- ### End-to-End OAuth + MCP Session Flow (bash) Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt This script demonstrates a full client flow including OAuth discovery, client registration, PKCE generation, and token exchange to establish an MCP session. It requires `curl`, `jq`, and `openssl`. ```bash BASE="http://localhost:3232" # 1. Discover OAuth endpoints curl -s "${BASE}/.well-known/oauth-authorization-server" | jq . # 2. Register a client CLIENT=$(curl -s -X POST "${BASE}/register" \ -H "Content-Type: application/json" \ -d '{"client_name":"shell-client","redirect_uris":["http://localhost:9999/cb"]}') CLIENT_ID=$(echo $CLIENT | jq -r .client_id) CLIENT_SECRET=$(echo $CLIENT | jq -r .client_secret) # 3. Generate PKCE VERIFIER=$(openssl rand -base64 32 | tr -d '=+/' | cut -c1-43) CHALLENGE=$(echo -n "$VERIFIER" | openssl dgst -sha256 -binary | openssl base64 | tr -d '=' | tr '+/' '-_') # 4. Open browser, get auth code, exchange for token AUTH_URL="${BASE}/authorize?client_id=${CLIENT_ID}&redirect_uri=http://localhost:9999/cb&response_type=code&code_challenge=${CHALLENGE}&code_challenge_method=S256&state=abc" echo "Open: $AUTH_URL" read -p "Paste auth code: " CODE TOKEN_RESP=$(curl -s -X POST "${BASE}/token" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "grant_type=authorization_code&client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}&code=${CODE}&redirect_uri=http://localhost:9999/cb&code_verifier=${VERIFIER}") ACCESS_TOKEN=$(echo $TOKEN_RESP | jq -r .access_token) ``` -------------------------------- ### Create MCP Server with Tools Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt Creates an MCP server instance with all registered tools, resources, and prompts. The returned cleanup function should be called to clear intervals. ```typescript import { createMcpServer } from './modules/mcp/services/mcp.js'; const { server, cleanup } = createMcpServer(); // server has capabilities: prompts, resources (with subscribe), tools, logging, completions // Periodic notifications fire automatically: // every 10s: resource update notifications for all subscribed URIs // every 20s: random log-level notification (debug/info/notice/warning/error/critical/alert/emergency) // every 30s: stderr notification with timestamp // Connect to a transport then serve: await server.connect(transport); // Clean up intervals when done: cleanup(); ``` -------------------------------- ### Run Linting and Tests Source: https://github.com/modelcontextprotocol/example-remote-server/blob/main/README.md Commands for running code linting, type checking, unit tests, and end-to-end tests for the project. ```bash npm run lint ``` ```bash npm run typecheck ``` ```bash npm test ``` ```bash npm run test:e2e ``` -------------------------------- ### Manually Clean Up Redis Auth Data Source: https://github.com/modelcontextprotocol/example-remote-server/blob/main/docs/oauth-implementation.md Commands for manually removing authentication data from Redis. Use with caution as `redis-cli DEL "auth:installation:ACCESS_TOKEN"` removes a specific session, while `redis-cli --scan --pattern "auth:*" | xargs redis-cli DEL` removes all auth data. ```bash # Remove all auth data (CAUTION: will log out all users) redis-cli --scan --pattern "auth:*" | xargs redis-cli DEL # Remove specific user session redis-cli DEL "auth:installation:ACCESS_TOKEN" ``` -------------------------------- ### Retrieve a Simple Prompt using MCP Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt Use this to fetch a predefined prompt that does not require any arguments. Ensure the MCP server is running and accessible. ```bash # Simple prompt (no arguments) curl -X POST http://localhost:3232/mcp \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Mcp-Session-Id: ${SESSION_ID}" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{ "jsonrpc": "2.0", "id": "p2", "method": "prompts/get", "params": { "name": "simple_prompt" } }' ``` -------------------------------- ### prompts/list Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt Lists all available prompts, including their names, descriptions, and arguments. ```APIDOC ## `prompts/list` — List all available prompts ### Description Fetches a list of all prompts available in the system. Each prompt includes its name, a description, and details about its arguments if any. ### Method POST ### Endpoint `http://localhost:3232/mcp` ### Headers - `Authorization`: Bearer ${ACCESS_TOKEN} - `Mcp-Session-Id`: ${SESSION_ID} - `Content-Type`: application/json - `Accept`: application/json, text/event-stream ### Request Body ```json { "jsonrpc": "2.0", "id": "p1", "method": "prompts/list" } ``` ### Response Example ```json { "result": { "prompts": [ { "name": "simple_prompt", "description": "A prompt without arguments" }, { "name": "complex_prompt", "description": "A prompt with arguments", "arguments": [ // ... argument definitions ... ] } ] } } ``` ``` -------------------------------- ### OAuth 2.0 Authorization Endpoint with PKCE Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt Initiate the OAuth 2.0 authorization flow with Proof Key for Code Exchange (PKCE). This involves generating a code verifier and challenge, opening the authorization URL in a browser, and handling the redirect with an authorization code. ```bash # 1. Client generates PKCE pair CODE_VERIFIER=$(openssl rand -base64 32 | tr -d '=+/' | cut -c1-43) CODE_CHALLENGE=$(echo -n "$CODE_VERIFIER" | openssl dgst -sha256 -binary | openssl base64 | tr -d '=' | tr '+/' '-_') # 2. Open in browser open "http://localhost:3232/authorize?\ client_id=a1b2c3d4&\ redirect_uri=http://localhost:3000/callback&\ response_type=code&\ code_challenge=${CODE_CHALLENGE}&\ code_challenge_method=S256&\ state=random-state-xyz" # Server shows HTML consent page, user clicks "Continue to Authentication" # Redirects to: http://localhost:3000/callback?code=AUTH_CODE&state=random-state-xyz # Redis key: auth:pending:{AUTH_CODE} (10-minute TTL) ``` -------------------------------- ### Production Server Commands Source: https://github.com/modelcontextprotocol/example-remote-server/blob/main/README.md Commands to build and run the server in production mode. This mode is optimized for performance and does not auto-restart. ```bash # Production mode - optimized build, no auto-restart npm run build # Build TypeScript to JavaScript first # then npm run start:internal # Internal auth # or npm run start:external # External auth ``` -------------------------------- ### prompts/get Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt Retrieve a specific prompt, optionally with arguments. This endpoint allows fetching predefined prompts and providing dynamic arguments to customize their behavior. ```APIDOC ## prompts/get — Retrieve a specific prompt, optionally with arguments ### Description Retrieve a specific prompt, optionally with arguments. This endpoint allows fetching predefined prompts and providing dynamic arguments to customize their behavior. ### Method POST ### Endpoint http://localhost:3232/mcp ### Parameters #### Request Body - **jsonrpc** (string) - Required - JSON-RPC version, must be "2.0". - **id** (string) - Required - Unique identifier for the request. - **method** (string) - Required - The method to call, must be "prompts/get". - **params** (object) - Required - Parameters for the method. - **name** (string) - Required - The name of the prompt to retrieve. - **arguments** (object) - Optional - Key-value pairs for prompt arguments. - **temperature** (string) - Optional - Temperature setting for the prompt. - **style** (string) - Optional - Output style for the prompt. - **resourceId** (string) - Optional - Resource ID to include in the prompt. ### Request Example ```json { "jsonrpc": "2.0", "id": "p2", "method": "prompts/get", "params": { "name": "simple_prompt" } } ``` ### Response #### Success Response (200) - **result.messages** (array) - An array of message objects representing the prompt's content. - **role** (string) - The role of the message sender (e.g., "user", "assistant"). - **content** (object) - The content of the message. - **type** (string) - The type of content (e.g., "text", "resource"). - **text** (string) - The text content of the message (if type is "text"). - **resource** (object) - Resource details (if type is "resource"). - **uri** (string) - The URI of the resource. #### Response Example ```json { "jsonrpc": "2.0", "id": "p2", "result": { "messages": [ { "role": "user", "content": { "type": "text", "text": "This is a simple prompt without arguments." } } ] } } ``` ``` -------------------------------- ### sampleLLM Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt Requests LLM sampling from the connected client. It takes a prompt and maximum tokens as arguments and returns the LLM's response. ```APIDOC ## POST /mcp ### Description Requests LLM sampling from the connected client. ### Method POST ### Endpoint /mcp ### Parameters #### Request Body - **jsonrpc** (string) - Required - JSON-RPC version, should be "2.0". - **id** (string) - Required - Unique identifier for the request. - **method** (string) - Required - The method to call, should be "tools/call". - **params** (object) - Required - Parameters for the tool call. - **name** (string) - Required - The name of the tool, should be "sampleLLM". - **arguments** (object) - Required - Arguments for the tool. - **prompt** (string) - Required - The prompt to send to the LLM. - **maxTokens** (integer) - Optional - The maximum number of tokens to generate. ### Request Example ```json { "jsonrpc": "2.0", "id": "t4", "method": "tools/call", "params": { "name": "sampleLLM", "arguments": { "prompt": "Summarize the MCP protocol in one sentence.", "maxTokens": 80 } } } ``` ### Response #### Success Response (200) - **jsonrpc** (string) - The JSON-RPC version. - **id** (string) - The request ID. - **result** (object) - The result of the LLM sampling. - **content** (array) - An array of content blocks. - **type** (string) - The type of content, e.g., "text". - **text** (string) - The LLM's response content. ``` -------------------------------- ### Call 'echo' Tool Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt Demonstrates calling the 'echo' tool via a POST request to the /mcp endpoint, including session ID and tool arguments. The result contains the echoed text. ```bash curl -X POST http://localhost:3232/mcp \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Mcp-Session-Id: ${SESSION_ID}" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{ "jsonrpc": "2.0", "id": "t1", "method": "tools/call", "params": { "name": "echo", "arguments": { "message": "Hello, MCP!" } } }' # result.content: [{ "type": "text", "text": "Echo: Hello, MCP!" }] ``` -------------------------------- ### Request LLM Sampling with sampleLLM Tool Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt Requests LLM sampling from the connected client. The response is sent back to the client via `sampling/createMessage` and depends on the client's LLM. ```bash curl -X POST http://localhost:3232/mcp \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Mcp-Session-Id: ${SESSION_ID}" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{ "jsonrpc": "2.0", "id": "t4", "method": "tools/call", "params": { "name": "sampleLLM", "arguments": { "prompt": "Summarize the MCP protocol in one sentence.", "maxTokens": 80 } } }' ``` -------------------------------- ### MCP Server Request Flow for Session Initialization Source: https://github.com/modelcontextprotocol/example-remote-server/blob/main/docs/session-ownership.md Illustrates the sequence of interactions between a client, the MCP server, and Redis when initializing a new session. ```mermaid sequenceDiagram participant Client participant MCP as MCP Server participant Redis Client->>MCP: POST /mcp (initialize) MCP->>MCP: Extract userId from OAuth token MCP->>MCP: Generate sessionId MCP->>Redis: SET session:{sessionId}:owner = userId MCP->>Client: Return sessionId ``` -------------------------------- ### completion/complete Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt Autocomplete for prompt arguments and resource URIs. This endpoint helps in providing suggestions for prompt arguments or resource identifiers based on partial input. ```APIDOC ## completion/complete — Autocomplete for prompt arguments and resource URIs ### Description Autocomplete for prompt arguments and resource URIs. This endpoint helps in providing suggestions for prompt arguments or resource identifiers based on partial input. ### Method POST ### Endpoint http://localhost:3232/mcp ### Parameters #### Request Body - **jsonrpc** (string) - Required - JSON-RPC version, must be "2.0". - **id** (string) - Required - Unique identifier for the request. - **method** (string) - Required - The method to call, must be "completion/complete". - **params** (object) - Required - Parameters for the method. - **ref** (object) - Required - A reference to the prompt or resource. - **type** (string) - Required - The type of reference (e.g., "ref/prompt", "ref/resource"). - **name** (string) - Required if type is "ref/prompt" - The name of the prompt. - **uri** (string) - Required if type is "ref/resource" - The URI pattern for the resource. - **argument** (object) - Required - The argument to complete. - **name** (string) - Required - The name of the argument. - **value** (string) - Required - The partial value of the argument. ### Request Example ```json { "jsonrpc": "2.0", "id": "c1", "method": "completion/complete", "params": { "ref": { "type": "ref/prompt", "name": "complex_prompt" }, "argument": { "name": "style", "value": "f" } } } ``` ### Response #### Success Response (200) - **result.completion** (object) - The completion results. - **values** (array of strings) - A list of possible completions. - **hasMore** (boolean) - Indicates if there are more results available. - **total** (integer) - The total number of available completions. #### Response Example ```json { "jsonrpc": "2.0", "id": "c1", "result": { "completion": { "values": ["formal", "friendly"], "hasMore": false, "total": 2 } } } ``` ``` -------------------------------- ### Update Server Configuration for External Auth Source: https://github.com/modelcontextprotocol/example-remote-server/blob/main/docs/oauth-implementation.md Configure the server to use an external OAuth provider by setting environment variables in a `.env` file. ```bash # .env file AUTH_MODE=external AUTH_SERVER_URL=https://your-tenant.auth0.com # For Okta: https://your-domain.okta.com # For Azure: https://login.microsoftonline.com/your-tenant ``` -------------------------------- ### Configuration Loading Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt The `loadConfig()` function loads server configuration from environment variables, returning a typed `Config` object. It validates specific configurations like external auth server URLs. ```APIDOC ## `loadConfig()` — Load server configuration from environment variables Reads environment variables and returns a typed `Config` object. Throws if `AUTH_MODE=external` but `AUTH_SERVER_URL` is not set. ```typescript // src/config.ts import { config } from './config.js'; // Default (internal auth, in-memory sessions, port 3232): // AUTH_MODE=internal BASE_URI=http://localhost:3232 PORT=3232 // External auth server + Redis sessions: // AUTH_MODE=external // AUTH_SERVER_URL=https://your-tenant.auth0.com // BASE_URI=https://my-mcp-server.example.com // REDIS_URL=redis://localhost:6379 // REDIS_TLS=1 // REDIS_PASSWORD=secret // NODE_ENV=production ← causes process.exit(1) if Redis fails to connect console.log(config.auth.mode); // 'internal' | 'external' | 'auth_server' console.log(config.redis.enabled); // true when REDIS_URL is set console.log(config.baseUri); // e.g. "http://localhost:3232" ``` ``` -------------------------------- ### Initialize AuthModule and Mount Routes Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt Instantiate the AuthModule and mount its OAuth routes onto an Express app. The AuthModule handles all OAuth logic, operating in internal mode by directly calling introspectToken or in external mode by returning data over HTTP. ```typescript import { AuthModule } from './modules/auth/index.js'; const authModule = new AuthModule({ baseUri: 'http://localhost:3232', authServerUrl: 'http://localhost:3232', // points to itself in internal mode redisUrl: process.env.REDIS_URL // optional }); // Mount all OAuth routes onto Express app app.use('/', authModule.getRouter()); ``` -------------------------------- ### Load Server Configuration Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt Loads server configuration from environment variables. Throws an error if external authentication is enabled but the authorization server URL is missing. Supports in-memory or Redis sessions. ```typescript // src/config.ts import { config } from './config.js'; // Default (internal auth, in-memory sessions, port 3232): // AUTH_MODE=internal BASE_URI=http://localhost:3232 PORT=3232 // External auth server + Redis sessions: // AUTH_MODE=external // AUTH_SERVER_URL=https://your-tenant.auth0.com // BASE_URI=https://my-mcp-server.example.com // REDIS_URL=redis://localhost:6379 // REDIS_TLS=1 // REDIS_PASSWORD=secret // NODE_ENV=production ← causes process.exit(1) if Redis fails to connect console.log(config.auth.mode); // 'internal' | 'external' | 'auth_server' console.log(config.redis.enabled); // true when REDIS_URL is set console.log(config.baseUri); // e.g. "http://localhost:3232" ``` -------------------------------- ### Client Registration Request Source: https://github.com/modelcontextprotocol/example-remote-server/blob/main/docs/oauth-implementation.md Register a new client application with the OAuth server using a POST request to /register. Include client name and redirect URIs. ```http POST /register Content-Type: application/json { "client_name": "My MCP Client", "redirect_uris": ["http://localhost:3000/callback"] } ``` -------------------------------- ### resources/templates/list Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt Lists available resource URI templates, which describe patterns for resource URIs. ```APIDOC ## `resources/templates/list` — List resource URI templates ### Description Retrieves a list of URI templates that define the structure and naming conventions for various resources within the MCP system. ### Method POST ### Endpoint `http://localhost:3232/mcp` ### Headers - `Authorization`: Bearer ${ACCESS_TOKEN} - `Mcp-Session-Id`: ${SESSION_ID} - `Content-Type`: application/json - `Accept`: application/json, text/event-stream ### Request Body ```json { "jsonrpc": "2.0", "id": "rt1", "method": "resources/templates/list" } ``` ### Response Example ```json { "result": { "resourceTemplates": [ { "uriTemplate": "test://static/resource/{id}", "name": "Static Resource", "description": "A static resource with a numeric ID" } ] } } ``` ``` -------------------------------- ### Development Server Commands Source: https://github.com/modelcontextprotocol/example-remote-server/blob/main/README.md Commands to run the development server with different authentication modes. The `dev` commands include auto-restarting on file changes and verbose logging. ```bash # Development mode - watches for file changes and auto-restarts npm run dev:internal # Internal auth # or npm run dev:external # External auth ``` -------------------------------- ### Elicit Structured User Input with elicitInputs Tool Source: https://context7.com/modelcontextprotocol/example-remote-server/llms.txt Requests structured user input through an elicitation process. The server defines the expected input fields and their types. ```bash curl -X POST http://localhost:3232/mcp \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H "Mcp-Session-Id: ${SESSION_ID}" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{ "jsonrpc": "2.0", "id": "t8", "method": "tools/call", "params": { "name": "elicitInputs", "arguments": {} } }' ```