Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 | 91x 91x 91x 14x 14x 14x 14x 14x 91x 9x 9x 9x 91x | /**
* OAuth Metadata Endpoint
*
* Implements the OAuth 2.0 Authorization Server Metadata endpoint
* (RFC 8414) at /.well-known/oauth-authorization-server
*
* This endpoint allows OAuth clients to discover server capabilities.
*/
import { Request, Response } from "express";
import { HOST, PORT } from "../../config";
/**
* MCP Protocol version supported by this server
* @see https://modelcontextprotocol.io/spec
*/
export const MCP_PROTOCOL_VERSION = "2025-03-26";
/**
* Get the base URL from the request
*
* Handles reverse proxy scenarios by checking X-Forwarded-* headers.
*
* @param req - Express request
* @returns Base URL string (e.g., "https://example.com")
*/
export function getBaseUrl(req: Request): string {
// Check for forwarded protocol (from reverse proxy)
const forwardedProto = req.get("x-forwarded-proto");
const protocol = forwardedProto ?? req.protocol ?? "http";
// Check for forwarded host (from reverse proxy)
const forwardedHost = req.get("x-forwarded-host");
const host = forwardedHost ?? req.get("host") ?? `${HOST}:${PORT}`;
return `${protocol}://${host}`;
}
/**
* OAuth Authorization Server Metadata endpoint handler
*
* Returns metadata about the OAuth server's capabilities including:
* - Issuer
* - Authorization and token endpoints
* - Supported response types, grant types, and PKCE methods
*
* @param req - Express request
* @param res - Express response
*/
export function metadataHandler(req: Request, res: Response): void {
const baseUrl = getBaseUrl(req);
// OAuth 2.0 Authorization Server Metadata (RFC 8414)
const metadata = {
// REQUIRED: Issuer identifier (must be HTTPS in production)
issuer: baseUrl,
// REQUIRED: Authorization endpoint
authorization_endpoint: `${baseUrl}/authorize`,
// REQUIRED: Token endpoint
token_endpoint: `${baseUrl}/token`,
// OPTIONAL: Supported response types
response_types_supported: ["code"],
// OPTIONAL: Supported grant types
grant_types_supported: ["authorization_code", "refresh_token"],
// OPTIONAL: Supported PKCE code challenge methods (S256 required for OAuth 2.1)
code_challenge_methods_supported: ["S256"],
// OPTIONAL: Token endpoint authentication methods
// "none" for public clients (device flow with non-confidential apps)
token_endpoint_auth_methods_supported: ["none"],
// OPTIONAL: Supported scopes
scopes_supported: ["mcp:tools", "mcp:resources"],
// REQUIRED for Claude.ai: Dynamic Client Registration endpoint (RFC 7591)
registration_endpoint: `${baseUrl}/register`,
// MCP-specific metadata
mcp_version: MCP_PROTOCOL_VERSION,
};
res.json(metadata);
}
/**
* OAuth Protected Resource Metadata endpoint handler (RFC 9470)
*
* Returns metadata about this MCP server as a protected resource,
* including a reference to the authorization server.
*
* @param req - Express request
* @param res - Express response
*/
export function protectedResourceHandler(req: Request, res: Response): void {
const baseUrl = getBaseUrl(req);
// OAuth 2.0 Protected Resource Metadata (RFC 9470)
const metadata = {
// REQUIRED: Resource identifier
resource: baseUrl,
// REQUIRED: Authorization servers that can be used to access this resource
authorization_servers: [baseUrl],
// OPTIONAL: Scopes required for this resource
scopes_supported: ["mcp:tools", "mcp:resources"],
// OPTIONAL: Bearer token methods supported
bearer_methods_supported: ["header"],
};
res.json(metadata);
}
// NOTE: healthHandler was removed in favor of a simple /health endpoint in server.ts.
// MCP metadata (version, tools, auth mode, instances) is available via GET / (dashboard)
// with Accept: application/json header.
|