@prefecthq/fastmcp-ts 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/server/FastMCP.ts","../src/server/auth/types.ts","../src/server/legacyEventStore.ts","../src/server/context.ts","../src/server/httpContext.ts","../src/server/env.ts","../src/server/middleware.ts","../src/server/transform.ts","../src/server/tool.ts","../src/server/mrtr.ts","../src/server/resource.ts","../src/server/apps/types.ts","../src/server/prompt.ts","../src/server/completion.ts","../src/server/auth/authorization.ts","../src/server/auth/multiAuth.ts","../src/server/auth/verifiers/jwt.ts","../src/server/auth/verifiers/introspection.ts","../src/server/auth/verifiers/static.ts","../src/server/auth/oauth/provider.ts","../src/server/auth/oauth/proxy.ts","../src/server/proxy.ts","../src/server/openapi/internal.ts","../src/server/openapi/parser.ts","../src/server/openapi/jsonSchema.ts","../src/server/openapi/schemas.ts","../src/server/openapi/routing.ts","../src/server/openapi/naming.ts","../src/server/openapi/director.ts","../src/server/openapi/execute.ts","../src/server/openapi/index.ts","../src/server/apps/FastMCPApp.ts","../src/server/apps/actionRef.ts","../src/server/apps/generative.ts","../src/server/apps/components.ts","../src/server/apps/providers/Approval.ts","../src/server/apps/providers/Choice.ts","../src/server/apps/providers/FileUpload.ts","../src/server/apps/providers/FormInput.ts"],"sourcesContent":["import type { NodeStreamableHTTPServerTransport } from \"@modelcontextprotocol/node\";\nimport { hostHeaderValidation, originValidation } from \"@modelcontextprotocol/node\";\nimport type { OAuthServerProvider } from \"@modelcontextprotocol/server-legacy/auth\";\nimport { ProtocolError, ProtocolErrorCode, ResourceNotFoundError, Server, createMcpHandler, legacyStatelessFallback, isLegacyRequest, isJsonContentType, createRequestStateCodec, localhostAllowedHostnames, localhostAllowedOrigins, assertCompleteRequestPrompt, assertCompleteRequestResourceTemplate } from \"@modelcontextprotocol/server\";\nimport type { Transport, AuthInfo, ListToolsResult, GetPromptResult, CompleteRequestParams, CompleteResult, McpHttpHandler, LegacyHttpHandler, McpHandlerRequestOptions, CacheHint, RequestStateCodec, ServerContext, ServerEventBus } from \"@modelcontextprotocol/server\";\n\n// Not exported by @modelcontextprotocol/server (CacheableResultMethod is internal-only);\n// mirrors its CACHEABLE_RESULT_METHODS literal union (SEP-2549 cacheable operations).\ntype CacheableResultMethod =\n | 'tools/list'\n | 'prompts/list'\n | 'resources/list'\n | 'resources/templates/list'\n | 'resources/read'\n | 'server/discover'\nimport type { StandardSchemaV1 } from '@standard-schema/spec'\nimport { randomUUID } from 'node:crypto'\nimport type { Readable, Writable } from 'node:stream'\nimport type { Server as HttpServer, IncomingMessage, ServerResponse } from 'node:http'\nimport type { AddressInfo } from 'node:net'\nimport { AuthorizationError } from './auth/types'\nimport type { TokenVerifier, AccessToken } from './auth/types'\nimport type { RequestVerifier } from './auth/types'\nimport { isRequestVerifier } from './auth/types'\nimport type { AuthCheck } from './auth/authorization'\nimport { BoundedEventStore, LEGACY_SSE_RETRY_MS } from './legacyEventStore'\nimport { contextStore, createContext, SESSION_CLOSE_CALLBACKS_KEY } from './context'\nimport type { McpContext } from './context'\nimport { resolveSensitiveHeaders, nodeRequestToHttpContext } from './httpContext'\nimport { envBool } from './env'\nimport { runMiddlewareChain } from './middleware'\nimport type { Middleware } from './middleware'\nimport { applyTransformChain } from './transform'\nimport type { Transform, ToolView, ResourceView, PromptView, SynthesizedTool } from './transform'\nimport { convertResult, toJsonSchema, validateInput, ToolResult } from './tool'\nimport { isInputRequiredResult } from './mrtr'\nimport {\n attachResourceUiMeta,\n convertResourceResult,\n isUriTemplate,\n matchTemplate,\n ResourceResult,\n} from './resource'\nimport type { ResourceConfig } from './resource'\nimport { UI_EXTENSION_KEY, UI_RESOURCE_MIME_TYPE, isUiCapable } from './apps/types'\nimport type { UiToolMeta } from './apps/types'\nimport { convertPromptResult, PromptResult } from './prompt'\nimport type { PromptConfig } from './prompt'\nimport { normalizeCompletion, EMPTY_COMPLETION } from './completion'\n\nfunction prefixResourceUri(uri: string, prefix: string): string {\n const idx = uri.indexOf('://')\n if (idx === -1) return `${prefix}/${uri}`\n return `${uri.slice(0, idx + 3)}${prefix}/${uri.slice(idx + 3)}`\n}\n\nexport interface OAuthConfig {\n /** OAuth server provider implementing the authorization and token flow. */\n provider: OAuthServerProvider\n /**\n * Issuer URL for the OAuth server (used in metadata endpoints).\n * Defaults to the HTTP server's bound address when not specified.\n */\n issuerUrl?: URL\n /** Scopes supported by this server, advertised in OAuth metadata. */\n scopes?: string[]\n}\n\nexport interface FastMCPOptions {\n name: string\n version?: string\n /**\n * Bearer-token verifier, or a RequestVerifier for header-based\n * (trusted-proxy) deployments. See each type's docs. A RequestVerifier\n * applies to HTTP transports only; stdio's FASTMCP_CLI_AUTH_TOKEN needs a\n * TokenVerifier. When both `oauth` and `auth` are set, `oauth` serves the\n * endpoint and `auth` is ignored.\n */\n auth?: TokenVerifier | RequestVerifier\n /** Full OAuth 2.1 server with Dynamic Client Registration support. */\n oauth?: OAuthConfig\n /**\n * HTTP request context tuning for `ctx.http`. `redactHeaders` adds names to\n * the sensitive set withheld from `ctx.http.headers` (defaults:\n * authorization, cookie, proxy-authorization, mcp-session-id); use it for\n * deployment-specific credentials such as a proxy shared-secret header.\n * `exposeHeaders` removes names from the set; it is the explicit, greppable\n * opt-out. Withheld names are listed in `ctx.http.redactedHeaderNames`.\n * Redaction applies to `ctx.http` only; a RequestVerifier always sees the\n * full wire headers.\n */\n http?: { redactHeaders?: string[]; exposeHeaders?: string[] }\n /** Maximum number of tools returned per listTools page. Default: 50. */\n toolsPageSize?: number\n /** Maximum number of resources (or templates) returned per page. Default: 50. */\n resourcesPageSize?: number\n /** Maximum number of prompts returned per prompts/list page. Default: 50. */\n promptsPageSize?: number\n /** Middleware applied to every request in registration order. */\n middleware?: Middleware[]\n /** Transforms applied to component list responses in registration order. */\n transforms?: Transform[]\n /**\n * Cache hints (`ttlMs` / `cacheScope`) for the 2026-07-28 protocol revision's\n * cacheable results (`tools/list`, `prompts/list`, `resources/list`,\n * `resources/templates/list`, `resources/read`, `server/discover`), keyed by\n * operation. Only affects modern (2026-07-28) responses — 2025-era responses\n * never carry these fields. Omitted operations (or omitting this option\n * entirely) keep the conservative defaults (`ttlMs: 0`, `cacheScope: 'private'`).\n * Applies uniformly per operation; per-resource cache hints are not currently\n * supported (that per-registration override is only available through the\n * SDK's high-level `McpServer.registerResource`, which FastMCP does not use).\n */\n cacheHints?: Partial<Record<CacheableResultMethod, CacheHint>>\n /**\n * HMAC-SHA256 integrity protection for multi-round-trip `requestState`\n * (protocol revision 2026-07-28) — see `ctx.requestState()` / `ctx.mintRequestState()`.\n * Backed by the SDK's `createRequestStateCodec`. When omitted, `requestState` passes\n * through unverified (the raw wire string) — the client can read and tamper with it,\n * so this MUST be configured for any flow whose `requestState` influences\n * authorization, resource access, or business logic.\n */\n requestState?: {\n /** HMAC secret. A `string` is UTF-8-encoded; MUST be at least 32 bytes (256 bits). */\n key: Uint8Array | string\n /** How long a minted `requestState` stays valid, in seconds. Default: 600 (10 minutes). */\n ttlSeconds?: number\n /** Binds a minted `requestState` to, e.g., the authenticated principal and/or the\n * originating method — a value minted under one binding is rejected when echoed\n * under a different one. See `RequestStateCodecOptions.bind`. */\n bind?: (ctx: ServerContext) => string\n }\n /**\n * Multi-round-trip (`inputRequired`) serving knobs (protocol revision 2026-07-28).\n * On 2026-era requests the client fulfils `input_required` returns directly; on\n * 2025-era connections the SDK's legacy shim fulfils them server-side (real\n * server→client requests + handler re-entry) — so handlers written with\n * `inputRequired(...)` serve both eras unchanged.\n */\n inputRequired?: {\n /** Handler re-entries per originating request before the shim fails (legacy era\n * only). Default: 8. */\n maxRounds?: number\n /** Per-leg timeout (ms) for the legacy shim's embedded server→client requests.\n * Default: 600_000 (10 minutes) — human-paced, deliberately above the 60s protocol default. */\n roundTimeoutMs?: number\n /** `false` disables the legacy shim: an `inputRequired(...)` return on a 2025-era\n * request fails loudly instead of being bridged. Default: true. */\n legacyShim?: boolean\n }\n /**\n * The change-event bus modern (2026-07-28) `subscriptions/listen` streams\n * subscribe to, and `tool()`/`resource()`/`prompt()` registration publishes\n * change events onto. Defaults to an in-process bus, which is correct for a\n * single server process. Supply your own `ServerEventBus` implementation over a\n * shared pub/sub backend (e.g. Redis) for a horizontally-scaled deployment,\n * where a `subscriptions/listen` stream and the request that changed the list it\n * cares about may land on different processes.\n */\n eventBus?: ServerEventBus\n /**\n * DNS-rebinding protection for the HTTP transport: validates the `Host` and\n * `Origin` request headers (port-agnostic, by hostname) and rejects mismatches\n * with `403`. Defends localhost servers against a malicious web page whose DNS\n * rebinds to `127.0.0.1` (MCP transport security best practice). Only affects the\n * HTTP transport — stdio is unaffected.\n *\n * Default posture (option omitted): protection auto-enables when, and only when,\n * `run()` binds the HTTP server to a loopback host (`127.0.0.1`, `::1`,\n * `localhost`) — the deployment the attack targets. A server bound to a routable\n * interface (e.g. `0.0.0.0` or a public host) is left open by default, because a\n * localhost-only allowlist would reject its legitimate traffic; such deployments\n * must opt in with an explicit `allowedHosts`/`allowedOrigins` for their domain.\n */\n dnsRebinding?: {\n /** Force protection on (`true`) or off (`false`). Omit for the loopback-auto default. */\n enabled?: boolean\n /**\n * Allowed `Host` header hostnames (no port; IPv6 in brackets, e.g. `[::1]`).\n * Supplying this list also implies protection on. Default: `localhost`,\n * `127.0.0.1`, `[::1]`.\n */\n allowedHosts?: string[]\n /**\n * Allowed `Origin` header hostnames (a missing `Origin` always passes — non-browser\n * clients send none). Supplying this list also implies protection on. Default:\n * `localhost`, `127.0.0.1`, `[::1]`.\n */\n allowedOrigins?: string[]\n }\n}\n\nexport interface RunOptions {\n transport?: 'stdio' | 'http'\n port?: number\n host?: string\n path?: string\n /**\n * Serve the legacy (2025-era) HTTP transport statelessly: a fresh server and\n * transport per request, no session registry, incoming `mcp-session-id`\n * ignored, and no session id issued. Use this behind a load balancer or on\n * serverless compute where consecutive requests reach different instances.\n *\n * Falls back to the `FASTMCP_STATELESS_HTTP` environment variable, then to\n * `false`. A valid value is ignored for the stdio transport, but a malformed\n * one still aborts stdio startup, deliberately. The modern (2026-07-28) era\n * is already stateless and is unaffected.\n */\n stateless?: boolean\n /** Custom stdin stream for the stdio transport. Defaults to process.stdin. */\n stdin?: Readable\n /** Custom stdout stream for the stdio transport. Defaults to process.stdout. */\n stdout?: Writable\n}\n\nexport interface ServerAddress {\n host: string\n port: number\n path: string\n}\n\nexport interface ToolConfig {\n name: string\n /** Human-readable display name shown in UIs. Takes precedence over `name` for display purposes. */\n title?: string\n description: string\n /** Standard Schema validator for the tool's input arguments. Used for runtime validation. */\n input?: StandardSchemaV1\n /**\n * Explicit JSON Schema advertised to clients as `inputSchema`. Overrides auto-generation from\n * `input`. Use when you need JSON Schema features beyond what your validator auto-generates\n * (e.g. `examples`, `$comment`, per-property descriptions, or custom annotations).\n */\n inputSchema?: Record<string, unknown>\n /** Standard Schema validator for the tool's return value. Validated before result conversion. */\n output?: StandardSchemaV1\n /**\n * Explicit JSON Schema advertised to clients as `outputSchema`. Overrides auto-generation from\n * `output`. Use when you need JSON Schema features beyond what your validator auto-generates.\n */\n outputSchema?: Record<string, unknown>\n /** Execution timeout in milliseconds. No timeout by default. */\n timeout?: number\n /** When true the tool is hidden from listTools and cannot be invoked via tools/call. */\n disabled?: boolean\n /** Arbitrary tags for server-side filtering. */\n tags?: string[]\n auth?: AuthCheck\n /** Apps extension — links this tool to a UI resource and controls visibility. */\n ui?: UiToolMeta\n}\n\ninterface RegisteredTool {\n config: ToolConfig\n handler: (args: unknown) => unknown\n}\n\ninterface RegisteredResource {\n config: ResourceConfig\n handler: (params?: Record<string, string>) => unknown\n}\n\ninterface ResolvedPromptConfig extends Required<Pick<PromptConfig, 'name' | 'description'>> {\n title?: string\n arguments?: PromptConfig['arguments']\n disabled?: boolean\n timeout?: number\n tags?: string[]\n auth?: PromptConfig['auth']\n}\n\ninterface RegisteredPrompt {\n config: ResolvedPromptConfig\n handler: (args?: Record<string, string>) => unknown\n}\n\ninterface Session {\n transport: NodeStreamableHTTPServerTransport\n server: Server\n state: Map<string, unknown>\n}\n\n/**\n * Per-session state key holding the set of resource URIs the connection has\n * subscribed to via `resources/subscribe`. Stored in the same per-session state\n * Map as `SESSION_CLOSE_CALLBACKS_KEY`, so it is torn down with the session (no\n * separate registry to leak). Only ever populated on legacy connections — the\n * modern era rejects the RPC at the wire seam before the handler runs.\n */\nconst RESOURCE_SUBSCRIPTIONS_KEY = '__fastmcp_resource_subscriptions'\n\n/**\n * Guard message for `resources/subscribe`/`unsubscribe` on a stateless HTTP\n * server. The server withdraws the `resources.subscribe` capability (see\n * `_makeServer`), so a compliant client never calls these; this is the\n * refusal for a non-compliant client that calls them anyway.\n */\nconst STATELESS_SUBSCRIBE_ERROR =\n '[fastmcp] resources/subscribe and resources/unsubscribe are unavailable on a stateless HTTP server. ' +\n 'A stateless server keeps no session, so a subscription has nowhere to live and no channel to deliver on. ' +\n 'The server does not advertise the resources.subscribe capability; a compliant client will not call this.'\n\n/** Converts a camelCase or PascalCase name to space-separated words. e.g. `getWeather` → `\"get weather\"` */\nfunction inferDescription(name: string): string {\n return name\n .replace(/([A-Z])/g, ' $1')\n .replace(/[-_]+/g, ' ')\n .trim()\n .toLowerCase()\n}\n\n/** True when `host` is a loopback address `run()` can bind — the deployment DNS-rebinding targets. */\nfunction isLoopbackHost(host: string): boolean {\n const h = host.toLowerCase()\n return h === '127.0.0.1' || h === 'localhost' || h === '::1' || h === '[::1]'\n}\n\n// Fired at most once per process: an HTTP serve on a routable host with no dnsRebinding\n// config at all. Any explicit dnsRebinding option (even `enabled: false`) suppresses the\n// warning — silence means the operator chose the open posture on purpose.\nlet _dnsRebindingWarned = false\n\n/** @internal Test-only reset of the once-per-process DNS-rebinding warning guard. Not\n * re-exported from `fastmcp-ts/server` (index.ts names its exports). */\nexport function __resetDnsRebindingWarningForTests(): void {\n _dnsRebindingWarned = false\n}\n\nfunction toAccessToken(authInfo: AuthInfo | undefined): AccessToken | undefined {\n if (!authInfo) return undefined\n return {\n token: authInfo.token,\n clientId: authInfo.clientId || undefined,\n scopes: authInfo.scopes,\n expiresAt: authInfo.expiresAt,\n claims: authInfo.extra ?? {},\n }\n}\n\n// Cached result of verifying FASTMCP_CLI_AUTH_TOKEN once per process.\n// undefined = not yet resolved; null = env var absent or verification failed.\nlet _cliEnvToken: AccessToken | null | undefined\n\nasync function resolveCliEnvToken(\n verifier: TokenVerifier | RequestVerifier | undefined,\n): Promise<AccessToken | undefined> {\n if (!verifier || !('verify' in verifier)) return undefined\n if (_cliEnvToken !== undefined) return _cliEnvToken ?? undefined\n const raw = process.env['FASTMCP_CLI_AUTH_TOKEN']\n if (!raw) { _cliEnvToken = null; return undefined }\n try {\n _cliEnvToken = await verifier.verify(raw)\n return _cliEnvToken\n } catch {\n _cliEnvToken = null\n return undefined\n }\n}\n\nasync function runAuthCheck(check: AuthCheck, token: AccessToken | undefined): Promise<void> {\n if (!token) throw new ProtocolError(ProtocolErrorCode.InvalidRequest, 'Authentication required')\n try {\n await check(token)\n } catch (err) {\n if (err instanceof AuthorizationError) {\n throw new ProtocolError(ProtocolErrorCode.InvalidRequest, err.message)\n }\n throw err\n }\n}\n\nexport class FastMCP {\n readonly name: string\n readonly version: string\n\n private _auth: TokenVerifier | RequestVerifier | undefined\n private _oauth: OAuthConfig | undefined\n private _sensitiveHeaders: Set<string>\n private _toolsPageSize: number\n private _resourcesPageSize: number\n private _tools = new Map<string, RegisteredTool>()\n private _staticResources = new Map<string, RegisteredResource>()\n private _templateResources = new Map<string, RegisteredResource>()\n private _prompts = new Map<string, RegisteredPrompt>()\n private _promptsPageSize: number\n private _middleware: Middleware[]\n private _transforms: Transform[]\n private _cacheHints: Partial<Record<CacheableResultMethod, CacheHint>> | undefined\n private _requestStateCodec: RequestStateCodec | undefined\n private _inputRequiredOptions: FastMCPOptions['inputRequired']\n private _eventBus: ServerEventBus | undefined\n private _dnsRebindingOptions: FastMCPOptions['dnsRebinding']\n // DNS-rebinding guards, resolved once per serve from _dnsRebindingOptions + the bind\n // host. null = protection off. Each returns false (and has already written a 403) when\n // it rejects; see the SDK's hostHeaderValidation/originValidation Node middleware.\n private _hostGuard: ((req: IncomingMessage, res: ServerResponse) => boolean) | null = null\n private _originGuard: ((req: IncomingMessage, res: ServerResponse) => boolean) | null = null\n private _primaryState = new Map<string, unknown>()\n private _httpServer: HttpServer | null = null\n private _address: ServerAddress | null = null\n private _isRunning = false\n private _sessions = new Map<string, Session>()\n private _stateless = false\n // Primary server used by connect() (in-process transports — always 2025-era)\n private _primaryServer: Server\n // The pinned Server instance for a run({transport:'stdio'}) connection (2025- or\n // 2026-era, decided by serveStdio's opening handshake). Null unless serving stdio.\n private _stdioServer: Server | null = null\n // The state Map paired with `_stdioServer` for the current stdio connection.\n // Holds this connection's resource-subscription set; read by the resource-updated\n // fan-out. Null unless serving stdio.\n private _stdioState: Map<string, unknown> | null = null\n private _stdioHandle: { close(): Promise<void> } | null = null\n // Modern (2026-07-28) HTTP handler — one per FastMCP instance, lazily created.\n // Builds a fresh Server (via _makeServer) per request; see createMcpHandler.\n private _modernHandler: McpHttpHandler | null = null\n private _statelessLegacyHandler: LegacyHttpHandler | null = null\n\n private _toolRegisteredCallbacks: Array<(tool: RegisteredTool) => void> = []\n private _resourceRegisteredCallbacks: Array<(resource: RegisteredResource) => void> = []\n private _promptRegisteredCallbacks: Array<(prompt: RegisteredPrompt) => void> = []\n private _proxyCloseCallbacks: Array<() => Promise<void>> = []\n private _mountedChildren = new Set<FastMCP>()\n\n constructor(options: FastMCPOptions) {\n this.name = options.name\n this.version = options.version ?? '0.0.1'\n this._auth = options.auth\n this._oauth = options.oauth\n this._sensitiveHeaders = resolveSensitiveHeaders(options.http)\n this._toolsPageSize = options.toolsPageSize ?? 50\n this._resourcesPageSize = options.resourcesPageSize ?? 50\n this._promptsPageSize = options.promptsPageSize ?? 50\n this._middleware = options.middleware ? [...options.middleware] : []\n this._transforms = options.transforms ? [...options.transforms] : []\n this._cacheHints = options.cacheHints\n this._requestStateCodec = options.requestState\n ? createRequestStateCodec(options.requestState)\n : undefined\n this._inputRequiredOptions = options.inputRequired\n this._eventBus = options.eventBus\n this._dnsRebindingOptions = options.dnsRebinding\n this._primaryServer = this._makeServer()\n }\n\n private _hasUiComponents(): boolean {\n for (const t of this._tools.values()) {\n if (t.config.ui) return true\n }\n for (const r of this._staticResources.values()) {\n if (r.config.ui || r.config.uri.startsWith('ui://')) return true\n }\n for (const r of this._templateResources.values()) {\n if (r.config.uri.startsWith('ui://')) return true\n }\n return false\n }\n\n /**\n * Create a new Server instance with all request handlers wired up.\n *\n * `modern` forks the advertised `resources.subscribe` capability. The legacy\n * `resources/subscribe`/`unsubscribe` RPCs are physically absent from the\n * 2026-07-28 wire registry (a modern client uses `subscriptions/listen`\n * instead), so a modern-only factory (the createMcpHandler path) must NOT\n * advertise `subscribe` — the modern `server/discover` document is pinned to\n * `resources: { listChanged: true }`. The primary in-process server and\n * legacy HTTP sessions are always legacy, so they always advertise it.\n * stdio forks it per-connection too: `run()`'s stdio branch reads the\n * `ctx.era` the SDK's `McpServerFactory` hook hands it (serveStdio only\n * calls the factory once the opening exchange has classified the era, so\n * the modern-vs-legacy choice is already known at construction time) and\n * passes it straight through as `opts.modern`.\n *\n * The `completions` capability is NOT era-forked: `completion/complete` is in\n * BOTH era wire registries (the legacy 2025-11-25 registry and the modern\n * 2026-07-28 `dispatchRequestSchemas`), and `completions` is a valid key in\n * both eras' ServerCapabilities schemas. So it is declared unconditionally —\n * unlike `subscribe`, there is no legacy-only surface to hide from a modern\n * client here, so nothing needs the era fork the way `subscribe` does. The\n * SDK also requires this capability to be present to register the\n * `completion/complete` handler (`assertRequestHandlerCapability`).\n *\n * `stateless` withdraws the same capability for a different reason. A\n * stateless server has no session for a subscription to live in and no\n * channel to deliver `notifications/resources/updated` on, so it must not\n * claim the capability.\n */\n private _makeServer(\n sessionState?: Map<string, unknown>,\n opts?: { modern?: boolean; stateless?: boolean },\n ): Server {\n const state = sessionState ?? this._primaryState\n // mimeTypes announces what fastmcp can serve, symmetric with the mimeTypes the\n // client is required to declare on its own extension entry (SEP-1865).\n const extensions = this._hasUiComponents()\n ? { [UI_EXTENSION_KEY]: { mimeTypes: [UI_RESOURCE_MIME_TYPE] } }\n : undefined\n const server = new Server(\n { name: this.name, version: this.version },\n {\n capabilities: { tools: { listChanged: true }, resources: { listChanged: true, ...(opts?.modern || opts?.stateless ? {} : { subscribe: true }) }, prompts: { listChanged: true }, logging: {}, completions: {}, ...(extensions ? { extensions } : {}) },\n ...(this._cacheHints ? { cacheHints: this._cacheHints } : {}),\n ...(this._requestStateCodec\n ? { requestState: { verify: this._requestStateCodec.verify.bind(this._requestStateCodec) } }\n : {}),\n ...(this._inputRequiredOptions ? { inputRequired: this._inputRequiredOptions } : {}),\n },\n )\n for (const mw of this._middleware) mw.setup?.(server)\n this._setupHandlers(server, state, opts)\n return server\n }\n\n private async _resolveToken(authInfo: AuthInfo | undefined): Promise<AccessToken | undefined> {\n return toAccessToken(authInfo) ?? await resolveCliEnvToken(this._auth)\n }\n\n private _setupHandlers(\n server: Server,\n sessionState: Map<string, unknown>,\n opts?: { stateless?: boolean },\n ): void {\n server.setRequestHandler('tools/list', async (req, sdkCtx) => {\n const token = await this._resolveToken(sdkCtx.http?.authInfo)\n const ctx = createContext(server, sdkCtx, token, sessionState, this._requestStateCodec, opts?.stateless, this._sensitiveHeaders)\n return contextStore.run(ctx, () =>\n runMiddlewareChain(this._middleware, 'tools/list', req.params, ctx, async () => {\n const clientIsUiCapable = isUiCapable(server.getClientCapabilities())\n\n const allVisible = (\n await Promise.all(\n [...this._tools.values()].map(async (t) => {\n if (t.config.disabled) return null\n // App-only tools are hidden from listTools (visible only inside the iframe)\n if (t.config.ui?.visibility && !t.config.ui.visibility.includes('model')) return null\n if (!t.config.auth) return t\n if (!token) return null\n try { await t.config.auth(token); return t } catch { return null }\n }),\n )\n ).filter((t): t is RegisteredTool => t !== null)\n\n const transformedTools = this._applyTransformsToTools(allVisible)\n const { resourceViews, promptViews } = await this._getVisibleViews(token)\n const synthesized = this._buildSynthesizedTools(resourceViews, promptViews)\n\n type ListEntry =\n | { kind: 'registered'; name: string; title: string | undefined; description: string; config: ToolConfig }\n | { kind: 'synthesized'; name: string; title: string | undefined; description: string; inputSchema: Record<string, unknown> | undefined }\n\n const allEntries: ListEntry[] = [\n ...transformedTools.map(\n (t): ListEntry => ({ kind: 'registered', name: t.name, title: t.title, description: t.description, config: t.config }),\n ),\n ...synthesized.map(\n (s): ListEntry => ({ kind: 'synthesized', name: s.name, title: s.title, description: s.description, inputSchema: s.inputSchema }),\n ),\n ]\n\n const pageSize = this._toolsPageSize\n const cursorName = req.params?.cursor\n ? Buffer.from(req.params.cursor, 'base64url').toString()\n : null\n let startIdx = 0\n if (cursorName !== null) {\n const idx = allEntries.findIndex((e) => e.name === cursorName)\n if (idx < 0) throw new ProtocolError(ProtocolErrorCode.InvalidParams, 'Invalid or expired cursor')\n startIdx = idx + 1\n }\n const page = allEntries.slice(startIdx, startIdx + pageSize)\n const nextCursor =\n startIdx + pageSize < allEntries.length\n ? Buffer.from(page[page.length - 1].name).toString('base64url')\n : undefined\n\n const tools = await Promise.all(\n page.map(async (entry) => {\n if (entry.kind === 'synthesized') {\n return {\n name: entry.name,\n ...(entry.title !== undefined ? { title: entry.title } : {}),\n description: entry.description,\n inputSchema: entry.inputSchema ?? { type: 'object' as const },\n }\n }\n const t = entry.config\n const inputSchema =\n t.inputSchema ??\n (t.input\n ? await toJsonSchema(t.input, `tool \"${t.name}\" input`)\n : { type: 'object' as const })\n const outputSchema =\n t.outputSchema ??\n (t.output\n ? await toJsonSchema(t.output, `tool \"${t.name}\" output`)\n : undefined)\n const uiMeta = clientIsUiCapable && t.ui\n ? {\n resourceUri: t.ui.resourceUri ?? `ui://${t.name}`,\n ...(t.ui.visibility ? { visibility: t.ui.visibility } : {}),\n }\n : undefined\n return {\n name: entry.name,\n ...(entry.title !== undefined ? { title: entry.title } : {}),\n description: entry.description,\n inputSchema,\n ...(outputSchema ? { outputSchema } : {}),\n ...(uiMeta ? { _meta: { ui: uiMeta } } : {}),\n }\n }),\n )\n\n // Cast: our JSON Schema generation (toJsonSchema / user-supplied inputSchema) is\n // typed loosely as Record<string, unknown>, while the SDK's Tool type is inferred\n // from a strict Zod schema requiring a literal `type: 'object'` root. The generated\n // schemas satisfy this at runtime (see tool.ts); this is a static-typing gap only.\n return { tools, ...(nextCursor ? { nextCursor } : {}) } as ListToolsResult\n }),\n )\n })\n\n server.setRequestHandler('tools/call', async (req, sdkCtx) => {\n const requestedName = req.params.name\n const token = await this._resolveToken(sdkCtx.http?.authInfo)\n\n // Check synthesized tools first\n const { resourceViews, promptViews } = await this._getVisibleViews(token)\n const synthesizedList = this._buildSynthesizedTools(resourceViews, promptViews)\n const synthTool = synthesizedList.find((s) => s.name === requestedName)\n if (synthTool) {\n if (synthTool.auth) await runAuthCheck(synthTool.auth, token)\n const ctx = createContext(server, sdkCtx, token, sessionState, this._requestStateCodec, opts?.stateless, this._sensitiveHeaders)\n try {\n return await contextStore.run(ctx, () =>\n runMiddlewareChain(this._middleware, 'tools/call', req.params, ctx, async () => {\n let executePromise: Promise<unknown> = Promise.resolve(\n synthTool.handler(req.params.arguments ?? {}),\n )\n if (synthTool.timeout) {\n const ms = synthTool.timeout\n let timer!: ReturnType<typeof setTimeout>\n const timeoutPromise = new Promise<never>((_, reject) => {\n timer = setTimeout(\n () => reject(new Error(`Tool \"${requestedName}\" timed out after ${ms}ms`)),\n ms,\n )\n })\n executePromise = Promise.race([executePromise, timeoutPromise]).finally(() =>\n clearTimeout(timer),\n )\n }\n return convertResult(await executePromise, opts?.stateless)\n }),\n )\n } catch (err) {\n if (err instanceof ProtocolError) throw err\n return {\n content: [{ type: 'text' as const, text: err instanceof Error ? err.message : String(err) }],\n isError: true,\n }\n }\n }\n\n // Find by transformed name, then fall back to direct registry (for hidden/unaffected tools)\n let tool: RegisteredTool | undefined\n if (this._transforms.length > 0) {\n for (const t of this._tools.values()) {\n const view = applyTransformChain<ToolView>(\n { name: t.config.name, description: t.config.description, tags: t.config.tags ?? [] },\n this._transforms,\n (tr, v) => tr.transformTool?.(v),\n )\n if (view && view.name === requestedName) { tool = t; break }\n }\n }\n if (!tool) tool = this._tools.get(requestedName)\n\n if (!tool || tool.config.disabled) {\n throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Unknown tool: \"${requestedName}\"`)\n }\n\n if (tool.config.auth) await runAuthCheck(tool.config.auth, token)\n\n const resolvedTool = tool\n const rawArgs: unknown = req.params.arguments ?? {}\n const ctx = createContext(server, sdkCtx, token, sessionState, this._requestStateCodec, opts?.stateless, this._sensitiveHeaders)\n\n try {\n return await contextStore.run(ctx, () =>\n runMiddlewareChain(this._middleware, 'tools/call', req.params, ctx, async () => {\n const args = resolvedTool.config.input ? await validateInput(resolvedTool.config.input, rawArgs, true) : rawArgs\n\n let executePromise: Promise<unknown> = Promise.resolve(resolvedTool.handler(args))\n\n if (resolvedTool.config.timeout) {\n const ms = resolvedTool.config.timeout\n let timer!: ReturnType<typeof setTimeout>\n const timeoutPromise = new Promise<never>((_, reject) => {\n timer = setTimeout(\n () => reject(new Error(`Tool \"${requestedName}\" timed out after ${ms}ms`)),\n ms,\n )\n })\n executePromise = Promise.race([executePromise, timeoutPromise]).finally(() =>\n clearTimeout(timer),\n )\n }\n\n let resultValue = await executePromise\n if (resolvedTool.config.output) resultValue = await validateInput(resolvedTool.config.output, resultValue)\n const callResult = convertResult(resultValue, opts?.stateless)\n // Graceful degradation: strip structuredContent for non-UI clients calling UI tools\n if (resolvedTool.config.ui) {\n const clientIsUi = isUiCapable(server.getClientCapabilities())\n if (!clientIsUi && callResult.structuredContent !== undefined) {\n return { content: [{ type: 'text' as const, text: '[UI not available in this client]' }] }\n }\n }\n return callResult\n }),\n )\n } catch (err) {\n if (err instanceof ProtocolError) throw err\n return {\n content: [{ type: 'text' as const, text: err instanceof Error ? err.message : String(err) }],\n isError: true,\n }\n }\n })\n\n server.setRequestHandler('resources/list', async (req, sdkCtx) => {\n const token = await this._resolveToken(sdkCtx.http?.authInfo)\n const ctx = createContext(server, sdkCtx, token, sessionState, this._requestStateCodec, opts?.stateless, this._sensitiveHeaders)\n return contextStore.run(ctx, () =>\n runMiddlewareChain(this._middleware, 'resources/list', req.params, ctx, async () => {\n const allVisible = (\n await Promise.all(\n [...this._staticResources.values()].map(async (r) => {\n if (r.config.disabled) return null\n if (!r.config.auth) return r\n if (!token) return null\n try { await r.config.auth(token); return r } catch { return null }\n }),\n )\n ).filter((r): r is RegisteredResource => r !== null)\n\n const transformedResources = this._applyTransformsToResources(allVisible)\n\n const pageSize = this._resourcesPageSize\n const cursorUri = req.params?.cursor\n ? Buffer.from(req.params.cursor, 'base64url').toString()\n : null\n let startIdx = 0\n if (cursorUri !== null) {\n const idx = transformedResources.findIndex((r) => r.uri === cursorUri)\n if (idx < 0) throw new ProtocolError(ProtocolErrorCode.InvalidParams, 'Invalid or expired cursor')\n startIdx = idx + 1\n }\n const page = transformedResources.slice(startIdx, startIdx + pageSize)\n const nextCursor =\n startIdx + pageSize < transformedResources.length\n ? Buffer.from(page[page.length - 1].uri).toString('base64url')\n : undefined\n\n const clientIsUiCapableRes = isUiCapable(server.getClientCapabilities())\n return {\n resources: page.map((r) => ({\n uri: r.uri,\n name: r.name,\n ...(r.config.title !== undefined ? { title: r.config.title } : {}),\n ...(r.config.description !== undefined ? { description: r.config.description } : {}),\n ...(r.config.mimeType !== undefined ? { mimeType: r.config.mimeType } : {}),\n ...(r.config.size !== undefined ? { size: r.config.size } : {}),\n ...(r.config.annotations !== undefined ? { annotations: r.config.annotations } : {}),\n ...(clientIsUiCapableRes && r.config.ui ? { _meta: { ui: r.config.ui } } : {}),\n })),\n ...(nextCursor ? { nextCursor } : {}),\n }\n }),\n )\n })\n\n server.setRequestHandler('resources/templates/list', async (req, sdkCtx) => {\n const token = await this._resolveToken(sdkCtx.http?.authInfo)\n const ctx = createContext(server, sdkCtx, token, sessionState, this._requestStateCodec, opts?.stateless, this._sensitiveHeaders)\n return contextStore.run(ctx, () =>\n runMiddlewareChain(this._middleware, 'resources/templates/list', req.params, ctx, async () => {\n const allVisible = (\n await Promise.all(\n [...this._templateResources.values()].map(async (r) => {\n if (r.config.disabled) return null\n if (!r.config.auth) return r\n if (!token) return null\n try { await r.config.auth(token); return r } catch { return null }\n }),\n )\n ).filter((r): r is RegisteredResource => r !== null)\n\n const transformedTemplates = this._applyTransformsToResourceTemplates(allVisible)\n\n const pageSize = this._resourcesPageSize\n const cursorUri = req.params?.cursor\n ? Buffer.from(req.params.cursor, 'base64url').toString()\n : null\n let startIdx = 0\n if (cursorUri !== null) {\n const idx = transformedTemplates.findIndex((r) => r.uri === cursorUri)\n if (idx < 0) throw new ProtocolError(ProtocolErrorCode.InvalidParams, 'Invalid or expired cursor')\n startIdx = idx + 1\n }\n const page = transformedTemplates.slice(startIdx, startIdx + pageSize)\n const nextCursor =\n startIdx + pageSize < transformedTemplates.length\n ? Buffer.from(page[page.length - 1].uri).toString('base64url')\n : undefined\n\n return {\n resourceTemplates: page.map((r) => ({\n uriTemplate: r.uri,\n name: r.name,\n ...(r.config.title !== undefined ? { title: r.config.title } : {}),\n ...(r.config.description !== undefined ? { description: r.config.description } : {}),\n ...(r.config.mimeType !== undefined ? { mimeType: r.config.mimeType } : {}),\n ...(r.config.annotations !== undefined ? { annotations: r.config.annotations } : {}),\n })),\n ...(nextCursor ? { nextCursor } : {}),\n }\n }),\n )\n })\n\n server.setRequestHandler('resources/read', async (req, sdkCtx) => {\n const requestedUri = req.params.uri\n const token = await this._resolveToken(sdkCtx.http?.authInfo)\n\n const resolved = this._resolveResource(requestedUri)\n if (!resolved || resolved.resource.config.disabled) {\n // ResourceNotFoundError stamps `data: { uri }` (exactly one key) and keeps the\n // -32602 code the SDK recognition contract requires, so a client can tell a\n // resource miss from a generic Invalid Params (task-9 Req 3; task-7 F1).\n throw new ResourceNotFoundError(requestedUri, `Unknown resource: \"${requestedUri}\"`)\n }\n const resource = resolved.resource\n const templateParams = resolved.templateParams\n\n if (resource.config.auth) await runAuthCheck(resource.config.auth, token)\n\n const ctx = createContext(server, sdkCtx, token, sessionState, this._requestStateCodec, opts?.stateless, this._sensitiveHeaders)\n\n return contextStore.run(ctx, () =>\n runMiddlewareChain(this._middleware, 'resources/read', req.params, ctx, async () => {\n let executePromise: Promise<unknown> = Promise.resolve(resource!.handler(templateParams))\n\n if (resource!.config.timeout) {\n const ms = resource!.config.timeout\n let timer!: ReturnType<typeof setTimeout>\n const timeoutPromise = new Promise<never>((_, reject) => {\n timer = setTimeout(\n () => reject(new Error(`Resource \"${requestedUri}\" timed out after ${ms}ms`)),\n ms,\n )\n })\n executePromise = Promise.race([executePromise, timeoutPromise]).finally(() =>\n clearTimeout(timer),\n ) as Promise<unknown>\n }\n\n const result = await executePromise\n const converted = convertResourceResult(result, requestedUri, resource!.config.mimeType, opts?.stateless)\n return attachResourceUiMeta(converted, resource!.config.ui, isUiCapable(server.getClientCapabilities()))\n }),\n )\n })\n\n // resources/subscribe / resources/unsubscribe (legacy era only).\n //\n // The 2026-07-28 wire registry omits both methods, so a modern connection\n // never reaches these handlers — the SDK rejects the method at the era seam\n // (-32601) before dispatch, and a modern client's own era guard rejects even\n // earlier. On legacy the handshake advertises `resources.subscribe: true`\n // (see _makeServer), so the client may call them here.\n //\n // The subscription set lives in the connection's per-session state Map (the\n // same Map SESSION_CLOSE_CALLBACKS_KEY uses), so it is discarded when the\n // session closes — no separate registry to leak. Delivery of\n // `notifications/resources/updated` is driven by notifyResourceUpdated(uri),\n // the single change signal shared with the modern subscriptions/listen bus.\n //\n // Only resources/subscribe mirrors resources/read's resolve → not-found →\n // auth → context → middleware sequencing, so subscribe is indistinguishable\n // from read as an oracle. resources/unsubscribe skips resolution and auth: it\n // only removes uri from the caller's own subscription set, so an unknown or\n // forbidden uri is a harmless no-op, not an oracle — there is nothing to guard.\n server.setRequestHandler('resources/subscribe', async (req, sdkCtx) => {\n if (opts?.stateless) throw new ProtocolError(ProtocolErrorCode.MethodNotFound, STATELESS_SUBSCRIBE_ERROR)\n const uri = req.params.uri\n const token = await this._resolveToken(sdkCtx.http?.authInfo)\n\n // Resolve against the same lookup resources/read uses; an unknown or\n // disabled URI is a bad parameter (ResourceNotFoundError → -32602), matching\n // resources/read's not-found contract exactly.\n const resolved = this._resolveResource(uri)\n if (!resolved || resolved.resource.config.disabled) {\n throw new ResourceNotFoundError(uri, `Unknown resource: \"${uri}\"`)\n }\n const resource = resolved.resource\n\n // Enforce the resource's auth guard identically to resources/read (same\n // rejection). Without this, subscribe leaks an existence/activity oracle for a\n // URI that read (and resources/list) deliberately hides from an under-scoped\n // caller: `{}` for a real-but-forbidden URI vs -32602 for an unknown one.\n if (resource.config.auth) await runAuthCheck(resource.config.auth, token)\n\n const ctx = createContext(server, sdkCtx, token, sessionState, this._requestStateCodec, opts?.stateless, this._sensitiveHeaders)\n\n return contextStore.run(ctx, () =>\n runMiddlewareChain(this._middleware, 'resources/subscribe', req.params, ctx, async () => {\n let subs = sessionState.get(RESOURCE_SUBSCRIPTIONS_KEY) as Set<string> | undefined\n if (!subs) {\n subs = new Set<string>()\n sessionState.set(RESOURCE_SUBSCRIPTIONS_KEY, subs)\n }\n subs.add(uri)\n return {}\n }),\n )\n })\n\n server.setRequestHandler('resources/unsubscribe', async (req, sdkCtx) => {\n if (opts?.stateless) throw new ProtocolError(ProtocolErrorCode.MethodNotFound, STATELESS_SUBSCRIBE_ERROR)\n const uri = req.params.uri\n const token = await this._resolveToken(sdkCtx.http?.authInfo)\n const ctx = createContext(server, sdkCtx, token, sessionState, this._requestStateCodec, opts?.stateless, this._sensitiveHeaders)\n\n return contextStore.run(ctx, () =>\n runMiddlewareChain(this._middleware, 'resources/unsubscribe', req.params, ctx, async () => {\n const subs = sessionState.get(RESOURCE_SUBSCRIPTIONS_KEY) as Set<string> | undefined\n subs?.delete(uri)\n return {}\n }),\n )\n })\n\n server.setRequestHandler('prompts/list', async (req, sdkCtx) => {\n const token = await this._resolveToken(sdkCtx.http?.authInfo)\n const ctx = createContext(server, sdkCtx, token, sessionState, this._requestStateCodec, opts?.stateless, this._sensitiveHeaders)\n return contextStore.run(ctx, () =>\n runMiddlewareChain(this._middleware, 'prompts/list', req.params, ctx, async () => {\n const allVisible = (\n await Promise.all(\n [...this._prompts.values()].map(async (p) => {\n if (p.config.disabled) return null\n if (!p.config.auth) return p\n if (!token) return null\n try { await p.config.auth(token); return p } catch { return null }\n }),\n )\n ).filter((p): p is RegisteredPrompt => p !== null)\n\n const transformedPrompts = this._applyTransformsToPrompts(allVisible)\n\n const pageSize = this._promptsPageSize\n const cursorName = req.params?.cursor\n ? Buffer.from(req.params.cursor, 'base64url').toString()\n : null\n let startIdx = 0\n if (cursorName !== null) {\n const idx = transformedPrompts.findIndex((p) => p.name === cursorName)\n if (idx < 0) throw new ProtocolError(ProtocolErrorCode.InvalidParams, 'Invalid or expired cursor')\n startIdx = idx + 1\n }\n const page = transformedPrompts.slice(startIdx, startIdx + pageSize)\n const nextCursor =\n startIdx + pageSize < transformedPrompts.length\n ? Buffer.from(page[page.length - 1].name).toString('base64url')\n : undefined\n\n return {\n prompts: page.map((p) => ({\n name: p.name,\n ...(p.config.title !== undefined ? { title: p.config.title } : {}),\n description: p.description,\n // Strip the per-argument `complete` callback — it is a server-side\n // completion hook, not part of the advertised argument schema.\n ...(p.config.arguments?.length\n ? {\n arguments: p.config.arguments.map((a) => ({\n name: a.name,\n ...(a.description !== undefined ? { description: a.description } : {}),\n ...(a.required !== undefined ? { required: a.required } : {}),\n })),\n }\n : {}),\n })),\n ...(nextCursor ? { nextCursor } : {}),\n }\n }),\n )\n })\n\n server.setRequestHandler('prompts/get', async (req, sdkCtx) => {\n const requestedName = req.params.name\n let prompt: RegisteredPrompt | undefined\n if (this._transforms.length > 0) {\n for (const p of this._prompts.values()) {\n const view = applyTransformChain<PromptView>(\n { name: p.config.name, description: p.config.description, tags: p.config.tags ?? [] },\n this._transforms,\n (t, v) => t.transformPrompt?.(v),\n )\n if (view && view.name === requestedName) { prompt = p; break }\n }\n }\n if (!prompt) prompt = this._prompts.get(requestedName)\n\n if (!prompt || prompt.config.disabled) {\n throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Unknown prompt: \"${requestedName}\"`)\n }\n\n const resolvedPrompt = prompt\n const token = await this._resolveToken(sdkCtx.http?.authInfo)\n if (resolvedPrompt.config.auth) await runAuthCheck(resolvedPrompt.config.auth, token)\n\n const suppliedArgs = req.params.arguments ?? {}\n for (const arg of resolvedPrompt.config.arguments ?? []) {\n if (arg.required && !(arg.name in suppliedArgs)) {\n throw new ProtocolError(\n ProtocolErrorCode.InvalidParams,\n `Missing required argument \"${arg.name}\" for prompt \"${requestedName}\"`,\n )\n }\n }\n\n const ctx = createContext(server, sdkCtx, token, sessionState, this._requestStateCodec, opts?.stateless, this._sensitiveHeaders)\n\n return contextStore.run(ctx, () =>\n runMiddlewareChain(this._middleware, 'prompts/get', req.params, ctx, async () => {\n let executePromise = Promise.resolve(resolvedPrompt.handler(suppliedArgs))\n if (resolvedPrompt.config.timeout) {\n const ms = resolvedPrompt.config.timeout\n let timer!: ReturnType<typeof setTimeout>\n const timeoutPromise = new Promise<never>((_, reject) => {\n timer = setTimeout(\n () => reject(new Error(`Prompt \"${requestedName}\" timed out after ${ms}ms`)),\n ms,\n )\n })\n executePromise = Promise.race([executePromise, timeoutPromise]).finally(() =>\n clearTimeout(timer),\n )\n }\n // Cast: the SDK infers the handler's return type as GetPromptResult |\n // InputRequiredResult (multi-round-trip); this handler only returns the\n // \"complete\" shape today. inputRequired(...) support lands separately.\n return convertPromptResult(await executePromise, opts?.stateless) as GetPromptResult\n }),\n )\n })\n\n // completion/complete — argument autocompletion for prompt arguments and\n // resource-template variables. Registered on every factory (both eras admit\n // the method; see _makeServer's `completions` capability note). Routes by the\n // request's ref type using the SDK's assert helpers (which narrow the request\n // after the `ref.type` switch has already established the branch), then\n // dispatches to _completePrompt / _completeResourceTemplate. Both mirror\n // prompts/get and resources/read: resolve → not-found (-32602) → auth → run,\n // so completion is no weaker an oracle than get/read and audit middleware\n // observes it.\n server.setRequestHandler('completion/complete', async (req, sdkCtx) => {\n const token = await this._resolveToken(sdkCtx.http?.authInfo)\n const ctx = createContext(server, sdkCtx, token, sessionState, this._requestStateCodec, opts?.stateless, this._sensitiveHeaders)\n return contextStore.run(ctx, () =>\n runMiddlewareChain(this._middleware, 'completion/complete', req.params, ctx, async () => {\n const ref = req.params.ref\n if (ref.type === 'ref/prompt') {\n assertCompleteRequestPrompt(req)\n return this._completePrompt(req.params, token)\n }\n if (ref.type === 'ref/resource') {\n assertCompleteRequestResourceTemplate(req)\n return this._completeResourceTemplate(req.params, token)\n }\n throw new ProtocolError(\n ProtocolErrorCode.InvalidParams,\n `Invalid completion reference type: \"${(ref as { type: string }).type}\"`,\n )\n }),\n )\n })\n }\n\n /**\n * Resolve a `completion/complete` request against a prompt argument's completer.\n * Mirrors prompts/get's transform-aware lookup, not-found contract (-32602), and\n * auth check; an argument with no completer yields an empty list (SDK parity).\n */\n private async _completePrompt(\n params: CompleteRequestParams,\n token: AccessToken | undefined,\n ): Promise<CompleteResult> {\n const ref = params.ref as { type: 'ref/prompt'; name: string }\n let prompt: RegisteredPrompt | undefined\n if (this._transforms.length > 0) {\n for (const p of this._prompts.values()) {\n const view = applyTransformChain<PromptView>(\n { name: p.config.name, description: p.config.description, tags: p.config.tags ?? [] },\n this._transforms,\n (t, v) => t.transformPrompt?.(v),\n )\n if (view && view.name === ref.name) { prompt = p; break }\n }\n }\n if (!prompt) prompt = this._prompts.get(ref.name)\n\n if (!prompt || prompt.config.disabled) {\n throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Unknown prompt: \"${ref.name}\"`)\n }\n if (prompt.config.auth) await runAuthCheck(prompt.config.auth, token)\n\n const arg = prompt.config.arguments?.find((a) => a.name === params.argument.name)\n if (!arg?.complete) return { completion: EMPTY_COMPLETION }\n\n const raw = await arg.complete(params.argument.value, params.context)\n return { completion: normalizeCompletion(raw) }\n }\n\n /**\n * Resolve a `completion/complete` request against a resource template's\n * per-variable completer. Mirrors resources/read's not-found contract (-32602)\n * and auth check; a variable with no completer yields an empty list. Following\n * the SDK's own high-level server, a `ref.uri` that names a registered STATIC\n * resource (not a template) is answered with an empty list rather than an error.\n */\n private async _completeResourceTemplate(\n params: CompleteRequestParams,\n token: AccessToken | undefined,\n ): Promise<CompleteResult> {\n const ref = params.ref as { type: 'ref/resource'; uri: string }\n let template = this._templateResources.get(ref.uri)\n if (!template && this._transforms.length > 0) {\n for (const r of this._templateResources.values()) {\n const view = applyTransformChain<ResourceView>(\n { uri: r.config.uri, name: r.config.name ?? r.config.uri, tags: r.config.tags ?? [], mimeType: r.config.mimeType, title: r.config.title },\n this._transforms,\n (t, v) => t.transformResourceTemplate?.(v),\n )\n if (view && view.uri === ref.uri) { template = r; break }\n }\n }\n\n if (!template || template.config.disabled) {\n // A concrete (non-template) resource URI is a valid ref with nothing to\n // complete — answer empty, matching the SDK's high-level server. But apply\n // resources/read's resolve → not-found → auth gate first, so a disabled or\n // auth-gated static resource is NOT an existence oracle: a hidden resource\n // must be indistinguishable from an unknown URI (task-11's subscribe standard).\n const staticResource = this._staticResources.get(ref.uri)\n if (staticResource && !staticResource.config.disabled) {\n // Enforce the resource's auth guard identically to resources/read (same\n // rejection). Without this, an auth-gated static resource answers `{}` here\n // while read rejects it — a caller could enumerate forbidden URIs.\n if (staticResource.config.auth) await runAuthCheck(staticResource.config.auth, token)\n return { completion: EMPTY_COMPLETION }\n }\n // Disabled or unknown: fall through to the identical not-found rejection, so a\n // disabled static resource is byte-indistinguishable from a URI that was never\n // registered (matches read's not-found code, -32602).\n throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Unknown resource template: \"${ref.uri}\"`)\n }\n if (template.config.auth) await runAuthCheck(template.config.auth, token)\n\n const completer = template.config.complete?.[params.argument.name]\n if (!completer) return { completion: EMPTY_COMPLETION }\n\n const raw = await completer(params.argument.value, params.context)\n return { completion: normalizeCompletion(raw) }\n }\n\n private _notifyToolListChanged(): void {\n this._primaryServer.sendToolListChanged().catch(() => {})\n this._stdioServer?.sendToolListChanged().catch(() => {})\n for (const { server } of this._sessions.values()) {\n server.sendToolListChanged().catch(() => {})\n }\n // Modern (2026-07-28) HTTP requests are stateless per-request — there is no live\n // connection to push an unsolicited notification to. Delivery for subscribed\n // modern clients instead goes through the shared modern handler's own\n // subscriptions/listen bus (see _getModernHandler / FastMCPOptions.eventBus).\n // Optional chaining: a no-op until the first modern HTTP request creates the\n // handler — nothing to notify before then, so there is no reason to force it\n // into existence just to publish to an empty bus.\n this._modernHandler?.notify.toolsChanged()\n }\n\n private _notifyResourceListChanged(): void {\n this._primaryServer.sendResourceListChanged().catch(() => {})\n this._stdioServer?.sendResourceListChanged().catch(() => {})\n for (const { server } of this._sessions.values()) {\n server.sendResourceListChanged().catch(() => {})\n }\n this._modernHandler?.notify.resourcesChanged()\n }\n\n private _notifyPromptListChanged(): void {\n this._primaryServer.sendPromptListChanged().catch(() => {})\n this._stdioServer?.sendPromptListChanged().catch(() => {})\n for (const { server } of this._sessions.values()) {\n server.sendPromptListChanged().catch(() => {})\n }\n this._modernHandler?.notify.promptsChanged()\n }\n\n /**\n * Signal that a resource changed and any subscriber should re-read it. This is\n * the SINGLE change signal for resource updates across both eras — the legacy\n * per-session push and the modern subscriptions/listen bus are driven from here:\n *\n * - Legacy connections (primary / stdio / legacy HTTP sessions) that called\n * `resources/subscribe` for `uri` are pushed `notifications/resources/updated`\n * directly on their live session (subscription set kept in per-session state).\n * - The modern handler's bus (W3) is published to as well; it does its own\n * per-stream filtering, delivering only to `subscriptions/listen` streams that\n * opted in to this URI. Optional chaining keeps it a no-op until the first\n * modern HTTP request has actually built the handler.\n *\n * Unsubscribed sessions (and the modern streams that never opted in) receive\n * nothing, so calling this for a URI with no subscribers is safe and cheap.\n */\n notifyResourceUpdated(uri: string): void {\n const pushIfSubscribed = (server: Server, state: Map<string, unknown> | null): void => {\n const subs = state?.get(RESOURCE_SUBSCRIPTIONS_KEY) as Set<string> | undefined\n if (subs?.has(uri)) server.sendResourceUpdated({ uri }).catch(() => {})\n }\n pushIfSubscribed(this._primaryServer, this._primaryState)\n if (this._stdioServer) pushIfSubscribed(this._stdioServer, this._stdioState)\n for (const { server, state } of this._sessions.values()) pushIfSubscribed(server, state)\n this._modernHandler?.notify.resourceUpdated(uri)\n }\n\n /**\n * Resolve a requested URI to a registered resource, mirroring the lookup order\n * `resources/read` uses: exact static match, then original template match, then\n * (only when transforms are registered) transformed-static and\n * transformed-template matches. Returns the resource plus any template params, or\n * undefined when nothing matches. Disabled static resources are still returned by\n * exact match — callers apply the `disabled` check themselves (as read does), so\n * a hidden-but-known URI is a not-found, not a silent miss.\n */\n private _resolveResource(\n requestedUri: string,\n ): { resource: RegisteredResource; templateParams?: Record<string, string> } | undefined {\n let resource: RegisteredResource | undefined = this._staticResources.get(requestedUri)\n let templateParams: Record<string, string> | undefined\n\n // Direct template matching (original URIs — also handles hidden-but-callable resources)\n if (!resource) {\n for (const r of this._templateResources.values()) {\n if (r.config.disabled) continue\n const params = matchTemplate(r.config.uri, requestedUri)\n if (params !== null) { resource = r; templateParams = params; break }\n }\n }\n\n // Transformed static lookup\n if (!resource && this._transforms.length > 0) {\n for (const r of this._staticResources.values()) {\n if (r.config.disabled) continue\n const view = applyTransformChain<ResourceView>(\n { uri: r.config.uri, name: r.config.name ?? r.config.uri, tags: r.config.tags ?? [], mimeType: r.config.mimeType, title: r.config.title },\n this._transforms,\n (t, v) => t.transformResource?.(v),\n )\n if (view && view.uri === requestedUri) { resource = r; break }\n }\n }\n\n // Transformed template matching\n if (!resource && this._transforms.length > 0) {\n for (const r of this._templateResources.values()) {\n if (r.config.disabled) continue\n const view = applyTransformChain<ResourceView>(\n { uri: r.config.uri, name: r.config.name ?? r.config.uri, tags: r.config.tags ?? [], mimeType: r.config.mimeType, title: r.config.title },\n this._transforms,\n (t, v) => t.transformResourceTemplate?.(v),\n )\n if (view) {\n const params = matchTemplate(view.uri, requestedUri)\n if (params !== null) { resource = r; templateParams = params; break }\n }\n }\n }\n\n if (!resource) return undefined\n return { resource, templateParams }\n }\n\n // Overload: typed handler inferred from input schema\n tool<S extends StandardSchemaV1>(\n config: Omit<ToolConfig, 'input'> & { input: S },\n handler: (args: StandardSchemaV1.InferOutput<S>) => unknown,\n ): void\n // Overload: untyped handler\n tool(config: ToolConfig, handler: (args: Record<string, unknown>) => unknown): void\n // Implementation (handler typed as any to satisfy both overload signatures)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n tool(config: ToolConfig, handler: (args: any) => any): void {\n const registered: RegisteredTool = { config, handler }\n this._tools.set(config.name, registered)\n this._notifyToolListChanged()\n for (const cb of this._toolRegisteredCallbacks) cb(registered)\n }\n\n prompt(config: PromptConfig, handler: (args?: Record<string, string>) => unknown): void {\n const name = config.name ?? (handler as { name?: string }).name\n if (!name) throw new Error('Prompt name must be provided in config or inferrable from the handler function name')\n const description = config.description ?? inferDescription(name)\n const resolvedConfig: ResolvedPromptConfig = { ...config, name, description }\n const registered: RegisteredPrompt = { config: resolvedConfig, handler }\n this._prompts.set(name, registered)\n this._notifyPromptListChanged()\n for (const cb of this._promptRegisteredCallbacks) cb(registered)\n }\n\n resource(config: ResourceConfig, handler: (params?: Record<string, string>) => unknown): void {\n const registered: RegisteredResource = { config, handler }\n if (isUriTemplate(config.uri)) {\n this._templateResources.set(config.uri, registered)\n } else {\n this._staticResources.set(config.uri, registered)\n }\n this._notifyResourceListChanged()\n for (const cb of this._resourceRegisteredCallbacks) cb(registered)\n }\n\n _removeTool(name: string): boolean {\n if (!this._tools.has(name)) return false\n this._tools.delete(name)\n this._notifyToolListChanged()\n return true\n }\n\n _removeResource(uri: string): boolean {\n if (this._staticResources.has(uri)) {\n this._staticResources.delete(uri)\n this._notifyResourceListChanged()\n return true\n }\n if (this._templateResources.has(uri)) {\n this._templateResources.delete(uri)\n this._notifyResourceListChanged()\n return true\n }\n return false\n }\n\n _removePrompt(name: string): boolean {\n if (!this._prompts.has(name)) return false\n this._prompts.delete(name)\n this._notifyPromptListChanged()\n return true\n }\n\n /** Add a transform to the pipeline. Applied to list responses in registration order. */\n transform(t: Transform): this {\n this._transforms.push(t)\n return this\n }\n\n /**\n * Dispatch a tool call through this server's middleware chain using an inherited context.\n * Used by parent servers to honour child-level middleware when routing mounted tool calls.\n */\n async _dispatchTool(\n name: string,\n rawArgs: unknown,\n ctx: McpContext,\n ) {\n const tool = this._tools.get(name)\n if (!tool || tool.config.disabled) {\n throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Unknown tool: \"${name}\"`)\n }\n if (tool.config.auth) await runAuthCheck(tool.config.auth, ctx.auth)\n\n try {\n return await contextStore.run(ctx, () =>\n runMiddlewareChain(this._middleware, 'tools/call', { name, arguments: rawArgs }, ctx, async () => {\n const args = tool.config.input\n ? await validateInput(tool.config.input, rawArgs, true)\n : rawArgs\n\n let executePromise: Promise<unknown> = Promise.resolve(tool.handler(args))\n if (tool.config.timeout) {\n const ms = tool.config.timeout\n let timer!: ReturnType<typeof setTimeout>\n const timeoutPromise = new Promise<never>((_, reject) => {\n timer = setTimeout(\n () => reject(new Error(`Tool \"${name}\" timed out after ${ms}ms`)),\n ms,\n )\n })\n executePromise = Promise.race([executePromise, timeoutPromise]).finally(() =>\n clearTimeout(timer),\n )\n }\n\n let resultValue = await executePromise\n if (tool.config.output) resultValue = await validateInput(tool.config.output, resultValue)\n // Deliberately no `stateless` argument here: this method has no per-server\n // `opts` in scope (it is only reached via `_mirrorTool`, for a mounted child),\n // and the stateless-ness that matters is the top-level server actually\n // serving the wire request, not this child. `_mirrorTool` passes an\n // InputRequiredResult straight through unwrapped, so it re-enters the\n // mounting parent's own top-level `convertResult(resultValue, opts?.stateless)`\n // call, which applies the guard with the correct flag.\n return convertResult(resultValue)\n }),\n )\n } catch (err) {\n if (err instanceof ProtocolError) throw err\n return {\n content: [{ type: 'text' as const, text: err instanceof Error ? err.message : String(err) }],\n isError: true,\n }\n }\n }\n\n /**\n * Run a resource read through this server's middleware chain using an inherited context.\n * Returns the raw handler result so the parent can apply convertResourceResult with the\n * actual requested URI (important for template resources).\n */\n async _dispatchResource(\n uri: string,\n params: Record<string, string> | undefined,\n ctx: McpContext,\n ): Promise<unknown> {\n const resource = isUriTemplate(uri)\n ? this._templateResources.get(uri)\n : this._staticResources.get(uri)\n\n if (!resource || resource.config.disabled) {\n // See resources/read handler: ResourceNotFoundError carries data.uri so the\n // miss is recognisable per the SDK contract (task-9 Req 3; task-7 F1).\n throw new ResourceNotFoundError(uri, `Unknown resource: \"${uri}\"`)\n }\n if (resource.config.auth) await runAuthCheck(resource.config.auth, ctx.auth)\n\n return contextStore.run(ctx, () =>\n runMiddlewareChain(this._middleware, 'resources/read', { uri }, ctx, async () => {\n let executePromise: Promise<unknown> = Promise.resolve(resource.handler(params))\n if (resource.config.timeout) {\n const ms = resource.config.timeout\n let timer!: ReturnType<typeof setTimeout>\n const timeoutPromise = new Promise<never>((_, reject) => {\n timer = setTimeout(\n () => reject(new Error(`Resource \"${uri}\" timed out after ${ms}ms`)),\n ms,\n )\n })\n executePromise = Promise.race([executePromise, timeoutPromise]).finally(() =>\n clearTimeout(timer),\n ) as Promise<unknown>\n }\n return await executePromise\n }),\n )\n }\n\n /**\n * Dispatch a prompt render through this server's middleware chain using an inherited context.\n */\n async _dispatchPrompt(\n name: string,\n args: Record<string, string>,\n ctx: McpContext,\n ) {\n const prompt = this._prompts.get(name)\n if (!prompt || prompt.config.disabled) {\n throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Unknown prompt: \"${name}\"`)\n }\n if (prompt.config.auth) await runAuthCheck(prompt.config.auth, ctx.auth)\n\n for (const arg of prompt.config.arguments ?? []) {\n if (arg.required && !(arg.name in args)) {\n throw new ProtocolError(\n ProtocolErrorCode.InvalidParams,\n `Missing required argument \"${arg.name}\" for prompt \"${name}\"`,\n )\n }\n }\n\n return contextStore.run(ctx, () =>\n runMiddlewareChain(this._middleware, 'prompts/get', { name, arguments: args }, ctx, async () => {\n let executePromise = Promise.resolve(prompt.handler(args))\n if (prompt.config.timeout) {\n const ms = prompt.config.timeout\n let timer!: ReturnType<typeof setTimeout>\n const timeoutPromise = new Promise<never>((_, reject) => {\n timer = setTimeout(\n () => reject(new Error(`Prompt \"${name}\" timed out after ${ms}ms`)),\n ms,\n )\n })\n executePromise = Promise.race([executePromise, timeoutPromise]).finally(() =>\n clearTimeout(timer),\n )\n }\n // Deliberately no `stateless` argument — see the matching comment in\n // `_dispatchTool` above. `_mirrorPrompt` passes an InputRequiredResult\n // straight through unwrapped, so it re-enters the mounting parent's own\n // top-level `convertPromptResult(await executePromise, opts?.stateless)`\n // call, which applies the guard with the correct top-level flag.\n return convertPromptResult(await executePromise)\n }),\n )\n }\n\n private _mirrorTool(child: FastMCP, tool: RegisteredTool, prefix?: string): void {\n const originalName = tool.config.name\n const key = prefix ? `${prefix}_${originalName}` : originalName\n if (this._tools.has(key)) throw new Error(`Tool name collision on mount: \"${key}\" is already registered`)\n // Strip runtime validators — child's _dispatchTool runs them.\n // inputSchema/outputSchema are kept so clients see the correct JSON Schema.\n const forwardedConfig: ToolConfig = { ...tool.config, name: key, input: undefined, output: undefined }\n this.tool(forwardedConfig, (args: unknown) => {\n const parentCtx = contextStore.getStore()!\n // Inject prefix-aware tool name resolver so toolRef() inside the child resolves correctly.\n const childCtx: typeof parentCtx = prefix\n ? { ...parentCtx, resolveToolName: (name) => `${prefix}_${name}` }\n : parentCtx\n // _dispatchTool already ran the child's own convertResult, so its resolved\n // value is either a finished CallToolResult (wrap in ToolResult so the parent's\n // own convertResult passes it through unchanged) or an InputRequiredResult\n // (multi-round-trip escape hatch — already recognized directly by convertResult,\n // must not be wrapped).\n //\n // LOAD-BEARING for the stateless inputRequests guard: if this ever wraps an\n // InputRequiredResult too, the parent's top-level convertResult takes the\n // `instanceof ToolResult` branch instead of the `isInputRequiredResult` one, which\n // skips assertInputRequestsAllowedStateless (mrtr.ts) entirely — a stateless legacy\n // client would then receive an unusable inputRequests result with no error. See the\n // matching comment on `_dispatchTool` above (this method's counterpart on the other\n // side of the coupling).\n return child._dispatchTool(originalName, args, childCtx).then((result) =>\n isInputRequiredResult(result) ? result : new ToolResult(result),\n )\n })\n }\n\n private _mirrorResource(child: FastMCP, resource: RegisteredResource, prefix?: string): void {\n const name = resource.config.name ?? resource.config.uri\n const originalUri = resource.config.uri\n const targetUri = prefix ? prefixResourceUri(originalUri, prefix) : originalUri\n if (this._staticResources.has(targetUri) || this._templateResources.has(targetUri)) {\n throw new Error(`Resource URI collision on mount: \"${targetUri}\" is already registered`)\n }\n const forwardedConfig: ResourceConfig = {\n ...resource.config,\n uri: targetUri,\n name: prefix ? `${prefix}_${name}` : name,\n }\n // Return the raw handler result so the parent's ReadResource handler can call\n // convertResourceResult with the actual requested URI (correct for template expansions).\n this.resource(forwardedConfig, (params?: Record<string, string>) => {\n const ctx = contextStore.getStore()!\n return child._dispatchResource(originalUri, params, ctx)\n })\n }\n\n private _mirrorPrompt(child: FastMCP, prompt: RegisteredPrompt, prefix?: string): void {\n const originalName = prompt.config.name\n const key = prefix ? `${prefix}_${originalName}` : originalName\n if (this._prompts.has(key)) throw new Error(`Prompt name collision on mount: \"${key}\" is already registered`)\n const forwardedConfig: PromptConfig = { ...(prompt.config as PromptConfig), name: key }\n this.prompt(forwardedConfig, (args?: Record<string, string>) => {\n const ctx = contextStore.getStore()!\n // LOAD-BEARING for the stateless inputRequests guard, same reasoning as _mirrorTool's\n // matching comment above: wrapping an InputRequiredResult here would skip the parent's\n // top-level convertPromptResult -> assertInputRequestsAllowedStateless (mrtr.ts) check,\n // silently handing a stateless legacy client an unusable inputRequests result.\n return child._dispatchPrompt(originalName, args ?? {}, ctx).then((result) =>\n isInputRequiredResult(result) ? result : new PromptResult(result.messages, result.description),\n )\n })\n }\n\n /** Mount a child server onto this server. All tools, resources, and prompts from the child become accessible via this server. Pass a prefix to namespace names and prevent collisions. */\n mount(child: FastMCP, prefix?: string): this {\n if (child === this) throw new Error('Cannot mount a server onto itself')\n if (this._mountedChildren.has(child)) return this\n this._mountedChildren.add(child)\n\n for (const tool of child._tools.values()) this._mirrorTool(child, tool, prefix)\n for (const resource of child._staticResources.values()) this._mirrorResource(child, resource, prefix)\n for (const resource of child._templateResources.values()) this._mirrorResource(child, resource, prefix)\n for (const prompt of child._prompts.values()) this._mirrorPrompt(child, prompt, prefix)\n\n child._toolRegisteredCallbacks.push((tool) => this._mirrorTool(child, tool, prefix))\n child._resourceRegisteredCallbacks.push((resource) => this._mirrorResource(child, resource, prefix))\n child._promptRegisteredCallbacks.push((prompt) => this._mirrorPrompt(child, prompt, prefix))\n\n // When this server closes, drain the child's owned proxy connections\n this._proxyCloseCallbacks.push(async () => {\n await Promise.all(child._proxyCloseCallbacks.map((cb) => cb().catch(() => {})))\n child._proxyCloseCallbacks.length = 0\n })\n\n return this\n }\n\n /** Register a callback invoked when this server is closed — used by proxy connections. */\n _addCloseCallback(cb: () => Promise<void>): void {\n this._proxyCloseCallbacks.push(cb)\n }\n\n /**\n * Register a provider (FastMCPApp or FastMCP) on this server.\n * All tools, resources, and prompts from the provider are mounted without a prefix.\n * For FastMCPApp, pass provider.server; for FastMCP, pass directly.\n */\n addProvider(provider: FastMCP | { server: FastMCP }): this {\n const child = 'server' in provider ? provider.server : provider\n return this.mount(child)\n }\n\n private _applyTransformsToTools(\n tools: RegisteredTool[],\n ): Array<{ name: string; title: string | undefined; description: string; originalName: string; config: ToolConfig; handler: (args: unknown) => unknown }> {\n return tools.flatMap((tool) => {\n const view = applyTransformChain<ToolView>(\n { name: tool.config.name, title: tool.config.title, description: tool.config.description, tags: tool.config.tags ?? [] },\n this._transforms,\n (t, v) => t.transformTool?.(v),\n )\n return view\n ? [{ name: view.name, title: view.title, description: view.description, originalName: tool.config.name, config: tool.config, handler: tool.handler }]\n : []\n })\n }\n\n private _applyTransformsToResources(\n resources: RegisteredResource[],\n ): Array<{ uri: string; name: string; originalUri: string; config: ResourceConfig; handler: (params?: Record<string, string>) => unknown }> {\n return resources.flatMap((r) => {\n const resolvedName = r.config.name ?? r.config.uri\n const view = applyTransformChain<ResourceView>(\n { uri: r.config.uri, name: resolvedName, tags: r.config.tags ?? [], mimeType: r.config.mimeType, title: r.config.title },\n this._transforms,\n (t, v) => t.transformResource?.(v),\n )\n return view\n ? [{ uri: view.uri, name: view.name, originalUri: r.config.uri, config: r.config, handler: r.handler }]\n : []\n })\n }\n\n private _applyTransformsToResourceTemplates(\n templates: RegisteredResource[],\n ): Array<{ uri: string; name: string; originalUri: string; config: ResourceConfig; handler: (params?: Record<string, string>) => unknown }> {\n return templates.flatMap((r) => {\n const resolvedName = r.config.name ?? r.config.uri\n const view = applyTransformChain<ResourceView>(\n { uri: r.config.uri, name: resolvedName, tags: r.config.tags ?? [], mimeType: r.config.mimeType, title: r.config.title },\n this._transforms,\n (t, v) => t.transformResourceTemplate?.(v),\n )\n return view\n ? [{ uri: view.uri, name: view.name, originalUri: r.config.uri, config: r.config, handler: r.handler }]\n : []\n })\n }\n\n private _applyTransformsToPrompts(\n prompts: RegisteredPrompt[],\n ): Array<{ name: string; description: string; originalName: string; config: ResolvedPromptConfig; handler: (args?: Record<string, string>) => unknown }> {\n return prompts.flatMap((p) => {\n const view = applyTransformChain<PromptView>(\n { name: p.config.name, description: p.config.description, tags: p.config.tags ?? [] },\n this._transforms,\n (t, v) => t.transformPrompt?.(v),\n )\n return view\n ? [{ name: view.name, description: view.description, originalName: p.config.name, config: p.config, handler: p.handler }]\n : []\n })\n }\n\n private _buildSynthesizedTools(resourceViews: ResourceView[], promptViews: PromptView[]): SynthesizedTool[] {\n if (this._transforms.length === 0) return []\n const raw = this._transforms.flatMap((t) => t.synthesizeTools?.(resourceViews, promptViews) ?? [])\n return raw.flatMap((s) => {\n const view = applyTransformChain<ToolView>(\n { name: s.name, title: s.title, description: s.description, tags: [] },\n this._transforms,\n (t, v) => t.transformTool?.(v),\n )\n return view ? [{ ...s, name: view.name, title: view.title, description: view.description }] : []\n })\n }\n\n private async _getVisibleViews(\n token: AccessToken | undefined,\n ): Promise<{ resourceViews: ResourceView[]; promptViews: PromptView[] }> {\n const visibleStatic = (\n await Promise.all(\n [...this._staticResources.values()].map(async (r) => {\n if (r.config.disabled) return null\n if (!r.config.auth) return r\n if (!token) return null\n try { await r.config.auth(token); return r } catch { return null }\n }),\n )\n ).filter((r): r is RegisteredResource => r !== null)\n\n const visibleTemplates = (\n await Promise.all(\n [...this._templateResources.values()].map(async (r) => {\n if (r.config.disabled) return null\n if (!r.config.auth) return r\n if (!token) return null\n try { await r.config.auth(token); return r } catch { return null }\n }),\n )\n ).filter((r): r is RegisteredResource => r !== null)\n\n const visiblePrompts = (\n await Promise.all(\n [...this._prompts.values()].map(async (p) => {\n if (p.config.disabled) return null\n if (!p.config.auth) return p\n if (!token) return null\n try { await p.config.auth(token); return p } catch { return null }\n }),\n )\n ).filter((p): p is RegisteredPrompt => p !== null)\n\n const resourceViews: ResourceView[] = [\n ...this._applyTransformsToResources(visibleStatic),\n ...this._applyTransformsToResourceTemplates(visibleTemplates),\n ].map((r) => ({\n uri: r.uri,\n name: r.name,\n tags: r.config.tags ?? [],\n mimeType: r.config.mimeType,\n title: r.config.title,\n }))\n\n const promptViews: PromptView[] = this._applyTransformsToPrompts(visiblePrompts).map((p) => ({\n name: p.name,\n description: p.description,\n tags: p.config.tags ?? [],\n }))\n\n return { resourceViews, promptViews }\n }\n\n /**\n * Add a middleware to the pipeline.\n *\n * Can be called at any point before the first request arrives. `setup()` is\n * called immediately on the primary server so that notification handlers and\n * other server-level side-effects are active before `connect()` / `run()` is\n * called. HTTP sessions created after `use()` will also have `setup()` called\n * via `_makeServer()`.\n */\n use(mw: Middleware): this {\n this._middleware.push(mw)\n mw.setup?.(this._primaryServer)\n return this\n }\n\n getContext(): McpContext {\n const ctx = contextStore.getStore()\n if (!ctx) throw new Error('getContext() called outside of a request handler')\n return ctx\n }\n\n /** The bound address after run() resolves for the http transport. Null for stdio or before run(). */\n get address(): ServerAddress | null {\n return this._address\n }\n\n /**\n * Whether `run()` or `connect()` has been called on this instance. Used by the\n * CLI's entrypoint loader to detect servers that already started themselves via\n * top-level code, so it doesn't attempt to start them a second time.\n */\n get isRunning(): boolean {\n return this._isRunning\n }\n\n async connect(transport: Transport): Promise<void> {\n this._isRunning = true\n // Rebuild so UI extension capability reflects all registered components.\n this._primaryServer = this._makeServer()\n await this._primaryServer.connect(transport)\n }\n\n /**\n * Modern-era (2026-07-28) in-process fetch entrypoint — the `McpServerLike`\n * duck-type hook `fastmcp-ts/client`'s `Client` looks for when a caller pins\n * modern era for an in-process server (`versionNegotiation: { mode: { pin:\n * '2026-07-28' } } }`). Delegates directly to the same `createMcpHandler`\n * instance the real HTTP modern path uses (`_getModernHandler`), so this is\n * the identical dispatch a real network connection would get — no sockets,\n * same code. Modern-only (`legacy: 'reject'`): a client using `'auto'` or\n * `'legacy'` negotiation instead goes through `connect()` + `InMemoryTransport`\n * (2025-era only), unaffected by this method.\n */\n async _modernFetch(request: Request, options?: McpHandlerRequestOptions): Promise<Response> {\n return this._getModernHandler().fetch(request, options)\n }\n\n async run(options?: RunOptions): Promise<void> {\n this._isRunning = true\n const rawTransport = process.env.MCP_TRANSPORT ?? options?.transport ?? 'stdio'\n if (rawTransport !== 'stdio' && rawTransport !== 'http') {\n throw new Error(`Unknown transport: \"${rawTransport}\". Supported: stdio, http.`)\n }\n const transport = rawTransport as 'stdio' | 'http'\n\n const port = options?.port ?? parseInt(process.env.MCP_PORT ?? process.env.PORT ?? '3000', 10)\n const host = options?.host ?? process.env.MCP_HOST ?? '127.0.0.1'\n const path = options?.path ?? process.env.MCP_PATH ?? '/mcp'\n\n // Resolved for every transport so a malformed value fails loudly at startup\n // regardless of how the server is being served. Only the http path reads it.\n this._stateless = options?.stateless ?? envBool('FASTMCP_STATELESS_HTTP') ?? false\n\n if (transport === 'stdio') {\n const { StdioServerTransport, serveStdio } = await import('@modelcontextprotocol/server/stdio')\n const stdioTransport = new StdioServerTransport(options?.stdin, options?.stdout)\n // serveStdio owns the connection's era decision (from the opening exchange) and\n // pins one instance from the factory for the connection's lifetime — unlike\n // connect(), which is always 2025-era (used by in-process/test transports).\n // The factory may be invoked twice (a discarded server/discover probe instance,\n // then the real pinned one); _stdioServer always ends up holding the latter.\n // The factory receives `ctx.era` because serveStdio always classifies the\n // opening exchange's era before constructing an instance for it (including\n // the discarded probe instance, which is itself a modern-era construction) —\n // so `ctx.era` is used to fork `_makeServer`'s `modern` option the same way\n // `_getModernHandler` does, and a modern connection no longer advertises the\n // legacy-only `resources.subscribe` capability.\n this._stdioHandle = serveStdio(\n (ctx) => {\n // Capture the state Map so the resource-updated fan-out can reach this\n // connection's per-session subscription set (see _notifyResourceUpdated).\n const stdioState = new Map<string, unknown>()\n this._stdioState = stdioState\n this._stdioServer = this._makeServer(stdioState, { modern: ctx.era === 'modern' })\n return this._stdioServer\n },\n { transport: stdioTransport },\n )\n } else if (this._oauth) {\n await this._runHttpOAuth(port, host, path)\n } else {\n await this._runHttpSimple(port, host, path)\n }\n }\n\n /** Lazily builds the modern (2026-07-28) HTTP handler. One per FastMCP instance;\n * builds a fresh Server (via _makeServer) per request, matching createMcpHandler's\n * per-request-factory model. Modern-only (legacy: 'reject') — legacy (2025-era)\n * traffic is routed to the existing sessionful transport by _dispatchHttp instead\n * of createMcpHandler's own stateless legacy fallback, so session state and the\n * legacy server-initiated-request shim keep working for 2025-era clients. */\n private _getModernHandler(): McpHttpHandler {\n if (!this._modernHandler) {\n this._modernHandler = createMcpHandler(() => this._makeServer(new Map(), { modern: true }), {\n legacy: 'reject',\n ...(this._eventBus ? { bus: this._eventBus } : {}),\n })\n }\n return this._modernHandler\n }\n\n /** Lazily builds the stateless legacy (2025-era) HTTP handler. One per FastMCP\n * instance, mirroring _getModernHandler's per-instance, per-request-factory model.\n *\n * The SDK serves each POST from a fresh instance of the factory over a transport\n * built with `sessionIdGenerator: undefined`, and answers GET and DELETE with 405\n * because both are session operations that mean nothing per request.\n *\n * Only reachable when `_stateless` is on. The sessionful transport in\n * _dispatchLegacyHttp is untouched and still serves every other deployment. */\n private _getStatelessLegacyHandler(): LegacyHttpHandler {\n if (!this._statelessLegacyHandler) {\n this._statelessLegacyHandler = legacyStatelessFallback(\n () => this._makeServer(new Map(), { stateless: true }),\n (error) => console.error('[fastmcp] stateless legacy serving failed:', error),\n )\n }\n return this._statelessLegacyHandler\n }\n\n /**\n * Dual-era HTTP dispatch shared by the OAuth and non-OAuth serve paths. Assumes CORS\n * and auth have already been handled by the caller (req.auth already set, if any —\n * both the legacy transport and the modern handler read it as pass-through authInfo).\n */\n private async _dispatchHttp(req: IncomingMessage, res: ServerResponse): Promise<void> {\n // DNS-rebinding protection runs first and is header-only, so it never reads the\n // request body — no contention with the body parsing the legacy/modern branches do\n // below. Each guard writes the SDK's 403 JSON-RPC rejection and returns false when it\n // rejects, covering BOTH the legacy sessionful transport and the modern\n // createMcpHandler path from this one shared choke point.\n if (this._hostGuard && !this._hostGuard(req, res)) return\n if (this._originGuard && !this._originGuard(req, res)) return\n\n const { toNodeHandler, toWebRequest } = await import('@modelcontextprotocol/node')\n\n // Drains the raw Node req stream and builds a web-standard Request from the\n // buffered bytes; req cannot be re-read as a stream after this.\n const request = await toWebRequest(req)\n\n if (req.method === 'POST' && !isJsonContentType(request.headers.get('content-type'))) {\n res\n .writeHead(415, { 'Content-Type': 'application/json' })\n .end(JSON.stringify({ error: 'Unsupported Media Type: expected application/json' }))\n return\n }\n\n // No parsedBody passed here, so isLegacyRequest reads from an internal clone —\n // `request` itself stays fully unread, so we can still read its body below.\n const legacy = await isLegacyRequest(request)\n\n const parsedBody = req.method === 'POST' ? await request.json().catch(() => undefined) : undefined\n\n if (legacy) {\n // Stateless serves 2025-era traffic per request through the SDK's own\n // stateless leg, so consecutive requests may land on different instances.\n // Sessionful serving is the default and keeps the in-memory session map.\n if (this._stateless) {\n // toNodeHandler wants a `{ fetch }`-shaped handler (FetchLikeMcpHandler);\n // LegacyHttpHandler is the bare fetch-shaped function itself, so wrap it\n // rather than widening toNodeHandler's own parameter type.\n await toNodeHandler({ fetch: this._getStatelessLegacyHandler() })(req, res, parsedBody)\n } else {\n await this._dispatchLegacyHttp(req, res, parsedBody)\n }\n } else {\n await toNodeHandler(this._getModernHandler())(req, res, parsedBody)\n }\n }\n\n /** Existing sessionful Streamable HTTP handling for 2025-era clients — unchanged\n * behavior from before the dual-era split, just shared between the OAuth and\n * non-OAuth serve paths instead of duplicated. */\n private async _dispatchLegacyHttp(\n req: IncomingMessage,\n res: ServerResponse,\n parsedBody: unknown,\n ): Promise<void> {\n const { NodeStreamableHTTPServerTransport } = await import('@modelcontextprotocol/node')\n const sessionId = req.headers['mcp-session-id'] as string | undefined\n let mcpTransport: NodeStreamableHTTPServerTransport\n\n if (sessionId) {\n const existing = this._sessions.get(sessionId)\n if (!existing) {\n res.writeHead(404, { 'Content-Type': 'application/json' }).end(JSON.stringify({ error: 'Session not found' }))\n return\n }\n mcpTransport = existing.transport\n } else {\n const sessionState = new Map<string, unknown>()\n const sessionServer = this._makeServer(sessionState)\n mcpTransport = new NodeStreamableHTTPServerTransport({\n sessionIdGenerator: () => randomUUID(),\n // SEP-1699 SSE resumability: a bounded per-session event store makes the\n // transport prime each 2025-11-25+ POST SSE stream with an `id`+empty-`data`\n // event (a Last-Event-ID resume anchor) and a `retry` hint, and lets a client\n // replay missed events after reconnecting. Retention is bounded (see\n // BoundedEventStore); the store is discarded with the session on close.\n eventStore: new BoundedEventStore(),\n retryInterval: LEGACY_SSE_RETRY_MS,\n onsessioninitialized: (id) => {\n this._sessions.set(id, { transport: mcpTransport, server: sessionServer, state: sessionState })\n },\n onsessionclosed: (id) => {\n const session = this._sessions.get(id)\n if (session) {\n const callbacks = (session.state.get(SESSION_CLOSE_CALLBACKS_KEY) as Array<() => void> | undefined) ?? []\n for (const cb of callbacks) cb()\n }\n this._sessions.delete(id)\n },\n })\n await sessionServer.connect(mcpTransport)\n }\n\n await mcpTransport.handleRequest(req, res, parsedBody)\n }\n\n /**\n * Resolve the DNS-rebinding Host/Origin guards for this serve from\n * `FastMCPOptions.dnsRebinding` and the bind `host`. Sets `_hostGuard` / `_originGuard`\n * (null = protection off). See the `dnsRebinding` option doc for the default posture.\n */\n private _resolveDnsRebindingGuards(host: string): void {\n const opt = this._dnsRebindingOptions\n // No config at all + a routable bind = open by default. Warn once so the operator\n // knows the posture; an explicit dnsRebinding (any shape) means they chose it.\n if (opt === undefined && !isLoopbackHost(host) && !_dnsRebindingWarned) {\n _dnsRebindingWarned = true\n console.warn(\n '[fastmcp] This HTTP server accepts requests from any Host or Origin. ' +\n 'Set dnsRebinding in FastMCPOptions to protect local deployments against DNS rebinding.',\n )\n }\n const hasExplicitAllowlist = opt?.allowedHosts !== undefined || opt?.allowedOrigins !== undefined\n // Explicit `enabled` wins; otherwise supplying an allowlist, or binding a loopback\n // host, turns protection on. A routable bind with no config stays off (see option doc).\n const enabled = opt?.enabled ?? (hasExplicitAllowlist || isLoopbackHost(host))\n if (!enabled) {\n this._hostGuard = null\n this._originGuard = null\n return\n }\n this._hostGuard = hostHeaderValidation(opt?.allowedHosts ?? localhostAllowedHostnames())\n this._originGuard = originValidation(opt?.allowedOrigins ?? localhostAllowedOrigins())\n }\n\n private async _runHttpOAuth(port: number, host: string, path: string): Promise<void> {\n this._resolveDnsRebindingGuards(host)\n const express = (await import('express')).default\n const { mcpAuthRouter } = await import('@modelcontextprotocol/server-legacy/auth')\n const { requireBearerAuth } = await import(\n '@modelcontextprotocol/server-legacy/auth'\n )\n\n const oauth = this._oauth!\n const app = express()\n\n // Bind first so we can infer the issuerUrl from the actual bound port (handles port=0)\n const httpServer = await new Promise<HttpServer>((resolve, reject) => {\n const srv = app.listen(port, host, () => resolve(srv))\n srv.on('error', reject)\n })\n\n const bound = httpServer.address() as AddressInfo\n const issuerUrl = oauth.issuerUrl ?? new URL(`http://${bound.address}:${bound.port}`)\n\n // OAuth endpoints (authorize, token, register, metadata)\n app.use(\n mcpAuthRouter({\n provider: oauth.provider,\n issuerUrl,\n scopesSupported: oauth.scopes,\n }),\n )\n\n // MCP endpoint — protected by bearer auth; requireBearerAuth sets req.auth, which\n // both the legacy transport and the modern handler read as pass-through authInfo.\n app.all(\n path,\n requireBearerAuth({ verifier: oauth.provider }),\n async (req, res) => {\n await this._dispatchHttp(req, res)\n },\n )\n\n this._httpServer = httpServer\n this._address = { host: bound.address, port: bound.port, path }\n }\n\n private async _runHttpSimple(port: number, host: string, path: string): Promise<void> {\n this._resolveDnsRebindingGuards(host)\n const { createServer } = await import('node:http')\n\n const auth = this._auth\n\n const corsHeaders = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, DELETE, OPTIONS',\n // Mcp-Session-Id: legacy (2025-era) session routing, still served alongside\n // modern traffic. MCP-Protocol-Version/Mcp-Method/Mcp-Name: required standard\n // headers for 2026-07-28 requests (SEP-2243). Mcp-Param-* (tool-argument\n // mirroring) is deliberately not listed: browser clients skip that mirroring\n // entirely (dynamically named headers cannot be statically allow-listed for\n // credentialed CORS), so no browser ever needs to send it.\n 'Access-Control-Allow-Headers':\n 'Content-Type, Authorization, Mcp-Session-Id, MCP-Protocol-Version, Mcp-Method, Mcp-Name',\n }\n\n const httpServer = createServer(async (req, res) => {\n // CORS preflight\n if (req.method === 'OPTIONS') {\n res.writeHead(204, corsHeaders).end()\n return\n }\n\n if (req.url?.split('?')[0] !== path) {\n res.writeHead(404).end()\n return\n }\n\n // Attach CORS headers to all responses\n for (const [k, v] of Object.entries(corsHeaders)) res.setHeader(k, v)\n\n // Auth middleware\n if (auth) {\n if (isRequestVerifier(auth)) {\n let accessToken: AccessToken\n try {\n accessToken = await auth.verifyRequest(nodeRequestToHttpContext(req))\n } catch (err) {\n if (err instanceof AuthorizationError) {\n res\n .writeHead(403, { 'Content-Type': 'application/json' })\n .end(JSON.stringify({ error: err.message }))\n } else {\n res\n .writeHead(401, { 'Content-Type': 'application/json' })\n .end(JSON.stringify({ error: err instanceof Error ? err.message : 'Authentication failed' }))\n }\n return\n }\n if (!accessToken.token) {\n // Operator bug, not a client error: an empty token would collapse\n // every header-authenticated caller into one response-cache\n // partition (see CachingMiddleware's auth partitioning).\n console.error(\n '[fastmcp] RequestVerifier.verifyRequest must set AccessToken.token to a stable, non-empty per-identity value. It keys response-cache partitioning and downstream identity.',\n )\n res\n .writeHead(500, { 'Content-Type': 'application/json' })\n .end(JSON.stringify({ error: 'verifyRequest returned an AccessToken with an empty token' }))\n return\n }\n ;(req as IncomingMessage & { auth: AuthInfo }).auth = {\n token: accessToken.token,\n clientId: accessToken.clientId ?? '',\n scopes: accessToken.scopes,\n expiresAt: accessToken.expiresAt,\n extra: accessToken.claims,\n }\n } else {\n const authHeader = req.headers.authorization\n const bearer = authHeader?.startsWith('Bearer ') ? authHeader.slice(7) : null\n\n if (!bearer) {\n res\n .writeHead(401, { 'Content-Type': 'application/json', 'WWW-Authenticate': 'Bearer realm=\"mcp\"' })\n .end(JSON.stringify({ error: 'Missing bearer token' }))\n return\n }\n\n try {\n const accessToken = await auth.verify(bearer)\n ;(req as IncomingMessage & { auth: AuthInfo }).auth = {\n token: accessToken.token,\n clientId: accessToken.clientId ?? '',\n scopes: accessToken.scopes,\n expiresAt: accessToken.expiresAt,\n extra: accessToken.claims,\n }\n } catch (err) {\n if (err instanceof AuthorizationError) {\n res\n .writeHead(403, { 'Content-Type': 'application/json' })\n .end(JSON.stringify({ error: err.message }))\n } else {\n res\n .writeHead(401, { 'Content-Type': 'application/json', 'WWW-Authenticate': 'Bearer realm=\"mcp\"' })\n .end(JSON.stringify({ error: err instanceof Error ? err.message : 'Authentication failed' }))\n }\n return\n }\n }\n }\n\n await this._dispatchHttp(req, res)\n })\n\n this._httpServer = httpServer\n\n await new Promise<void>((resolve, reject) => {\n httpServer.once('error', reject)\n httpServer.listen(port, host, resolve)\n })\n\n const bound = httpServer.address() as AddressInfo\n this._address = { host: bound.address, port: bound.port, path }\n }\n\n async close(): Promise<void> {\n await Promise.all(this._proxyCloseCallbacks.map((cb) => cb().catch(() => {})))\n this._proxyCloseCallbacks.length = 0\n\n await Promise.all(\n [...this._sessions.values()].map(({ transport }) => transport.close().catch(() => {})),\n )\n this._sessions.clear()\n\n if (this._modernHandler) {\n await this._modernHandler.close()\n this._modernHandler = null\n }\n\n // LegacyHttpHandler is a bare fetch-shaped function (no `.close()` to call), but it\n // still gets nulled out here, symmetric with `_modernHandler` above: both are\n // per-instance, lazily-built handlers (see `_getStatelessLegacyHandler`'s doc\n // comment), and leaving this one set after close() would serve a stale handler\n // instance if the server is run() again instead of rebuilding a fresh one.\n this._statelessLegacyHandler = null\n\n if (this._stdioHandle) {\n await this._stdioHandle.close()\n this._stdioHandle = null\n this._stdioServer = null\n this._stdioState = null\n }\n\n if (this._httpServer) {\n await new Promise<void>((resolve, reject) => {\n this._httpServer!.close((err) => (err != null ? reject(err) : resolve()))\n })\n this._httpServer = null\n }\n this._address = null\n await this._primaryServer.close()\n }\n}\n","import type { HttpRequestContext } from '../httpContext'\n\nexport interface AccessToken {\n /** The raw bearer token string. */\n token: string\n /** The subject/client identifier from the token. */\n clientId?: string\n /** Scopes granted to the token. */\n scopes: string[]\n /** Unix timestamp (seconds) when the token expires. */\n expiresAt?: number\n /** All claims from the token payload. */\n claims: Record<string, unknown>\n}\n\nexport interface TokenVerifier {\n verify(token: string): Promise<AccessToken>\n}\n\n/**\n * Request-level verifier for HTTP deployments where identity does not arrive\n * as a bearer token. The typical case is a trusted reverse proxy that\n * authenticates the caller and forwards the resolved identity as request\n * headers.\n *\n * Called once per HTTP request, before dispatch, with that request's own FULL\n * wire headers (no redaction; `request.redactedHeaderNames` is empty here —\n * the verifier is the credential-handling code). Return an AccessToken to\n * admit the request. The result becomes `ctx.auth`, feeds per-item `auth`\n * checks and list filtering, and its `token` (hashed) keys response-cache\n * partitioning. `token` MUST therefore be a stable, non-empty, per-identity\n * value, such as the verified user id. The server rejects an empty `token`\n * with HTTP 500. Throw `AuthorizationError` to produce 403; any other throw\n * produces 401.\n *\n * SECURITY: request headers are forgeable by anyone who can reach this server\n * directly. Trust them only after verifying provenance: a shared secret the\n * proxy injects, mTLS, or network isolation. Add your provenance-secret\n * header to `FastMCPOptions.http.redactHeaders` so it never surfaces in\n * `ctx.http`. See docs: servers/auth/trusted-proxy.\n *\n * HTTP transports only. On stdio there is no HTTP request; configure a\n * TokenVerifier if you need `FASTMCP_CLI_AUTH_TOKEN` support.\n */\nexport interface RequestVerifier {\n verifyRequest(request: HttpRequestContext): Promise<AccessToken>\n}\n\n/** Narrow a `FastMCPOptions.auth` value to the request-level flavor. */\nexport function isRequestVerifier(\n v: TokenVerifier | RequestVerifier,\n): v is RequestVerifier {\n return 'verifyRequest' in v\n}\n\n/**\n * Thrown by authorization checks to produce a 403 response.\n * Any other error thrown during verification produces a 401.\n */\nexport class AuthorizationError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'AuthorizationError'\n }\n}\n","import { randomUUID } from 'node:crypto'\nimport type { EventStore, EventId, StreamId, JSONRPCMessage } from '@modelcontextprotocol/server'\n\n/**\n * Default per-session retention cap for {@link BoundedEventStore}.\n *\n * SEP-1699 resumability without unbounded growth: one store lives per legacy\n * session and holds at most this many most-recent events across all of that\n * session's SSE streams. Older events are evicted FIFO; a client that has fallen\n * further behind than the cap reconnects fresh instead of resuming.\n *\n * This is a COUNT cap (event count), not a byte cap: a burst of large tool results\n * can retain up to 256 large messages, so worst-case bytes scale with message\n * size. A POST tools/call stream normally carries only a handful of events\n * (priming + optional progress + result), so 256 is generous headroom in practice.\n *\n * The store is freed with the session only on GRACEFUL close (client `DELETE` or\n * `mcp.close()`). A client that drops its TCP connection without a `DELETE` leaves\n * the session — and this store — resident until process shutdown; that is the\n * pre-existing legacy-session retention behavior, which an event store makes\n * heavier per session. There is no idle reaper.\n */\nexport const DEFAULT_MAX_EVENTS = 256\n\n/**\n * `retry:` hint (milliseconds) sent in the SSE priming event (SEP-1699).\n *\n * The SDK transport renders a `retry:` field only when this is set, so fastmcp\n * supplies a sane fixed value rather than a tunable option (YAGNI — operators do\n * not normally tune SSE reconnect timing). 1000 ms is a responsive-yet-calm\n * reconnect cadence: fast enough to resume a dropped poll promptly, slow enough\n * to avoid a reconnect storm.\n */\nexport const LEGACY_SSE_RETRY_MS = 1000\n\n/**\n * Bounded in-memory {@link EventStore} for the legacy Streamable HTTP transport's\n * SSE resumability (SEP-1699). Enabling an event store makes the SDK transport\n * emit a priming event (an SSE `id:` with empty `data:`) — plus a `retry:` hint\n * when `retryInterval` is set — at the head of each POST SSE stream, and lets a\n * client replay missed events after reconnecting with `Last-Event-ID`.\n *\n * Retention is bounded to `maxEvents` (default {@link DEFAULT_MAX_EVENTS}): once\n * the cap is exceeded the oldest event is evicted. `Map` preserves insertion\n * order, so eviction and ordered replay are both O(1) amortized off that order.\n * The event id carries a monotonic sequence plus a UUID so ids are unique and\n * stable; stream recovery is a plain map lookup, not id parsing.\n */\nexport class BoundedEventStore implements EventStore {\n private readonly _events = new Map<EventId, { streamId: StreamId; message: JSONRPCMessage }>()\n private _seq = 0\n\n constructor(private readonly _maxEvents: number = DEFAULT_MAX_EVENTS) {}\n\n async storeEvent(streamId: StreamId, message: JSONRPCMessage): Promise<EventId> {\n // seq + uuid make the id unique and per-store ordered. The `streamId` prefix is\n // decorative (aids debugging only) — getStreamIdForEventId reads the stored\n // record, it never parses the id — so an opaque streamId can contain \"::\".\n const eventId = `${streamId}::${(this._seq++).toString(36)}::${randomUUID()}`\n this._events.set(eventId, { streamId, message })\n // FIFO eviction keeps retention bounded. Map iteration order is insertion\n // order, so the first key is always the oldest retained event.\n while (this._events.size > this._maxEvents) {\n const oldest = this._events.keys().next().value as EventId | undefined\n if (oldest === undefined) break\n this._events.delete(oldest)\n }\n return eventId\n }\n\n async getStreamIdForEventId(eventId: EventId): Promise<StreamId | undefined> {\n // Undefined for an unknown/evicted id — the SDK answers 400 rather than\n // silently replaying an empty stream, which is the correct resume error.\n return this._events.get(eventId)?.streamId\n }\n\n async replayEventsAfter(\n lastEventId: EventId,\n { send }: { send: (eventId: EventId, message: JSONRPCMessage) => Promise<void> },\n ): Promise<StreamId> {\n const anchor = this._events.get(lastEventId)\n if (!anchor) return '' // unknown/evicted anchor: nothing to replay\n const { streamId } = anchor\n let pastAnchor = false\n for (const [eventId, stored] of this._events) {\n if (eventId === lastEventId) {\n pastAnchor = true\n continue\n }\n if (pastAnchor && stored.streamId === streamId) await send(eventId, stored.message)\n }\n return streamId\n }\n}\n","import { AsyncLocalStorage } from 'node:async_hooks'\nimport type { Server, ServerContext, RequestStateCodec } from '@modelcontextprotocol/server'\nimport type { AccessToken } from './auth/types'\nimport type { InputResponses } from './mrtr'\nimport { buildHttpRequestContext, resolveSensitiveHeaders } from './httpContext'\nimport type { HttpRequestContext } from './httpContext'\n\n// ---------------------------------------------------------------------------\n// Supporting types\n// ---------------------------------------------------------------------------\n\nexport type LogLevel =\n | 'debug'\n | 'info'\n | 'notice'\n | 'warning'\n | 'error'\n | 'critical'\n | 'alert'\n | 'emergency'\n\nexport interface SamplingMessage {\n role: 'user' | 'assistant'\n content:\n | { type: 'text'; text: string }\n | { type: 'image'; data: string; mimeType: string }\n}\n\nexport interface SamplingParams {\n messages: SamplingMessage[]\n systemPrompt?: string\n /** Maximum tokens to generate. Defaults to 1024. */\n maxTokens?: number\n temperature?: number\n stopSequences?: string[]\n modelPreferences?: {\n hints?: Array<{ name?: string }>\n costPriority?: number\n speedPriority?: number\n intelligencePriority?: number\n }\n}\n\nexport interface SamplingResult {\n role: 'assistant'\n content:\n | { type: 'text'; text: string }\n | { type: 'image'; data: string; mimeType: string }\n model: string\n stopReason?: string\n}\n\n/**\n * Flat JSON Schema object describing fields to collect from the user.\n * Only primitive property types (string, number, boolean) are allowed per the MCP spec.\n */\nexport interface ElicitationSchema {\n type: 'object'\n properties: Record<\n string,\n { type: 'string' | 'number' | 'boolean'; title?: string; description?: string }\n >\n required?: string[]\n}\n\nexport interface ElicitationResult {\n /** How the user responded to the elicitation. */\n action: 'accept' | 'decline' | 'cancel'\n /** Submitted form values. Present only when action is 'accept'. */\n content?: Record<string, string | number | boolean>\n}\n\nexport interface Root {\n uri: string\n name?: string\n}\n\n// ---------------------------------------------------------------------------\n// McpContext — public interface returned by mcp.getContext()\n// ---------------------------------------------------------------------------\n\nexport interface McpContext {\n /** Auth token for the current request, if any. */\n auth: AccessToken | undefined\n /** The MCP request ID for the current call. */\n requestId: string | undefined\n\n /**\n * The HTTP request carrying the current MCP message, when serving over an\n * HTTP transport; `undefined` on stdio. Fresh per request: on a sessionful\n * connection each request's own headers appear here, never the\n * initialize-time ones. Credential headers are withheld by default and\n * listed in `http.redactedHeaderNames` (tune with `FastMCPOptions.http`).\n * Untrusted input; see HttpRequestContext's docs before deriving any\n * authorization from it.\n */\n http: HttpRequestContext | undefined\n\n // --- Logging ---\n\n /** Send a log message to the client at the specified RFC 5424 severity level. */\n log(level: LogLevel, message: string, loggerName?: string): Promise<void>\n debug(message: string, loggerName?: string): Promise<void>\n info(message: string, loggerName?: string): Promise<void>\n notice(message: string, loggerName?: string): Promise<void>\n warning(message: string, loggerName?: string): Promise<void>\n error(message: string, loggerName?: string): Promise<void>\n critical(message: string, loggerName?: string): Promise<void>\n alert(message: string, loggerName?: string): Promise<void>\n emergency(message: string, loggerName?: string): Promise<void>\n\n // --- Progress ---\n\n /**\n * Send a progress notification to the client.\n * No-op if the request did not include a `progressToken` in its `_meta`.\n */\n reportProgress(progress: number, total?: number, message?: string): Promise<void>\n\n // --- Sampling ---\n\n /**\n * Ask the client to perform an LLM inference call and return the result.\n * Throws if the client has not advertised the `sampling` capability.\n *\n * @deprecated Sampling is deprecated as of protocol revision 2026-07-28 (SEP-2577)\n * and this push-style call only works on a legacy (2025-era) connection — calling it\n * on a modern request throws a clear error naming the replacement (return\n * `inputRequired({ inputRequests: { id: inputRequired.createMessage({...}) } })` from\n * the handler instead; see `fastmcp-ts/server`'s re-exported `inputRequired`). A\n * handler written the `inputRequired` way serves both eras unchanged — the SDK's\n * legacy shim fulfils it via a real server→client request on 2025-era connections, so\n * there is rarely a reason to keep calling `ctx.sample()` directly in new code.\n */\n sample(params: SamplingParams): Promise<SamplingResult>\n\n // --- Elicitation ---\n\n /**\n * Ask the client to collect input from the user via a form dialog.\n * Throws if the client has not advertised the `elicitation` capability.\n *\n * @deprecated Throws a clear error naming the replacement when called on a modern\n * (2026-07-28) request — return `inputRequired({ inputRequests: { id:\n * inputRequired.elicit({...}) } })` instead (see `ctx.sample`'s docs; the same\n * write-once, serve-both-eras guidance applies).\n */\n elicit(message: string, schema: ElicitationSchema): Promise<ElicitationResult>\n\n // --- Roots ---\n\n /**\n * Request the list of filesystem roots the client has declared.\n * Throws if the client has not advertised the `roots` capability.\n *\n * @deprecated Roots is deprecated as of protocol revision 2026-07-28 (SEP-2577) —\n * prefer passing paths via tool parameters, resource URIs, or server configuration.\n * Throws a clear error naming `inputRequired(...)` as the multi-round-trip\n * replacement when called on a modern request (see `ctx.sample`'s docs).\n */\n listRoots(): Promise<Root[]>\n\n // --- Multi-round-trip requests (MRTR, protocol revision 2026-07-28) ---\n\n /**\n * The current round's embedded input responses, when this request is a retry of an\n * earlier `inputRequired(...)` return. `undefined` on the flow's first call (no\n * prior round to respond to). Read with the SDK's `acceptedContent(ctx.inputResponses,\n * key)` / `inputResponse(ctx.inputResponses, key)` (re-exported from\n * `fastmcp-ts/server`) rather than indexing this object directly — those readers\n * validate shape and, for `acceptedContent`, optionally the content against a schema.\n */\n inputResponses: InputResponses | undefined\n\n /**\n * Reads the current round's `requestState`, already verified and decoded when\n * `FastMCPOptions.requestState` is configured (the payload `verify` resolved with);\n * the raw, unverified wire string when it is not configured — treat that case as\n * attacker-controlled input. `undefined` when the round carried no state.\n */\n requestState<T = unknown>(): T | undefined\n\n /**\n * Seals `payload` into the opaque `requestState` string to return from\n * `inputRequired({ requestState })`. HMAC-signed via `FastMCPOptions.requestState`\n * when configured; otherwise a plain `JSON.stringify(payload)` with a console\n * warning — the resulting state is unsigned and MUST NOT be trusted for\n * anything that influences authorization, resource access, or business logic (the\n * client can read and tamper with it) unless `FastMCPOptions.requestState` is set.\n */\n mintRequestState<T = unknown>(payload: T): Promise<string>\n\n // --- Session state ---\n\n /** Retrieve a value from session-scoped state. Returns undefined if not set. */\n getState(key: string): unknown\n /** Store a value in session-scoped state. Persists for the lifetime of the session. */\n setState(key: string, value: unknown): void\n /** Remove a value from session-scoped state. */\n deleteState(key: string): void\n\n // --- Apps ---\n\n /**\n * Resolve a logical tool name to its current external name, accounting for\n * any namespace prefix applied when the owning FastMCPApp was mounted.\n * Returns the name unchanged when called outside a mounted context.\n */\n resolveToolName(name: string): string\n\n // --- Session lifecycle ---\n\n /**\n * Register a callback that runs when the current session closes.\n * Useful for releasing per-session resources (e.g. uploaded files).\n * No-op if called outside an active HTTP session.\n */\n onClose(callback: () => void): void\n}\n\n// ---------------------------------------------------------------------------\n// AsyncLocalStorage store\n// ---------------------------------------------------------------------------\n\nexport const contextStore = new AsyncLocalStorage<McpContext>()\n\n/** Internal session-state key for per-session close callbacks. */\nexport const SESSION_CLOSE_CALLBACKS_KEY = '__fastmcp_session_close_callbacks'\n\n/**\n * Pointed error thrown by `ctx.getState` / `ctx.setState` / `ctx.deleteState` on a\n * modern (2026-07-28) HTTP request. Plan §3: session state stays for stdio and legacy\n * HTTP sessions; on modern HTTP every accessor throws instead of silently dropping the\n * read/write/delete against a fresh per-request state map. The message steers to the\n * request-scoped replacement.\n */\nconst SESSION_STATE_MODERN_HTTP_ERROR =\n '[fastmcp] Session state is not available on modern HTTP requests (protocol revision 2026-07-28). ' +\n 'Each request runs statelessly with no shared session store. ' +\n 'Use ctx.requestState() to read per-request state. ' +\n 'Use ctx.mintRequestState() to carry state across a multi-round-trip flow.'\n\n/**\n * Pointed error thrown by the same three accessors on a stateless HTTP request.\n * Distinct from the modern-era message: this one names the switch an operator\n * set, because the cause is deploy configuration rather than protocol revision.\n */\nconst SESSION_STATE_STATELESS_HTTP_ERROR =\n '[fastmcp] Session state is not available on a stateless HTTP server ' +\n '(RunOptions.stateless or FASTMCP_STATELESS_HTTP). ' +\n 'Each request runs against a fresh store that is discarded when the request ends. ' +\n 'Use ctx.requestState() to read per-request state. ' +\n 'Use ctx.mintRequestState() to carry state across a multi-round-trip flow. ' +\n 'Turn stateless off to use session state, or keep state in your own external store.'\n\n/**\n * Pointed error for the server-initiated request APIs on a stateless HTTP\n * request. These need a live session: capabilities are negotiated once at\n * initialize, and the client's reply arrives as a separate request. Neither\n * survives per-request server construction. The default \"Client does not\n * support elicitation\" would blame the client for a server-side choice.\n *\n * Names `inputRequired({ requestState })` as the replacement, because it is the\n * one multi-round-trip form that works without a session; the embedded-request\n * form fails for the same reason these APIs do (see mrtr.ts's\n * INPUT_REQUESTS_STATELESS_HTTP_ERROR). Deliberately avoids the literal\n * \"inputRequests\" so the three stateless messages stay distinguishable by\n * substring in tests: only the mrtr.ts constant contains both \"inputRequests\"\n * and \"requestState\".\n */\nconst SERVER_INITIATED_STATELESS_HTTP_ERROR =\n '[fastmcp] Server-initiated requests (ctx.elicit, ctx.sample, ctx.listRoots) are not available ' +\n 'on a stateless HTTP server (RunOptions.stateless or FASTMCP_STATELESS_HTTP). ' +\n 'They need a session: client capabilities are negotiated once at initialize, and the client ' +\n 'replies on a separate request. Return inputRequired({ requestState }) to carry a ' +\n 'multi-round-trip flow without a session; the embedded-request form of inputRequired needs ' +\n 'a session too. Turn stateless off to use server-initiated requests.'\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Builds a McpContext for a single request.\n *\n * @param server The SDK Server instance for this session.\n * @param sdkCtx The SDK's own per-request ServerContext (the second argument passed to\n * every `server.setRequestHandler` callback). Supplies the request ID,\n * progress token, and — critically — `mcpReq.log` / `mcpReq.notify`, which\n * route era-appropriately: on a legacy (2025-era) connection they behave\n * exactly like the old `server.sendLoggingMessage` / `server.notification`\n * push; on a modern (2026-07-28) request, logging is gated on the\n * per-request `_meta` `logLevel` envelope key (absent = suppressed, not\n * unfiltered — see `ctx.log`'s own docs) and progress/related messages are\n * correctly attached to the current request's response (single JSON body\n * or SSE stream) rather than pushed as a request-agnostic notification.\n * @param auth The verified access token, if any.\n * @param sessionState The per-session state Map (shared across requests in the same session).\n * @param requestStateCodec The HMAC codec built from `FastMCPOptions.requestState`, if\n * configured. Backs `ctx.mintRequestState()`; `ctx.requestState()` itself always reads\n * through `sdkCtx.mcpReq.requestState()`, which already reflects whatever\n * `ServerOptions.requestState.verify` (built from this same codec) resolved.\n * @param stateless Whether this request is being served by a stateless HTTP server\n * (`_makeServer`'s `opts.stateless`). Gates session state and the server-initiated\n * request APIs on the legacy path with a message naming the switch, distinct from the\n * modern era's own established errors for the same APIs.\n */\nexport function createContext(\n server: Server,\n sdkCtx: ServerContext,\n auth: AccessToken | undefined,\n sessionState: Map<string, unknown>,\n requestStateCodec?: RequestStateCodec,\n stateless?: boolean,\n sensitiveHeaders?: ReadonlySet<string>,\n): McpContext {\n const requestId = String(sdkCtx.mcpReq.id)\n const progressToken = (sdkCtx.mcpReq._meta as { progressToken?: string | number } | undefined)\n ?.progressToken\n\n // Per-request era + transport, read from the SDK context:\n // - a modern (2026-07-28) request carries a `_meta` envelope; a legacy one does not.\n // - an HTTP-transport request carries `sdkCtx.http`; a stdio one does not.\n // These back the era gates below. `isModernEra` reorders the sample/elicit/listRoots\n // capability guard (Req 2); `isModernHttpRequest` is one of `sessionlessReason`'s two\n // inputs, which gates session state (Req 1) below.\n const isModernEra = sdkCtx.mcpReq.envelope !== undefined\n const isModernHttpRequest = isModernEra && sdkCtx.http !== undefined\n\n // Why session state is unavailable, or null when it is available. Two HTTP\n // paths are sessionless for different reasons and need different messages:\n // the modern era has no protocol session, and a stateless server discards its\n // store per request.\n const sessionlessReason: 'modern-http' | 'stateless-http' | null = isModernHttpRequest\n ? 'modern-http'\n : stateless && sdkCtx.http !== undefined\n ? 'stateless-http'\n : null\n\n const sessionStateError = (): Error =>\n new Error(\n sessionlessReason === 'modern-http'\n ? SESSION_STATE_MODERN_HTTP_ERROR\n : SESSION_STATE_STATELESS_HTTP_ERROR,\n )\n\n // Route the push-style server→client requests (sampling/createMessage,\n // elicitation/create, roots/list) raised INSIDE this tool call onto the\n // in-flight request's own response stream.\n //\n // These requests carry `relatedRequestId === undefined` by default, which the\n // SDK routes to the STANDALONE server→client stream — on legacy sessionful HTTP\n // the \"_GET_stream\". The sessionful transport DROPS such a message silently when\n // that stream is not yet attached (the client opens it fire-and-forget after\n // `initialize`, and a fresh GET carries no Last-Event-ID so nothing replays it).\n // A real client whose first post-connect operation is a sampling/elicit tool can\n // therefore hang to its timeout, awaiting a reply the server already dropped.\n //\n // Threading the in-flight request id makes the transport pick the POST stream\n // keyed by that id in `_requestToStreamMapping` — the very stream the client is\n // already awaiting the tools/call response on — so the round-trip completes with\n // no dependence on the standalone stream. This is exactly what the SDK's own\n // legacy `inputRequired` shim does for its embedded input-request legs.\n //\n // Threaded unconditionally, which is correct on every combo: the modern era gate\n // (`_assertPushApiInServedEra`) throws before any wire send, and the stdio\n // transport ignores send options entirely (a single bidirectional pipe). Only the\n // legacy sessionful-HTTP transport reads `relatedRequestId` — the path this fixes.\n // (task-25)\n const serverRequestOptions = { relatedRequestId: sdkCtx.mcpReq.id }\n\n async function log(level: LogLevel, message: string, loggerName?: string): Promise<void> {\n await sdkCtx.mcpReq.log(level, message, loggerName)\n }\n\n const httpReq = sdkCtx.http?.req\n // Default to the standard sensitive set if a call site does not pass one:\n // redaction must fail closed, never open.\n const sensitive = sensitiveHeaders ?? resolveSensitiveHeaders()\n\n return {\n auth,\n requestId,\n\n http: httpReq ? buildHttpRequestContext(httpReq, sensitive) : undefined,\n\n log,\n debug: (msg, logger) => log('debug', msg, logger),\n info: (msg, logger) => log('info', msg, logger),\n notice: (msg, logger) => log('notice', msg, logger),\n warning: (msg, logger) => log('warning', msg, logger),\n error: (msg, logger) => log('error', msg, logger),\n critical: (msg, logger) => log('critical', msg, logger),\n alert: (msg, logger) => log('alert', msg, logger),\n emergency: (msg, logger) => log('emergency', msg, logger),\n\n async reportProgress(progress, total, message) {\n if (progressToken === undefined) return\n await sdkCtx.mcpReq.notify({\n method: 'notifications/progress',\n params: {\n progressToken,\n progress,\n ...(total !== undefined ? { total } : {}),\n ...(message !== undefined ? { message } : {}),\n },\n })\n },\n\n async sample(params) {\n if (sessionlessReason === 'stateless-http') throw new Error(SERVER_INITIATED_STATELESS_HTTP_ERROR)\n // On a modern (2026-07-28) request there is no server→client channel: skip the\n // legacy capability guard so the SDK's era gate throws first, naming the\n // inputRequired(...) replacement. On legacy the capability guard stays intact\n // (getClientCapabilities reflects the initialize handshake). (task-9 Req 2)\n if (!isModernEra) {\n const caps = server.getClientCapabilities()\n if (!caps?.sampling) {\n throw new Error(\n '[fastmcp] Client does not support sampling. Ensure the client advertises the sampling capability before calling ctx.sample().',\n )\n }\n }\n const result = await server.createMessage(\n {\n messages: params.messages,\n maxTokens: params.maxTokens ?? 1024,\n ...(params.systemPrompt !== undefined ? { systemPrompt: params.systemPrompt } : {}),\n ...(params.temperature !== undefined ? { temperature: params.temperature } : {}),\n ...(params.stopSequences !== undefined ? { stopSequences: params.stopSequences } : {}),\n ...(params.modelPreferences !== undefined\n ? { modelPreferences: params.modelPreferences }\n : {}),\n },\n serverRequestOptions,\n )\n return {\n role: 'assistant' as const,\n content: result.content as SamplingResult['content'],\n model: result.model,\n stopReason: result.stopReason,\n }\n },\n\n async elicit(message, schema) {\n if (sessionlessReason === 'stateless-http') throw new Error(SERVER_INITIATED_STATELESS_HTTP_ERROR)\n // Modern era: skip the legacy capability guard so the SDK era gate throws first,\n // naming inputRequired(...). Legacy: capability guard intact. (task-9 Req 2)\n if (!isModernEra) {\n const caps = server.getClientCapabilities()\n if (!caps?.elicitation) {\n throw new Error(\n '[fastmcp] Client does not support elicitation. Ensure the client advertises the elicitation capability before calling ctx.elicit().',\n )\n }\n }\n const result = await server.elicitInput(\n {\n message,\n // Cast: our simplified ElicitationSchema is a subset of the SDK's PrimitiveSchemaDefinition union\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n requestedSchema: schema as any,\n },\n serverRequestOptions,\n )\n return {\n action: result.action,\n content: result.content as ElicitationResult['content'],\n }\n },\n\n async listRoots() {\n if (sessionlessReason === 'stateless-http') throw new Error(SERVER_INITIATED_STATELESS_HTTP_ERROR)\n // Modern era: skip the legacy capability guard so the SDK era gate throws first,\n // naming inputRequired(...). Legacy: capability guard intact. (task-9 Req 2)\n if (!isModernEra) {\n const caps = server.getClientCapabilities()\n if (!caps?.roots) {\n throw new Error(\n '[fastmcp] Client does not support roots. Ensure the client advertises the roots capability before calling ctx.listRoots().',\n )\n }\n }\n const result = await server.listRoots(undefined, serverRequestOptions)\n return result.roots\n },\n\n inputResponses: sdkCtx.mcpReq.inputResponses as InputResponses | undefined,\n\n requestState: <T = unknown>() => sdkCtx.mcpReq.requestState<T>(),\n\n async mintRequestState<T = unknown>(payload: T): Promise<string> {\n if (requestStateCodec) return requestStateCodec.mint(payload, sdkCtx)\n console.warn(\n '[fastmcp] ctx.mintRequestState() called without FastMCPOptions.requestState configured — ' +\n 'the resulting requestState is unsigned. Configure FastMCPOptions.requestState for any ' +\n 'state that influences authorization, resource access, or business logic.',\n )\n return JSON.stringify(payload)\n },\n\n getState: (key) => {\n if (sessionlessReason) throw sessionStateError()\n return sessionState.get(key)\n },\n setState: (key, value) => {\n if (sessionlessReason) throw sessionStateError()\n sessionState.set(key, value)\n },\n deleteState: (key) => {\n if (sessionlessReason) throw sessionStateError()\n sessionState.delete(key)\n },\n\n resolveToolName: (name) => name,\n\n onClose(callback) {\n const existing = (sessionState.get(SESSION_CLOSE_CALLBACKS_KEY) as Array<() => void> | undefined) ?? []\n sessionState.set(SESSION_CLOSE_CALLBACKS_KEY, [...existing, callback])\n },\n }\n}\n","import type { IncomingMessage } from 'node:http'\n\n/**\n * Header names whose VALUES are credentials for this hop. Withheld from\n * `ctx.http.headers` by default (observable via `redactedHeaderNames`) and\n * dropped by `forwardableHeaders`. Adjust per deployment with\n * `FastMCPOptions.http.redactHeaders` / `exposeHeaders`.\n */\nexport const DEFAULT_SENSITIVE_HEADERS: readonly string[] = [\n 'authorization',\n 'cookie',\n 'proxy-authorization',\n 'mcp-session-id',\n]\n\n/**\n * Effective sensitive-header set: the defaults, plus `redactHeaders`, minus\n * `exposeHeaders`. Names are compared lowercased (HTTP headers are\n * case-insensitive).\n */\nexport function resolveSensitiveHeaders(options?: {\n redactHeaders?: string[]\n exposeHeaders?: string[]\n}): Set<string> {\n const set = new Set<string>(DEFAULT_SENSITIVE_HEADERS)\n for (const h of options?.redactHeaders ?? []) set.add(h.toLowerCase())\n for (const h of options?.exposeHeaders ?? []) set.delete(h.toLowerCase())\n return set\n}\n\n/**\n * Read-only, per-request snapshot of the HTTP request that carried the current\n * MCP message. Present wherever the server is reached over an HTTP transport;\n * `undefined` on stdio.\n *\n * REDACTION: credential headers (see {@link DEFAULT_SENSITIVE_HEADERS}, tuned\n * by `FastMCPOptions.http`) are withheld from `headers` and listed in\n * `redactedHeaderNames`, so a `null` lookup is never silent. The redaction\n * guards accidental egress: tool results and logs flow into model context by\n * design. A `RequestVerifier` receives the FULL wire headers instead (its\n * `redactedHeaderNames` is empty): the verifier is the credential-handling\n * code.\n *\n * TRUST: every value here is client-controlled input. Nothing in this object\n * is authenticated. Do not derive authorization from it in handlers. For\n * header-established identity (trusted reverse proxy), configure\n * `FastMCPOptions.auth` with a `RequestVerifier` so identity flows through\n * `ctx.auth` like every other authenticated request. See docs:\n * servers/auth/trusted-proxy.\n */\nexport interface HttpRequestContext {\n /** Headers of the carrying HTTP request, minus the sensitive set. A per-request copy; mutations affect nothing. */\n readonly headers: Headers\n /** Names (lowercase, sorted) that were present on the wire but withheld from `headers`. */\n readonly redactedHeaderNames: readonly string[]\n /** HTTP method of the carrying request (e.g. 'POST'). */\n readonly method: string\n /**\n * Origin-form request target (path + query, e.g. '/mcp?tenant=a'). Scheme and\n * authority are deliberately absent: behind a proxy this server cannot know\n * the external URL. Reconstruct it from your proxy's forwarded headers if you\n * need it.\n */\n readonly url: string\n}\n\n/**\n * Build an {@link HttpRequestContext} from a web-standard Request (the SDK's\n * `ctx.http.req`), withholding `sensitiveHeaders`.\n */\nexport function buildHttpRequestContext(\n req: Request,\n sensitiveHeaders: ReadonlySet<string>,\n): HttpRequestContext {\n const headers = new Headers()\n const redacted: string[] = []\n req.headers.forEach((value, name) => {\n // Headers.forEach reports names lowercased.\n if (sensitiveHeaders.has(name)) {\n redacted.push(name)\n return\n }\n headers.append(name, value)\n })\n redacted.sort()\n let url: string\n try {\n const u = new URL(req.url)\n url = u.pathname + u.search\n } catch {\n url = req.url // already origin-form\n }\n return { headers, redactedHeaderNames: redacted, method: req.method, url }\n}\n\n/**\n * Build an {@link HttpRequestContext} from a Node IncomingMessage, with NO\n * redaction. This feeds `RequestVerifier.verifyRequest` at the HTTP auth gate;\n * the verifier is the credential-handling code and must see the wire.\n */\nexport function nodeRequestToHttpContext(req: IncomingMessage): HttpRequestContext {\n const headers = new Headers()\n for (const [name, value] of Object.entries(req.headers)) {\n if (value === undefined) continue\n if (Array.isArray(value)) {\n for (const v of value) headers.append(name, v)\n } else {\n headers.append(name, value)\n }\n }\n return { headers, redactedHeaderNames: [], method: req.method ?? 'GET', url: req.url ?? '/' }\n}\n\nconst UNFORWARDABLE = new Set([\n // credentials (see also DEFAULT_SENSITIVE_HEADERS; kept here too so the\n // helper is safe on Headers that did not come from a redacted ctx.http)\n 'authorization', 'cookie', 'proxy-authorization', 'proxy-authenticate',\n // hop-by-hop (RFC 9110 §7.6.1) and connection management\n 'connection', 'keep-alive', 'te', 'trailer', 'transfer-encoding', 'upgrade', 'proxy-connection',\n // message framing / target-specific\n 'host', 'content-length', 'content-type', 'expect',\n])\n\n/**\n * Copy of `headers` that is safe to attach to an outbound request to another\n * service. Drops credentials (authorization, cookie, proxy-*), hop-by-hop\n * headers, message-framing headers (host, content-length, content-type,\n * expect), and every `mcp-*` protocol header. Deployment-specific credential\n * headers are covered by `FastMCPOptions.http.redactHeaders`: they are already\n * absent from `ctx.http.headers`. `include` re-admits specific names.\n * Re-admitting 'authorization' forwards the caller's credential; the MCP spec\n * forbids passing the inbound token to upstream APIs, so mint your own\n * upstream credential instead.\n */\nexport function forwardableHeaders(\n headers: Headers,\n options?: { include?: string[] },\n): Headers {\n const include = new Set((options?.include ?? []).map((h) => h.toLowerCase()))\n const out = new Headers()\n headers.forEach((value, name) => {\n if (include.has(name)) {\n out.append(name, value)\n return\n }\n if (UNFORWARDABLE.has(name) || name.startsWith('mcp-')) return\n out.append(name, value)\n })\n return out\n}\n","const TRUE_VALUES = new Set(['1', 'true', 'yes', 'on'])\nconst FALSE_VALUES = new Set(['0', 'false', 'no', 'off'])\n\n/**\n * Read a boolean environment variable.\n *\n * Returns `undefined` when the variable is unset or empty so the caller can fall\n * through to its own default. Throws when the variable is set to a value that is\n * not recognised.\n *\n * The throw is deliberate. A misspelled or malformed boolean operations variable\n * must fail loudly at startup rather than silently fall back to its default. A\n * typo in FASTMCP_STATELESS_HTTP that goes unnoticed leaves a fleet sessionful\n * when the operator believes it is stateless, and that class of mistake tends to\n * surface later as a partial failure rate in production rather than as an error\n * at deploy time.\n */\nexport function envBool(name: string): boolean | undefined {\n const raw = process.env[name]\n if (raw === undefined || raw.trim() === '') return undefined\n const normalized = raw.trim().toLowerCase()\n if (TRUE_VALUES.has(normalized)) return true\n if (FALSE_VALUES.has(normalized)) return false\n throw new Error(\n `[fastmcp] ${name} must be one of 1/true/yes/on or 0/false/no/off (case-insensitive). Received: ${JSON.stringify(raw)}`,\n )\n}\n","import { ProtocolError, ProtocolErrorCode, Server } from \"@modelcontextprotocol/server\";\nimport { createHash } from 'node:crypto'\nimport type { McpContext } from './context'\n\n// ---------------------------------------------------------------------------\n// Core types\n// ---------------------------------------------------------------------------\n\nexport interface MiddlewareContext<T = unknown> {\n readonly method: string\n readonly request: T\n readonly mcpContext: McpContext\n}\n\nexport type Next<R = unknown> = () => Promise<R>\n\n/**\n * A middleware hook. Either call `next()` and return (optionally transforming) its\n * result, or short-circuit by returning your own result without calling `next()`.\n * The return is typed `Promise<unknown>` because a hook can substitute any result\n * shape for the method it intercepts; the framework resolves the concrete type at\n * the call boundary.\n */\nexport interface Middleware {\n /** Called once per Server instance. Use to register notification handlers or other server-level setup. */\n setup?(server: Server): void\n\n // Coarse hook — fires for every request that has no more-specific hook on this instance\n onRequest?(ctx: MiddlewareContext, next: Next): Promise<unknown>\n\n // Per-method hooks — take precedence over onRequest for their specific method\n onCallTool?(ctx: MiddlewareContext, next: Next): Promise<unknown>\n onListTools?(ctx: MiddlewareContext, next: Next): Promise<unknown>\n onReadResource?(ctx: MiddlewareContext, next: Next): Promise<unknown>\n onListResources?(ctx: MiddlewareContext, next: Next): Promise<unknown>\n onListResourceTemplates?(ctx: MiddlewareContext, next: Next): Promise<unknown>\n onGetPrompt?(ctx: MiddlewareContext, next: Next): Promise<unknown>\n onListPrompts?(ctx: MiddlewareContext, next: Next): Promise<unknown>\n}\n\n// ---------------------------------------------------------------------------\n// Chain execution\n// ---------------------------------------------------------------------------\n\nconst METHOD_HOOK_KEY: Partial<Record<string, keyof Middleware>> = {\n 'tools/call': 'onCallTool',\n 'tools/list': 'onListTools',\n 'resources/read': 'onReadResource',\n 'resources/list': 'onListResources',\n 'resources/templates/list': 'onListResourceTemplates',\n 'prompts/get': 'onGetPrompt',\n 'prompts/list': 'onListPrompts',\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyHookFn = (ctx: MiddlewareContext<any>, next: Next<any>) => Promise<any>\n\nfunction selectHook(mw: Middleware, method: string): AnyHookFn | null {\n const key = METHOD_HOOK_KEY[method]\n const specific = key ? (mw[key] as AnyHookFn | undefined) : undefined\n if (specific) return specific.bind(mw)\n if (mw.onRequest) return (mw.onRequest as AnyHookFn).bind(mw)\n return null\n}\n\n/** Build and execute the middleware chain, calling `handler` at the innermost level. */\nexport function runMiddlewareChain<R>(\n middleware: Middleware[],\n method: string,\n request: unknown,\n mcpContext: McpContext,\n handler: () => Promise<R>,\n): Promise<R> {\n const hooks: AnyHookFn[] = []\n for (const mw of middleware) {\n const hook = selectHook(mw, method)\n if (hook) hooks.push(hook)\n }\n\n const ctx: MiddlewareContext = { method, request, mcpContext }\n\n function dispatch(i: number): Promise<R> {\n if (i >= hooks.length) return handler()\n return hooks[i](ctx, () => dispatch(i + 1))\n }\n\n return dispatch(0)\n}\n\n// ---------------------------------------------------------------------------\n// Built-in middleware\n// ---------------------------------------------------------------------------\n\n/** Logs every request with method, outcome, and elapsed time. */\nexport class LoggingMiddleware implements Middleware {\n constructor(private readonly emit: (msg: string) => void = console.log) {}\n\n async onRequest(ctx: MiddlewareContext, next: Next): Promise<unknown> {\n const t0 = Date.now()\n this.emit(`[fastmcp] → ${ctx.method}`)\n try {\n const result = await next()\n this.emit(`[fastmcp] ← ${ctx.method} (${Date.now() - t0}ms)`)\n return result\n } catch (err) {\n this.emit(\n `[fastmcp] ✗ ${ctx.method} (${Date.now() - t0}ms): ${err instanceof Error ? err.message : String(err)}`,\n )\n throw err\n }\n }\n}\n\n/**\n * Custom cache key function. Receives the full middleware context so callers can\n * incorporate auth identity or any other dimension into the key.\n *\n * **The default key already partitions by auth identity — you do not need a `keyFn`\n * for auth safety.** The default is\n * `\"method:<auth-partition>:JSON(params)\"`, where the auth partition is `anon` for a\n * request with no bearer token and the SHA-256 hash of the bearer token for an\n * authenticated request. So a result computed under one identity is never served under\n * another (anonymous and authenticated included, both directions), and auth-filtered\n * list results (tools, resources, prompts) stay per identity.\n *\n * **A custom `keyFn` REPLACES the default partitioning entirely — you then own it.**\n * The key you return is used verbatim; the auth partition is not merged in. If your\n * cached values depend on the caller identity, include an identity dimension yourself.\n * Use the same dimension the default uses — the bearer token, HASHED. Never place the\n * raw token in a cache key:\n *\n * ```ts\n * import { createHash } from 'node:crypto'\n *\n * new CachingMiddleware(60_000, (ctx) => {\n * const token = ctx.mcpContext.auth?.token\n * const id = token ? createHash('sha256').update(token).digest('hex') : 'anon'\n * return `${ctx.method}:${id}:${JSON.stringify(ctx.request)}`\n * })\n * ```\n *\n * `clientId` is a coarser alternative (`ctx.mcpContext.auth?.clientId`), but two tokens\n * may share a `clientId` yet differ in scope, so a `clientId` key can merge identities\n * that must stay apart. Prefer the hashed token.\n */\nexport type CacheKeyFn = (ctx: MiddlewareContext) => string\n\n/** TTL-based response cache. The default key is method + auth partition + serialised\n * request params, so a cached result is served only to the identity that produced it\n * (anonymous is its own partition; authenticated requests partition by bearer-token\n * hash). Auth-filtered results (tools/list visibility, resources/read contents,\n * prompts, completion) therefore never cross identities. Pass a custom `keyFn` to\n * replace this partitioning — the caller then owns identity partitioning (see\n * {@link CacheKeyFn}). */\nexport class CachingMiddleware implements Middleware {\n private readonly _cache = new Map<string, { value: unknown; expiresAt: number }>()\n\n /**\n * Side-effectful control RPCs that must never be cached. The cache keys on method\n * + params, but these methods MUTATE per-session state (the resource subscription\n * set) instead of computing a pure function of their params. A repeated\n * `resources/subscribe` sends byte-identical params, so serving the cached `{}`\n * would skip the handler: after subscribe → unsubscribe → subscribe within the\n * TTL the client believes it re-subscribed, but the server never re-added the URI\n * and `notifyResourceUpdated` delivers nothing. Same class as the inputRequired\n * exclusion in `onRequest`.\n *\n * `completion/complete` is deliberately NOT here: it is read-only — a pure\n * function of `ref` + `argument` with no state mutation — so caching it is correct,\n * exactly like `tools/list` or `resources/read`. (Its auth-per-identity concern is\n * the same one every read method has and is handled by the default key's auth\n * partitioning — see _authPartition — not by excluding it here.)\n */\n private static readonly _nonCacheableMethods = new Set<string>([\n 'resources/subscribe',\n 'resources/unsubscribe',\n ])\n\n constructor(\n readonly ttl: number = 60_000,\n private readonly _keyFn?: CacheKeyFn,\n ) {}\n\n /**\n * Auth partition for the default cache key. A cache entry written under one auth\n * identity must never be served under another, so the identity is folded into the\n * key. Anonymous requests (`mcpContext.auth` undefined — a stdio request without a\n * CLI env token, and every request to a server with no auth configured) share the\n * single `anon` partition, matching the pre-partition default. An authenticated request is\n * partitioned by the SHA-256 hash of its bearer token: the token is the identity\n * credential, so two callers can never collide, and its hash — never the raw token —\n * goes in the key. The bearer token is used rather than `clientId` because two tokens\n * may share a `clientId` yet differ in scope, which must NOT share a partition. A\n * 64-char hex hash can never equal the literal `anon`, so anonymous and authenticated\n * partitions are disjoint in both directions.\n */\n private static _authPartition(ctx: MiddlewareContext): string {\n const token = ctx.mcpContext.auth?.token\n if (token === undefined) return 'anon'\n return createHash('sha256').update(token).digest('hex')\n }\n\n async onRequest(ctx: MiddlewareContext, next: Next): Promise<unknown> {\n // Side-effectful control RPC exclusion: never serve or store a method that\n // mutates per-session state (see _nonCacheableMethods).\n if (CachingMiddleware._nonCacheableMethods.has(ctx.method)) return next()\n\n // Multi-round-trip (inputRequired) exclusion. A retry re-sends byte-identical\n // tools/call params — the SDK lifts inputResponses / requestState out of params —\n // so the default cache key is identical across every round. Caching would replay\n // the first round's input_required result forever and the tool could never\n // complete. Rule: never serve/store when the request carries per-round input, and\n // never store an input_required result (each embeds a single-use flow token).\n const mc = ctx.mcpContext\n const carriesRoundInput = mc.inputResponses !== undefined || mc.requestState() !== undefined\n if (carriesRoundInput) return next()\n\n // Default key partitions by auth identity (see _authPartition) so a result cached\n // for one identity is never served to another. A custom keyFn REPLACES this — its\n // owner is then responsible for any identity partitioning (see CacheKeyFn docs).\n const key = this._keyFn\n ? this._keyFn(ctx as MiddlewareContext)\n : `${ctx.method}:${CachingMiddleware._authPartition(ctx)}:${JSON.stringify(ctx.request)}`\n const entry = this._cache.get(key)\n if (entry && entry.expiresAt > Date.now()) return entry.value\n const result = await next()\n if (!isInputRequiredResultValue(result)) {\n this._cache.set(key, { value: result, expiresAt: Date.now() + this.ttl })\n }\n return result\n }\n}\n\n/** True when a handler result is a multi-round-trip `input_required` round (never cacheable). */\nfunction isInputRequiredResultValue(value: unknown): boolean {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { resultType?: unknown }).resultType === 'input_required'\n )\n}\n\n/** Fixed-window counter rate limiter. Resets to full capacity after every windowMs interval. */\nexport class RateLimitingMiddleware implements Middleware {\n private _tokens: number\n private _lastRefill: number\n\n constructor(\n private readonly limit: number,\n private readonly windowMs: number = 60_000,\n ) {\n this._tokens = limit\n this._lastRefill = Date.now()\n }\n\n async onRequest(ctx: MiddlewareContext, next: Next): Promise<unknown> {\n const now = Date.now()\n if (now - this._lastRefill >= this.windowMs) {\n this._tokens = this.limit\n this._lastRefill = now\n }\n if (this._tokens <= 0) {\n throw new ProtocolError(ProtocolErrorCode.InvalidRequest, 'Rate limit exceeded')\n }\n this._tokens--\n return next()\n }\n}\n\n/** Rejects responses whose JSON serialisation exceeds maxBytes. */\nexport class SizeLimitingMiddleware implements Middleware {\n constructor(private readonly maxBytes: number) {}\n\n async onRequest(ctx: MiddlewareContext, next: Next): Promise<unknown> {\n const result = await next()\n const size = Buffer.byteLength(JSON.stringify(result), 'utf8')\n if (size > this.maxBytes) {\n throw new ProtocolError(\n ProtocolErrorCode.InternalError,\n `Response size (${size} bytes) exceeds limit (${this.maxBytes} bytes)`,\n )\n }\n return result\n }\n}\n\n/**\n * Normalises errors thrown by handlers to proper MCP shapes:\n * - tools/call plain errors → { isError: true, content: [...] } (per MCP spec)\n * - tools/call McpError → re-thrown as a protocol-level error\n * - all other methods → McpError(InternalError, message)\n *\n * Re-throwing McpError from onCallTool ensures that middleware-level errors\n * (e.g. from RateLimitingMiddleware or SizeLimitingMiddleware stacked before\n * this middleware) always propagate as protocol errors and are never silently\n * converted to isError:true tool responses.\n */\nexport class ErrorNormalizationMiddleware implements Middleware {\n async onCallTool(ctx: MiddlewareContext, next: Next): Promise<unknown> {\n try {\n return await next()\n } catch (err) {\n if (err instanceof ProtocolError) throw err\n return {\n content: [{ type: 'text' as const, text: err instanceof Error ? err.message : String(err) }],\n isError: true,\n }\n }\n }\n\n async onRequest(ctx: MiddlewareContext, next: Next): Promise<unknown> {\n try {\n return await next()\n } catch (err) {\n if (err instanceof ProtocolError) throw err\n throw new ProtocolError(\n ProtocolErrorCode.InternalError,\n err instanceof Error ? err.message : String(err),\n )\n }\n }\n}\n\n/**\n * Intercepts `notifications/cancelled` from the client and aborts the matching\n * in-flight handler via Promise.race + AbortController.\n *\n * KNOWN GAP (2026-07-28): this only covers legacy (2025-era) and stdio cancellation.\n * On a modern Streamable HTTP connection, the SDK signals cancellation by closing the\n * request's response stream rather than sending `notifications/cancelled` — the client\n * is correctly told the call was cancelled either way, but a handler registered here\n * keeps running server-side to completion on the modern path, since this middleware\n * never observes that stream closure. The SDK exposes it per-request as\n * `ctx.mcpReq.signal` (a `BaseContext` field, present on every era) — unifying this\n * middleware with that signal (so long-running handlers actually stop executing on\n * both eras) is tracked as follow-up work, not yet implemented here.\n */\nexport class CancellationMiddleware implements Middleware {\n private readonly _inFlight = new Map<string, AbortController>()\n\n setup(server: Server): void {\n server.setNotificationHandler('notifications/cancelled', (notification) => {\n const requestId = String(notification.params.requestId)\n this._inFlight.get(requestId)?.abort()\n })\n }\n\n async onRequest(ctx: MiddlewareContext, next: Next): Promise<unknown> {\n const { requestId } = ctx.mcpContext\n if (!requestId) return next()\n\n const controller = new AbortController()\n this._inFlight.set(requestId, controller)\n\n const abortPromise = new Promise<never>((_, reject) => {\n controller.signal.addEventListener('abort', () =>\n reject(new ProtocolError(ProtocolErrorCode.InternalError, 'Request was cancelled by the client')),\n )\n })\n\n try {\n return await Promise.race([next(), abortPromise])\n } finally {\n this._inFlight.delete(requestId)\n }\n }\n}\n","// ---------------------------------------------------------------------------\n// View types — simplified projections passed to transforms\n// ---------------------------------------------------------------------------\n\nexport interface ToolView {\n readonly name: string\n /** Human-readable display name shown in UIs. Takes precedence over `name` for display purposes. */\n readonly title?: string\n readonly description: string\n readonly tags: readonly string[]\n}\n\nexport interface ResourceView {\n readonly uri: string\n readonly name: string\n readonly tags: readonly string[]\n readonly mimeType?: string\n readonly title?: string\n}\n\nexport interface PromptView {\n readonly name: string\n readonly description: string\n readonly tags: readonly string[]\n}\n\n// ---------------------------------------------------------------------------\n// Synthesized tool — produced by a transform from other components\n// ---------------------------------------------------------------------------\n\nexport interface SynthesizedTool {\n readonly name: string\n /** Human-readable display name shown in UIs. Takes precedence over `name` for display purposes. */\n readonly title?: string\n readonly description: string\n readonly inputSchema?: Record<string, unknown>\n readonly auth?: import('./auth/authorization').AuthCheck\n readonly timeout?: number\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly handler: (args: any) => unknown\n}\n\n// ---------------------------------------------------------------------------\n// Transform interface\n// ---------------------------------------------------------------------------\n\nexport interface Transform {\n /**\n * Transform a tool view before it appears in list responses.\n * Return a modified view to rename/redescribe; return null to hide the tool\n * from list responses (it remains callable by its original name).\n */\n transformTool?(view: ToolView): ToolView | null\n\n /** Transform a static resource view. */\n transformResource?(view: ResourceView): ResourceView | null\n\n /** Transform a URI-template resource view. */\n transformResourceTemplate?(view: ResourceView): ResourceView | null\n\n /** Transform a prompt view. */\n transformPrompt?(view: PromptView): PromptView | null\n\n /**\n * Synthesize additional tools derived from the current resource and prompt lists.\n * Called at request time so the snapshot is always fresh.\n */\n synthesizeTools?(resources: ResourceView[], prompts: PromptView[]): SynthesizedTool[]\n}\n\n// ---------------------------------------------------------------------------\n// Internal helper — apply a chain of transforms to a single view\n// ---------------------------------------------------------------------------\n\nexport function applyTransformChain<T>(\n value: T,\n transforms: Transform[],\n pick: (t: Transform, v: T) => T | null | undefined,\n): T | null {\n let current: T | null = value\n for (const t of transforms) {\n if (current === null) break\n const next = pick(t, current)\n if (next !== undefined) current = next\n }\n return current\n}\n\n// ---------------------------------------------------------------------------\n// Built-in transforms\n// ---------------------------------------------------------------------------\n\n/** Rename a single tool. The original name still resolves at call time. */\nexport function renameTool(originalName: string, newName: string): Transform {\n return {\n transformTool: (v) => (v.name === originalName ? { ...v, name: newName } : v),\n }\n}\n\n/** Rewrite the description of a single tool. */\nexport function redescribeTool(toolName: string, description: string): Transform {\n return {\n transformTool: (v) => (v.name === toolName ? { ...v, description } : v),\n }\n}\n\n/**\n * Hide components whose predicate returns false.\n * Hidden items are removed from list responses but remain callable by original name.\n */\nexport class FilterTransform implements Transform {\n constructor(\n private readonly predicates: {\n tools?: (v: ToolView) => boolean\n resources?: (v: ResourceView) => boolean\n /** When omitted, falls back to the `resources` predicate. */\n resourceTemplates?: (v: ResourceView) => boolean\n prompts?: (v: PromptView) => boolean\n },\n ) {}\n\n transformTool(v: ToolView): ToolView | null {\n return (this.predicates.tools?.(v) ?? true) ? v : null\n }\n transformResource(v: ResourceView): ResourceView | null {\n return (this.predicates.resources?.(v) ?? true) ? v : null\n }\n transformResourceTemplate(v: ResourceView): ResourceView | null {\n const pred = this.predicates.resourceTemplates ?? this.predicates.resources\n return (pred?.(v) ?? true) ? v : null\n }\n transformPrompt(v: PromptView): PromptView | null {\n return (this.predicates.prompts?.(v) ?? true) ? v : null\n }\n}\n\n/** Prefix all tool, prompt, and resource names with a string. URIs are left unchanged. */\nexport class NamespaceTransform implements Transform {\n constructor(private readonly prefix: string) {}\n\n transformTool(v: ToolView): ToolView {\n return { ...v, name: `${this.prefix}${v.name}` }\n }\n transformResource(v: ResourceView): ResourceView {\n return { ...v, name: `${this.prefix}${v.name}` }\n }\n transformResourceTemplate(v: ResourceView): ResourceView {\n return { ...v, name: `${this.prefix}${v.name}` }\n }\n transformPrompt(v: PromptView): PromptView {\n return { ...v, name: `${this.prefix}${v.name}` }\n }\n}\n\n/** Expose registered resources as a `list_resources` tool. */\nexport class ResourcesAsTools implements Transform {\n synthesizeTools(resources: ResourceView[]): SynthesizedTool[] {\n return [\n {\n name: 'list_resources',\n description: 'List all available MCP resources',\n inputSchema: { type: 'object', properties: {} },\n handler: () => resources.map((r) => ({ uri: r.uri, name: r.name, mimeType: r.mimeType })),\n },\n ]\n }\n}\n\n/** Expose registered prompts as a `list_prompts` tool. */\nexport class PromptsAsTools implements Transform {\n synthesizeTools(_resources: ResourceView[], prompts: PromptView[]): SynthesizedTool[] {\n return [\n {\n name: 'list_prompts',\n description: 'List all available MCP prompts',\n inputSchema: { type: 'object', properties: {} },\n handler: () => prompts.map((p) => ({ name: p.name, description: p.description })),\n },\n ]\n }\n}\n\n/**\n * Expose only components whose tags include the specified version string.\n * Components with no tags are always excluded.\n */\nexport class VersionFilter implements Transform {\n constructor(private readonly version: string) {}\n\n private _matches(tags: readonly string[]): boolean {\n return tags.includes(this.version)\n }\n\n transformTool(v: ToolView): ToolView | null {\n return this._matches(v.tags) ? v : null\n }\n transformResource(v: ResourceView): ResourceView | null {\n return this._matches(v.tags) ? v : null\n }\n transformResourceTemplate(v: ResourceView): ResourceView | null {\n return this._matches(v.tags) ? v : null\n }\n transformPrompt(v: PromptView): PromptView | null {\n return this._matches(v.tags) ? v : null\n }\n}\n","import { ProtocolError, ProtocolErrorCode } from \"@modelcontextprotocol/server\";\nimport type { CallToolResult } from \"@modelcontextprotocol/server\";\nimport type { StandardSchemaV1 } from '@standard-schema/spec'\nimport { isInputRequiredResult, assertInputRequestsAllowedStateless } from './mrtr'\nimport type { InputRequiredResult } from './mrtr'\n\nexport class Image {\n constructor(\n readonly buffer: Buffer | Uint8Array,\n readonly mimeType: string,\n ) {}\n}\n\nexport class File {\n constructor(\n readonly buffer: Buffer | Uint8Array,\n readonly name: string,\n readonly mimeType: string,\n ) {}\n}\n\nexport class ToolResult {\n constructor(readonly result: CallToolResult) {}\n}\n\nexport function convertResult(\n value: unknown,\n stateless?: boolean,\n): CallToolResult | InputRequiredResult {\n // Multi-round-trip escape hatch (protocol revision 2026-07-28): a handler that\n // needs more input from the client returns inputRequired({ ... }) — passed through\n // untouched, exactly like the ToolResult escape hatch below. See inputRequired /\n // acceptedContent / inputResponse (re-exported from fastmcp-ts/server).\n //\n // `stateless` is undefined for FastMCP.ts's `_dispatchTool` helper (mounted-server\n // dispatch): that call site has no per-server `opts` in scope, and its result flows\n // back up through the mounting parent's own top-level `convertResult` call, which\n // does have `opts.stateless` and applies the guard there — see mrtr.ts's\n // assertInputRequestsAllowedStateless doc for why the check must key off that\n // per-server flag rather than an instance-wide one.\n if (isInputRequiredResult(value)) {\n assertInputRequestsAllowedStateless(value, stateless)\n return value\n }\n if (value instanceof ToolResult) {\n return value.result\n }\n if (value instanceof Image) {\n return {\n content: [\n {\n type: 'image',\n data: Buffer.from(value.buffer).toString('base64'),\n mimeType: value.mimeType,\n },\n ],\n }\n }\n if (value instanceof File) {\n return {\n content: [\n {\n type: 'resource',\n resource: {\n uri: `file://${value.name}`,\n mimeType: value.mimeType,\n blob: Buffer.from(value.buffer).toString('base64'),\n },\n },\n ],\n }\n }\n if (value === undefined || value === null) {\n return { content: [] }\n }\n if (Array.isArray(value)) {\n console.warn(\n '[fastmcp] Tool returned an array — structuredContent will not be set (MCP spec requires a plain object). Wrap in an object or use ToolResult to suppress this warning.',\n )\n return {\n content: [{ type: 'text', text: JSON.stringify(value) }],\n }\n }\n if (typeof value === 'object') {\n const json = JSON.stringify(value)\n return {\n content: [{ type: 'text', text: json }],\n structuredContent: value as Record<string, unknown>,\n }\n }\n // string, number, boolean\n return {\n content: [{ type: 'text', text: String(value) }],\n }\n}\n\nexport async function toJsonSchema(\n schema: StandardSchemaV1,\n context?: string,\n): Promise<Record<string, unknown>> {\n // Strategy 1: schema-native .toJsonSchema() method (ArkType and any library following this convention)\n const maybeNative = schema as { toJsonSchema?: () => unknown }\n if (typeof maybeNative.toJsonSchema === 'function') {\n try {\n const result = maybeNative.toJsonSchema()\n if (result !== null && typeof result === 'object') {\n return result as Record<string, unknown>\n }\n } catch {\n // fall through\n }\n }\n\n // Strategy 2: Zod v4 z.toJSONSchema()\n try {\n const { z } = await import('zod')\n return (z as unknown as { toJSONSchema: (s: unknown) => Record<string, unknown> }).toJSONSchema(\n schema,\n )\n } catch {\n // fall through\n }\n\n const where = context ? ` for ${context}` : ''\n console.warn(\n `[fastmcp] Could not auto-generate JSON schema${where}. Sending { type: 'object' } to clients. Provide an explicit 'inputSchema' in ToolConfig to suppress this warning.`,\n )\n return { type: 'object' }\n}\n\nexport async function validateInput<S extends StandardSchemaV1>(\n schema: S,\n input: unknown,\n throwAsProtocolError = false,\n): Promise<StandardSchemaV1.InferOutput<S>> {\n const result = await schema['~standard'].validate(input)\n if (result.issues) {\n const messages = result.issues.map((i) => i.message).join('; ')\n if (throwAsProtocolError) {\n throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Validation failed: ${messages}`)\n }\n throw new Error(`Validation failed: ${messages}`)\n }\n return result.value as StandardSchemaV1.InferOutput<S>\n}\n","/**\n * Multi Round-Trip Requests (MRTR) — protocol revision 2026-07-28.\n *\n * On the modern era, servers can no longer send server-initiated requests\n * (sampling, elicitation, roots) mid-call — there is no server→client channel.\n * Instead, a `tools/call`, `prompts/get`, or `resources/read` handler that needs\n * more input from the client returns `inputRequired({ ... })`. The client\n * fulfils the embedded requests and retries the original call with\n * `inputResponses` and an echoed `requestState`.\n *\n * These are thin re-exports of the SDK's own generic, already well-designed\n * primitives — fastmcp-ts adds no behavior on top. See `McpContext.inputResponses`\n * / `McpContext.requestState()` / `McpContext.mintRequestState()` for how a\n * handler reads and mints state through fastmcp's own context, and\n * `FastMCPOptions.requestState` / `FastMCPOptions.inputRequired` for server-wide\n * configuration.\n *\n * Handlers written with `inputRequired(...)` work unchanged on legacy (2025-era)\n * connections too: the SDK's legacy shim fulfils them via real server→client\n * requests and re-enters the handler, so this is a write-once, serve-both-eras\n * pattern — `ctx.elicit()` / `ctx.sample()` / `ctx.listRoots()` remain available\n * for legacy-only code, but throw a clear error naming this replacement when\n * called on a modern-era request.\n */\nimport type { InputRequiredResult } from '@modelcontextprotocol/server'\n\nexport { inputRequired, acceptedContent, inputResponse, isInputRequiredResult } from '@modelcontextprotocol/server'\nexport type {\n InputRequiredResult,\n InputRequiredSpec,\n InputRequest,\n InputRequests,\n InputResponse,\n InputResponses,\n InputResponseView,\n} from '@modelcontextprotocol/server'\n\n/**\n * Pointed error thrown when a handler returns `inputRequired({ inputRequests })` while\n * serving a stateless HTTP server (`RunOptions.stateless` / `FASTMCP_STATELESS_HTTP`).\n *\n * Same structural cause as `ctx.elicit()` / `ctx.sample()` / `ctx.listRoots()` — see\n * `SERVER_INITIATED_STATELESS_HTTP_ERROR` in context.ts — but a DIFFERENT constant on\n * purpose: a handler that returns `inputRequired(...)` never called those APIs, so\n * their wording (\"Server-initiated requests (ctx.elicit, ctx.sample, ctx.listRoots)...\")\n * would name the wrong thing to someone debugging this path. `inputRequests` hits the\n * same wall for its own reason: on legacy connections it is fulfilled by the SDK's\n * legacy shim pushing each embedded request over the server→client channel and awaiting\n * the reply — the exact channel `ctx.elicit()` etc. use, and one a stateless server's\n * per-request `Server` instance does not live long enough to keep open.\n *\n * The bare `inputRequired({ requestState })` form (no `inputRequests`) is NOT affected:\n * it is the supported stateless multi-round-trip pattern (the SDK's legacy shim re-enters\n * the handler in-process, inside the same HTTP request, needing no session) — see\n * docs/concepts/input-required.mdx#the-requeststate-only-pattern.\n */\nexport const INPUT_REQUESTS_STATELESS_HTTP_ERROR =\n '[fastmcp] inputRequired({ inputRequests }) is not available on a stateless HTTP server ' +\n '(RunOptions.stateless or FASTMCP_STATELESS_HTTP). ' +\n \"Fulfilling inputRequests needs a session: the client's reply to each embedded request \" +\n 'arrives on a separate request, and a stateless server discards its per-request Server ' +\n 'before that reply could arrive — the same reason ctx.elicit/ctx.sample/ctx.listRoots ' +\n 'are unavailable here. inputRequired({ requestState }), with no inputRequests, remains ' +\n 'available — it carries state across rounds without needing a session. ' +\n 'Turn stateless off to use inputRequests.'\n\n/**\n * Shared guard called from each of the three result converters (tool.ts convertResult,\n * resource.ts convertResourceResult, prompt.ts convertPromptResult) right after they\n * recognize an `InputRequiredResult`. Throws {@link INPUT_REQUESTS_STATELESS_HTTP_ERROR}\n * when `stateless` is true and `value` carries `inputRequests`; a no-op otherwise —\n * including for the `requestState`-only form, which has no `inputRequests` key. Kept in\n * one place rather than duplicated per converter so the message and the condition can\n * only drift once.\n *\n * `stateless` must be the per-server `opts.stateless` a request handler was built with\n * (the same value threaded into `createContext`), NOT an instance-wide flag — a stdio\n * server can carry `_stateless: true` from `FASTMCP_STATELESS_HTTP` while serving every\n * request sessionfully, because the flag is never passed into `_makeServer` on that path.\n */\nexport function assertInputRequestsAllowedStateless(\n value: InputRequiredResult,\n stateless: boolean | undefined,\n): void {\n // Matches the SDK's own notion of \"has inputRequests\" (buildInputRequired in\n // @modelcontextprotocol/server's core-internal/src/shared/inputRequired.ts: `spec.inputRequests\n // !== void 0 && Object.keys(spec.inputRequests).length > 0`), not merely `!== undefined`.\n // Without the length check, the degenerate-but-legal `inputRequired({ inputRequests: {},\n // requestState: <token> })` -- legal because `requestState` alone already satisfies the SDK's\n // at-least-one-of-the-two rule -- would throw here even though there is nothing to fulfil and\n // the requestState mechanism carries it through fine: a false positive on the one pattern this\n // guard exists to keep working.\n const hasInputRequests =\n value.inputRequests !== undefined && Object.keys(value.inputRequests).length > 0\n // Unlike the sibling guard in context.ts:312 (same root cause, the server-initiated request\n // APIs), this does not also check `sdkCtx.http !== undefined`. Today `stateless: true` only\n // ever reaches a request handler via `_getStatelessLegacyHandler` (FastMCP.ts), whose single\n // call site is HTTP-only (`_makeServer(new Map(), { stateless: true })` inside the legacy HTTP\n // dispatch path) — stdio never passes `stateless` into `_makeServer` (see this function's doc\n // comment above). A transport check here would therefore be dead code with no way to exercise\n // it; add one only if a future stateless path over a non-HTTP transport is introduced.\n if (stateless && hasInputRequests) {\n throw new Error(INPUT_REQUESTS_STATELESS_HTTP_ERROR)\n }\n}\n","import type { AuthCheck } from './auth/authorization'\nimport type { ResourceUiMeta } from './apps/types'\nimport { isInputRequiredResult, assertInputRequestsAllowedStateless } from './mrtr'\nimport type { InputRequiredResult } from './mrtr'\nimport type { CompleteCallback } from './completion'\n\nexport interface ResourceAnnotations {\n /** Intended audience(s) — 'user', 'assistant', or both. */\n audience?: Array<'user' | 'assistant'>\n /** Importance hint from 0 (least) to 1 (most). */\n priority?: number\n /** ISO 8601 timestamp of last modification. */\n lastModified?: string\n}\n\nexport interface ResourceConfig {\n /** Static URI (e.g. `file://readme`) or RFC 6570 template (e.g. `user://{id}`). */\n uri: string\n /** Programmatic identifier. Defaults to the uri. */\n name?: string\n /** Human-readable display name shown in UIs. Defaults to `name`. */\n title?: string\n description?: string\n /** MIME type of the resource content. Defaults to 'text/plain' for strings, 'application/octet-stream' for binary. */\n mimeType?: string\n /**\n * Size of the resource content in bytes, if known.\n * Only meaningful for static resources; ignored for URI templates.\n */\n size?: number\n /** Behavioral hints for clients. */\n annotations?: ResourceAnnotations\n /** Execution timeout in milliseconds. No timeout by default. */\n timeout?: number\n /** When true the resource is hidden from list responses and cannot be read. */\n disabled?: boolean\n /** Arbitrary tags for server-side filtering. */\n tags?: string[]\n auth?: AuthCheck\n /** Apps extension metadata. Included as `_meta.ui` on resources/list entries and on every resources/read content item for UI-capable clients. */\n ui?: ResourceUiMeta\n /**\n * Autocompletion callbacks for this resource template's RFC 6570 variables,\n * keyed by variable name. Only meaningful for URI templates. When set, a\n * `completion/complete` request for\n * `{ ref: { type: 'ref/resource', uri: <this template> }, argument: { name, value } }`\n * routes to `complete[name]`.\n */\n complete?: Record<string, CompleteCallback>\n}\n\n/**\n * Escape hatch for full control over resource response content.\n * Return this from a resource handler to specify content directly.\n */\nexport class ResourceResult {\n constructor(\n readonly contents: Array<{\n uri: string\n mimeType?: string\n text?: string\n blob?: string\n _meta?: Record<string, unknown>\n }>,\n ) {}\n}\n\ntype ResourceContent =\n | { uri: string; mimeType?: string; text: string; _meta?: Record<string, unknown> }\n | { uri: string; mimeType?: string; blob: string; _meta?: Record<string, unknown> }\n\n/**\n * Converts a resource handler's return value into the MCP ReadResourceResult shape.\n *\n * - string → text content\n * - Buffer / Uint8Array → base64 blob content\n * - object / array → JSON-serialised text with mimeType application/json\n * - ResourceResult → passthrough\n * - null / undefined → empty text content\n */\nexport function convertResourceResult(\n value: unknown,\n uri: string,\n mimeType?: string,\n stateless?: boolean,\n): { contents: ResourceContent[] } | InputRequiredResult {\n // Multi-round-trip escape hatch (protocol revision 2026-07-28) — see tool.ts's\n // convertResult for the same pattern applied to tools/call, including why\n // `stateless` is a per-call parameter rather than read off an instance field.\n if (isInputRequiredResult(value)) {\n assertInputRequestsAllowedStateless(value, stateless)\n return value\n }\n if (value instanceof ResourceResult) {\n return { contents: value.contents as ResourceContent[] }\n }\n if (value instanceof Buffer || value instanceof Uint8Array) {\n return {\n contents: [\n {\n uri,\n mimeType: mimeType ?? 'application/octet-stream',\n blob: Buffer.from(value).toString('base64'),\n },\n ],\n }\n }\n if (value === null || value === undefined) {\n return { contents: [{ uri, mimeType: mimeType ?? 'text/plain', text: '' }] }\n }\n if (typeof value === 'object') {\n return {\n contents: [{ uri, mimeType: mimeType ?? 'application/json', text: JSON.stringify(value) }],\n }\n }\n // string, number, boolean\n return { contents: [{ uri, mimeType: mimeType ?? 'text/plain', text: String(value) }] }\n}\n\n/**\n * Attaches the resource's declared `ui` config to every content item as\n * `_meta.ui`, mirroring the resources/list gating. SEP-1865 hosts build the\n * sandboxed iframe's CSP from the resources/read response, so the metadata\n * must ride on the read contents, not only on list entries.\n *\n * No-op when the resource declares no `ui`, the client is not UI-capable, or\n * the result is an InputRequiredResult. A handler-provided `_meta` (via\n * ResourceResult) wins key-by-key; an explicit `_meta.ui` overrides the\n * declared config for that item.\n */\nexport function attachResourceUiMeta(\n result: { contents: ResourceContent[] } | InputRequiredResult,\n ui: ResourceUiMeta | undefined,\n uiCapable: boolean,\n): { contents: ResourceContent[] } | InputRequiredResult {\n if (!ui || !uiCapable || isInputRequiredResult(result)) return result\n return {\n contents: result.contents.map((c) => ({ ...c, _meta: { ui, ...c._meta } })),\n }\n}\n\n/** Returns true if the URI string contains RFC 6570 template expressions. */\nexport function isUriTemplate(uri: string): boolean {\n return uri.includes('{')\n}\n\n/**\n * Matches a concrete URI against an RFC 6570 URI template and returns the\n * extracted parameter values, or null if the URI does not match the template.\n *\n * Supports:\n * - Simple path params: {id} → matches a single path segment\n * - Wildcard path params: {path*} → matches multiple segments (including '/')\n * - Query params: {?q,lang} → extracted from the query string\n */\nexport function matchTemplate(\n uriTemplate: string,\n uri: string,\n): Record<string, string> | null {\n // Split URI into base and query string\n const qIdx = uri.indexOf('?')\n const baseUri = qIdx >= 0 ? uri.slice(0, qIdx) : uri\n const queryString = qIdx >= 0 ? uri.slice(qIdx + 1) : ''\n\n // Pull out query param names from {?...} expressions and strip them from the template\n const queryParamNames: string[] = []\n const baseTemplate = uriTemplate.replace(/\\{[?][^}]+\\}/g, (match) => {\n match\n .slice(2, -1)\n .split(',')\n .map((s) => s.trim())\n .forEach((n) => queryParamNames.push(n))\n return ''\n })\n\n // Build a regex from the base template, collecting path param names\n const names: string[] = []\n const segments = baseTemplate.split(/(\\{[^}]+\\})/g)\n let pattern = '^'\n for (const seg of segments) {\n if (seg.startsWith('{') && seg.endsWith('}')) {\n const inner = seg.slice(1, -1)\n if (inner.endsWith('*')) {\n names.push(inner.slice(0, -1))\n pattern += '(.+)'\n } else {\n names.push(inner)\n pattern += '([^/?]+)'\n }\n } else if (seg) {\n // Escape regex metacharacters in literal parts\n pattern += seg.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n }\n }\n pattern += '$'\n\n const pathMatch = baseUri.match(new RegExp(pattern))\n if (!pathMatch) return null\n\n const params: Record<string, string> = {}\n names.forEach((name, i) => {\n params[name] = decodeURIComponent(pathMatch[i + 1])\n })\n\n // Extract query parameters\n if (queryParamNames.length > 0 && queryString) {\n const sp = new URLSearchParams(queryString)\n for (const name of queryParamNames) {\n const val = sp.get(name)\n if (val !== null) params[name] = val\n }\n }\n\n return params\n}\n","export const UI_EXTENSION_KEY = 'io.modelcontextprotocol/ui'\nexport const UI_RESOURCE_MIME_TYPE = 'text/html;profile=mcp-app'\n\n/**\n * Checks whether a client has declared MCP Apps support with a `mimeTypes` list\n * that includes the profile fastmcp serves (`UI_RESOURCE_MIME_TYPE`).\n *\n * SEP-1865's Client<>Server Capability Negotiation section requires the client to\n * declare `mimeTypes` (REQUIRED) as the *value* of its `io.modelcontextprotocol/ui`\n * extension entry, and directs servers to check it (the SDK's own\n * `getUiCapability`/`mimeTypes.includes(RESOURCE_MIME_TYPE)` pattern) before\n * registering UI-enabled tools — a bare presence check on the extension key is not\n * sufficient. Used for both `tools/list` UI-meta inclusion and the `tools/call`\n * graceful-degradation check.\n */\nexport function isUiCapable(\n clientCapabilities: { extensions?: Record<string, unknown> } | undefined,\n): boolean {\n const uiCapability = clientCapabilities?.extensions?.[UI_EXTENSION_KEY] as\n | { mimeTypes?: string[] }\n | undefined\n return !!uiCapability?.mimeTypes?.includes(UI_RESOURCE_MIME_TYPE)\n}\n\nexport type Visibility = 'model' | 'app'\n\nexport interface CspPolicy {\n connectDomains?: string[]\n /** Covers img-src, script-src, style-src, font-src, media-src. */\n resourceDomains?: string[]\n frameDomains?: string[]\n baseUriDomains?: string[]\n}\n\nexport interface UiToolMeta {\n /** Explicit resource URI. Auto-derived from tool name when omitted. */\n resourceUri?: string\n /**\n * Who can see and call this tool. Defaults to `['model', 'app']` per SEP-1865\n * (visible to the model, and callable by the app served from this same\n * connection) when omitted.\n */\n visibility?: Visibility[]\n}\n\nexport interface BrowserPermissions {\n camera?: Record<string, never>\n microphone?: Record<string, never>\n geolocation?: Record<string, never>\n clipboardWrite?: Record<string, never>\n}\n\nexport interface ResourceUiMeta {\n csp?: CspPolicy\n permissions?: BrowserPermissions\n domain?: string\n prefersBorder?: boolean\n}\n","import type { AuthCheck } from './auth/authorization'\nimport { isInputRequiredResult, assertInputRequestsAllowedStateless } from './mrtr'\nimport type { InputRequiredResult } from './mrtr'\nimport type { CompleteCallback } from './completion'\n\nexport interface PromptArgument {\n name: string\n description?: string\n /** When true, the client must supply this argument. Defaults to false. */\n required?: boolean\n /**\n * Autocompletion callback for this argument. When set, a `completion/complete`\n * request for `{ ref: { type: 'ref/prompt', name }, argument: { name, value } }`\n * routes here. Not advertised in `prompts/list` — the client discovers it by\n * calling `completion/complete`.\n */\n complete?: CompleteCallback\n}\n\nexport interface PromptConfig {\n /** Unique prompt identifier. Inferred from the handler function name when omitted. */\n name?: string\n /** Human-readable display name shown in UIs. */\n title?: string\n /** Description shown to clients and LLMs. Inferred from name when omitted. */\n description?: string\n /** Declared arguments. Advertised to clients in prompts/list. */\n arguments?: PromptArgument[]\n /** When true the prompt is hidden from list responses and cannot be invoked. */\n disabled?: boolean\n /** Execution timeout in milliseconds. No timeout by default. */\n timeout?: number\n /** Arbitrary tags for server-side filtering and transforms. */\n tags?: string[]\n auth?: AuthCheck\n}\n\n// ---------------------------------------------------------------------------\n// Content and message types\n// ---------------------------------------------------------------------------\n\nexport type TextContent = { type: 'text'; text: string }\nexport type ImageContent = { type: 'image'; data: string; mimeType: string }\nexport type AudioContent = { type: 'audio'; data: string; mimeType: string }\nexport type ResourceLinkContent = {\n type: 'resource_link'\n uri: string\n name?: string\n description?: string\n mimeType?: string\n}\nexport type EmbeddedResource = {\n type: 'resource'\n resource: { uri: string; mimeType?: string } & ({ text: string } | { blob: string })\n}\n\nexport type PromptContent = TextContent | ImageContent | AudioContent | EmbeddedResource | ResourceLinkContent\n\nexport interface PromptMessage {\n role: 'user' | 'assistant'\n content: PromptContent\n}\n\n/**\n * Escape hatch for full control over the prompt response.\n * Return this from a prompt handler to set an explicit description and/or\n * supply a custom multi-turn message sequence.\n */\nexport class PromptResult {\n constructor(\n readonly messages: PromptMessage[],\n readonly description?: string,\n ) {}\n}\n\n// ---------------------------------------------------------------------------\n// Return value conversion\n// ---------------------------------------------------------------------------\n\nfunction isPromptMessage(value: unknown): value is PromptMessage {\n if (value === null || typeof value !== 'object') return false\n const v = value as Record<string, unknown>\n if (v.role !== 'user' && v.role !== 'assistant') return false\n if (!v.content || typeof v.content !== 'object') return false\n return typeof (v.content as Record<string, unknown>).type === 'string'\n}\n\n/**\n * Converts a prompt handler's return value into the MCP GetPromptResult shape.\n *\n * - string → single user text message\n * - PromptMessage → wrapped in a one-element array\n * - PromptMessage[] → used as-is\n * - PromptResult → passthrough (escape hatch)\n */\nexport function convertPromptResult(\n value: unknown,\n stateless?: boolean,\n): { description?: string; messages: PromptMessage[] } | InputRequiredResult {\n // Multi-round-trip escape hatch (protocol revision 2026-07-28) — see tool.ts's\n // convertResult for the same pattern applied to tools/call, including why\n // `stateless` is a per-call parameter rather than read off an instance field.\n if (isInputRequiredResult(value)) {\n assertInputRequestsAllowedStateless(value, stateless)\n return value\n }\n if (value instanceof PromptResult) {\n return { description: value.description, messages: value.messages }\n }\n if (typeof value === 'string') {\n return { messages: [{ role: 'user', content: { type: 'text', text: value } }] }\n }\n if (isPromptMessage(value)) {\n return { messages: [value] }\n }\n if (Array.isArray(value) && value.every(isPromptMessage)) {\n return { messages: value }\n }\n throw new Error(\n `Prompt handler returned an unsupported value. Expected string, PromptMessage, PromptMessage[], or PromptResult.`,\n )\n}\n","/**\n * Argument completion (`completion/complete`) — the callback contract shared by\n * prompt arguments and resource-template variables.\n *\n * A completion callback turns a partial value the user has typed into a set of\n * suggestions. It attaches to a single prompt argument (`PromptArgument.complete`)\n * or a single resource-template variable (`ResourceConfig.complete[variable]`);\n * the server routes each `completion/complete` request to the matching callback\n * by the request's `ref` type. See FastMCP `_completePrompt` /\n * `_completeResourceTemplate`.\n *\n * `completion/complete` lives in BOTH protocol eras' wire registries (the legacy\n * 2025-11-25 registry and the modern 2026-07-28 `dispatchRequestSchemas`), so the\n * handler and the `completions` capability are declared unconditionally — no\n * per-era fork, unlike `resources/subscribe`.\n */\n\n/**\n * Optional context the client forwards with a completion request: the values it\n * has already resolved for the prompt's OTHER arguments (or the template's other\n * variables). Use it to narrow suggestions — e.g. offer cities once a country is\n * chosen.\n */\nexport interface CompletionContext {\n arguments?: Record<string, string>\n}\n\n/**\n * The paginated shape a completion callback MAY return for full control over the\n * `total` / `hasMore` hints. Mirrors the wire `CompleteResult.completion` object.\n * Returning a bare `string[]` instead is the common case.\n */\nexport interface CompletionResult {\n /** Suggested values. Capped to 100 on the wire (the spec's maximum). */\n values: string[]\n /** Total number of matches available, if larger than `values`. */\n total?: number\n /** Whether more matches exist beyond `values`. */\n hasMore?: boolean\n}\n\n/**\n * A completion callback. Receives the partial `value` the user has typed and the\n * optional resolved-argument `context`, and returns suggestions — either a bare\n * `string[]` or a {@link CompletionResult} with explicit pagination hints. May be\n * async.\n */\nexport type CompleteCallback = (\n value: string,\n context?: CompletionContext,\n) => string[] | CompletionResult | Promise<string[] | CompletionResult>\n\n/**\n * Normalise a callback's return value into the wire `completion` object.\n *\n * - Bare `string[]` → matches the SDK's own `createCompletionResult`: `values`\n * sliced to the 100-item wire cap, `total` = the full length, `hasMore` = true\n * when the callback produced more than 100.\n * - {@link CompletionResult} → the author is managing pagination, so `total` and\n * `hasMore` pass through exactly as given (omitted when undefined); `values` is\n * still capped to 100 to satisfy the wire schema.\n */\nexport function normalizeCompletion(\n raw: string[] | CompletionResult,\n): { values: string[]; total?: number; hasMore?: boolean } {\n if (Array.isArray(raw)) {\n return {\n values: raw.slice(0, 100),\n total: raw.length,\n hasMore: raw.length > 100,\n }\n }\n return {\n values: raw.values.slice(0, 100),\n ...(raw.total !== undefined ? { total: raw.total } : {}),\n ...(raw.hasMore !== undefined ? { hasMore: raw.hasMore } : {}),\n }\n}\n\n/** The `completion` object for a ref/argument that has no completer: an empty list. */\nexport const EMPTY_COMPLETION = { values: [] as string[] }\n","import type { AccessToken } from './types'\nimport { AuthorizationError } from './types'\n\nexport type AuthCheck = (token: AccessToken) => void | Promise<void>\n\nexport function requireScopes(...scopes: string[]): AuthCheck {\n return async (token) => {\n for (const scope of scopes) {\n if (!token.scopes.includes(scope)) {\n throw new AuthorizationError(`Missing required scope: \"${scope}\"`)\n }\n }\n }\n}\n","import type { AccessToken, TokenVerifier } from './types'\n\nexport function multiAuth(...verifiers: TokenVerifier[]): TokenVerifier {\n return {\n async verify(token: string): Promise<AccessToken> {\n const errors: string[] = []\n for (const verifier of verifiers) {\n try {\n return await verifier.verify(token)\n } catch (err) {\n errors.push(err instanceof Error ? err.message : String(err))\n }\n }\n throw new Error(`All auth sources rejected the token: ${errors.join('; ')}`)\n },\n }\n}\n","import { createRemoteJWKSet, jwtVerify } from 'jose'\nimport type { AccessToken, TokenVerifier } from '../types'\n\nexport interface JwtVerifierOptions {\n jwksUri: string\n issuer?: string\n audience?: string | string[]\n /** Clock skew tolerance in seconds. Default: 0. */\n leeway?: number\n}\n\nexport function jwtVerifier(options: JwtVerifierOptions): TokenVerifier {\n const JWKS = createRemoteJWKSet(new URL(options.jwksUri))\n\n return {\n async verify(token: string): Promise<AccessToken> {\n const { payload } = await jwtVerify(token, JWKS, {\n issuer: options.issuer,\n audience: options.audience,\n clockTolerance: options.leeway ?? 0,\n })\n\n const scopes =\n typeof payload.scope === 'string'\n ? payload.scope.split(' ').filter(Boolean)\n : Array.isArray(payload.scope)\n ? (payload.scope as string[])\n : []\n\n return {\n token,\n clientId: typeof payload.sub === 'string' ? payload.sub : undefined,\n scopes,\n expiresAt: payload.exp,\n claims: payload as Record<string, unknown>,\n }\n },\n }\n}\n","import type { AccessToken, TokenVerifier } from '../types'\n\nexport interface IntrospectionVerifierOptions {\n endpoint: string\n credentials: { clientId: string; clientSecret: string }\n /** Cache TTL in seconds. Omit or set to 0 to disable caching. */\n cacheTtl?: number\n}\n\ninterface CacheEntry {\n token: AccessToken\n expiresAt: number\n}\n\nexport function introspectionVerifier(options: IntrospectionVerifierOptions): TokenVerifier {\n const cache = options.cacheTtl ? new Map<string, CacheEntry>() : null\n\n return {\n async verify(rawToken: string): Promise<AccessToken> {\n if (cache) {\n const cached = cache.get(rawToken)\n if (cached && Date.now() < cached.expiresAt) {\n return cached.token\n }\n cache.delete(rawToken)\n }\n\n const credentials = Buffer.from(\n `${options.credentials.clientId}:${options.credentials.clientSecret}`,\n ).toString('base64')\n\n const response = await fetch(options.endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n Authorization: `Basic ${credentials}`,\n },\n body: new URLSearchParams({ token: rawToken }),\n })\n\n if (!response.ok) {\n throw new Error(`Introspection endpoint returned ${response.status}`)\n }\n\n const data = (await response.json()) as {\n active: boolean\n scope?: string\n client_id?: string\n exp?: number\n [key: string]: unknown\n }\n\n if (!data.active) {\n throw new Error('Token is not active')\n }\n\n const accessToken: AccessToken = {\n token: rawToken,\n clientId: data.client_id,\n scopes: data.scope ? data.scope.split(' ').filter(Boolean) : [],\n expiresAt: data.exp,\n claims: data as Record<string, unknown>,\n }\n\n if (cache && options.cacheTtl) {\n cache.set(rawToken, {\n token: accessToken,\n expiresAt: Date.now() + options.cacheTtl * 1000,\n })\n }\n\n return accessToken\n },\n }\n}\n","import type { AccessToken, TokenVerifier } from '../types'\n\nexport function staticTokenVerifier(\n map: Record<string, Partial<Omit<AccessToken, 'token'>>>,\n): TokenVerifier {\n return {\n async verify(token: string): Promise<AccessToken> {\n const entry = map[token]\n if (!entry) {\n throw new Error('Unknown token')\n }\n if (entry.expiresAt !== undefined && entry.expiresAt < Math.floor(Date.now() / 1000)) {\n throw new Error('Token has expired')\n }\n return {\n token,\n clientId: entry.clientId,\n scopes: entry.scopes ?? [],\n expiresAt: entry.expiresAt,\n claims: entry.claims ?? {},\n }\n },\n }\n}\n\nexport function debugTokenVerifier(): TokenVerifier {\n console.warn('[fastmcp] debugTokenVerifier() accepts all bearer tokens — never use in production')\n return {\n async verify(token: string): Promise<AccessToken> {\n if (!token) {\n throw new Error('Empty token')\n }\n return { token, scopes: [], claims: {} }\n },\n }\n}\n","import { randomUUID } from 'node:crypto'\nimport type { OAuthClientInformationFull, AuthInfo } from \"@modelcontextprotocol/server\";\nimport { UnsupportedGrantTypeError } from \"@modelcontextprotocol/server-legacy/auth\";\nimport type { OAuthServerProvider, AuthorizationParams, OAuthRegisteredClientsStore } from \"@modelcontextprotocol/server-legacy/auth\";\nimport type { Response } from 'express'\n\nexport interface OAuthProviderOptions {\n /**\n * Called during the authorization step. Implementations must eventually redirect\n * to `params.redirectUri` with a `code` query parameter (and `state` if present).\n *\n * If omitted, all authorization requests are auto-approved immediately — suitable\n * for testing and development only.\n */\n onAuthorize?: (\n client: OAuthClientInformationFull,\n params: AuthorizationParams,\n res: Response,\n ) => Promise<void>\n /** Scopes supported by this server, advertised in OAuth metadata. */\n scopes?: string[]\n /** Access token lifetime in seconds. Default: 3600. */\n tokenTtl?: number\n}\n\n/**\n * Creates an in-memory OAuth 2.1 server provider with Dynamic Client Registration support.\n *\n * Suitable for development, testing, and simple deployments where persistence is not required.\n * All state (clients, codes, tokens) is held in memory and lost on restart.\n */\nexport function oauthProvider(options: OAuthProviderOptions = {}): OAuthServerProvider {\n const clients = new Map<string, OAuthClientInformationFull>()\n const codes = new Map<string, { client: OAuthClientInformationFull; params: AuthorizationParams }>()\n const tokens = new Map<string, { clientId: string; scopes: string[]; expiresAt: number }>()\n\n // The SDK registration handler generates client_id and other fields before calling\n // registerClient, so at runtime the argument is always a full OAuthClientInformationFull.\n const clientsStore: OAuthRegisteredClientsStore = {\n async getClient(clientId) {\n return clients.get(clientId)\n },\n async registerClient(client) {\n const full = client as OAuthClientInformationFull\n clients.set(full.client_id, full)\n return full\n },\n }\n\n return {\n clientsStore,\n\n async authorize(client, params, res) {\n if (options.onAuthorize) {\n return options.onAuthorize(client, params, res)\n }\n // Default: auto-approve — issue code and redirect immediately\n const code = randomUUID()\n codes.set(code, { client, params })\n const redirectUrl = new URL(params.redirectUri)\n redirectUrl.searchParams.set('code', code)\n if (params.state) redirectUrl.searchParams.set('state', params.state)\n res.redirect(redirectUrl.toString())\n },\n\n async challengeForAuthorizationCode(_client, authorizationCode) {\n const data = codes.get(authorizationCode)\n if (!data) throw new Error('Invalid authorization code')\n return data.params.codeChallenge\n },\n\n async exchangeAuthorizationCode(client, authorizationCode) {\n const data = codes.get(authorizationCode)\n if (!data) throw new Error('Invalid authorization code')\n if (data.client.client_id !== client.client_id) {\n throw new Error('Authorization code was not issued to this client')\n }\n codes.delete(authorizationCode)\n\n const token = randomUUID()\n const ttl = options.tokenTtl ?? 3600\n const requestedScopes = data.params.scopes ?? []\n const grantedScopes =\n options.scopes !== undefined\n ? requestedScopes.filter((s) => options.scopes!.includes(s))\n : requestedScopes\n tokens.set(token, {\n clientId: client.client_id,\n scopes: grantedScopes,\n expiresAt: Math.floor(Date.now() / 1000) + ttl,\n })\n return {\n access_token: token,\n token_type: 'bearer',\n expires_in: ttl,\n scope: grantedScopes.join(' '),\n }\n },\n\n async exchangeRefreshToken() {\n throw new UnsupportedGrantTypeError('Refresh tokens are not supported by this provider')\n },\n\n async verifyAccessToken(token): Promise<AuthInfo> {\n const data = tokens.get(token)\n if (!data) throw new Error('Invalid token')\n if (data.expiresAt < Math.floor(Date.now() / 1000)) throw new Error('Token has expired')\n return {\n token,\n clientId: data.clientId,\n scopes: data.scopes,\n expiresAt: data.expiresAt,\n }\n },\n }\n}\n","import type { OAuthClientInformationFull, OAuthTokenRevocationRequest, OAuthTokens, AuthInfo } from \"@modelcontextprotocol/server\";\nimport type { OAuthServerProvider, AuthorizationParams, OAuthRegisteredClientsStore } from \"@modelcontextprotocol/server-legacy/auth\";\n\nexport interface OAuthProxyOptions {\n /** Pre-registered credentials this proxy uses when talking to the upstream server. */\n upstreamCredentials: {\n clientId: string\n clientSecret?: string\n }\n /** Upstream OAuth server endpoint URLs. */\n endpoints: {\n authorizationUrl: string\n tokenUrl: string\n revocationUrl?: string\n }\n /**\n * Verifies an access token issued by the upstream and returns information about it.\n * Called for every MCP request to validate the bearer token.\n */\n verifyAccessToken: (token: string) => Promise<AuthInfo>\n}\n\n/**\n * Creates an OAuth provider that proxies to an existing upstream OAuth server using\n * pre-registered credentials.\n *\n * MCP clients interact with this proxy using Dynamic Client Registration. The proxy\n * presents a DCR-compliant interface while internally using its own fixed credentials\n * (`upstreamCredentials`) when communicating with the upstream authorization server.\n */\nexport function oauthProxy(options: OAuthProxyOptions): OAuthServerProvider {\n const clients = new Map<string, OAuthClientInformationFull>()\n\n const clientsStore: OAuthRegisteredClientsStore = {\n async getClient(clientId) {\n return clients.get(clientId)\n },\n // DCR for incoming MCP clients — stored locally, not proxied upstream\n async registerClient(client) {\n const full = client as OAuthClientInformationFull\n clients.set(full.client_id, full)\n return full\n },\n }\n\n return {\n clientsStore,\n // Let the upstream server validate PKCE — we pass code_verifier through\n skipLocalPkceValidation: true as const,\n\n async authorize(_client, params, res) {\n // Redirect to upstream using the proxy's registered client_id\n const targetUrl = new URL(options.endpoints.authorizationUrl)\n targetUrl.searchParams.set('client_id', options.upstreamCredentials.clientId)\n targetUrl.searchParams.set('response_type', 'code')\n targetUrl.searchParams.set('redirect_uri', params.redirectUri)\n targetUrl.searchParams.set('code_challenge', params.codeChallenge)\n targetUrl.searchParams.set('code_challenge_method', 'S256')\n if (params.state) targetUrl.searchParams.set('state', params.state)\n if (params.scopes?.length) targetUrl.searchParams.set('scope', params.scopes.join(' '))\n res.redirect(targetUrl.toString())\n },\n\n async challengeForAuthorizationCode() {\n // PKCE is validated by the upstream; returning empty string skips local validation\n return ''\n },\n\n async exchangeAuthorizationCode(_client, authorizationCode, codeVerifier, redirectUri): Promise<OAuthTokens> {\n const body = new URLSearchParams({\n grant_type: 'authorization_code',\n client_id: options.upstreamCredentials.clientId,\n code: authorizationCode,\n })\n if (options.upstreamCredentials.clientSecret) {\n body.set('client_secret', options.upstreamCredentials.clientSecret)\n }\n if (codeVerifier) body.set('code_verifier', codeVerifier)\n if (redirectUri) body.set('redirect_uri', redirectUri)\n\n const response = await fetch(options.endpoints.tokenUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: body.toString(),\n })\n if (!response.ok) {\n await response.body?.cancel()\n throw new Error(`Upstream token exchange failed: ${response.status}`)\n }\n return response.json() as Promise<OAuthTokens>\n },\n\n async exchangeRefreshToken(_client, refreshToken, scopes): Promise<OAuthTokens> {\n const body = new URLSearchParams({\n grant_type: 'refresh_token',\n client_id: options.upstreamCredentials.clientId,\n refresh_token: refreshToken,\n })\n if (options.upstreamCredentials.clientSecret) {\n body.set('client_secret', options.upstreamCredentials.clientSecret)\n }\n if (scopes?.length) body.set('scope', scopes.join(' '))\n\n const response = await fetch(options.endpoints.tokenUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: body.toString(),\n })\n if (!response.ok) {\n await response.body?.cancel()\n throw new Error(`Upstream token refresh failed: ${response.status}`)\n }\n return response.json() as Promise<OAuthTokens>\n },\n\n verifyAccessToken: options.verifyAccessToken,\n\n ...(options.endpoints.revocationUrl\n ? {\n async revokeToken(\n _client: OAuthClientInformationFull,\n request: OAuthTokenRevocationRequest,\n ): Promise<void> {\n const body = new URLSearchParams({\n token: request.token,\n client_id: options.upstreamCredentials.clientId,\n })\n if (options.upstreamCredentials.clientSecret) {\n body.set('client_secret', options.upstreamCredentials.clientSecret)\n }\n if (request.token_type_hint) {\n body.set('token_type_hint', request.token_type_hint)\n }\n const response = await fetch(options.endpoints.revocationUrl!, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: body.toString(),\n })\n if (!response.ok) {\n await response.body?.cancel()\n // RFC 7009 §2.2: servers should not signal errors on revocation\n }\n },\n }\n : {}),\n }\n}\n","import { Client } from \"@modelcontextprotocol/client\";\nimport type { CallToolResult } from \"@modelcontextprotocol/client\";\nimport { parseTemplate } from 'url-template'\nimport { FastMCP } from './FastMCP'\nimport { ToolResult } from './tool'\nimport { ResourceResult } from './resource'\nimport { PromptResult } from './prompt'\nimport type { PromptMessage } from './prompt'\n\ntype StdioTransport = {\n type: 'stdio'\n command: string\n args?: string[]\n env?: Record<string, string>\n cwd?: string\n /** How long (ms) before the proxy re-fetches component lists. Default 30 000. Set 0 for notifications-only. */\n cacheTtl?: number\n}\n\ntype HttpTransport = {\n type: 'http'\n url: string\n requestInit?: RequestInit\n /** How long (ms) before the proxy re-fetches component lists. Default 30 000. Set 0 for notifications-only. */\n cacheTtl?: number\n}\n\nexport type ProxyTransport = StdioTransport | HttpTransport\n\n/**\n * Build a FastMCP proxy around an already-connected MCP Client.\n * Exported to enable testing with in-memory transports.\n */\nexport async function buildProxyFromClient(\n client: Client,\n options?: { cacheTtl?: number; name?: string },\n): Promise<FastMCP> {\n const cacheTtl = options?.cacheTtl ?? 30_000\n\n const serverInfo = client.getServerVersion()\n const proxyName = options?.name ?? serverInfo?.name ?? 'proxy'\n const proxyVersion = serverInfo?.version ?? '0.0.1'\n\n const proxy = new FastMCP({ name: proxyName, version: proxyVersion })\n\n // Track which component identifiers were registered by this proxy so we can diff on resync.\n const proxiedTools = new Set<string>()\n const proxiedResources = new Set<string>()\n const proxiedPrompts = new Set<string>()\n\n // Per-type timestamp of last successful sync (0 forces an immediate resync on first list request).\n const lastSync = { tools: 0, resources: 0, prompts: 0 }\n\n async function resyncTools(): Promise<void> {\n // client.listTools() with no cursor auto-aggregates every page for us (v2 SDK\n // behavior — see ClientOptions.listMaxPages, default cap 64 pages).\n const { tools } = await client.listTools()\n\n const incoming = new Set(tools.map((t) => t.name))\n\n for (const name of proxiedTools) {\n if (!incoming.has(name)) {\n proxy._removeTool(name)\n proxiedTools.delete(name)\n }\n }\n\n for (const tool of tools) {\n if (proxiedTools.has(tool.name)) {\n // Update metadata if it changed\n proxy._removeTool(tool.name)\n proxiedTools.delete(tool.name)\n }\n proxy.tool(\n {\n name: tool.name,\n ...(tool.title !== undefined ? { title: tool.title } : {}),\n description: tool.description ?? tool.name,\n inputSchema: (tool.inputSchema as Record<string, unknown>) ?? {},\n },\n async (args: unknown) => {\n const result = await client.callTool(\n { name: tool.name, arguments: args as Record<string, unknown> }\n )\n // Zod infers _meta on content items as Record<string,unknown> but\n // CallToolResult types it more specifically — identical at runtime.\n return new ToolResult(result as unknown as CallToolResult)\n },\n )\n proxiedTools.add(tool.name)\n }\n\n lastSync.tools = Date.now()\n }\n\n async function resyncResources(): Promise<void> {\n const incoming = new Set<string>()\n\n try {\n // client.listResources() with no cursor auto-aggregates every page for us.\n const { resources } = await client.listResources()\n\n for (const resource of resources) {\n incoming.add(resource.uri)\n if (!proxiedResources.has(resource.uri)) {\n proxy.resource(\n {\n uri: resource.uri,\n name: resource.name,\n ...(resource.description !== undefined ? { description: resource.description } : {}),\n ...(resource.mimeType !== undefined ? { mimeType: resource.mimeType } : {}),\n },\n async () => {\n const result = await client.readResource({ uri: resource.uri })\n return new ResourceResult(\n result.contents as Array<{\n uri: string\n mimeType?: string\n text?: string\n blob?: string\n }>,\n )\n },\n )\n proxiedResources.add(resource.uri)\n }\n }\n } catch {\n // server may not support resources\n }\n\n try {\n // client.listResourceTemplates() with no cursor auto-aggregates every page for us.\n const { resourceTemplates } = await client.listResourceTemplates()\n\n for (const template of resourceTemplates) {\n const uriTemplate = template.uriTemplate\n incoming.add(uriTemplate)\n if (!proxiedResources.has(uriTemplate)) {\n const expander = parseTemplate(uriTemplate)\n proxy.resource(\n {\n uri: uriTemplate,\n name: template.name,\n ...(template.description !== undefined\n ? { description: template.description }\n : {}),\n ...(template.mimeType !== undefined ? { mimeType: template.mimeType } : {}),\n },\n async (params?: Record<string, string>) => {\n const actualUri = params ? expander.expand(params) : uriTemplate\n const result = await client.readResource({ uri: actualUri })\n return new ResourceResult(\n result.contents as Array<{\n uri: string\n mimeType?: string\n text?: string\n blob?: string\n }>,\n )\n },\n )\n proxiedResources.add(uriTemplate)\n }\n }\n } catch {\n // server may not support resource templates\n }\n\n for (const uri of proxiedResources) {\n if (!incoming.has(uri)) {\n proxy._removeResource(uri)\n proxiedResources.delete(uri)\n }\n }\n\n lastSync.resources = Date.now()\n }\n\n async function resyncPrompts(): Promise<void> {\n // client.listPrompts() with no cursor auto-aggregates every page for us.\n const { prompts } = await client.listPrompts()\n\n const incoming = new Set(prompts.map((p) => p.name))\n\n for (const name of proxiedPrompts) {\n if (!incoming.has(name)) {\n proxy._removePrompt(name)\n proxiedPrompts.delete(name)\n }\n }\n\n for (const prompt of prompts) {\n if (!proxiedPrompts.has(prompt.name)) {\n proxy.prompt(\n {\n name: prompt.name,\n description: prompt.description,\n ...(prompt.arguments?.length ? { arguments: prompt.arguments } : {}),\n },\n async (args?: Record<string, string>) => {\n const result = await client.getPrompt({ name: prompt.name, arguments: args })\n return new PromptResult(result.messages as PromptMessage[], result.description)\n },\n )\n proxiedPrompts.add(prompt.name)\n }\n }\n\n lastSync.prompts = Date.now()\n }\n\n // Initial sync.\n await Promise.all([\n resyncTools().catch(() => {}),\n resyncResources().catch(() => {}),\n resyncPrompts().catch(() => {}),\n ])\n\n // Subscribe to backend change notifications for immediate resync.\n client.setNotificationHandler('notifications/tools/list_changed', () => {\n resyncTools().catch(() => {})\n })\n client.setNotificationHandler('notifications/resources/list_changed', () => {\n resyncResources().catch(() => {})\n })\n client.setNotificationHandler('notifications/prompts/list_changed', () => {\n resyncPrompts().catch(() => {})\n })\n\n // TTL-based lazy resync: re-fetch on list requests when the cache is stale.\n if (cacheTtl > 0) {\n proxy.use({\n async onListTools(ctx, next) {\n if (Date.now() - lastSync.tools > cacheTtl) await resyncTools().catch(() => {})\n return next()\n },\n async onListResources(ctx, next) {\n if (Date.now() - lastSync.resources > cacheTtl) await resyncResources().catch(() => {})\n return next()\n },\n async onListResourceTemplates(ctx, next) {\n if (Date.now() - lastSync.resources > cacheTtl) await resyncResources().catch(() => {})\n return next()\n },\n async onListPrompts(ctx, next) {\n if (Date.now() - lastSync.prompts > cacheTtl) await resyncPrompts().catch(() => {})\n return next()\n },\n })\n }\n\n proxy._addCloseCallback(async () => {\n await client.close()\n })\n\n return proxy\n}\n\n/**\n * Create a FastMCP instance that proxies all requests to a remote MCP server.\n * The returned instance can be mounted onto a parent server via `parent.mount(proxy)`.\n *\n * Component lists (tools, resources, prompts) are kept in sync via:\n * - Change notifications from the backend (immediate resync)\n * - TTL-based lazy resync on each list request (configurable via `cacheTtl`, default 30 s)\n */\nexport async function createProxy(config: ProxyTransport, name?: string): Promise<FastMCP> {\n let transport: import('@modelcontextprotocol/client').Transport\n\n if (config.type === 'stdio') {\n const { StdioClientTransport } = await import('@modelcontextprotocol/client/stdio')\n transport = new StdioClientTransport({\n command: config.command,\n args: config.args,\n env: config.env,\n cwd: config.cwd,\n })\n } else {\n const { StreamableHTTPClientTransport } = await import(\n '@modelcontextprotocol/client'\n )\n transport = new StreamableHTTPClientTransport(new URL(config.url), {\n requestInit: config.requestInit,\n })\n }\n\n const client = new Client(\n { name: name ?? 'fastmcp-proxy', version: '0.0.1' },\n { capabilities: {} },\n )\n\n await client.connect(transport)\n\n return buildProxyFromClient(client, { cacheTtl: config.cacheTtl, name })\n}\n","/** Small shared helpers for the OpenAPI port. Not exported from the package. */\n\n/**\n * Python-style truthiness: the ported logic from Python FastMCP branches on\n * `if value:` where empty dicts, arrays, and strings are falsy. Faithful\n * branching needs the same notion here.\n */\nexport function truthy(value: unknown): boolean {\n if (value === null || value === undefined || value === false) return false\n if (typeof value === 'number') return value !== 0\n if (typeof value === 'string') return value.length > 0\n if (Array.isArray(value)) return value.length > 0\n if (typeof value === 'object') return Object.keys(value).length > 0\n return true\n}\n\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n/** Structural equality; object key order ignored, array order significant. */\nexport function deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true\n if (Array.isArray(a) && Array.isArray(b)) {\n return a.length === b.length && a.every((item, i) => deepEqual(item, b[i]))\n }\n if (isPlainObject(a) && isPlainObject(b)) {\n const aKeys = Object.keys(a)\n const bKeys = Object.keys(b)\n return (\n aKeys.length === bKeys.length &&\n aKeys.every((k) => Object.prototype.hasOwnProperty.call(b, k) && deepEqual(a[k], b[k]))\n )\n }\n return false\n}\n\nexport function warn(message: string): void {\n console.warn(`[fastmcp] ${message}`)\n}\n","/**\n * OpenAPI spec → HTTPRoute parsing.\n *\n * Port of Python FastMCP's `fastmcp.utilities.openapi.parser`, operating on\n * the plain spec object instead of validated pydantic models (the TypeScript\n * side does not validate the spec; malformed pieces are skipped with a\n * warning where Python's per-item error handling does the same). Reference\n * resolution is local-only: an external `$ref` in a request body, response,\n * or component walk throws; one in a parameter skips that parameter, exactly\n * like Python's per-scope error handling.\n */\n\nimport { parse as parseYaml } from 'yaml'\nimport type {\n HTTPRoute,\n HttpMethod,\n JsonSchema,\n ParameterInfo,\n ParameterLocation,\n RequestBodyInfo,\n ResponseInfo,\n} from './types'\nimport { isPlainObject, truthy, warn } from './internal'\nimport { combineSchemasAndMapParams, discriminatorTargetName, isExternalRefError, replaceRefWithDefs } from './schemas'\n\n/**\n * Load an OpenAPI spec from an object or from YAML/JSON text. YAML 1.2 is a\n * superset of JSON, so JSON text parses through the same path.\n */\nexport function loadSpec(spec: Record<string, unknown> | string): Record<string, unknown> {\n if (typeof spec !== 'string') return spec\n const parsed: unknown = parseYaml(spec)\n if (!isPlainObject(parsed)) {\n throw new Error('OpenAPI spec text must parse to an object')\n }\n return parsed\n}\n\nconst HTTP_METHODS_LOWER = [\n 'get',\n 'put',\n 'post',\n 'delete',\n 'options',\n 'head',\n 'patch',\n 'trace',\n] as const\n\nconst PRIMARY_SUCCESS_PRIORITY = ['200', '201', '202', '204', '207'] as const\n\nconst PARAMETER_LOCATIONS: readonly ParameterLocation[] = ['path', 'query', 'header', 'cookie']\n\nfunction isSuccessStatusCode(statusCode: string): boolean {\n if (/^\\s*[+-]?\\d+\\s*$/.test(statusCode)) {\n const code = parseInt(statusCode, 10)\n return code >= 200 && code < 300\n }\n return ['default', '2xx'].includes(statusCode.toLowerCase())\n}\n\n/** Parse an OpenAPI 3.x spec object into a list of HTTPRoute objects. */\nexport function parseOpenAPIToHttpRoutes(spec: Record<string, unknown>): HTTPRoute[] {\n const openapiVersion = typeof spec.openapi === 'string' ? spec.openapi : ''\n return new SpecParser(spec, openapiVersion).parse()\n}\n\nclass SpecParser {\n constructor(\n private readonly spec: Record<string, unknown>,\n private readonly openapiVersion: string,\n ) {}\n\n private toParameterLocation(paramIn: string): ParameterLocation {\n if ((PARAMETER_LOCATIONS as readonly string[]).includes(paramIn)) {\n return paramIn as ParameterLocation\n }\n warn(`Unknown parameter location: ${paramIn}, defaulting to 'query'`)\n return 'query'\n }\n\n /** Resolve a `{$ref}` object to its target within the spec (local only). */\n private resolveRef(item: unknown): unknown {\n if (!isPlainObject(item) || typeof item.$ref !== 'string') return item\n const ref = item.$ref\n try {\n if (!ref.startsWith('#/')) {\n throw new Error(`External or non-local reference not supported: ${ref}`)\n }\n const parts = ref.replace(/^[#/]+/, '').replace(/[#/]+$/, '').split('/')\n let target: unknown = this.spec\n for (const part of parts) {\n if (/^\\d+$/.test(part) && Array.isArray(target)) {\n target = target[Number(part)]\n } else if (isPlainObject(target)) {\n target = target[part]\n } else {\n throw new Error(`Cannot traverse part '${part}' in reference '${ref}'`)\n }\n if (target === null || target === undefined) {\n throw new Error(`Reference part '${part}' not found in path '${ref}'`)\n }\n }\n if (isPlainObject(target) && typeof target.$ref === 'string') {\n return this.resolveRef(target)\n }\n return target\n } catch (error) {\n throw new Error(`Failed to resolve reference '${ref}': ${(error as Error).message}`)\n }\n }\n\n /** Resolve a schema (or ref to one) and return it as a ref-converted copy. */\n private extractSchemaAsDict(schemaObj: unknown): JsonSchema {\n try {\n const resolved = this.resolveRef(schemaObj)\n let result: JsonSchema\n if (isPlainObject(resolved)) {\n // Deep copy: downstream steps mutate schemas in place, and the same\n // spec object may be parsed more than once.\n result = structuredClone(resolved)\n } else {\n warn(`Expected a schema object after resolving, got ${typeof resolved}. Using empty schema.`)\n result = {}\n }\n return replaceRefWithDefs(result)\n } catch (error) {\n if (isExternalRefError(error)) throw error\n warn(`Failed to extract schema: ${(error as Error).message}`)\n return {}\n }\n }\n\n private extractParameters(operationParams: unknown, pathItemParams: unknown): ParameterInfo[] {\n const extracted: ParameterInfo[] = []\n const seen = new Set<string>()\n const all = [\n ...(Array.isArray(operationParams) ? operationParams : []),\n ...(Array.isArray(pathItemParams) ? pathItemParams : []),\n ]\n\n for (const paramOrRef of all) {\n try {\n const parameter = this.resolveRef(paramOrRef)\n if (\n !isPlainObject(parameter) ||\n typeof parameter.name !== 'string' ||\n typeof parameter.in !== 'string'\n ) {\n warn(`Expected a parameter object after resolving. Skipping.`)\n continue\n }\n\n const location = this.toParameterLocation(parameter.in)\n\n // Skip duplicate parameters (same name and location).\n const key = `${parameter.name}\u0000${parameter.in}`\n if (seen.has(key)) continue\n seen.add(key)\n\n let paramSchema: JsonSchema = {}\n if (truthy(parameter.schema)) {\n paramSchema = this.extractSchemaAsDict(parameter.schema)\n } else if (isPlainObject(parameter.content) && truthy(parameter.content)) {\n // Content-based parameter: use the first media type's schema.\n const firstMediaType = Object.values(parameter.content)[0]\n if (isPlainObject(firstMediaType) && truthy(firstMediaType.schema)) {\n paramSchema = this.extractSchemaAsDict(firstMediaType.schema)\n }\n }\n\n extracted.push({\n name: parameter.name,\n location,\n required: Boolean(parameter.required),\n schema: paramSchema,\n ...(typeof parameter.description === 'string'\n ? { description: parameter.description }\n : {}),\n ...(typeof parameter.explode === 'boolean' ? { explode: parameter.explode } : {}),\n ...(typeof parameter.style === 'string' ? { style: parameter.style } : {}),\n })\n } catch (error) {\n // Per-parameter failures (including external refs) skip the parameter.\n warn(`Failed to extract parameter: ${(error as Error).message}`)\n }\n }\n\n return extracted\n }\n\n private extractRequestBody(requestBodyOrRef: unknown): RequestBodyInfo | undefined {\n if (!truthy(requestBodyOrRef)) return undefined\n\n try {\n const requestBody = this.resolveRef(requestBodyOrRef)\n if (!isPlainObject(requestBody)) {\n warn(`Expected a request body object after resolving. Skipping request body.`)\n return undefined\n }\n\n const info: RequestBodyInfo = {\n required: Boolean(requestBody.required),\n contentSchema: {},\n ...(typeof requestBody.description === 'string'\n ? { description: requestBody.description }\n : {}),\n }\n\n if (isPlainObject(requestBody.content)) {\n for (const [mediaType, mediaTypeObj] of Object.entries(requestBody.content)) {\n if (isPlainObject(mediaTypeObj) && truthy(mediaTypeObj.schema)) {\n try {\n info.contentSchema[mediaType] = this.extractSchemaAsDict(mediaTypeObj.schema)\n } catch (error) {\n if (isExternalRefError(error)) throw error\n warn(`Failed to extract schema for media type '${mediaType}': ${(error as Error).message}`)\n }\n }\n }\n }\n\n return info\n } catch (error) {\n if (isExternalRefError(error)) throw error\n warn(`Failed to extract request body: ${(error as Error).message}`)\n return undefined\n }\n }\n\n private getPrimarySuccessResponse(\n operationResponses: Record<string, unknown>,\n ): [string, unknown] | null {\n for (const code of PRIMARY_SUCCESS_PRIORITY) {\n if (code in operationResponses) return [code, operationResponses[code]]\n }\n for (const [statusCode, respOrRef] of Object.entries(operationResponses)) {\n if (isSuccessStatusCode(statusCode)) return [statusCode, respOrRef]\n }\n return null\n }\n\n /** Extract only the primary success response for the MCP component. */\n private extractResponses(operationResponses: unknown): Record<string, ResponseInfo> {\n const extracted: Record<string, ResponseInfo> = {}\n if (!isPlainObject(operationResponses) || !truthy(operationResponses)) return extracted\n\n const primary = this.getPrimarySuccessResponse(operationResponses)\n if (primary === null) return extracted\n\n const [statusCode, respOrRef] = primary\n try {\n const response = this.resolveRef(respOrRef)\n if (!isPlainObject(response)) {\n warn(`Expected a response object after resolving for status code ${statusCode}. Skipping.`)\n return extracted\n }\n\n const respInfo: ResponseInfo = {\n contentSchema: {},\n ...(typeof response.description === 'string' ? { description: response.description } : {}),\n }\n\n if (isPlainObject(response.content)) {\n for (const [mediaType, mediaTypeObj] of Object.entries(response.content)) {\n if (isPlainObject(mediaTypeObj) && truthy(mediaTypeObj.schema)) {\n try {\n // Track whether this was a top-level component ref before resolution.\n let topLevelSchemaName: string | null = null\n const mediaSchema = mediaTypeObj.schema\n if (isPlainObject(mediaSchema) && typeof mediaSchema.$ref === 'string') {\n if (mediaSchema.$ref.startsWith('#/components/schemas/')) {\n topLevelSchemaName = mediaSchema.$ref.split('/').pop() as string\n }\n }\n\n const schemaDict = this.extractSchemaAsDict(mediaSchema)\n if (topLevelSchemaName !== null) {\n schemaDict['x-fastmcp-top-level-schema'] = topLevelSchemaName\n }\n respInfo.contentSchema[mediaType] = schemaDict\n } catch (error) {\n if (isExternalRefError(error)) throw error\n warn(\n `Failed to extract schema for media type '${mediaType}' in response ${statusCode}: ${(error as Error).message}`,\n )\n }\n } else {\n // Record the media type even without a schema so MIME type\n // inference can still use the declared content type.\n respInfo.contentSchema[mediaType] ??= {}\n }\n }\n }\n\n extracted[statusCode] = respInfo\n } catch (error) {\n if (isExternalRefError(error)) throw error\n warn(`Failed to extract response for status code ${statusCode}: ${(error as Error).message}`)\n }\n\n return extracted\n }\n\n /** Collect schema names referenced by `schema`, transitively. */\n private extractSchemaDependencies(\n schema: unknown,\n allSchemas: Record<string, JsonSchema>,\n collected: Set<string> = new Set(),\n followDiscriminator = false,\n ): Set<string> {\n const collect = (schemaName: string): void => {\n if (!collected.has(schemaName) && schemaName in allSchemas) {\n collected.add(schemaName)\n findRefs(allSchemas[schemaName])\n }\n }\n\n const findRefs = (obj: unknown): void => {\n if (isPlainObject(obj)) {\n if (typeof obj.$ref === 'string') {\n const ref = obj.$ref\n if (ref.startsWith('#/$defs/') || ref.startsWith('#/components/schemas/')) {\n collect(ref.split('/').pop() as string)\n }\n }\n\n if (followDiscriminator) {\n const discriminator = obj.discriminator\n if (isPlainObject(discriminator) && isPlainObject(discriminator.mapping)) {\n for (const target of Object.values(discriminator.mapping)) {\n if (typeof target !== 'string') continue\n const name = discriminatorTargetName(target)\n if (name !== null) collect(name)\n }\n }\n }\n\n for (const value of Object.values(obj)) findRefs(value)\n } else if (Array.isArray(obj)) {\n for (const item of obj) findRefs(item)\n }\n }\n\n findRefs(schema)\n return collected\n }\n\n private extractInputSchemaDependencies(\n parameters: ParameterInfo[],\n requestBody: RequestBodyInfo | undefined,\n allSchemas: Record<string, JsonSchema>,\n ): Record<string, JsonSchema> {\n const needed = new Set<string>()\n\n for (const param of parameters) {\n if (truthy(param.schema)) {\n this.extractSchemaDependencies(param.schema, allSchemas, needed)\n }\n }\n\n // Request bodies are flattened into a single object, so discriminated\n // subtypes need to come along.\n if (requestBody && truthy(requestBody.contentSchema)) {\n for (const contentSchema of Object.values(requestBody.contentSchema)) {\n this.extractSchemaDependencies(contentSchema, allSchemas, needed, true)\n }\n }\n\n return Object.fromEntries([...needed].filter((n) => n in allSchemas).map((n) => [n, allSchemas[n]]))\n }\n\n private extractOutputSchemaDependencies(\n responses: Record<string, ResponseInfo>,\n allSchemas: Record<string, JsonSchema>,\n ): Record<string, JsonSchema> {\n if (!truthy(responses) || !truthy(allSchemas)) return {}\n\n const needed = new Set<string>()\n\n for (const response of Object.values(responses)) {\n if (!truthy(response.contentSchema)) continue\n\n for (const contentSchema of Object.values(response.contentSchema)) {\n this.extractSchemaDependencies(contentSchema, allSchemas, needed)\n\n const schemaName = contentSchema['x-fastmcp-top-level-schema']\n if (typeof schemaName === 'string' && schemaName in allSchemas) {\n needed.add(schemaName)\n this.extractSchemaDependencies(allSchemas[schemaName], allSchemas, needed)\n }\n }\n }\n\n return Object.fromEntries([...needed].filter((n) => n in allSchemas).map((n) => [n, allSchemas[n]]))\n }\n\n parse(): HTTPRoute[] {\n const routes: HTTPRoute[] = []\n\n const paths = this.spec.paths\n if (!isPlainObject(paths) || !truthy(paths)) {\n warn('OpenAPI schema has no paths defined.')\n return []\n }\n\n // Extract component schema definitions (per-definition failures skip\n // that definition, external refs included — Python parity).\n const schemaDefinitions: Record<string, JsonSchema> = {}\n const components = this.spec.components\n if (isPlainObject(components) && isPlainObject(components.schemas)) {\n for (const [name, schema] of Object.entries(components.schemas)) {\n try {\n schemaDefinitions[name] = this.extractSchemaAsDict(this.resolveRef(schema))\n } catch (error) {\n warn(`Failed to extract schema definition '${name}': ${(error as Error).message}`)\n }\n }\n }\n for (const [name, schema] of Object.entries(schemaDefinitions)) {\n if (isPlainObject(schema)) {\n schemaDefinitions[name] = replaceRefWithDefs(schema)\n }\n }\n\n for (const [pathStr, pathItemObj] of Object.entries(paths)) {\n if (!isPlainObject(pathItemObj)) {\n warn(`Skipping invalid path item for path '${pathStr}'`)\n continue\n }\n\n const pathLevelParams = pathItemObj.parameters\n\n for (const methodLower of HTTP_METHODS_LOWER) {\n const operation = pathItemObj[methodLower]\n if (!isPlainObject(operation)) continue\n\n const method = methodLower.toUpperCase() as HttpMethod\n\n try {\n const parameters = this.extractParameters(operation.parameters, pathLevelParams)\n const requestBody = this.extractRequestBody(operation.requestBody)\n const responses = this.extractResponses(operation.responses)\n\n const extensions = Object.fromEntries(\n Object.entries(operation).filter(([key]) => key.startsWith('x-')),\n )\n\n const requestSchemas = this.extractInputSchemaDependencies(\n parameters,\n requestBody,\n schemaDefinitions,\n )\n const responseSchemas = this.extractOutputSchemaDependencies(\n responses,\n schemaDefinitions,\n )\n\n const route: HTTPRoute = {\n path: pathStr,\n method,\n ...(typeof operation.operationId === 'string'\n ? { operationId: operation.operationId }\n : {}),\n ...(typeof operation.summary === 'string' ? { summary: operation.summary } : {}),\n ...(typeof operation.description === 'string'\n ? { description: operation.description }\n : {}),\n tags: Array.isArray(operation.tags) ? [...(operation.tags as string[])] : [],\n parameters,\n ...(requestBody !== undefined ? { requestBody } : {}),\n responses,\n requestSchemas,\n responseSchemas,\n extensions,\n openapiVersion: this.openapiVersion,\n flatParamSchema: {},\n parameterMap: {},\n }\n\n // Pre-calculate the flat schema and parameter mapping.\n try {\n const [flatSchema, parameterMap] = combineSchemasAndMapParams(route)\n route.flatParamSchema = flatSchema\n route.parameterMap = parameterMap\n } catch (error) {\n warn(\n `Failed to pre-calculate schema for route ${method} ${pathStr}: ${(error as Error).message}`,\n )\n route.flatParamSchema = { type: 'object', properties: {} }\n route.parameterMap = {}\n }\n routes.push(route)\n } catch (error) {\n if (isExternalRefError(error)) throw error\n const opId =\n typeof operation.operationId === 'string' ? operation.operationId : 'unknown'\n warn(\n `Failed to process operation ${method} ${pathStr} (ID: ${opId}): ${(error as Error).message}`,\n )\n }\n }\n }\n\n return routes\n }\n}\n","/**\n * OpenAPI 3.x schema → JSON Schema conversion.\n *\n * Port of Python FastMCP's `fastmcp.utilities.openapi.json_schema_converter`\n * (plus `require_discriminator_property` from `fastmcp.utilities.json_schema`).\n * The conversion order is part of the parity contract:\n *\n * 1. nullable → type arrays / anyOf-with-null (OpenAPI 3.0 only; 3.1 has no\n * `nullable`, so the keyword is simply stripped there)\n * 2. oneOf → anyOf (all 3.x — overlapping unions must not hard-fail)\n * 3. the discriminator's tag property is forced into each variant's\n * `required` BEFORE the keyword is removed\n * 4. OpenAPI-specific fields removed\n * 5. recurse into nested schemas\n */\n\nimport type { JsonSchema } from './types'\nimport { isPlainObject } from './internal'\n\nconst OPENAPI_SPECIFIC_FIELDS = [\n 'nullable',\n 'discriminator',\n 'readOnly',\n 'writeOnly',\n 'xml',\n 'externalDocs',\n 'deprecated',\n] as const\n\nconst RECURSIVE_MAP_FIELDS = ['properties', '$defs', '$definitions'] as const\nconst RECURSIVE_SINGLE_FIELDS = ['items', 'additionalProperties', 'not'] as const\nconst RECURSIVE_LIST_FIELDS = ['allOf', 'anyOf', 'oneOf'] as const\n\n/** Convert an OpenAPI 3.x schema (and everything nested in it) to JSON Schema. */\nexport function convertOpenAPISchemaToJsonSchema(\n schema: JsonSchema,\n openapiVersion?: string,\n): JsonSchema {\n if (!isPlainObject(schema)) return schema\n\n let result: JsonSchema = { ...schema }\n\n if (openapiVersion?.startsWith('3.0')) {\n result = convertNullableField(result)\n }\n\n if ('oneOf' in result) {\n result.anyOf = result.oneOf\n delete result.oneOf\n }\n\n result = requireDiscriminatorProperty(result)\n\n for (const field of OPENAPI_SPECIFIC_FIELDS) {\n delete result[field]\n }\n\n for (const field of RECURSIVE_MAP_FIELDS) {\n const map = result[field]\n if (isPlainObject(map)) {\n result[field] = Object.fromEntries(\n Object.entries(map).map(([name, sub]) => [\n name,\n isPlainObject(sub) ? convertOpenAPISchemaToJsonSchema(sub, openapiVersion) : sub,\n ]),\n )\n }\n }\n for (const field of RECURSIVE_SINGLE_FIELDS) {\n const sub = result[field]\n if (isPlainObject(sub)) {\n result[field] = convertOpenAPISchemaToJsonSchema(sub, openapiVersion)\n }\n }\n for (const field of RECURSIVE_LIST_FIELDS) {\n const list = result[field]\n if (Array.isArray(list)) {\n result[field] = list.map((item) =>\n isPlainObject(item) ? convertOpenAPISchemaToJsonSchema(item, openapiVersion) : item,\n )\n }\n }\n\n return result\n}\n\n/** Convert OpenAPI 3.0 `nullable: true` into JSON Schema null unions. */\nfunction convertNullableField(schema: JsonSchema): JsonSchema {\n if (!('nullable' in schema)) return schema\n\n const result = { ...schema }\n const nullableValue = result.nullable\n delete result.nullable\n\n if (!nullableValue) return result\n\n const currentType = result.type\n if ('type' in result) {\n if (typeof currentType === 'string') {\n result.type = [currentType, 'null']\n } else if (Array.isArray(currentType) && !currentType.includes('null')) {\n result.type = [...currentType, 'null']\n }\n } else if ('oneOf' in result) {\n result.anyOf = [...(result.oneOf as unknown[]), { type: 'null' }]\n delete result.oneOf\n } else if ('anyOf' in result) {\n const anyOf = result.anyOf as unknown[]\n if (!anyOf.some((item) => isPlainObject(item) && item.type === 'null')) {\n result.anyOf = [...anyOf, { type: 'null' }]\n }\n } else if ('allOf' in result) {\n result.anyOf = [{ allOf: result.allOf }, { type: 'null' }]\n delete result.allOf\n }\n\n if (Array.isArray(result.enum) && !result.enum.includes(null)) {\n result.enum = [...result.enum, null]\n }\n\n return result\n}\n\n/** Return a copy of `schema` with `propertyName` added to `required`. */\nfunction requireProperty(schema: JsonSchema, propertyName: string): JsonSchema {\n const required = schema.required\n if (required === undefined || required === null) {\n return { ...schema, required: [propertyName] }\n }\n if (Array.isArray(required) && !required.includes(propertyName)) {\n return { ...schema, required: [...required, propertyName] }\n }\n return schema\n}\n\n/**\n * Keep an OpenAPI discriminator's tag mandatory after the keyword is dropped:\n * adds `discriminator.propertyName` to each anyOf/oneOf variant's `required`.\n */\nexport function requireDiscriminatorProperty(schema: JsonSchema): JsonSchema {\n const discriminator = schema.discriminator\n if (!isPlainObject(discriminator)) return schema\n const propertyName = discriminator.propertyName\n if (typeof propertyName !== 'string') return schema\n\n const result = { ...schema }\n for (const key of ['anyOf', 'oneOf'] as const) {\n const variants = result[key]\n if (!Array.isArray(variants)) continue\n result[key] = variants.map((variant) =>\n isPlainObject(variant) ? requireProperty(variant, propertyName) : variant,\n )\n }\n return result\n}\n","/**\n * Schema manipulation for OpenAPI operations.\n *\n * Port of Python FastMCP's `fastmcp.utilities.openapi.schemas`. The quirks are\n * deliberate parity: the flat input schema keeps an empty `required: []`, the\n * request-body content schema is mutated IN PLACE (the request director later\n * reads the mutated version to decide body construction), and discriminator\n * subtypes are flattened into optional fields rather than emitted as a\n * top-level union. The snapshots in `tests/fixtures/openapi/` pin all of it.\n */\n\nimport type { HTTPRoute, JsonSchema, ParameterMapping, ResponseInfo } from './types'\nimport { deepEqual, isPlainObject, truthy } from './internal'\nimport { convertOpenAPISchemaToJsonSchema } from './jsonSchema'\n\nexport const EXTERNAL_REF_MESSAGE = 'External or non-local reference not supported'\n\nexport function isExternalRefError(error: unknown): boolean {\n return error instanceof Error && error.message.includes(EXTERNAL_REF_MESSAGE)\n}\n\n/**\n * Replace OpenAPI `#/components/schemas/X` refs with JSON Schema `#/$defs/X`\n * recursively. Throws on external (non-`#/`) references.\n */\nexport function replaceRefWithDefs(info: JsonSchema, description?: string): JsonSchema {\n const schema: JsonSchema = { ...info }\n const refPath = schema.$ref\n if (truthy(refPath)) {\n if (typeof refPath === 'string') {\n if (refPath.startsWith('#/components/schemas/')) {\n schema.$ref = `#/$defs/${refPath.split('/').pop()}`\n } else if (!refPath.startsWith('#/')) {\n throw new Error(\n `${EXTERNAL_REF_MESSAGE}: ${refPath}. FastMCP only supports local schema ` +\n `references starting with '#/'. Please include all schema definitions ` +\n `within the OpenAPI document.`,\n )\n }\n }\n } else if (truthy(schema.properties)) {\n const properties = schema.properties as Record<string, unknown>\n if ('$ref' in properties) {\n // A property literally named \"$ref\": the Python implementation treats the\n // whole properties map as one schema in this case. Same here, for parity.\n schema.properties = replaceRefWithDefs(properties as JsonSchema)\n } else {\n schema.properties = Object.fromEntries(\n Object.entries(properties).map(([name, prop]) => [\n name,\n isPlainObject(prop) ? replaceRefWithDefs(prop) : prop,\n ]),\n )\n }\n } else if (truthy(schema.items)) {\n if (isPlainObject(schema.items)) {\n schema.items = replaceRefWithDefs(schema.items)\n }\n }\n for (const section of ['anyOf', 'allOf', 'oneOf'] as const) {\n const list = schema[section]\n if (Array.isArray(list)) {\n schema[section] = list.map((item) => (isPlainObject(item) ? replaceRefWithDefs(item) : item))\n }\n }\n const additionalProperties = schema.additionalProperties\n if (truthy(additionalProperties) && isPlainObject(additionalProperties)) {\n schema.additionalProperties = replaceRefWithDefs(additionalProperties)\n }\n const propertyNames = schema.propertyNames\n if (truthy(propertyNames) && isPlainObject(propertyNames)) {\n schema.propertyNames = replaceRefWithDefs(propertyNames)\n }\n const patternProperties = schema.patternProperties\n if (truthy(patternProperties) && isPlainObject(patternProperties)) {\n schema.patternProperties = Object.fromEntries(\n Object.entries(patternProperties).map(([pattern, sub]) => [\n pattern,\n isPlainObject(sub) ? replaceRefWithDefs(sub) : sub,\n ]),\n )\n }\n if (info.description === undefined && truthy(description) && !truthy(schema.description)) {\n schema.description = description\n }\n return schema\n}\n\n/** Expand local schema references while collecting `allOf` members. */\nfunction allofMembers(\n schema: JsonSchema,\n schemaDefs: Record<string, JsonSchema>,\n resolving: ReadonlySet<string> = new Set(),\n): JsonSchema[] {\n const ref = schema.$ref\n if (typeof ref === 'string') {\n for (const prefix of ['#/$defs/', '#/components/schemas/']) {\n if (ref.startsWith(prefix)) {\n const name = ref.slice(prefix.length)\n const referenced = schemaDefs[name]\n if (isPlainObject(referenced) && !resolving.has(name)) {\n const siblings = Object.fromEntries(\n Object.entries(schema).filter(([key]) => key !== '$ref'),\n )\n const members = allofMembers(referenced, schemaDefs, new Set([...resolving, name]))\n return truthy(siblings) ? [...members, siblings] : members\n }\n break\n }\n }\n }\n\n const allOf = schema.allOf\n if (Array.isArray(allOf)) {\n const members: JsonSchema[] = []\n for (const member of allOf) {\n if (isPlainObject(member)) {\n members.push(...allofMembers(member, schemaDefs, resolving))\n }\n }\n const siblings = Object.fromEntries(Object.entries(schema).filter(([key]) => key !== 'allOf'))\n return truthy(siblings) ? [...members, siblings] : members\n }\n\n return [schema]\n}\n\n/**\n * Resolve a `discriminator.mapping` value to a local schema name. Mapping\n * values hold \"schema names or references\": a bare `\"Cat\"` means the `Cat`\n * component just as `\"#/components/schemas/Cat\"` does.\n */\nexport function discriminatorTargetName(target: string): string | null {\n for (const prefix of ['#/$defs/', '#/components/schemas/']) {\n if (target.startsWith(prefix)) {\n return target.slice(prefix.length) || null\n }\n }\n if (target.startsWith('#') || target.includes('/')) return null\n return target || null\n}\n\n/**\n * Flatten the subtypes named by an OpenAPI `discriminator.mapping` into the\n * parent's properties. Variant fields merge in as optional; properties that\n * disagree between variants become an anyOf; the tag property's description\n * spells out the accepted values. Returns replacement properties, or null when\n * there is no usable mapping.\n */\nfunction flattenDiscriminatorSubtypes(\n schema: JsonSchema,\n schemaDefs: Record<string, JsonSchema>,\n): Record<string, unknown> | null {\n const discriminator = schema.discriminator\n if (!isPlainObject(discriminator)) return null\n\n const propertyName = discriminator.propertyName\n const mapping = discriminator.mapping\n if (typeof propertyName !== 'string' || !isPlainObject(mapping)) return null\n\n const ownProps = isPlainObject(schema.properties) ? schema.properties : {}\n const alternatives = new Map<string, unknown[]>()\n const values: string[] = []\n const variants: string[] = []\n\n for (const [value, target] of Object.entries(mapping)) {\n if (typeof target !== 'string') continue\n\n const name = discriminatorTargetName(target)\n const subtype = name !== null ? schemaDefs[name] : undefined\n if (!isPlainObject(subtype)) continue\n\n // Fields the parent already declares are shared, not variant-specific.\n const variantFields: string[] = []\n for (const member of allofMembers(subtype, schemaDefs)) {\n const memberProps = isPlainObject(member.properties) ? member.properties : {}\n for (const [propName, propSchema] of Object.entries(memberProps)) {\n if (propName in ownProps) continue\n if (!variantFields.includes(propName)) variantFields.push(propName)\n const seen = alternatives.get(propName) ?? []\n if (!seen.some((existing) => deepEqual(existing, propSchema))) seen.push(propSchema)\n alternatives.set(propName, seen)\n }\n }\n\n values.push(`'${value}'`)\n if (variantFields.length > 0) {\n variants.push(`'${value}' uses ${variantFields.join(', ')}`)\n }\n }\n\n if (values.length === 0) return null\n\n const subtypeProps = Object.fromEntries(\n [...alternatives.entries()].map(([propName, schemas]) => [\n propName,\n schemas.length === 1 ? schemas[0] : { anyOf: schemas },\n ]),\n )\n const properties: Record<string, unknown> = { ...ownProps, ...subtypeProps }\n\n let note = `Selects the variant. Accepted values: ${values.join(', ')}.`\n if (variants.length > 0) {\n note += ` ${variants.join('; ')}. Send only the fields belonging to the selected variant.`\n }\n\n // The discriminator names a property of the payload, so give it a schema even\n // when the parent left it undeclared.\n const existing = properties[propertyName]\n const tagSchema: JsonSchema = isPlainObject(existing) ? existing : { type: 'string' }\n const existingDesc = tagSchema.description\n properties[propertyName] = {\n ...tagSchema,\n description: truthy(existingDesc) ? `${existingDesc as string} ${note}` : note,\n }\n\n return properties\n}\n\nfunction capitalize(text: string): string {\n return text.charAt(0).toUpperCase() + text.slice(1)\n}\n\n/**\n * Combine parameter and request-body schemas into the flat input schema\n * advertised on the MCP tool, and build the parameter map that routes flat\n * arguments back to their OpenAPI locations at request time.\n *\n * Mirrors the Python parser's pre-calculation path (`convert_refs=False`):\n * refs are already converted, `$defs` is attached unpruned, and the body\n * content schema is mutated in place.\n */\nexport function combineSchemasAndMapParams(\n route: HTTPRoute,\n): [JsonSchema, Record<string, ParameterMapping>] {\n const properties: Record<string, unknown> = {}\n const required: string[] = []\n const parameterMap: Record<string, ParameterMapping> = {}\n\n const paramNamesByLocation = {\n path: new Set<string>(),\n query: new Set<string>(),\n header: new Set<string>(),\n cookie: new Set<string>(),\n }\n let bodySchema: JsonSchema = {}\n let bodyProps: Record<string, unknown> = {}\n\n for (const param of route.parameters) {\n paramNamesByLocation[param.location].add(param.name)\n }\n\n const requestBody = route.requestBody\n if (requestBody && truthy(requestBody.contentSchema)) {\n const contentType = Object.keys(requestBody.contentSchema)[0]\n bodySchema = requestBody.contentSchema[contentType]\n\n if (truthy(requestBody.description) && !truthy(bodySchema.description)) {\n bodySchema.description = requestBody.description\n }\n\n if ('allOf' in bodySchema && Array.isArray(bodySchema.allOf)) {\n const mergedProps: Record<string, unknown> = {}\n const mergedRequired: string[] = []\n\n for (const subSchema of allofMembers(bodySchema, route.requestSchemas)) {\n if ('properties' in subSchema && isPlainObject(subSchema.properties)) {\n Object.assign(mergedProps, subSchema.properties)\n }\n if ('required' in subSchema && Array.isArray(subSchema.required)) {\n mergedRequired.push(...(subSchema.required as string[]))\n }\n }\n\n bodySchema.properties = mergedProps\n if (mergedRequired.length > 0) {\n bodySchema.required = [...new Set(mergedRequired)]\n }\n delete bodySchema.allOf\n }\n\n // Merge discriminated subtype fields in as optional. The discriminator\n // itself is dropped: its mapping points at definitions that would leave\n // dangling refs once pruned from $defs.\n const flattenedProps = flattenDiscriminatorSubtypes(bodySchema, route.requestSchemas)\n if (flattenedProps !== null) {\n bodySchema.properties = flattenedProps\n delete bodySchema.discriminator\n }\n\n bodyProps = isPlainObject(bodySchema.properties) ? bodySchema.properties : {}\n }\n\n // Collisions: a name used in more than one non-body location, or shared\n // between body and a parameter location.\n const allNonBodyParams = new Set<string>()\n for (const names of Object.values(paramNamesByLocation)) {\n for (const name of names) allNonBodyParams.add(name)\n }\n const bodyParamNames = new Set(Object.keys(bodyProps))\n const paramCounts = new Map<string, number>()\n for (const param of route.parameters) {\n paramCounts.set(param.name, (paramCounts.get(param.name) ?? 0) + 1)\n }\n const collidingParams = new Set<string>()\n for (const name of allNonBodyParams) {\n if (bodyParamNames.has(name)) collidingParams.add(name)\n }\n for (const [name, count] of paramCounts) {\n if (count > 1) collidingParams.add(name)\n }\n\n for (const param of route.parameters) {\n const paramSchema: JsonSchema = { ...param.schema }\n if (truthy(param.description) && !truthy(paramSchema.description)) {\n paramSchema.description = param.description\n }\n\n if (collidingParams.has(param.name)) {\n const suffixedName = `${param.name}__${param.location}`\n if (param.required) required.push(suffixedName)\n parameterMap[suffixedName] = { location: param.location, openapiName: param.name }\n\n const originalDesc = truthy(paramSchema.description) ? (paramSchema.description as string) : ''\n const locationDesc = `(${capitalize(param.location)} parameter)`\n paramSchema.description = originalDesc ? `${originalDesc} ${locationDesc}` : locationDesc\n\n properties[suffixedName] = paramSchema\n } else {\n if (param.required) required.push(param.name)\n parameterMap[param.name] = { location: param.location, openapiName: param.name }\n properties[param.name] = paramSchema\n }\n }\n\n // Request body properties are added without suffixes.\n if (requestBody && truthy(requestBody.contentSchema)) {\n if ('$ref' in bodySchema && !truthy(bodyProps)) {\n // The entire body is a reference: keep it as a single `body` property.\n properties.body = bodySchema\n if (requestBody.required) required.push('body')\n parameterMap.body = { location: 'body', openapiName: 'body' }\n } else if (truthy(bodyProps)) {\n for (const [propName, propSchema] of Object.entries(bodyProps)) {\n properties[propName] = propSchema\n parameterMap[propName] = { location: 'body', openapiName: propName }\n }\n if (requestBody.required) {\n required.push(...((bodySchema.required as string[] | undefined) ?? []))\n }\n } else {\n // Direct array/primitive body: name the parameter from the schema title.\n let paramName = String(\n typeof bodySchema.title === 'string' ? bodySchema.title : 'body',\n ).toLowerCase()\n paramName = paramName.replace(/[^a-zA-Z0-9_]/g, '_')\n if (!paramName || /^\\d/.test(paramName)) paramName = 'body_data'\n\n properties[paramName] = bodySchema\n if (requestBody.required) required.push(paramName)\n parameterMap[paramName] = { location: 'body', openapiName: paramName }\n }\n }\n\n let result: JsonSchema = { type: 'object', properties, required }\n if (truthy(route.requestSchemas)) {\n result.$defs = route.requestSchemas\n }\n\n if (route.openapiVersion?.startsWith('3')) {\n result = convertOpenAPISchemaToJsonSchema(result, route.openapiVersion)\n }\n\n return [result, parameterMap]\n}\n\nconst SUCCESS_CODE_PRIORITY = ['200', '201', '202', '204'] as const\n\nconst JSON_COMPATIBLE_TYPES = [\n 'application/json',\n 'application/vnd.api+json',\n 'application/hal+json',\n 'application/ld+json',\n 'text/json',\n] as const\n\n/**\n * Extract the MCP tool output schema from OpenAPI responses: first success\n * response, JSON-compatible content type preferred, non-object schemas\n * wrapped in `{result}` with the `x-fastmcp-wrap-result` marker.\n */\nexport function extractOutputSchemaFromResponses(\n responses: Record<string, ResponseInfo>,\n schemaDefinitions?: Record<string, JsonSchema>,\n openapiVersion?: string,\n): JsonSchema | null {\n if (!truthy(responses)) return null\n\n let responseInfo: ResponseInfo | undefined\n for (const statusCode of SUCCESS_CODE_PRIORITY) {\n if (statusCode in responses) {\n responseInfo = responses[statusCode]\n break\n }\n }\n if (responseInfo === undefined) {\n for (const [statusCode, respInfo] of Object.entries(responses)) {\n if (statusCode.startsWith('2')) {\n responseInfo = respInfo\n break\n }\n }\n }\n if (responseInfo === undefined || !truthy(responseInfo.contentSchema)) return null\n\n let schema: JsonSchema | undefined\n for (const contentType of JSON_COMPATIBLE_TYPES) {\n if (contentType in responseInfo.contentSchema) {\n schema = responseInfo.contentSchema[contentType]\n break\n }\n }\n if (schema === undefined) {\n const firstContentType = Object.keys(responseInfo.contentSchema)[0]\n schema = responseInfo.contentSchema[firstContentType]\n }\n\n if (!truthy(schema) || !isPlainObject(schema)) return null\n\n let outputSchema = replaceRefWithDefs(schema)\n\n // A top-level $ref is inlined from the definitions before further handling.\n if (typeof outputSchema.$ref === 'string' && schemaDefinitions && truthy(schemaDefinitions)) {\n const refPath = outputSchema.$ref\n if (refPath.startsWith('#/$defs/')) {\n const schemaName = refPath.split('/').pop() as string\n if (schemaName in schemaDefinitions) {\n outputSchema = replaceRefWithDefs(schemaDefinitions[schemaName])\n }\n }\n }\n\n if (openapiVersion?.startsWith('3')) {\n outputSchema = convertOpenAPISchemaToJsonSchema(outputSchema, openapiVersion)\n }\n\n // MCP requires output schemas to be objects; wrap anything else.\n if (outputSchema.type !== 'object') {\n outputSchema = {\n type: 'object',\n properties: { result: outputSchema },\n required: ['result'],\n 'x-fastmcp-wrap-result': true,\n }\n }\n\n if (schemaDefinitions && truthy(schemaDefinitions)) {\n const processedDefs: Record<string, JsonSchema> = { ...schemaDefinitions }\n for (const [name, defSchema] of Object.entries(processedDefs)) {\n if (isPlainObject(defSchema)) {\n processedDefs[name] = replaceRefWithDefs(defSchema)\n }\n }\n if (openapiVersion?.startsWith('3')) {\n for (const name of Object.keys(processedDefs)) {\n processedDefs[name] = convertOpenAPISchemaToJsonSchema(processedDefs[name], openapiVersion)\n }\n }\n outputSchema.$defs = processedDefs\n }\n\n return outputSchema\n}\n","/**\n * Route mapping: which MCP component type each HTTP route becomes.\n *\n * Port of Python FastMCP's `fastmcp.server.providers.openapi.routing`. User\n * maps are checked in order before the default map (everything becomes a\n * tool); the first map whose methods, pattern, and tags all match wins.\n */\n\nimport type { HTTPRoute, RouteMap } from './types'\n\n/** Default route mapping: every route becomes a tool. */\nexport const DEFAULT_ROUTE_MAPPINGS: readonly RouteMap[] = [{ mcpType: 'tool' }]\n\nfunction patternMatches(pattern: RegExp | string | undefined, path: string): boolean {\n if (pattern === undefined) return true\n if (typeof pattern === 'string') return new RegExp(pattern).test(path)\n // Unanchored search independent of the RegExp's lastIndex state.\n return path.search(pattern) !== -1\n}\n\n/** Find the first route map matching the route. Falls back to tool. */\nexport function determineRouteType(route: HTTPRoute, mappings: readonly RouteMap[]): RouteMap {\n for (const routeMap of mappings) {\n const methods = routeMap.methods ?? '*'\n if (methods !== '*' && !methods.includes(route.method)) continue\n\n if (!patternMatches(routeMap.pattern, route.path)) continue\n\n if (routeMap.tags && routeMap.tags.length > 0) {\n const routeTags = new Set(route.tags ?? [])\n if (!routeMap.tags.every((tag) => routeTags.has(tag))) continue\n }\n\n return routeMap\n }\n\n return { mcpType: 'tool' }\n}\n","/**\n * Component naming for generated MCP components.\n *\n * Port of Python FastMCP's `_slugify`, `_generate_default_name`, and\n * `_get_unique_name`. The order of operations is part of the parity contract:\n * names truncate to 56 characters BEFORE per-type numeric deduplication, so a\n * long name that collides becomes `<56 chars>_2`, not a re-truncated hybrid.\n */\n\nimport type { HTTPRoute } from './types'\n\n/** Slug containing only letters, numbers, and underscores (case preserved). */\nexport function slugify(text: string): string {\n if (!text) return ''\n return text\n .replace(/[\\s\\-.]+/g, '_')\n .replace(/[^a-zA-Z0-9_]/g, '')\n .replace(/_+/g, '_')\n .replace(/^_+|_+$/g, '')\n}\n\n/**\n * Default component name for a route: operationId (before any `__` suffix),\n * overridden by the `names` map, else summary, else `{METHOD}_{path}`.\n */\nexport function generateDefaultName(route: HTTPRoute, names?: Record<string, string>): string {\n let name: string\n if (route.operationId) {\n name = names?.[route.operationId] ?? route.operationId.split('__')[0]\n } else {\n name = route.summary || `${route.method}_${route.path}`\n }\n\n name = slugify(name)\n if (name.length > 56) name = name.slice(0, 56)\n return name\n}\n\nexport type ComponentNameType = 'tool' | 'resource' | 'resourceTemplate' | 'prompt'\n\n/** Per-type name counter that appends `_2`, `_3`, ... on collisions. */\nexport class NameRegistry {\n private readonly counters: Record<ComponentNameType, Map<string, number>> = {\n tool: new Map(),\n resource: new Map(),\n resourceTemplate: new Map(),\n prompt: new Map(),\n }\n\n getUniqueName(name: string, componentType: ComponentNameType): string {\n const counter = this.counters[componentType]\n const count = (counter.get(name) ?? 0) + 1\n counter.set(name, count)\n if (count === 1) return name\n return `${name}_${count}`\n }\n}\n","/**\n * Request building: flat MCP tool arguments → a concrete HTTP request.\n *\n * Port of Python FastMCP's `fastmcp.utilities.openapi.director`\n * (RequestDirector). Handles un-flattening via the parameter map, OpenAPI\n * query style/explode serialization, strict path-parameter percent-encoding\n * (everything encoded, plus `.` → `%2E`), and request-body dispatch on the\n * FIRST declared content type.\n */\n\nimport type { HTTPRoute, ParameterInfo } from './types'\nimport { isPlainObject, warn } from './internal'\n\n/** A fully built HTTP request, ready to hand to fetch. */\nexport interface DirectedRequest {\n method: string\n /** Absolute URL including any query string. */\n url: string\n headers: Record<string, string>\n body?: string | URLSearchParams | FormData\n}\n\n/**\n * Query-string representation of a scalar. Booleans are lowercased to match\n * JSON/OpenAPI conventions (true/false).\n */\nfunction queryScalarToStr(value: unknown): string {\n if (typeof value === 'boolean') return value ? 'true' : 'false'\n return String(value)\n}\n\n/** Delimiter per OpenAPI style when explode=false. */\nconst STYLE_DELIMITERS: Record<string, string> = {\n form: ',',\n spaceDelimited: ' ',\n pipeDelimited: '|',\n}\n\ninterface UnflattenedArguments {\n pathParams: Record<string, unknown>\n queryParams: Record<string, unknown>\n headerParams: Record<string, unknown>\n cookieParams: Record<string, unknown>\n body: unknown\n}\n\n/** Map flat arguments back to their OpenAPI locations via the parameter map. */\nfunction unflattenArguments(route: HTTPRoute, flatArgs: Record<string, unknown>): UnflattenedArguments {\n const pathParams: Record<string, unknown> = {}\n const queryParams: Record<string, unknown> = {}\n const headerParams: Record<string, unknown> = {}\n const cookieParams: Record<string, unknown> = {}\n const bodyProps: Record<string, unknown> = {}\n\n const buckets: Record<string, Record<string, unknown>> = {\n path: pathParams,\n query: queryParams,\n header: headerParams,\n cookie: cookieParams,\n body: bodyProps,\n }\n\n if (Object.keys(route.parameterMap).length > 0) {\n for (const [argName, value] of Object.entries(flatArgs)) {\n if (value === null || value === undefined) continue // optional parameter omitted\n\n const mapping = route.parameterMap[argName]\n if (mapping === undefined) {\n warn(`Argument '${argName}' not found in parameter map for ${route.operationId ?? route.path}`)\n continue\n }\n buckets[mapping.location][mapping.openapiName] = value\n }\n } else {\n // Fallback when pre-calculation failed: suffix parsing, then declared\n // parameter locations, else body.\n const paramLocations = new Map(route.parameters.map((p) => [p.name, p.location]))\n\n for (const [argName, value] of Object.entries(flatArgs)) {\n if (value === null || value === undefined) continue\n\n const suffixIdx = argName.lastIndexOf('__')\n if (suffixIdx !== -1) {\n const baseName = argName.slice(0, suffixIdx)\n const location = argName.slice(suffixIdx + 2)\n if (location in buckets && location !== 'body') {\n buckets[location][baseName] = value\n continue\n }\n }\n\n const location = paramLocations.get(argName)\n if (location !== undefined) {\n buckets[location][argName] = value\n } else {\n bodyProps[argName] = value\n }\n }\n }\n\n // Body construction: an object-typed body schema keeps the property map; a\n // non-object schema with exactly one property sends the value directly.\n let body: unknown\n if (Object.keys(bodyProps).length > 0) {\n const contentSchema = route.requestBody?.contentSchema\n if (contentSchema && Object.keys(contentSchema).length > 0) {\n const contentType = Object.keys(contentSchema)[0]\n const bodySchema = contentSchema[contentType]\n\n if (isPlainObject(bodySchema) && bodySchema.type === 'object') {\n body = bodyProps\n } else if (Object.keys(bodyProps).length === 1) {\n body = Object.values(bodyProps)[0]\n } else {\n body = bodyProps\n }\n } else {\n body = bodyProps\n }\n }\n\n return { pathParams, queryParams, headerParams, cookieParams, body }\n}\n\n/**\n * Serialize query values per their OpenAPI style/explode settings. Exploded\n * arrays stay arrays (the key repeats in the query string); explode=false\n * joins with the style's delimiter; exploded objects fan out into separate\n * keys (bare property names for form style, `key[prop]` for deepObject).\n */\nfunction serializeQueryParams(\n route: HTTPRoute,\n queryParams: Record<string, unknown>,\n): Record<string, unknown> {\n if (Object.keys(queryParams).length === 0) return queryParams\n\n const paramLookup = new Map<string, ParameterInfo>(\n route.parameters.filter((p) => p.location === 'query').map((p) => [p.name, p]),\n )\n\n const serialized: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(queryParams)) {\n const paramInfo = paramLookup.get(key)\n if (paramInfo !== undefined) {\n const explode = paramInfo.explode ?? true\n if (isPlainObject(value)) {\n if (Object.keys(value).length === 0) continue\n if (explode) {\n for (const [propKey, propValue] of Object.entries(value)) {\n const propertyName =\n paramInfo.style === 'deepObject'\n ? `${key}[${queryScalarToStr(propKey)}]`\n : queryScalarToStr(propKey)\n serialized[propertyName] = queryScalarToStr(propValue)\n }\n } else {\n const delimiter = STYLE_DELIMITERS[paramInfo.style ?? 'form'] ?? ','\n // form,explode=false on objects: key,value pairs (R,100,G,200).\n const parts: string[] = []\n for (const [propKey, propValue] of Object.entries(value)) {\n parts.push(queryScalarToStr(propKey), queryScalarToStr(propValue))\n }\n serialized[key] = parts.join(delimiter)\n }\n continue\n }\n if (!explode && Array.isArray(value)) {\n if (value.length === 0) continue\n const delimiter = STYLE_DELIMITERS[paramInfo.style ?? 'form'] ?? ','\n serialized[key] = value.map(queryScalarToStr).join(delimiter)\n continue\n }\n }\n serialized[key] = value\n }\n return serialized\n}\n\n/**\n * Percent-encode a path parameter value. Everything outside [A-Za-z0-9_~-]\n * is encoded (Python `quote(safe=\"\")` parity), and `.` becomes `%2E` so a\n * crafted value can never traverse the path.\n */\nfunction quotePathValue(value: string): string {\n return encodeURIComponent(value)\n .replace(/[!'()*]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`)\n .replace(/\\./g, '%2E')\n}\n\n/** Substitute path parameters into the template and join with the base URL. */\nfunction buildUrl(pathTemplate: string, pathParams: Record<string, unknown>, baseUrl: string): string {\n let urlPath = pathTemplate\n for (const [paramName, paramValue] of Object.entries(pathParams)) {\n const placeholder = `{${paramName}}`\n if (urlPath.includes(placeholder)) {\n urlPath = urlPath.split(placeholder).join(quotePathValue(String(paramValue)))\n }\n }\n const base = `${baseUrl.replace(/\\/+$/, '')}/`\n return new URL(urlPath.replace(/^\\/+/, ''), base).toString()\n}\n\n/**\n * Build the complete HTTP request for a route from flat tool arguments,\n * handling all OpenAPI serialization rules.\n */\nexport function buildRequest(\n route: HTTPRoute,\n flatArgs: Record<string, unknown>,\n baseUrl: string,\n): DirectedRequest {\n const { pathParams, queryParams, headerParams, cookieParams, body } = unflattenArguments(\n route,\n flatArgs,\n )\n\n const serializedQuery = serializeQueryParams(route, queryParams)\n\n const url = new URL(buildUrl(route.path, pathParams, baseUrl))\n for (const [key, value] of Object.entries(serializedQuery)) {\n if (Array.isArray(value)) {\n for (const item of value) url.searchParams.append(key, queryScalarToStr(item))\n } else {\n url.searchParams.append(key, queryScalarToStr(value))\n }\n }\n\n const headers: Record<string, string> = {}\n for (const [key, value] of Object.entries(headerParams)) {\n headers[key] = queryScalarToStr(value)\n }\n const cookiePairs = Object.entries(cookieParams).map(\n ([key, value]) => `${key}=${queryScalarToStr(value)}`,\n )\n if (cookiePairs.length > 0) {\n headers.cookie = cookiePairs.join('; ')\n }\n\n // Declared content type from the spec: raw value for the outgoing header\n // (preserves parameters like charset), normalized for dispatch matching.\n let rawContentType: string | undefined\n let declaredContentType: string | undefined\n const contentSchema = route.requestBody?.contentSchema\n if (contentSchema && Object.keys(contentSchema).length > 0) {\n rawContentType = Object.keys(contentSchema)[0]\n declaredContentType = rawContentType.split(';')[0].trim().toLowerCase()\n }\n\n let requestBody: DirectedRequest['body']\n if (body !== null && body !== undefined) {\n if (declaredContentType === 'multipart/form-data' && isPlainObject(body)) {\n const form = new FormData()\n for (const [key, value] of Object.entries(body)) {\n if (value instanceof Uint8Array) {\n form.append(key, new Blob([value as BlobPart]))\n } else {\n form.append(key, queryScalarToStr(value))\n }\n }\n requestBody = form\n // fetch sets the multipart boundary header itself.\n } else if (declaredContentType === 'application/x-www-form-urlencoded' && isPlainObject(body)) {\n const params = new URLSearchParams()\n for (const [key, value] of Object.entries(body)) {\n params.append(key, queryScalarToStr(value))\n }\n requestBody = params\n } else if (isPlainObject(body) || Array.isArray(body)) {\n requestBody = JSON.stringify(body)\n // JSON-compatible types like application/json-patch+json keep their\n // declared content type; everything else is plain application/json.\n headers['content-type'] =\n declaredContentType !== undefined &&\n declaredContentType !== 'application/json' &&\n declaredContentType.includes('json')\n ? (rawContentType as string)\n : 'application/json'\n } else {\n requestBody = String(body)\n if (rawContentType !== undefined) {\n headers['content-type'] = rawContentType\n }\n }\n }\n\n return {\n method: route.method.toUpperCase(),\n url: url.toString(),\n headers,\n ...(requestBody !== undefined ? { body: requestBody } : {}),\n }\n}\n\n/** @internal Exported for the resource template path-argument reverse lookup. */\nexport function pathArgumentName(route: HTTPRoute, parameterName: string): string {\n for (const [argumentName, mapping] of Object.entries(route.parameterMap)) {\n if (mapping.location === 'path' && mapping.openapiName === parameterName) {\n return argumentName\n }\n }\n return parameterName\n}\n","/**\n * HTTP execution for generated components.\n *\n * Port of Python FastMCP's `OpenAPITool.run` / `OpenAPIResource.read`\n * (`fastmcp.server.providers.openapi.components`): bare fetch with a timeout,\n * Python-compatible error messages (they surface as tool errors, so clients\n * may match on them), JSON responses as structuredContent with the\n * `x-fastmcp-wrap-result` unwrap applied, non-JSON as text.\n */\n\nimport { ToolResult } from '../tool'\nimport { ResourceResult } from '../resource'\nimport type { HTTPRoute, JsonSchema } from './types'\nimport { buildRequest } from './director'\nimport { isPlainObject, truthy } from './internal'\n\nexport const DEFAULT_TIMEOUT_MS = 30_000\n\n/** HTTP client configuration for a generated OpenAPI server. */\nexport interface OpenAPIClientOptions {\n /**\n * Base URL for requests. Defaults to the spec's first `servers` entry\n * (with server variables filled from their defaults). Required when the\n * spec has no absolute server URL.\n */\n baseUrl?: string\n /** Default headers sent on every request. Request-specific headers win. */\n headers?: Record<string, string>\n /** Async header provider, resolved per request (e.g. a token refresher). */\n auth?: { getHeaders(): Promise<Record<string, string>> }\n /** Custom fetch implementation. Defaults to the global fetch. */\n fetch?: typeof globalThis.fetch\n /** Per-request timeout in milliseconds. Default 30 000. */\n timeoutMs?: number\n}\n\n/** @internal Resolved client with all defaults applied. */\nexport interface ResolvedClient {\n baseUrl: string\n headers: Record<string, string>\n auth?: { getHeaders(): Promise<Record<string, string>> }\n fetch: typeof globalThis.fetch\n timeoutMs: number\n}\n\n/** Substitute server variables with their defaults: `{region}` → `us-east-1`. */\nfunction fillServerVariables(url: string, variables: unknown): string {\n if (!isPlainObject(variables)) return url\n let filled = url\n for (const [name, variable] of Object.entries(variables)) {\n const fallback = isPlainObject(variable) ? variable.default : undefined\n filled = filled.split(`{${name}}`).join(typeof fallback === 'string' ? fallback : '')\n }\n return filled\n}\n\n/** @internal Resolve client options against the spec's servers entry. */\nexport function resolveClient(\n options: OpenAPIClientOptions,\n spec: Record<string, unknown>,\n): ResolvedClient {\n let baseUrl = options.baseUrl\n if (baseUrl === undefined) {\n const servers = spec.servers\n const first = Array.isArray(servers) ? servers[0] : undefined\n const serverUrl = isPlainObject(first) && typeof first.url === 'string' ? first.url : undefined\n if (serverUrl === undefined) {\n throw new Error(\n \"No server URL found in OpenAPI spec. Either add a 'servers' entry to the \" +\n 'spec or provide client.baseUrl explicitly.',\n )\n }\n baseUrl = fillServerVariables(serverUrl, first?.variables)\n }\n try {\n new URL(baseUrl)\n } catch {\n throw new Error(\n `OpenAPI base URL must be absolute, got '${baseUrl}'. Provide client.baseUrl explicitly.`,\n )\n }\n\n return {\n baseUrl,\n headers: options.headers ?? {},\n ...(options.auth !== undefined ? { auth: options.auth } : {}),\n fetch: options.fetch ?? globalThis.fetch,\n timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,\n }\n}\n\nfunction isTimeoutError(error: unknown): boolean {\n return (\n error instanceof Error &&\n (error.name === 'TimeoutError' || error.name === 'AbortError')\n )\n}\n\nasync function sendRequest(\n client: ResolvedClient,\n route: HTTPRoute,\n args: Record<string, unknown>,\n): Promise<Response> {\n let url: string\n let init: RequestInit\n try {\n const directed = buildRequest(route, args, client.baseUrl)\n const authHeaders = client.auth ? await client.auth.getHeaders() : {}\n // Client defaults merge under auth headers; directed headers win over\n // both. HTTP header names are case-insensitive, so merge on lowercase\n // keys — otherwise a parameter named X-Trace would ride ALONGSIDE a\n // default x-trace instead of replacing it.\n const headers: Record<string, string> = {}\n for (const source of [client.headers, authHeaders, directed.headers]) {\n for (const [name, value] of Object.entries(source)) {\n headers[name.toLowerCase()] = value\n }\n }\n url = directed.url\n init = {\n method: directed.method,\n headers,\n ...(directed.body !== undefined ? { body: directed.body } : {}),\n signal: AbortSignal.timeout(client.timeoutMs),\n }\n } catch (error) {\n const e = error as Error\n throw new Error(\n `Error building request for ${route.method.toUpperCase()} ${route.path}: ${e.name}: ${e.message}`,\n )\n }\n\n let response: Response\n try {\n response = await client.fetch(url, init)\n } catch (error) {\n if (isTimeoutError(error)) {\n throw new Error(`HTTP request timed out (${(error as Error).name})`)\n }\n const e = error as Error\n throw new Error(`Request error (${e.name}): ${e.message}`)\n }\n\n if (!response.ok) {\n let message = `HTTP error ${response.status}: ${response.statusText}`\n const text = await response.text().catch(() => '')\n if (text) message += ` - ${text}`\n throw new Error(message)\n }\n\n return response\n}\n\n/** Execute a tool call: send the HTTP request and convert the response. */\nexport async function runToolRequest(\n client: ResolvedClient,\n route: HTTPRoute,\n args: Record<string, unknown>,\n outputSchema: JsonSchema | null | undefined,\n): Promise<ToolResult> {\n const response = await sendRequest(client, route, args)\n const text = await response.text()\n\n let result: unknown\n try {\n result = JSON.parse(text)\n } catch {\n // Not JSON: return the raw text.\n return new ToolResult({ content: [{ type: 'text', text }] })\n }\n\n let structured: unknown\n if (outputSchema !== null && outputSchema !== undefined) {\n structured = truthy(outputSchema['x-fastmcp-wrap-result']) ? { result } : result\n } else if (!isPlainObject(result)) {\n structured = { result }\n } else {\n structured = result\n }\n // structuredContent must be a plain object on the wire; wrap anything that\n // slipped through (e.g. a backend returning an array against an object schema).\n if (!isPlainObject(structured)) {\n structured = { result: structured }\n }\n\n return new ToolResult({\n content: [{ type: 'text', text: JSON.stringify(structured) }],\n structuredContent: structured as Record<string, unknown>,\n })\n}\n\n/** Execute a resource read: send the HTTP request and convert the response. */\nexport async function readResourceRequest(\n client: ResolvedClient,\n route: HTTPRoute,\n args: Record<string, unknown>,\n uri: string,\n mimeType: string,\n): Promise<ResourceResult> {\n const response = await sendRequest(client, route, args)\n const contentType = (response.headers.get('content-type') ?? '').toLowerCase()\n\n if (contentType.includes('application/json')) {\n const result: unknown = JSON.parse(await response.text())\n return new ResourceResult([\n { uri, mimeType: 'application/json', text: JSON.stringify(result) },\n ])\n }\n if (contentType.includes('text/') || contentType.includes('application/xml')) {\n return new ResourceResult([{ uri, mimeType, text: await response.text() }])\n }\n const bytes = Buffer.from(await response.arrayBuffer())\n return new ResourceResult([{ uri, mimeType, blob: bytes.toString('base64') }])\n}\n","/**\n * createOpenAPIServer: build a FastMCP server from an OpenAPI 3.x spec.\n *\n * TypeScript port of Python FastMCP's `FastMCP.from_openapi` /\n * `OpenAPIProvider`. Components are generated eagerly: parse the spec into\n * routes, map each route to a component type, name it, derive its schemas,\n * and register it on a plain FastMCP with a forwarding handler that calls the\n * described HTTP API. Generated names and schemas match the Python\n * implementation byte for byte; the snapshots under `tests/fixtures/openapi/`\n * pin that contract.\n */\n\nimport { FastMCP } from '../FastMCP'\nimport type { FastMCPOptions } from '../FastMCP'\nimport type {\n ComponentFn,\n HTTPRoute,\n JsonSchema,\n OpenAPIComponent,\n OpenAPIResourceComponent,\n OpenAPIResourceTemplateComponent,\n OpenAPIToolComponent,\n RouteMap,\n RouteMapFn,\n} from './types'\nimport { isPlainObject, truthy, warn } from './internal'\nimport { loadSpec, parseOpenAPIToHttpRoutes } from './parser'\nimport { extractOutputSchemaFromResponses } from './schemas'\nimport { DEFAULT_ROUTE_MAPPINGS, determineRouteType } from './routing'\nimport { NameRegistry, generateDefaultName } from './naming'\nimport { pathArgumentName } from './director'\nimport {\n readResourceRequest,\n resolveClient,\n runToolRequest,\n} from './execute'\nimport type { OpenAPIClientOptions, ResolvedClient } from './execute'\n\nexport interface OpenAPIServerOptions {\n /** The OpenAPI 3.0/3.1 spec: a parsed object, or YAML/JSON text. */\n spec: Record<string, unknown> | string\n /** Server name. Default 'OpenAPI Server'. */\n name?: string\n /** Server version. Defaults to FastMCP's own default. */\n version?: string\n /** HTTP client configuration (base URL, headers, auth, fetch, timeout). */\n client?: OpenAPIClientOptions\n /** Route maps checked in order before the default (everything → tool). */\n routeMaps?: RouteMap[]\n /** Route-type hook, run after the route maps on every route. */\n routeMapFn?: RouteMapFn\n /** Component customization hook, called before each registration. */\n componentFn?: ComponentFn\n /** Overrides mapping operationId → component name. */\n names?: Record<string, string>\n /** Tags added to every generated component. */\n tags?: string[]\n /**\n * When true (default), tools advertise the output schema extracted from\n * the spec. When false, a permissive schema is advertised instead (the\n * wrap-result marker is preserved).\n */\n validateOutput?: boolean\n /** Remaining FastMCP options (auth, middleware, page sizes, ...). */\n serverOptions?: Omit<FastMCPOptions, 'name' | 'version'>\n}\n\nconst DEFAULT_MIME_TYPE = 'application/json'\n\nconst JSON_COMPATIBLE_TYPES = [\n 'application/json',\n 'application/vnd.api+json',\n 'application/hal+json',\n 'application/ld+json',\n 'text/json',\n] as const\n\n/** Primary MIME type from a route's success response; application/json fallback. */\nfunction extractMimeTypeFromRoute(route: HTTPRoute): string {\n if (!truthy(route.responses)) return DEFAULT_MIME_TYPE\n\n let responseInfo = undefined\n for (const statusCode of ['200', '201', '202', '204']) {\n if (statusCode in route.responses) {\n responseInfo = route.responses[statusCode]\n break\n }\n }\n if (responseInfo === undefined) {\n for (const [statusCode, respInfo] of Object.entries(route.responses)) {\n if (statusCode.startsWith('2')) {\n responseInfo = respInfo\n break\n }\n }\n }\n if (responseInfo === undefined || !truthy(responseInfo.contentSchema)) return DEFAULT_MIME_TYPE\n\n const contentTypes = Object.keys(responseInfo.contentSchema)\n if (contentTypes.length === 1) return contentTypes[0]\n\n for (const contentType of JSON_COMPATIBLE_TYPES) {\n if (contentType in responseInfo.contentSchema) return contentType\n }\n return contentTypes[0]\n}\n\n/** Expand a `resource://name/{a}/{b}` template with matched parameter values. */\nfunction expandTemplateUri(uriTemplate: string, params: Record<string, string>): string {\n let uri = uriTemplate\n for (const [name, value] of Object.entries(params)) {\n uri = uri.split(`{${name}}`).join(encodeURIComponent(value))\n }\n return uri\n}\n\n/** Map matched template params back to flat tool-argument names. */\nfunction templateArguments(\n route: HTTPRoute,\n params: Record<string, string>,\n): Record<string, unknown> {\n const args: Record<string, unknown> = {}\n for (const parameter of route.parameters) {\n if (parameter.location !== 'path') continue\n const argumentName = pathArgumentName(route, parameter.name)\n if (parameter.name in params) {\n args[argumentName] = params[parameter.name]\n continue\n }\n const normalizedName = parameter.name.replace(/-/g, '_')\n if (normalizedName in params) {\n args[argumentName] = params[normalizedName]\n }\n }\n return args\n}\n\n/**\n * Create a FastMCP server from an OpenAPI 3.0/3.1 specification. Every\n * operation becomes an MCP component (tool by default; see `routeMaps`)\n * whose handler calls the described HTTP endpoint.\n */\nexport function createOpenAPIServer(options: OpenAPIServerOptions): FastMCP {\n const spec = loadSpec(options.spec)\n const client = resolveClient(options.client ?? {}, spec)\n const routes = parseOpenAPIToHttpRoutes(spec)\n\n const server = new FastMCP({\n name: options.name ?? 'OpenAPI Server',\n ...(options.version !== undefined ? { version: options.version } : {}),\n ...options.serverOptions,\n })\n\n const routeMaps = [...(options.routeMaps ?? []), ...DEFAULT_ROUTE_MAPPINGS]\n const registry = new NameRegistry()\n const validateOutput = options.validateOutput ?? true\n\n for (const route of routes) {\n const routeMap = determineRouteType(route, routeMaps)\n let routeType = routeMap.mcpType\n\n if (options.routeMapFn !== undefined) {\n try {\n const result = options.routeMapFn(route, routeType)\n if (result !== null && result !== undefined) {\n routeType = result\n }\n } catch (error) {\n warn(\n `Error in routeMapFn for ${route.method} ${route.path}: ${(error as Error).message}. Using mapped type.`,\n )\n }\n }\n\n const componentName = generateDefaultName(route, options.names)\n const componentTags = [\n ...new Set([...route.tags, ...(routeMap.mcpTags ?? []), ...(options.tags ?? [])]),\n ].sort()\n\n if (routeType === 'tool') {\n createTool(server, client, route, componentName, componentTags, registry, validateOutput, options.componentFn)\n } else if (routeType === 'resource') {\n createResource(server, client, route, componentName, componentTags, registry, options.componentFn)\n } else if (routeType === 'resourceTemplate') {\n createTemplate(server, client, route, componentName, componentTags, registry, options.componentFn)\n }\n // 'exclude' routes are skipped.\n }\n\n return server\n}\n\nfunction applyComponentFn(\n componentFn: ComponentFn | undefined,\n route: HTTPRoute,\n component: OpenAPIComponent,\n): void {\n if (componentFn === undefined) return\n try {\n componentFn(route, component)\n } catch (error) {\n warn(\n `Error in componentFn for ${component.kind} '${component.name}': ${(error as Error).message}`,\n )\n }\n}\n\nfunction createTool(\n server: FastMCP,\n client: ResolvedClient,\n route: HTTPRoute,\n name: string,\n tags: string[],\n registry: NameRegistry,\n validateOutput: boolean,\n componentFn: ComponentFn | undefined,\n): void {\n let outputSchema = extractOutputSchemaFromResponses(\n route.responses,\n route.responseSchemas,\n route.openapiVersion,\n )\n\n if (!validateOutput && outputSchema !== null) {\n // Permissive schema: accept any object, but keep the wrap-result flag so\n // non-object responses still get wrapped.\n const permissive: JsonSchema = { type: 'object', additionalProperties: true }\n if (truthy(outputSchema['x-fastmcp-wrap-result'])) {\n permissive['x-fastmcp-wrap-result'] = true\n }\n outputSchema = permissive\n }\n\n const component: OpenAPIToolComponent = {\n kind: 'tool',\n name: registry.getUniqueName(name, 'tool'),\n description: route.description || route.summary || `Executes ${route.method} ${route.path}`,\n inputSchema: route.flatParamSchema,\n ...(outputSchema !== null ? { outputSchema } : {}),\n tags,\n }\n applyComponentFn(componentFn, route, component)\n\n server.tool(\n {\n name: component.name,\n description: component.description,\n inputSchema: component.inputSchema,\n ...(component.outputSchema !== undefined ? { outputSchema: component.outputSchema } : {}),\n tags: component.tags,\n },\n async (args: unknown) =>\n runToolRequest(client, route, isPlainObject(args) ? args : {}, component.outputSchema),\n )\n}\n\nfunction createResource(\n server: FastMCP,\n client: ResolvedClient,\n route: HTTPRoute,\n name: string,\n tags: string[],\n registry: NameRegistry,\n componentFn: ComponentFn | undefined,\n): void {\n const uniqueName = registry.getUniqueName(name, 'resource')\n const component: OpenAPIResourceComponent = {\n kind: 'resource',\n uri: `resource://${uniqueName}`,\n name: uniqueName,\n description: route.description || route.summary || `Represents ${route.path}`,\n mimeType: extractMimeTypeFromRoute(route),\n tags,\n }\n applyComponentFn(componentFn, route, component)\n\n server.resource(\n {\n uri: component.uri,\n name: component.name,\n description: component.description,\n mimeType: component.mimeType,\n tags: component.tags,\n },\n async () => readResourceRequest(client, route, {}, component.uri, component.mimeType),\n )\n}\n\nfunction createTemplate(\n server: FastMCP,\n client: ResolvedClient,\n route: HTTPRoute,\n name: string,\n tags: string[],\n registry: NameRegistry,\n componentFn: ComponentFn | undefined,\n): void {\n const uniqueName = registry.getUniqueName(name, 'resourceTemplate')\n\n // Template path parameters appear in the URI sorted alphabetically.\n const pathParams = route.parameters\n .filter((p) => p.location === 'path')\n .map((p) => p.name)\n .sort()\n let uriTemplate = `resource://${uniqueName}`\n if (pathParams.length > 0) {\n uriTemplate += '/' + pathParams.map((p) => `{${p}}`).join('/')\n }\n\n const parametersSchema: JsonSchema = {\n type: 'object',\n properties: Object.fromEntries(\n route.parameters\n .filter((p) => p.location === 'path')\n .map((p) => [\n p.name,\n {\n ...(isPlainObject(p.schema) ? p.schema : {}),\n ...(truthy(p.description) && !(isPlainObject(p.schema) && 'description' in p.schema)\n ? { description: p.description }\n : {}),\n },\n ]),\n ),\n required: route.parameters\n .filter((p) => p.location === 'path' && p.required)\n .map((p) => p.name),\n }\n\n const component: OpenAPIResourceTemplateComponent = {\n kind: 'resourceTemplate',\n uriTemplate,\n name: uniqueName,\n description: route.description || route.summary || `Template for ${route.path}`,\n mimeType: extractMimeTypeFromRoute(route),\n parameters: parametersSchema,\n tags,\n }\n applyComponentFn(componentFn, route, component)\n\n server.resource(\n {\n uri: component.uriTemplate,\n name: component.name,\n description: component.description,\n mimeType: component.mimeType,\n tags: component.tags,\n },\n async (params?: Record<string, string>) => {\n const matched = params ?? {}\n const concreteUri = expandTemplateUri(component.uriTemplate, matched)\n return readResourceRequest(\n client,\n route,\n templateArguments(route, matched),\n concreteUri,\n component.mimeType,\n )\n },\n )\n}\n\nexport type { OpenAPIClientOptions } from './execute'\nexport type {\n ComponentFn,\n HTTPRoute,\n HttpMethod,\n JsonSchema,\n MCPType,\n OpenAPIComponent,\n OpenAPIResourceComponent,\n OpenAPIResourceTemplateComponent,\n OpenAPIToolComponent,\n ParameterInfo,\n ParameterLocation,\n RequestBodyInfo,\n ResponseInfo,\n RouteMap,\n RouteMapFn,\n} from './types'\n","import { FastMCP } from '../FastMCP'\nimport type { ToolConfig } from '../FastMCP'\nimport { contextStore } from '../context'\nimport type { Component } from './components'\nimport type { Visibility } from './types'\n\nexport interface EntrypointConfig {\n name: string\n description: string\n title?: string\n}\n\nexport interface BackendToolConfig {\n name: string\n description: string\n title?: string\n /** Defaults to ['app']. Pass ['model', 'app'] to also expose to the LLM. */\n visibility?: Visibility[]\n}\n\nexport interface FastMCPAppOptions {\n name: string\n version?: string\n}\n\nexport class FastMCPApp {\n readonly server: FastMCP\n\n constructor(options: FastMCPAppOptions) {\n this.server = new FastMCP({ name: options.name, version: options.version })\n }\n\n /**\n * Register an entry-point tool.\n * Entry-points are visible to the LLM (visibility: ['model', 'app']) and\n * automatically linked to a generated ui:// resource URI.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n entrypoint(config: EntrypointConfig, handler: (args?: any) => Component): void {\n const resourceUri = `ui://${config.name}`\n const toolConfig: ToolConfig = {\n name: config.name,\n description: config.description,\n ...(config.title !== undefined ? { title: config.title } : {}),\n ui: { visibility: ['model', 'app'], resourceUri },\n }\n this.server.tool(toolConfig, handler)\n // Stub resource so resources/read on the ui:// URI doesn't 404.\n // Replaced by the real UI runtime bundle when bundling is implemented.\n this.server.resource(\n { uri: resourceUri, mimeType: 'text/html;profile=mcp-app', name: config.name },\n () => `<!doctype html><html><head><meta charset=\"utf-8\"></head><body><!-- fastmcp ui-runtime placeholder --></body></html>`,\n )\n }\n\n /**\n * Register a backend tool.\n * Backend tools are hidden from listTools by default (visibility: ['app']).\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n backendTool(config: BackendToolConfig, handler: (args: any) => unknown): void {\n const visibility = config.visibility ?? ['app']\n const toolConfig: ToolConfig = {\n name: config.name,\n description: config.description,\n ...(config.title !== undefined ? { title: config.title } : {}),\n ui: { visibility },\n }\n this.server.tool(toolConfig, handler)\n }\n\n /**\n * Returns a reference to a tool that resolves to the correct external name\n * (including any mount prefix) when evaluated inside a request handler.\n * Call inside a handler function — not at definition time.\n */\n toolRef(name: string): string {\n const ctx = contextStore.getStore()\n if (!ctx) return name\n return ctx.resolveToolName(name)\n }\n}\n","import { contextStore } from '../context'\n\n/**\n * Resolve a logical tool name to its current external name inside a request\n * handler, accounting for any mount prefix applied by a parent server.\n *\n * Use this in providers that are built on bare FastMCP (not FastMCPApp) to\n * produce mount-prefix–aware action strings for Button components.\n */\nexport function actionRef(name: string): string {\n return contextStore.getStore()?.resolveToolName(name) ?? name\n}\n","import { runInNewContext } from 'node:vm'\nimport { FastMCP } from '../FastMCP'\nimport { ToolResult } from '../tool'\nimport { COMPONENT_CATALOG } from './components'\nimport * as Components from './components'\n\nexport class GenerativeUI {\n readonly server: FastMCP\n\n constructor() {\n this.server = new FastMCP({ name: 'generative-ui' })\n\n // Regular LLM tool — catalog lookup, always returns structured data\n this.server.tool(\n {\n name: 'search_components',\n description: 'List available UI components with their types and descriptions',\n },\n () => new ToolResult({\n content: [{ type: 'text', text: JSON.stringify(COMPONENT_CATALOG) }],\n }),\n )\n\n // LLM-visible tool — executes component code in an isolated sandbox\n this.server.tool(\n {\n name: 'generate_ui',\n description: 'Execute a UI component expression and return the component tree. Use search_components to discover available component APIs first.',\n inputSchema: {\n type: 'object',\n properties: {\n code: { type: 'string', description: 'A JavaScript expression using the component builders (Column, Text, Button, etc.) that evaluates to a component tree' },\n },\n required: ['code'],\n },\n },\n (args: Record<string, unknown>) => {\n const { code } = args as { code: string }\n // Sandbox: only the component builder functions are in scope — no Node globals\n const sandbox: Record<string, unknown> = { ...Components }\n delete sandbox['COMPONENT_CATALOG']\n\n try {\n // NOTE: vm.runInNewContext is NOT a true security sandbox — prototype chain\n // escapes are possible. Do not execute untrusted code in production.\n return runInNewContext(code, sandbox, { timeout: 2000 })\n } catch (err) {\n throw new Error(`[generate_ui] ${err instanceof Error ? err.message : String(err)}`)\n }\n },\n )\n }\n}\n","// ---------------------------------------------------------------------------\n// Component tree types\n// ---------------------------------------------------------------------------\n\nexport interface Component {\n type: string\n props?: Record<string, unknown>\n children?: Component[]\n}\n\n// If-node carries builder methods but they must be non-enumerable so\n// toEqual/JSON.stringify treat the node as a plain object.\nexport interface IfNode extends Component {\n type: 'if'\n branches: Array<{ condition: string; node: Component }>\n fallback?: Component\n elif(condition: string, node: Component): IfNode\n else(node: Component): Component\n}\n\n// ---------------------------------------------------------------------------\n// Component catalog — used by GenerativeUI.search_components\n// ---------------------------------------------------------------------------\n\nexport interface CatalogEntry {\n type: string\n description: string\n}\n\nexport const COMPONENT_CATALOG: CatalogEntry[] = [\n { type: 'column', description: 'Vertical stack layout. Props: gap, align, padding. Children: any components.' },\n { type: 'row', description: 'Horizontal stack layout. Props: gap, align, justify, wrap. Children: any components.' },\n { type: 'grid', description: 'CSS grid layout. Props: columns, gap. Children: any components.' },\n { type: 'text', description: 'Text display. Props: content (string or Rx), variant (heading|body|caption|code), color.' },\n { type: 'badge', description: 'Status badge. Props: text, color, variant.' },\n { type: 'table', description: 'Data table. Props: columns (string[]), rows (string[][]). No children.' },\n { type: 'chart-bar', description: 'Bar chart. Props: data (object[]), xKey, yKey, title.' },\n { type: 'chart-line', description: 'Line chart. Props: data (object[]), xKey, yKey, title.' },\n { type: 'chart-area', description: 'Area chart. Props: data (object[]), xKey, yKey, title.' },\n { type: 'chart-pie', description: 'Pie chart. Props: data (object[]), labelKey, valueKey, title.' },\n { type: 'input', description: 'Form text input. Props: name, label, type (text|email|number|password), placeholder, required.' },\n { type: 'select', description: 'Dropdown select. Props: name, label, options (string[] or {value,label}[]), required.' },\n { type: 'button', description: 'Clickable button. Props: label, action (tool name string), variant, disabled.' },\n { type: 'if', description: 'Conditional rendering. branches: [{condition, node}], fallback.' },\n { type: 'foreach', description: 'Dynamic list. Props: items (binding expression). Children: [template].' },\n { type: 'rx', description: 'Reactive value. Props: expression (client-side state binding). Embeddable as prop.' },\n]\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction withChildren(type: string, props?: Record<string, unknown>, children?: Component[]): Component {\n const node: Component = { type }\n if (props && Object.keys(props).length > 0) node.props = props\n if (children && children.length > 0) node.children = children\n return node\n}\n\nfunction withProps(type: string, props: Record<string, unknown>): Component {\n return { type, props }\n}\n\n// ---------------------------------------------------------------------------\n// Layout\n// ---------------------------------------------------------------------------\n\nexport function Column(props?: Record<string, unknown>, children?: Component[]): Component {\n return withChildren('column', props, children)\n}\n\nexport function Row(props?: Record<string, unknown>, children?: Component[]): Component {\n return withChildren('row', props, children)\n}\n\nexport function Grid(props?: Record<string, unknown>, children?: Component[]): Component {\n return withChildren('grid', props, children)\n}\n\n// ---------------------------------------------------------------------------\n// Data display\n// ---------------------------------------------------------------------------\n\nexport function Text(content: string | Component, extraProps?: Record<string, unknown>): Component {\n return withProps('text', { content, ...extraProps })\n}\n\nexport function Badge(text: string, extraProps?: Record<string, unknown>): Component {\n return withProps('badge', { text, ...extraProps })\n}\n\nexport function Table(props: { columns: string[]; rows: string[][]; [key: string]: unknown }): Component {\n return withProps('table', props as Record<string, unknown>)\n}\n\n// ---------------------------------------------------------------------------\n// Charts\n// ---------------------------------------------------------------------------\n\nexport function Bar(props: Record<string, unknown>): Component {\n return withProps('chart-bar', props)\n}\n\nexport function Line(props: Record<string, unknown>): Component {\n return withProps('chart-line', props)\n}\n\nexport function Area(props: Record<string, unknown>): Component {\n return withProps('chart-area', props)\n}\n\nexport function Pie(props: Record<string, unknown>): Component {\n return withProps('chart-pie', props)\n}\n\n// ---------------------------------------------------------------------------\n// Forms\n// ---------------------------------------------------------------------------\n\nexport function Input(props: Record<string, unknown>): Component {\n return withProps('input', props)\n}\n\nexport function Select(props: Record<string, unknown>): Component {\n return withProps('select', props)\n}\n\nexport function Button(props: Record<string, unknown>): Component {\n return withProps('button', props)\n}\n\n// ---------------------------------------------------------------------------\n// Control flow — If with non-enumerable builder methods\n// ---------------------------------------------------------------------------\n\nfunction makeIfNode(\n branches: Array<{ condition: string; node: Component }>,\n fallback?: Component,\n): IfNode {\n const node = { type: 'if' as const, branches, ...(fallback !== undefined ? { fallback } : {}) } as IfNode\n\n Object.defineProperty(node, 'elif', {\n enumerable: false,\n value(condition: string, child: Component): IfNode {\n return makeIfNode([...branches, { condition, node: child }], fallback)\n },\n })\n\n Object.defineProperty(node, 'else', {\n enumerable: false,\n value(child: Component): Component {\n return makeIfNode(branches, child)\n },\n })\n\n return node\n}\n\nexport function If(condition: string, then: Component, fallback?: Component): IfNode {\n return makeIfNode([{ condition, node: then }], fallback)\n}\n\n// ---------------------------------------------------------------------------\n// Dynamic list\n// ---------------------------------------------------------------------------\n\nexport function ForEach(items: string, template: Component): Component {\n return { type: 'foreach', props: { items }, children: [template] }\n}\n\n// ---------------------------------------------------------------------------\n// Reactive state binding\n// ---------------------------------------------------------------------------\n\nexport function Rx(expression: string): Component {\n return withProps('rx', { expression })\n}\n","import { FastMCP } from '../../FastMCP'\nimport { actionRef } from '../actionRef'\nimport { Column, Text, Button } from '../components'\n\nexport class Approval {\n readonly server: FastMCP\n\n constructor() {\n this.server = new FastMCP({ name: 'approval' })\n\n this.server.tool(\n {\n name: 'approval_request',\n description: 'Present a confirm/deny approval card to the user',\n inputSchema: {\n type: 'object',\n properties: {\n message: { type: 'string', description: 'The question or action to seek approval for' },\n },\n required: ['message'],\n },\n ui: { visibility: ['model', 'app'] },\n },\n (args: Record<string, unknown>) => {\n const message = (args.message as string) ?? 'Approve?'\n return Column({}, [\n Text(message),\n Button({ label: 'Confirm', action: actionRef('approval_confirm') }),\n Button({ label: 'Deny', action: actionRef('approval_deny'), variant: 'secondary' }),\n ])\n },\n )\n\n this.server.resource(\n { uri: 'ui://approval_request', mimeType: 'text/html;profile=mcp-app', name: 'approval_request' },\n () => `<!doctype html><html><head><meta charset=\"utf-8\"></head><body><!-- fastmcp ui-runtime placeholder --></body></html>`,\n )\n\n this.server.tool(\n {\n name: 'approval_confirm',\n description: 'Record a confirmed approval decision',\n ui: { visibility: ['app'] },\n },\n () => ({ decision: 'approved' as const }),\n )\n\n this.server.tool(\n {\n name: 'approval_deny',\n description: 'Record a denied approval decision',\n ui: { visibility: ['app'] },\n },\n () => ({ decision: 'denied' as const }),\n )\n }\n}\n","import { FastMCP } from '../../FastMCP'\nimport { actionRef } from '../actionRef'\nimport { Row, Button } from '../components'\n\nexport class Choice {\n readonly server: FastMCP\n\n constructor() {\n this.server = new FastMCP({ name: 'choice' })\n\n this.server.tool(\n {\n name: 'choice_present',\n description: 'Present a list of options for the user to choose from',\n inputSchema: {\n type: 'object',\n properties: {\n question: { type: 'string', description: 'The question to ask the user' },\n options: { type: 'array', items: { type: 'string' }, description: 'The options to present' },\n },\n required: ['question', 'options'],\n },\n ui: { visibility: ['model', 'app'] },\n },\n (args: Record<string, unknown>) => {\n const options = (args.options as string[]) ?? []\n return Row(\n {},\n // Each button carries its option value as args so the host can\n // forward it to choice_select without extra state.\n options.map((opt) =>\n Button({ label: opt, action: actionRef('choice_select'), args: { option: opt } }),\n ),\n )\n },\n )\n\n this.server.resource(\n { uri: 'ui://choice_present', mimeType: 'text/html;profile=mcp-app', name: 'choice_present' },\n () => `<!doctype html><html><head><meta charset=\"utf-8\"></head><body><!-- fastmcp ui-runtime placeholder --></body></html>`,\n )\n\n this.server.tool(\n {\n name: 'choice_select',\n description: \"Record the user's selection\",\n ui: { visibility: ['app'] },\n },\n (args: Record<string, unknown>) => ({ selected: args.option as string }),\n )\n }\n}\n","import { randomUUID } from 'node:crypto'\nimport { FastMCP } from '../../FastMCP'\nimport { ResourceResult } from '../../resource'\nimport { contextStore } from '../../context'\nimport { actionRef } from '../actionRef'\nimport { Column, Text, Button } from '../components'\n\nexport interface FileHandle {\n handle: string\n name: string\n mimeType: string\n data: Buffer\n}\n\nexport interface FileStorageAdapter {\n save(handle: string, file: FileHandle): void\n load(handle: string): FileHandle | undefined\n delete(handle: string): void\n}\n\n/**\n * Default in-memory adapter with TTL-based expiry. Expiry is checked lazily on\n * every save/load (no timer), so it costs nothing when idle. This is the\n * era-agnostic cleanup mechanism for uploaded files: unlike session-close\n * cleanup (ctx.onClose, below), which only fires for transports that actually\n * have a session (stdio, legacy HTTP), TTL expiry works uniformly for\n * stateless modern (2026-07-28) HTTP requests too, where there is no session\n * to close.\n */\nfunction makeInMemoryAdapter(ttlMs: number): FileStorageAdapter {\n const store = new Map<string, { file: FileHandle; expiresAt: number }>()\n function sweep(): void {\n const now = Date.now()\n for (const [handle, entry] of store) {\n if (entry.expiresAt <= now) store.delete(handle)\n }\n }\n return {\n save: (handle, file) => {\n sweep()\n store.set(handle, { file, expiresAt: Date.now() + ttlMs })\n },\n load: (handle) => {\n sweep()\n return store.get(handle)?.file\n },\n delete: (handle) => {\n store.delete(handle)\n },\n }\n}\n\nexport interface FileUploadOptions {\n storage?: FileStorageAdapter\n /**\n * How long (ms) an uploaded file is retained by the default in-memory storage\n * adapter before automatic expiry. Only applies when no custom `storage` is\n * supplied. Default: 30 minutes.\n */\n ttlMs?: number\n}\n\nexport class FileUpload {\n readonly server: FastMCP\n private readonly _storage: FileStorageAdapter\n\n constructor(options?: FileUploadOptions) {\n this._storage = options?.storage ?? makeInMemoryAdapter(options?.ttlMs ?? 30 * 60_000)\n this.server = new FastMCP({ name: 'file-upload' })\n\n const storage = this._storage\n\n this.server.tool(\n {\n name: 'file_upload_open',\n description: 'Open a file picker UI for the user to upload a file',\n inputSchema: {\n type: 'object',\n properties: {\n prompt: { type: 'string', description: 'Instructions shown above the file picker' },\n },\n },\n ui: { visibility: ['model', 'app'] },\n },\n (args: Record<string, unknown>) => {\n return Column({}, [\n Text((args.prompt as string | undefined) ?? 'Upload a file'),\n Button({ label: 'Choose file', action: actionRef('file_upload_submit') }),\n ])\n },\n )\n\n this.server.tool(\n {\n name: 'file_upload_submit',\n description: 'Receive and store uploaded file bytes server-side',\n inputSchema: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'File name' },\n mimeType: { type: 'string', description: 'MIME type of the file' },\n data: { type: 'string', description: 'Base64-encoded file content' },\n },\n required: ['name', 'mimeType', 'data'],\n },\n ui: { visibility: ['app'] },\n },\n (args: Record<string, unknown>) => {\n // The handle is the durable, portable identifier for this upload — it works\n // the same way whether the caller is on a session-based transport (stdio,\n // legacy HTTP) or a stateless modern (2026-07-28) HTTP request: the model\n // threads it back as an ordinary tool argument on later calls (file_upload_delete,\n // reading the ui://files/{handle} resource), the same explicit-handle pattern\n // the spec recommends in place of session state.\n const handle = randomUUID()\n const fileData = Buffer.from(args.data as string, 'base64')\n storage.save(handle, {\n handle,\n name: args.name as string,\n mimeType: args.mimeType as string,\n data: fileData,\n })\n\n // Best-effort early cleanup for transports that actually have a session\n // (stdio, legacy HTTP) — a no-op on stateless modern HTTP, where there is no\n // session to close. The real, era-agnostic cleanup is the storage adapter's\n // own TTL expiry (see makeInMemoryAdapter / FileUploadOptions.ttlMs).\n contextStore.getStore()?.onClose(() => storage.delete(handle))\n\n const uri = `ui://files/${handle}`\n return { handle, uri }\n },\n )\n\n this.server.tool(\n {\n name: 'file_upload_delete',\n description: 'Delete a previously uploaded file by its handle',\n inputSchema: {\n type: 'object',\n properties: {\n handle: { type: 'string', description: 'The file handle returned by file_upload_submit' },\n },\n required: ['handle'],\n },\n ui: { visibility: ['app'] },\n },\n (args: Record<string, unknown>) => {\n const handle = args.handle as string\n storage.delete(handle)\n return { deleted: handle }\n },\n )\n\n this.server.resource(\n { uri: 'ui://files/{handle}', name: 'uploaded-file', mimeType: 'application/octet-stream' },\n (params) => {\n const h = params?.handle\n if (!h) throw new Error('Missing file handle')\n const file = storage.load(h)\n if (!file) throw new Error(`File not found: ${h}`)\n const uri = `ui://files/${h}`\n if (file.mimeType.startsWith('text/')) {\n return new ResourceResult([{ uri, mimeType: file.mimeType, text: file.data.toString('utf8') }])\n }\n return new ResourceResult([{ uri, mimeType: file.mimeType, blob: file.data.toString('base64') }])\n },\n )\n }\n}\n","import type { StandardSchemaV1 } from '@standard-schema/spec'\nimport { FastMCP } from '../../FastMCP'\nimport { toJsonSchema } from '../../tool'\nimport { actionRef } from '../actionRef'\nimport { Column, Input, Select, Button } from '../components'\n\nexport interface FormInputOptions {\n name: string\n description: string\n schema: StandardSchemaV1\n}\n\ntype FieldSchema = Record<string, unknown>\n\nfunction buildField(fieldName: string, fieldSchema: FieldSchema, required: string[]) {\n const isRequired = required.includes(fieldName)\n const type = fieldSchema.type as string | undefined\n if (Array.isArray(fieldSchema.enum)) {\n return Select({ name: fieldName, label: fieldName, options: fieldSchema.enum as string[], required: isRequired })\n }\n if (type === 'number' || type === 'integer') {\n return Input({ name: fieldName, label: fieldName, type: 'number', required: isRequired })\n }\n return Input({ name: fieldName, label: fieldName, type: 'text', required: isRequired })\n}\n\nasync function validateWithSchema(\n schema: StandardSchemaV1,\n data: unknown,\n): Promise<{ valid: true; value: unknown } | { valid: false; errors: Record<string, string> }> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const result = await (schema['~standard'].validate as (v: unknown) => Promise<any>)(data)\n if (result.issues && result.issues.length > 0) {\n const errors: Record<string, string> = {}\n for (const issue of result.issues) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const path = issue.path?.map((p: any) => String(typeof p === 'object' ? p.key : p)).join('.') ?? 'root'\n errors[path] = String(issue.message)\n }\n return { valid: false, errors }\n }\n return { valid: true, value: result.value }\n}\n\nexport class FormInput {\n readonly server: FastMCP\n\n constructor(options: FormInputOptions) {\n this.server = new FastMCP({ name: options.name })\n const { name, description, schema } = options\n const submitName = `${name}_submit`\n\n this.server.resource(\n { uri: `ui://${name}`, mimeType: 'text/html;profile=mcp-app', name },\n () => `<!doctype html><html><head><meta charset=\"utf-8\"></head><body><!-- fastmcp ui-runtime placeholder --></body></html>`,\n )\n\n this.server.tool(\n { name, description, ui: { visibility: ['model', 'app'] } },\n async () => {\n // Use the shared extractor so Zod, Valibot, ArkType, etc. all work.\n const jsonSchema = await toJsonSchema(schema, `form \"${name}\"`)\n const properties = (jsonSchema.properties ?? {}) as Record<string, FieldSchema>\n const required = (jsonSchema.required ?? []) as string[]\n\n const fields = Object.entries(properties).map(([fieldName, fieldSchema]) =>\n buildField(fieldName, fieldSchema, required),\n )\n\n return Column({}, [...fields, Button({ label: 'Submit', action: actionRef(submitName) })])\n },\n )\n\n this.server.tool(\n {\n name: submitName,\n description: `Submit ${name} form data`,\n inputSchema: {\n type: 'object',\n properties: {\n data: { type: 'object', description: 'Form field values keyed by field name' },\n },\n required: ['data'],\n },\n ui: { visibility: ['app'] },\n },\n async (args: Record<string, unknown>) => {\n const result = await validateWithSchema(schema, args.data)\n if (!result.valid) {\n return { errors: result.errors }\n }\n return result.value\n },\n )\n }\n}\n"],"mappings":"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","names":["ProtocolError","ProtocolErrorCode","Server","randomUUID","ProtocolError","ProtocolErrorCode","ProtocolError","ProtocolErrorCode","ProtocolError","ProtocolErrorCode","Server","ctx","randomUUID","randomUUID","existing","location","JSON_COMPATIBLE_TYPES","randomUUID","randomUUID"]}
1
+ {"version":3,"sources":["../src/server/FastMCP.ts","../src/server/auth/types.ts","../src/server/legacyEventStore.ts","../src/server/context.ts","../src/server/httpContext.ts","../src/server/env.ts","../src/server/middleware.ts","../src/server/transform.ts","../src/server/tool.ts","../src/server/mrtr.ts","../src/server/resource.ts","../src/server/apps/types.ts","../src/server/prompt.ts","../src/server/completion.ts","../src/server/auth/authorization.ts","../src/server/auth/multiAuth.ts","../src/server/auth/verifiers/jwt.ts","../src/server/auth/verifiers/introspection.ts","../src/server/auth/verifiers/static.ts","../src/server/auth/oauth/provider.ts","../src/server/auth/oauth/proxy.ts","../src/server/proxy.ts","../src/server/openapi/internal.ts","../src/server/openapi/parser.ts","../src/server/openapi/jsonSchema.ts","../src/server/openapi/schemas.ts","../src/server/openapi/routing.ts","../src/server/openapi/naming.ts","../src/server/openapi/director.ts","../src/server/openapi/execute.ts","../src/server/openapi/index.ts","../src/server/apps/FastMCPApp.ts","../src/server/apps/actionRef.ts","../src/server/apps/generative.ts","../src/server/apps/components.ts","../src/server/apps/providers/Approval.ts","../src/server/apps/providers/Choice.ts","../src/server/apps/providers/FileUpload.ts","../src/server/apps/providers/FormInput.ts"],"sourcesContent":["import type { NodeStreamableHTTPServerTransport } from \"@modelcontextprotocol/node\";\nimport { hostHeaderValidation, originValidation } from \"@modelcontextprotocol/node\";\nimport type { OAuthServerProvider } from \"@modelcontextprotocol/server-legacy/auth\";\nimport { ProtocolError, ProtocolErrorCode, ResourceNotFoundError, Server, createMcpHandler, legacyStatelessFallback, isLegacyRequest, isJsonContentType, createRequestStateCodec, localhostAllowedHostnames, localhostAllowedOrigins, assertCompleteRequestPrompt, assertCompleteRequestResourceTemplate } from \"@modelcontextprotocol/server\";\nimport type { Transport, AuthInfo, ListToolsResult, GetPromptResult, CompleteRequestParams, CompleteResult, McpHttpHandler, LegacyHttpHandler, McpHandlerRequestOptions, CacheHint, RequestStateCodec, ServerContext, ServerEventBus } from \"@modelcontextprotocol/server\";\n\n// Not exported by @modelcontextprotocol/server (CacheableResultMethod is internal-only);\n// mirrors its CACHEABLE_RESULT_METHODS literal union (SEP-2549 cacheable operations).\ntype CacheableResultMethod =\n | 'tools/list'\n | 'prompts/list'\n | 'resources/list'\n | 'resources/templates/list'\n | 'resources/read'\n | 'server/discover'\nimport type { StandardSchemaV1 } from '@standard-schema/spec'\nimport { randomUUID } from 'node:crypto'\nimport type { Readable, Writable } from 'node:stream'\nimport type { Server as HttpServer, IncomingMessage, ServerResponse } from 'node:http'\nimport type { AddressInfo } from 'node:net'\nimport { AuthorizationError } from './auth/types'\nimport type { TokenVerifier, AccessToken } from './auth/types'\nimport type { RequestVerifier } from './auth/types'\nimport { isRequestVerifier } from './auth/types'\nimport type { AuthCheck } from './auth/authorization'\nimport { BoundedEventStore, LEGACY_SSE_RETRY_MS } from './legacyEventStore'\nimport { contextStore, createContext, SESSION_CLOSE_CALLBACKS_KEY } from './context'\nimport type { McpContext } from './context'\nimport { resolveSensitiveHeaders, nodeRequestToHttpContext } from './httpContext'\nimport { envBool } from './env'\nimport { runMiddlewareChain } from './middleware'\nimport type { Middleware } from './middleware'\nimport { applyTransformChain } from './transform'\nimport type { Transform, ToolView, ResourceView, PromptView, SynthesizedTool } from './transform'\nimport { convertResult, toJsonSchema, validateInput, ToolResult } from './tool'\nimport { isInputRequiredResult } from './mrtr'\nimport {\n attachResourceUiMeta,\n convertResourceResult,\n isUriTemplate,\n matchTemplate,\n ResourceResult,\n} from './resource'\nimport type { ResourceConfig } from './resource'\nimport { UI_EXTENSION_KEY, UI_RESOURCE_MIME_TYPE, isUiCapable } from './apps/types'\nimport type { UiToolMeta } from './apps/types'\nimport { convertPromptResult, PromptResult } from './prompt'\nimport type { PromptConfig } from './prompt'\nimport { normalizeCompletion, EMPTY_COMPLETION } from './completion'\n\nfunction prefixResourceUri(uri: string, prefix: string): string {\n const idx = uri.indexOf('://')\n if (idx === -1) return `${prefix}/${uri}`\n return `${uri.slice(0, idx + 3)}${prefix}/${uri.slice(idx + 3)}`\n}\n\nexport interface OAuthConfig {\n /** OAuth server provider implementing the authorization and token flow. */\n provider: OAuthServerProvider\n /**\n * Issuer URL for the OAuth server (used in metadata endpoints).\n * Defaults to the HTTP server's bound address when not specified.\n */\n issuerUrl?: URL\n /** Scopes supported by this server, advertised in OAuth metadata. */\n scopes?: string[]\n}\n\nexport interface FastMCPOptions {\n name: string\n version?: string\n /**\n * Bearer-token verifier, or a RequestVerifier for header-based\n * (trusted-proxy) deployments. See each type's docs. A RequestVerifier\n * applies to HTTP transports only; stdio's FASTMCP_CLI_AUTH_TOKEN needs a\n * TokenVerifier. When both `oauth` and `auth` are set, `oauth` serves the\n * endpoint and `auth` is ignored.\n */\n auth?: TokenVerifier | RequestVerifier\n /** Full OAuth 2.1 server with Dynamic Client Registration support. */\n oauth?: OAuthConfig\n /**\n * HTTP request context tuning for `ctx.http`. `redactHeaders` adds names to\n * the sensitive set withheld from `ctx.http.headers` (defaults:\n * authorization, cookie, proxy-authorization, mcp-session-id); use it for\n * deployment-specific credentials such as a proxy shared-secret header.\n * `exposeHeaders` removes names from the set; it is the explicit, greppable\n * opt-out. Withheld names are listed in `ctx.http.redactedHeaderNames`.\n * Redaction applies to `ctx.http` only; a RequestVerifier always sees the\n * full wire headers.\n */\n http?: { redactHeaders?: string[]; exposeHeaders?: string[] }\n /** Maximum number of tools returned per listTools page. Default: 50. */\n toolsPageSize?: number\n /** Maximum number of resources (or templates) returned per page. Default: 50. */\n resourcesPageSize?: number\n /** Maximum number of prompts returned per prompts/list page. Default: 50. */\n promptsPageSize?: number\n /** Middleware applied to every request in registration order. */\n middleware?: Middleware[]\n /** Transforms applied to component list responses in registration order. */\n transforms?: Transform[]\n /**\n * Cache hints (`ttlMs` / `cacheScope`) for the 2026-07-28 protocol revision's\n * cacheable results (`tools/list`, `prompts/list`, `resources/list`,\n * `resources/templates/list`, `resources/read`, `server/discover`), keyed by\n * operation. Only affects modern (2026-07-28) responses — 2025-era responses\n * never carry these fields. Omitted operations (or omitting this option\n * entirely) keep the conservative defaults (`ttlMs: 0`, `cacheScope: 'private'`).\n * Applies uniformly per operation; per-resource cache hints are not currently\n * supported (that per-registration override is only available through the\n * SDK's high-level `McpServer.registerResource`, which FastMCP does not use).\n */\n cacheHints?: Partial<Record<CacheableResultMethod, CacheHint>>\n /**\n * HMAC-SHA256 integrity protection for multi-round-trip `requestState`\n * (protocol revision 2026-07-28) — see `ctx.requestState()` / `ctx.mintRequestState()`.\n * Backed by the SDK's `createRequestStateCodec`. When omitted, `requestState` passes\n * through unverified (the raw wire string) — the client can read and tamper with it,\n * so this MUST be configured for any flow whose `requestState` influences\n * authorization, resource access, or business logic.\n */\n requestState?: {\n /** HMAC secret. A `string` is UTF-8-encoded; MUST be at least 32 bytes (256 bits). */\n key: Uint8Array | string\n /** How long a minted `requestState` stays valid, in seconds. Default: 600 (10 minutes). */\n ttlSeconds?: number\n /** Binds a minted `requestState` to, e.g., the authenticated principal and/or the\n * originating method — a value minted under one binding is rejected when echoed\n * under a different one. See `RequestStateCodecOptions.bind`. */\n bind?: (ctx: ServerContext) => string\n }\n /**\n * Multi-round-trip (`inputRequired`) serving knobs (protocol revision 2026-07-28).\n * On 2026-era requests the client fulfils `input_required` returns directly; on\n * 2025-era connections the SDK's legacy shim fulfils them server-side (real\n * server→client requests + handler re-entry) — so handlers written with\n * `inputRequired(...)` serve both eras unchanged.\n */\n inputRequired?: {\n /** Handler re-entries per originating request before the shim fails (legacy era\n * only). Default: 8. */\n maxRounds?: number\n /** Per-leg timeout (ms) for the legacy shim's embedded server→client requests.\n * Default: 600_000 (10 minutes) — human-paced, deliberately above the 60s protocol default. */\n roundTimeoutMs?: number\n /** `false` disables the legacy shim: an `inputRequired(...)` return on a 2025-era\n * request fails loudly instead of being bridged. Default: true. */\n legacyShim?: boolean\n }\n /**\n * The change-event bus modern (2026-07-28) `subscriptions/listen` streams\n * subscribe to, and `tool()`/`resource()`/`prompt()` registration publishes\n * change events onto. Defaults to an in-process bus, which is correct for a\n * single server process. Supply your own `ServerEventBus` implementation over a\n * shared pub/sub backend (e.g. Redis) for a horizontally-scaled deployment,\n * where a `subscriptions/listen` stream and the request that changed the list it\n * cares about may land on different processes.\n */\n eventBus?: ServerEventBus\n /**\n * DNS-rebinding protection for the HTTP listener started by `run()`: validates\n * the `Host` and `Origin` request headers (port-agnostic, by hostname) and rejects\n * mismatches with `403`. Defends localhost servers against a malicious web page\n * whose DNS rebinds to `127.0.0.1` (MCP transport security best practice).\n *\n * This option does not apply to `fetch()`, which has no bind address from which\n * to infer a trusted host. A framework embedding `fetch()` owns Host/Origin\n * validation at its HTTP boundary. stdio is unaffected.\n *\n * Default posture (option omitted): protection auto-enables when, and only when,\n * `run()` binds the HTTP server to a loopback host (`127.0.0.1`, `::1`,\n * `localhost`) — the deployment the attack targets. A server bound to a routable\n * interface (e.g. `0.0.0.0` or a public host) is left open by default, because a\n * localhost-only allowlist would reject its legitimate traffic; such deployments\n * must opt in with an explicit `allowedHosts`/`allowedOrigins` for their domain.\n */\n dnsRebinding?: {\n /** Force protection on (`true`) or off (`false`). Omit for the loopback-auto default. */\n enabled?: boolean\n /**\n * Allowed `Host` header hostnames (no port; IPv6 in brackets, e.g. `[::1]`).\n * Supplying this list also implies protection on. Default: `localhost`,\n * `127.0.0.1`, `[::1]`.\n */\n allowedHosts?: string[]\n /**\n * Allowed `Origin` header hostnames (a missing `Origin` always passes — non-browser\n * clients send none). Supplying this list also implies protection on. Default:\n * `localhost`, `127.0.0.1`, `[::1]`.\n */\n allowedOrigins?: string[]\n }\n}\n\nexport interface RunOptions {\n transport?: 'stdio' | 'http'\n port?: number\n host?: string\n path?: string\n /**\n * Serve the legacy (2025-era) HTTP transport statelessly: a fresh server and\n * transport per request, no session registry, incoming `mcp-session-id`\n * ignored, and no session id issued. Use this behind a load balancer or on\n * serverless compute where consecutive requests reach different instances.\n *\n * Falls back to the `FASTMCP_STATELESS_HTTP` environment variable, then to\n * `false`. A valid value is ignored for the stdio transport, but a malformed\n * one still aborts stdio startup, deliberately. The modern (2026-07-28) era\n * is already stateless and is unaffected.\n */\n stateless?: boolean\n /** Custom stdin stream for the stdio transport. Defaults to process.stdin. */\n stdin?: Readable\n /** Custom stdout stream for the stdio transport. Defaults to process.stdout. */\n stdout?: Writable\n}\n\nexport interface ServerAddress {\n host: string\n port: number\n path: string\n}\n\nexport interface ToolConfig {\n name: string\n /** Human-readable display name shown in UIs. Takes precedence over `name` for display purposes. */\n title?: string\n description: string\n /** Standard Schema validator for the tool's input arguments. Used for runtime validation. */\n input?: StandardSchemaV1\n /**\n * Explicit JSON Schema advertised to clients as `inputSchema`. Overrides auto-generation from\n * `input`. Use when you need JSON Schema features beyond what your validator auto-generates\n * (e.g. `examples`, `$comment`, per-property descriptions, or custom annotations).\n */\n inputSchema?: Record<string, unknown>\n /** Standard Schema validator for the tool's return value. Validated before result conversion. */\n output?: StandardSchemaV1\n /**\n * Explicit JSON Schema advertised to clients as `outputSchema`. Overrides auto-generation from\n * `output`. Use when you need JSON Schema features beyond what your validator auto-generates.\n */\n outputSchema?: Record<string, unknown>\n /** Execution timeout in milliseconds. No timeout by default. */\n timeout?: number\n /** When true the tool is hidden from listTools and cannot be invoked via tools/call. */\n disabled?: boolean\n /** Arbitrary tags for server-side filtering. */\n tags?: string[]\n auth?: AuthCheck\n /** Apps extension — links this tool to a UI resource and controls visibility. */\n ui?: UiToolMeta\n}\n\ninterface RegisteredTool {\n config: ToolConfig\n handler: (args: unknown) => unknown\n}\n\ninterface RegisteredResource {\n config: ResourceConfig\n handler: (params?: Record<string, string>) => unknown\n}\n\ninterface ResolvedPromptConfig extends Required<Pick<PromptConfig, 'name' | 'description'>> {\n title?: string\n arguments?: PromptConfig['arguments']\n disabled?: boolean\n timeout?: number\n tags?: string[]\n auth?: PromptConfig['auth']\n}\n\ninterface RegisteredPrompt {\n config: ResolvedPromptConfig\n handler: (args?: Record<string, string>) => unknown\n}\n\ninterface Session {\n transport: NodeStreamableHTTPServerTransport\n server: Server\n state: Map<string, unknown>\n}\n\n/**\n * Per-session state key holding the set of resource URIs the connection has\n * subscribed to via `resources/subscribe`. Stored in the same per-session state\n * Map as `SESSION_CLOSE_CALLBACKS_KEY`, so it is torn down with the session (no\n * separate registry to leak). Only ever populated on legacy connections — the\n * modern era rejects the RPC at the wire seam before the handler runs.\n */\nconst RESOURCE_SUBSCRIPTIONS_KEY = '__fastmcp_resource_subscriptions'\n\n/**\n * Guard message for `resources/subscribe`/`unsubscribe` on a stateless HTTP\n * server. The server withdraws the `resources.subscribe` capability (see\n * `_makeServer`), so a compliant client never calls these; this is the\n * refusal for a non-compliant client that calls them anyway.\n */\nconst STATELESS_SUBSCRIBE_ERROR =\n '[fastmcp] resources/subscribe and resources/unsubscribe are unavailable on a stateless HTTP server. ' +\n 'A stateless server keeps no session, so a subscription has nowhere to live and no channel to deliver on. ' +\n 'The server does not advertise the resources.subscribe capability; a compliant client will not call this.'\n\n/** Converts a camelCase or PascalCase name to space-separated words. e.g. `getWeather` → `\"get weather\"` */\nfunction inferDescription(name: string): string {\n return name\n .replace(/([A-Z])/g, ' $1')\n .replace(/[-_]+/g, ' ')\n .trim()\n .toLowerCase()\n}\n\n/** True when `host` is a loopback address `run()` can bind — the deployment DNS-rebinding targets. */\nfunction isLoopbackHost(host: string): boolean {\n const h = host.toLowerCase()\n return h === '127.0.0.1' || h === 'localhost' || h === '::1' || h === '[::1]'\n}\n\n// Fired at most once per process: an HTTP serve on a routable host with no dnsRebinding\n// config at all. Any explicit dnsRebinding option (even `enabled: false`) suppresses the\n// warning — silence means the operator chose the open posture on purpose.\nlet _dnsRebindingWarned = false\n\n/** @internal Test-only reset of the once-per-process DNS-rebinding warning guard. Not\n * re-exported from `fastmcp-ts/server` (index.ts names its exports). */\nexport function __resetDnsRebindingWarningForTests(): void {\n _dnsRebindingWarned = false\n}\n\nfunction toAccessToken(authInfo: AuthInfo | undefined): AccessToken | undefined {\n if (!authInfo) return undefined\n return {\n token: authInfo.token,\n clientId: authInfo.clientId || undefined,\n scopes: authInfo.scopes,\n expiresAt: authInfo.expiresAt,\n claims: authInfo.extra ?? {},\n }\n}\n\n// Cached result of verifying FASTMCP_CLI_AUTH_TOKEN once per process.\n// undefined = not yet resolved; null = env var absent or verification failed.\nlet _cliEnvToken: AccessToken | null | undefined\n\nasync function resolveCliEnvToken(\n verifier: TokenVerifier | RequestVerifier | undefined,\n): Promise<AccessToken | undefined> {\n if (!verifier || !('verify' in verifier)) return undefined\n if (_cliEnvToken !== undefined) return _cliEnvToken ?? undefined\n const raw = process.env['FASTMCP_CLI_AUTH_TOKEN']\n if (!raw) { _cliEnvToken = null; return undefined }\n try {\n _cliEnvToken = await verifier.verify(raw)\n return _cliEnvToken\n } catch {\n _cliEnvToken = null\n return undefined\n }\n}\n\nasync function runAuthCheck(check: AuthCheck, token: AccessToken | undefined): Promise<void> {\n if (!token) throw new ProtocolError(ProtocolErrorCode.InvalidRequest, 'Authentication required')\n try {\n await check(token)\n } catch (err) {\n if (err instanceof AuthorizationError) {\n throw new ProtocolError(ProtocolErrorCode.InvalidRequest, err.message)\n }\n throw err\n }\n}\n\nexport class FastMCP {\n readonly name: string\n readonly version: string\n\n private _auth: TokenVerifier | RequestVerifier | undefined\n private _oauth: OAuthConfig | undefined\n private _sensitiveHeaders: Set<string>\n private _toolsPageSize: number\n private _resourcesPageSize: number\n private _tools = new Map<string, RegisteredTool>()\n private _staticResources = new Map<string, RegisteredResource>()\n private _templateResources = new Map<string, RegisteredResource>()\n private _prompts = new Map<string, RegisteredPrompt>()\n private _promptsPageSize: number\n private _middleware: Middleware[]\n private _transforms: Transform[]\n private _cacheHints: Partial<Record<CacheableResultMethod, CacheHint>> | undefined\n private _requestStateCodec: RequestStateCodec | undefined\n private _inputRequiredOptions: FastMCPOptions['inputRequired']\n private _eventBus: ServerEventBus | undefined\n private _dnsRebindingOptions: FastMCPOptions['dnsRebinding']\n // DNS-rebinding guards, resolved once per serve from _dnsRebindingOptions + the bind\n // host. null = protection off. Each returns false (and has already written a 403) when\n // it rejects; see the SDK's hostHeaderValidation/originValidation Node middleware.\n private _hostGuard: ((req: IncomingMessage, res: ServerResponse) => boolean) | null = null\n private _originGuard: ((req: IncomingMessage, res: ServerResponse) => boolean) | null = null\n private _primaryState = new Map<string, unknown>()\n private _httpServer: HttpServer | null = null\n private _address: ServerAddress | null = null\n private _isRunning = false\n private _sessions = new Map<string, Session>()\n private _stateless = false\n // Primary server used by connect() (in-process transports — always 2025-era)\n private _primaryServer: Server\n // The pinned Server instance for a run({transport:'stdio'}) connection (2025- or\n // 2026-era, decided by serveStdio's opening handshake). Null unless serving stdio.\n private _stdioServer: Server | null = null\n // The state Map paired with `_stdioServer` for the current stdio connection.\n // Holds this connection's resource-subscription set; read by the resource-updated\n // fan-out. Null unless serving stdio.\n private _stdioState: Map<string, unknown> | null = null\n private _stdioHandle: { close(): Promise<void> } | null = null\n // Modern (2026-07-28) HTTP handler — one per FastMCP instance, lazily created.\n // Builds a fresh Server (via _makeServer) per request; see createMcpHandler.\n private _modernHandler: McpHttpHandler | null = null\n private _statelessLegacyHandler: LegacyHttpHandler | null = null\n\n private _toolRegisteredCallbacks: Array<(tool: RegisteredTool) => void> = []\n private _resourceRegisteredCallbacks: Array<(resource: RegisteredResource) => void> = []\n private _promptRegisteredCallbacks: Array<(prompt: RegisteredPrompt) => void> = []\n private _proxyCloseCallbacks: Array<() => Promise<void>> = []\n private _mountedChildren = new Set<FastMCP>()\n\n constructor(options: FastMCPOptions) {\n this.name = options.name\n this.version = options.version ?? '0.0.1'\n this._auth = options.auth\n this._oauth = options.oauth\n this._sensitiveHeaders = resolveSensitiveHeaders(options.http)\n this._toolsPageSize = options.toolsPageSize ?? 50\n this._resourcesPageSize = options.resourcesPageSize ?? 50\n this._promptsPageSize = options.promptsPageSize ?? 50\n this._middleware = options.middleware ? [...options.middleware] : []\n this._transforms = options.transforms ? [...options.transforms] : []\n this._cacheHints = options.cacheHints\n this._requestStateCodec = options.requestState\n ? createRequestStateCodec(options.requestState)\n : undefined\n this._inputRequiredOptions = options.inputRequired\n this._eventBus = options.eventBus\n this._dnsRebindingOptions = options.dnsRebinding\n this._primaryServer = this._makeServer()\n }\n\n private _hasUiComponents(): boolean {\n for (const t of this._tools.values()) {\n if (t.config.ui) return true\n }\n for (const r of this._staticResources.values()) {\n if (r.config.ui || r.config.uri.startsWith('ui://')) return true\n }\n for (const r of this._templateResources.values()) {\n if (r.config.uri.startsWith('ui://')) return true\n }\n return false\n }\n\n /**\n * Create a new Server instance with all request handlers wired up.\n *\n * `modern` forks the advertised `resources.subscribe` capability. The legacy\n * `resources/subscribe`/`unsubscribe` RPCs are physically absent from the\n * 2026-07-28 wire registry (a modern client uses `subscriptions/listen`\n * instead), so a modern-only factory (the createMcpHandler path) must NOT\n * advertise `subscribe` — the modern `server/discover` document is pinned to\n * `resources: { listChanged: true }`. The primary in-process server and\n * legacy HTTP sessions are always legacy, so they always advertise it.\n * stdio forks it per-connection too: `run()`'s stdio branch reads the\n * `ctx.era` the SDK's `McpServerFactory` hook hands it (serveStdio only\n * calls the factory once the opening exchange has classified the era, so\n * the modern-vs-legacy choice is already known at construction time) and\n * passes it straight through as `opts.modern`.\n *\n * The `completions` capability is NOT era-forked: `completion/complete` is in\n * BOTH era wire registries (the legacy 2025-11-25 registry and the modern\n * 2026-07-28 `dispatchRequestSchemas`), and `completions` is a valid key in\n * both eras' ServerCapabilities schemas. So it is declared unconditionally —\n * unlike `subscribe`, there is no legacy-only surface to hide from a modern\n * client here, so nothing needs the era fork the way `subscribe` does. The\n * SDK also requires this capability to be present to register the\n * `completion/complete` handler (`assertRequestHandlerCapability`).\n *\n * `stateless` withdraws the same capability for a different reason. A\n * stateless server has no session for a subscription to live in and no\n * channel to deliver `notifications/resources/updated` on, so it must not\n * claim the capability.\n */\n private _makeServer(\n sessionState?: Map<string, unknown>,\n opts?: { modern?: boolean; stateless?: boolean },\n ): Server {\n const state = sessionState ?? this._primaryState\n // mimeTypes announces what fastmcp can serve, symmetric with the mimeTypes the\n // client is required to declare on its own extension entry (SEP-1865).\n const extensions = this._hasUiComponents()\n ? { [UI_EXTENSION_KEY]: { mimeTypes: [UI_RESOURCE_MIME_TYPE] } }\n : undefined\n const server = new Server(\n { name: this.name, version: this.version },\n {\n capabilities: { tools: { listChanged: true }, resources: { listChanged: true, ...(opts?.modern || opts?.stateless ? {} : { subscribe: true }) }, prompts: { listChanged: true }, logging: {}, completions: {}, ...(extensions ? { extensions } : {}) },\n ...(this._cacheHints ? { cacheHints: this._cacheHints } : {}),\n ...(this._requestStateCodec\n ? { requestState: { verify: this._requestStateCodec.verify.bind(this._requestStateCodec) } }\n : {}),\n ...(this._inputRequiredOptions ? { inputRequired: this._inputRequiredOptions } : {}),\n },\n )\n for (const mw of this._middleware) mw.setup?.(server)\n this._setupHandlers(server, state, opts)\n return server\n }\n\n private async _resolveToken(authInfo: AuthInfo | undefined): Promise<AccessToken | undefined> {\n return toAccessToken(authInfo) ?? await resolveCliEnvToken(this._auth)\n }\n\n private _setupHandlers(\n server: Server,\n sessionState: Map<string, unknown>,\n opts?: { stateless?: boolean },\n ): void {\n server.setRequestHandler('tools/list', async (req, sdkCtx) => {\n const token = await this._resolveToken(sdkCtx.http?.authInfo)\n const ctx = createContext(server, sdkCtx, token, sessionState, this._requestStateCodec, opts?.stateless, this._sensitiveHeaders)\n return contextStore.run(ctx, () =>\n runMiddlewareChain(this._middleware, 'tools/list', req.params, ctx, async () => {\n const clientIsUiCapable = isUiCapable(server.getClientCapabilities())\n\n const allVisible = (\n await Promise.all(\n [...this._tools.values()].map(async (t) => {\n if (t.config.disabled) return null\n // App-only tools are hidden from listTools (visible only inside the iframe)\n if (t.config.ui?.visibility && !t.config.ui.visibility.includes('model')) return null\n if (!t.config.auth) return t\n if (!token) return null\n try { await t.config.auth(token); return t } catch { return null }\n }),\n )\n ).filter((t): t is RegisteredTool => t !== null)\n\n const transformedTools = this._applyTransformsToTools(allVisible)\n const { resourceViews, promptViews } = await this._getVisibleViews(token)\n const synthesized = this._buildSynthesizedTools(resourceViews, promptViews)\n\n type ListEntry =\n | { kind: 'registered'; name: string; title: string | undefined; description: string; config: ToolConfig }\n | { kind: 'synthesized'; name: string; title: string | undefined; description: string; inputSchema: Record<string, unknown> | undefined }\n\n const allEntries: ListEntry[] = [\n ...transformedTools.map(\n (t): ListEntry => ({ kind: 'registered', name: t.name, title: t.title, description: t.description, config: t.config }),\n ),\n ...synthesized.map(\n (s): ListEntry => ({ kind: 'synthesized', name: s.name, title: s.title, description: s.description, inputSchema: s.inputSchema }),\n ),\n ]\n\n const pageSize = this._toolsPageSize\n const cursorName = req.params?.cursor\n ? Buffer.from(req.params.cursor, 'base64url').toString()\n : null\n let startIdx = 0\n if (cursorName !== null) {\n const idx = allEntries.findIndex((e) => e.name === cursorName)\n if (idx < 0) throw new ProtocolError(ProtocolErrorCode.InvalidParams, 'Invalid or expired cursor')\n startIdx = idx + 1\n }\n const page = allEntries.slice(startIdx, startIdx + pageSize)\n const nextCursor =\n startIdx + pageSize < allEntries.length\n ? Buffer.from(page[page.length - 1].name).toString('base64url')\n : undefined\n\n const tools = await Promise.all(\n page.map(async (entry) => {\n if (entry.kind === 'synthesized') {\n return {\n name: entry.name,\n ...(entry.title !== undefined ? { title: entry.title } : {}),\n description: entry.description,\n inputSchema: entry.inputSchema ?? { type: 'object' as const },\n }\n }\n const t = entry.config\n const inputSchema =\n t.inputSchema ??\n (t.input\n ? await toJsonSchema(t.input, `tool \"${t.name}\" input`)\n : { type: 'object' as const })\n const outputSchema =\n t.outputSchema ??\n (t.output\n ? await toJsonSchema(t.output, `tool \"${t.name}\" output`)\n : undefined)\n const uiMeta = clientIsUiCapable && t.ui\n ? {\n resourceUri: t.ui.resourceUri ?? `ui://${t.name}`,\n ...(t.ui.visibility ? { visibility: t.ui.visibility } : {}),\n }\n : undefined\n return {\n name: entry.name,\n ...(entry.title !== undefined ? { title: entry.title } : {}),\n description: entry.description,\n inputSchema,\n ...(outputSchema ? { outputSchema } : {}),\n ...(uiMeta ? { _meta: { ui: uiMeta } } : {}),\n }\n }),\n )\n\n // Cast: our JSON Schema generation (toJsonSchema / user-supplied inputSchema) is\n // typed loosely as Record<string, unknown>, while the SDK's Tool type is inferred\n // from a strict Zod schema requiring a literal `type: 'object'` root. The generated\n // schemas satisfy this at runtime (see tool.ts); this is a static-typing gap only.\n return { tools, ...(nextCursor ? { nextCursor } : {}) } as ListToolsResult\n }),\n )\n })\n\n server.setRequestHandler('tools/call', async (req, sdkCtx) => {\n const requestedName = req.params.name\n const token = await this._resolveToken(sdkCtx.http?.authInfo)\n\n // Check synthesized tools first\n const { resourceViews, promptViews } = await this._getVisibleViews(token)\n const synthesizedList = this._buildSynthesizedTools(resourceViews, promptViews)\n const synthTool = synthesizedList.find((s) => s.name === requestedName)\n if (synthTool) {\n if (synthTool.auth) await runAuthCheck(synthTool.auth, token)\n const ctx = createContext(server, sdkCtx, token, sessionState, this._requestStateCodec, opts?.stateless, this._sensitiveHeaders)\n try {\n return await contextStore.run(ctx, () =>\n runMiddlewareChain(this._middleware, 'tools/call', req.params, ctx, async () => {\n let executePromise: Promise<unknown> = Promise.resolve(\n synthTool.handler(req.params.arguments ?? {}),\n )\n if (synthTool.timeout) {\n const ms = synthTool.timeout\n let timer!: ReturnType<typeof setTimeout>\n const timeoutPromise = new Promise<never>((_, reject) => {\n timer = setTimeout(\n () => reject(new Error(`Tool \"${requestedName}\" timed out after ${ms}ms`)),\n ms,\n )\n })\n executePromise = Promise.race([executePromise, timeoutPromise]).finally(() =>\n clearTimeout(timer),\n )\n }\n return convertResult(await executePromise, opts?.stateless)\n }),\n )\n } catch (err) {\n if (err instanceof ProtocolError) throw err\n return {\n content: [{ type: 'text' as const, text: err instanceof Error ? err.message : String(err) }],\n isError: true,\n }\n }\n }\n\n // Find by transformed name, then fall back to direct registry (for hidden/unaffected tools)\n let tool: RegisteredTool | undefined\n if (this._transforms.length > 0) {\n for (const t of this._tools.values()) {\n const view = applyTransformChain<ToolView>(\n { name: t.config.name, description: t.config.description, tags: t.config.tags ?? [] },\n this._transforms,\n (tr, v) => tr.transformTool?.(v),\n )\n if (view && view.name === requestedName) { tool = t; break }\n }\n }\n if (!tool) tool = this._tools.get(requestedName)\n\n if (!tool || tool.config.disabled) {\n throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Unknown tool: \"${requestedName}\"`)\n }\n\n if (tool.config.auth) await runAuthCheck(tool.config.auth, token)\n\n const resolvedTool = tool\n const rawArgs: unknown = req.params.arguments ?? {}\n const ctx = createContext(server, sdkCtx, token, sessionState, this._requestStateCodec, opts?.stateless, this._sensitiveHeaders)\n\n try {\n return await contextStore.run(ctx, () =>\n runMiddlewareChain(this._middleware, 'tools/call', req.params, ctx, async () => {\n const args = resolvedTool.config.input ? await validateInput(resolvedTool.config.input, rawArgs, true) : rawArgs\n\n let executePromise: Promise<unknown> = Promise.resolve(resolvedTool.handler(args))\n\n if (resolvedTool.config.timeout) {\n const ms = resolvedTool.config.timeout\n let timer!: ReturnType<typeof setTimeout>\n const timeoutPromise = new Promise<never>((_, reject) => {\n timer = setTimeout(\n () => reject(new Error(`Tool \"${requestedName}\" timed out after ${ms}ms`)),\n ms,\n )\n })\n executePromise = Promise.race([executePromise, timeoutPromise]).finally(() =>\n clearTimeout(timer),\n )\n }\n\n let resultValue = await executePromise\n if (resolvedTool.config.output) resultValue = await validateInput(resolvedTool.config.output, resultValue)\n const callResult = convertResult(resultValue, opts?.stateless)\n // Graceful degradation: strip structuredContent for non-UI clients calling UI tools\n if (resolvedTool.config.ui) {\n const clientIsUi = isUiCapable(server.getClientCapabilities())\n if (!clientIsUi && callResult.structuredContent !== undefined) {\n return { content: [{ type: 'text' as const, text: '[UI not available in this client]' }] }\n }\n }\n return callResult\n }),\n )\n } catch (err) {\n if (err instanceof ProtocolError) throw err\n return {\n content: [{ type: 'text' as const, text: err instanceof Error ? err.message : String(err) }],\n isError: true,\n }\n }\n })\n\n server.setRequestHandler('resources/list', async (req, sdkCtx) => {\n const token = await this._resolveToken(sdkCtx.http?.authInfo)\n const ctx = createContext(server, sdkCtx, token, sessionState, this._requestStateCodec, opts?.stateless, this._sensitiveHeaders)\n return contextStore.run(ctx, () =>\n runMiddlewareChain(this._middleware, 'resources/list', req.params, ctx, async () => {\n const allVisible = (\n await Promise.all(\n [...this._staticResources.values()].map(async (r) => {\n if (r.config.disabled) return null\n if (!r.config.auth) return r\n if (!token) return null\n try { await r.config.auth(token); return r } catch { return null }\n }),\n )\n ).filter((r): r is RegisteredResource => r !== null)\n\n const transformedResources = this._applyTransformsToResources(allVisible)\n\n const pageSize = this._resourcesPageSize\n const cursorUri = req.params?.cursor\n ? Buffer.from(req.params.cursor, 'base64url').toString()\n : null\n let startIdx = 0\n if (cursorUri !== null) {\n const idx = transformedResources.findIndex((r) => r.uri === cursorUri)\n if (idx < 0) throw new ProtocolError(ProtocolErrorCode.InvalidParams, 'Invalid or expired cursor')\n startIdx = idx + 1\n }\n const page = transformedResources.slice(startIdx, startIdx + pageSize)\n const nextCursor =\n startIdx + pageSize < transformedResources.length\n ? Buffer.from(page[page.length - 1].uri).toString('base64url')\n : undefined\n\n const clientIsUiCapableRes = isUiCapable(server.getClientCapabilities())\n return {\n resources: page.map((r) => ({\n uri: r.uri,\n name: r.name,\n ...(r.config.title !== undefined ? { title: r.config.title } : {}),\n ...(r.config.description !== undefined ? { description: r.config.description } : {}),\n ...(r.config.mimeType !== undefined ? { mimeType: r.config.mimeType } : {}),\n ...(r.config.size !== undefined ? { size: r.config.size } : {}),\n ...(r.config.annotations !== undefined ? { annotations: r.config.annotations } : {}),\n ...(clientIsUiCapableRes && r.config.ui ? { _meta: { ui: r.config.ui } } : {}),\n })),\n ...(nextCursor ? { nextCursor } : {}),\n }\n }),\n )\n })\n\n server.setRequestHandler('resources/templates/list', async (req, sdkCtx) => {\n const token = await this._resolveToken(sdkCtx.http?.authInfo)\n const ctx = createContext(server, sdkCtx, token, sessionState, this._requestStateCodec, opts?.stateless, this._sensitiveHeaders)\n return contextStore.run(ctx, () =>\n runMiddlewareChain(this._middleware, 'resources/templates/list', req.params, ctx, async () => {\n const allVisible = (\n await Promise.all(\n [...this._templateResources.values()].map(async (r) => {\n if (r.config.disabled) return null\n if (!r.config.auth) return r\n if (!token) return null\n try { await r.config.auth(token); return r } catch { return null }\n }),\n )\n ).filter((r): r is RegisteredResource => r !== null)\n\n const transformedTemplates = this._applyTransformsToResourceTemplates(allVisible)\n\n const pageSize = this._resourcesPageSize\n const cursorUri = req.params?.cursor\n ? Buffer.from(req.params.cursor, 'base64url').toString()\n : null\n let startIdx = 0\n if (cursorUri !== null) {\n const idx = transformedTemplates.findIndex((r) => r.uri === cursorUri)\n if (idx < 0) throw new ProtocolError(ProtocolErrorCode.InvalidParams, 'Invalid or expired cursor')\n startIdx = idx + 1\n }\n const page = transformedTemplates.slice(startIdx, startIdx + pageSize)\n const nextCursor =\n startIdx + pageSize < transformedTemplates.length\n ? Buffer.from(page[page.length - 1].uri).toString('base64url')\n : undefined\n\n return {\n resourceTemplates: page.map((r) => ({\n uriTemplate: r.uri,\n name: r.name,\n ...(r.config.title !== undefined ? { title: r.config.title } : {}),\n ...(r.config.description !== undefined ? { description: r.config.description } : {}),\n ...(r.config.mimeType !== undefined ? { mimeType: r.config.mimeType } : {}),\n ...(r.config.annotations !== undefined ? { annotations: r.config.annotations } : {}),\n })),\n ...(nextCursor ? { nextCursor } : {}),\n }\n }),\n )\n })\n\n server.setRequestHandler('resources/read', async (req, sdkCtx) => {\n const requestedUri = req.params.uri\n const token = await this._resolveToken(sdkCtx.http?.authInfo)\n\n const resolved = this._resolveResource(requestedUri)\n if (!resolved || resolved.resource.config.disabled) {\n // ResourceNotFoundError stamps `data: { uri }` (exactly one key) and keeps the\n // -32602 code the SDK recognition contract requires, so a client can tell a\n // resource miss from a generic Invalid Params (task-9 Req 3; task-7 F1).\n throw new ResourceNotFoundError(requestedUri, `Unknown resource: \"${requestedUri}\"`)\n }\n const resource = resolved.resource\n const templateParams = resolved.templateParams\n\n if (resource.config.auth) await runAuthCheck(resource.config.auth, token)\n\n const ctx = createContext(server, sdkCtx, token, sessionState, this._requestStateCodec, opts?.stateless, this._sensitiveHeaders)\n\n return contextStore.run(ctx, () =>\n runMiddlewareChain(this._middleware, 'resources/read', req.params, ctx, async () => {\n let executePromise: Promise<unknown> = Promise.resolve(resource!.handler(templateParams))\n\n if (resource!.config.timeout) {\n const ms = resource!.config.timeout\n let timer!: ReturnType<typeof setTimeout>\n const timeoutPromise = new Promise<never>((_, reject) => {\n timer = setTimeout(\n () => reject(new Error(`Resource \"${requestedUri}\" timed out after ${ms}ms`)),\n ms,\n )\n })\n executePromise = Promise.race([executePromise, timeoutPromise]).finally(() =>\n clearTimeout(timer),\n ) as Promise<unknown>\n }\n\n const result = await executePromise\n const converted = convertResourceResult(result, requestedUri, resource!.config.mimeType, opts?.stateless)\n return attachResourceUiMeta(converted, resource!.config.ui, isUiCapable(server.getClientCapabilities()))\n }),\n )\n })\n\n // resources/subscribe / resources/unsubscribe (legacy era only).\n //\n // The 2026-07-28 wire registry omits both methods, so a modern connection\n // never reaches these handlers — the SDK rejects the method at the era seam\n // (-32601) before dispatch, and a modern client's own era guard rejects even\n // earlier. On legacy the handshake advertises `resources.subscribe: true`\n // (see _makeServer), so the client may call them here.\n //\n // The subscription set lives in the connection's per-session state Map (the\n // same Map SESSION_CLOSE_CALLBACKS_KEY uses), so it is discarded when the\n // session closes — no separate registry to leak. Delivery of\n // `notifications/resources/updated` is driven by notifyResourceUpdated(uri),\n // the single change signal shared with the modern subscriptions/listen bus.\n //\n // Only resources/subscribe mirrors resources/read's resolve → not-found →\n // auth → context → middleware sequencing, so subscribe is indistinguishable\n // from read as an oracle. resources/unsubscribe skips resolution and auth: it\n // only removes uri from the caller's own subscription set, so an unknown or\n // forbidden uri is a harmless no-op, not an oracle — there is nothing to guard.\n server.setRequestHandler('resources/subscribe', async (req, sdkCtx) => {\n if (opts?.stateless) throw new ProtocolError(ProtocolErrorCode.MethodNotFound, STATELESS_SUBSCRIBE_ERROR)\n const uri = req.params.uri\n const token = await this._resolveToken(sdkCtx.http?.authInfo)\n\n // Resolve against the same lookup resources/read uses; an unknown or\n // disabled URI is a bad parameter (ResourceNotFoundError → -32602), matching\n // resources/read's not-found contract exactly.\n const resolved = this._resolveResource(uri)\n if (!resolved || resolved.resource.config.disabled) {\n throw new ResourceNotFoundError(uri, `Unknown resource: \"${uri}\"`)\n }\n const resource = resolved.resource\n\n // Enforce the resource's auth guard identically to resources/read (same\n // rejection). Without this, subscribe leaks an existence/activity oracle for a\n // URI that read (and resources/list) deliberately hides from an under-scoped\n // caller: `{}` for a real-but-forbidden URI vs -32602 for an unknown one.\n if (resource.config.auth) await runAuthCheck(resource.config.auth, token)\n\n const ctx = createContext(server, sdkCtx, token, sessionState, this._requestStateCodec, opts?.stateless, this._sensitiveHeaders)\n\n return contextStore.run(ctx, () =>\n runMiddlewareChain(this._middleware, 'resources/subscribe', req.params, ctx, async () => {\n let subs = sessionState.get(RESOURCE_SUBSCRIPTIONS_KEY) as Set<string> | undefined\n if (!subs) {\n subs = new Set<string>()\n sessionState.set(RESOURCE_SUBSCRIPTIONS_KEY, subs)\n }\n subs.add(uri)\n return {}\n }),\n )\n })\n\n server.setRequestHandler('resources/unsubscribe', async (req, sdkCtx) => {\n if (opts?.stateless) throw new ProtocolError(ProtocolErrorCode.MethodNotFound, STATELESS_SUBSCRIBE_ERROR)\n const uri = req.params.uri\n const token = await this._resolveToken(sdkCtx.http?.authInfo)\n const ctx = createContext(server, sdkCtx, token, sessionState, this._requestStateCodec, opts?.stateless, this._sensitiveHeaders)\n\n return contextStore.run(ctx, () =>\n runMiddlewareChain(this._middleware, 'resources/unsubscribe', req.params, ctx, async () => {\n const subs = sessionState.get(RESOURCE_SUBSCRIPTIONS_KEY) as Set<string> | undefined\n subs?.delete(uri)\n return {}\n }),\n )\n })\n\n server.setRequestHandler('prompts/list', async (req, sdkCtx) => {\n const token = await this._resolveToken(sdkCtx.http?.authInfo)\n const ctx = createContext(server, sdkCtx, token, sessionState, this._requestStateCodec, opts?.stateless, this._sensitiveHeaders)\n return contextStore.run(ctx, () =>\n runMiddlewareChain(this._middleware, 'prompts/list', req.params, ctx, async () => {\n const allVisible = (\n await Promise.all(\n [...this._prompts.values()].map(async (p) => {\n if (p.config.disabled) return null\n if (!p.config.auth) return p\n if (!token) return null\n try { await p.config.auth(token); return p } catch { return null }\n }),\n )\n ).filter((p): p is RegisteredPrompt => p !== null)\n\n const transformedPrompts = this._applyTransformsToPrompts(allVisible)\n\n const pageSize = this._promptsPageSize\n const cursorName = req.params?.cursor\n ? Buffer.from(req.params.cursor, 'base64url').toString()\n : null\n let startIdx = 0\n if (cursorName !== null) {\n const idx = transformedPrompts.findIndex((p) => p.name === cursorName)\n if (idx < 0) throw new ProtocolError(ProtocolErrorCode.InvalidParams, 'Invalid or expired cursor')\n startIdx = idx + 1\n }\n const page = transformedPrompts.slice(startIdx, startIdx + pageSize)\n const nextCursor =\n startIdx + pageSize < transformedPrompts.length\n ? Buffer.from(page[page.length - 1].name).toString('base64url')\n : undefined\n\n return {\n prompts: page.map((p) => ({\n name: p.name,\n ...(p.config.title !== undefined ? { title: p.config.title } : {}),\n description: p.description,\n // Strip the per-argument `complete` callback — it is a server-side\n // completion hook, not part of the advertised argument schema.\n ...(p.config.arguments?.length\n ? {\n arguments: p.config.arguments.map((a) => ({\n name: a.name,\n ...(a.description !== undefined ? { description: a.description } : {}),\n ...(a.required !== undefined ? { required: a.required } : {}),\n })),\n }\n : {}),\n })),\n ...(nextCursor ? { nextCursor } : {}),\n }\n }),\n )\n })\n\n server.setRequestHandler('prompts/get', async (req, sdkCtx) => {\n const requestedName = req.params.name\n let prompt: RegisteredPrompt | undefined\n if (this._transforms.length > 0) {\n for (const p of this._prompts.values()) {\n const view = applyTransformChain<PromptView>(\n { name: p.config.name, description: p.config.description, tags: p.config.tags ?? [] },\n this._transforms,\n (t, v) => t.transformPrompt?.(v),\n )\n if (view && view.name === requestedName) { prompt = p; break }\n }\n }\n if (!prompt) prompt = this._prompts.get(requestedName)\n\n if (!prompt || prompt.config.disabled) {\n throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Unknown prompt: \"${requestedName}\"`)\n }\n\n const resolvedPrompt = prompt\n const token = await this._resolveToken(sdkCtx.http?.authInfo)\n if (resolvedPrompt.config.auth) await runAuthCheck(resolvedPrompt.config.auth, token)\n\n const suppliedArgs = req.params.arguments ?? {}\n for (const arg of resolvedPrompt.config.arguments ?? []) {\n if (arg.required && !(arg.name in suppliedArgs)) {\n throw new ProtocolError(\n ProtocolErrorCode.InvalidParams,\n `Missing required argument \"${arg.name}\" for prompt \"${requestedName}\"`,\n )\n }\n }\n\n const ctx = createContext(server, sdkCtx, token, sessionState, this._requestStateCodec, opts?.stateless, this._sensitiveHeaders)\n\n return contextStore.run(ctx, () =>\n runMiddlewareChain(this._middleware, 'prompts/get', req.params, ctx, async () => {\n let executePromise = Promise.resolve(resolvedPrompt.handler(suppliedArgs))\n if (resolvedPrompt.config.timeout) {\n const ms = resolvedPrompt.config.timeout\n let timer!: ReturnType<typeof setTimeout>\n const timeoutPromise = new Promise<never>((_, reject) => {\n timer = setTimeout(\n () => reject(new Error(`Prompt \"${requestedName}\" timed out after ${ms}ms`)),\n ms,\n )\n })\n executePromise = Promise.race([executePromise, timeoutPromise]).finally(() =>\n clearTimeout(timer),\n )\n }\n // Cast: the SDK infers the handler's return type as GetPromptResult |\n // InputRequiredResult (multi-round-trip); this handler only returns the\n // \"complete\" shape today. inputRequired(...) support lands separately.\n return convertPromptResult(await executePromise, opts?.stateless) as GetPromptResult\n }),\n )\n })\n\n // completion/complete — argument autocompletion for prompt arguments and\n // resource-template variables. Registered on every factory (both eras admit\n // the method; see _makeServer's `completions` capability note). Routes by the\n // request's ref type using the SDK's assert helpers (which narrow the request\n // after the `ref.type` switch has already established the branch), then\n // dispatches to _completePrompt / _completeResourceTemplate. Both mirror\n // prompts/get and resources/read: resolve → not-found (-32602) → auth → run,\n // so completion is no weaker an oracle than get/read and audit middleware\n // observes it.\n server.setRequestHandler('completion/complete', async (req, sdkCtx) => {\n const token = await this._resolveToken(sdkCtx.http?.authInfo)\n const ctx = createContext(server, sdkCtx, token, sessionState, this._requestStateCodec, opts?.stateless, this._sensitiveHeaders)\n return contextStore.run(ctx, () =>\n runMiddlewareChain(this._middleware, 'completion/complete', req.params, ctx, async () => {\n const ref = req.params.ref\n if (ref.type === 'ref/prompt') {\n assertCompleteRequestPrompt(req)\n return this._completePrompt(req.params, token)\n }\n if (ref.type === 'ref/resource') {\n assertCompleteRequestResourceTemplate(req)\n return this._completeResourceTemplate(req.params, token)\n }\n throw new ProtocolError(\n ProtocolErrorCode.InvalidParams,\n `Invalid completion reference type: \"${(ref as { type: string }).type}\"`,\n )\n }),\n )\n })\n }\n\n /**\n * Resolve a `completion/complete` request against a prompt argument's completer.\n * Mirrors prompts/get's transform-aware lookup, not-found contract (-32602), and\n * auth check; an argument with no completer yields an empty list (SDK parity).\n */\n private async _completePrompt(\n params: CompleteRequestParams,\n token: AccessToken | undefined,\n ): Promise<CompleteResult> {\n const ref = params.ref as { type: 'ref/prompt'; name: string }\n let prompt: RegisteredPrompt | undefined\n if (this._transforms.length > 0) {\n for (const p of this._prompts.values()) {\n const view = applyTransformChain<PromptView>(\n { name: p.config.name, description: p.config.description, tags: p.config.tags ?? [] },\n this._transforms,\n (t, v) => t.transformPrompt?.(v),\n )\n if (view && view.name === ref.name) { prompt = p; break }\n }\n }\n if (!prompt) prompt = this._prompts.get(ref.name)\n\n if (!prompt || prompt.config.disabled) {\n throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Unknown prompt: \"${ref.name}\"`)\n }\n if (prompt.config.auth) await runAuthCheck(prompt.config.auth, token)\n\n const arg = prompt.config.arguments?.find((a) => a.name === params.argument.name)\n if (!arg?.complete) return { completion: EMPTY_COMPLETION }\n\n const raw = await arg.complete(params.argument.value, params.context)\n return { completion: normalizeCompletion(raw) }\n }\n\n /**\n * Resolve a `completion/complete` request against a resource template's\n * per-variable completer. Mirrors resources/read's not-found contract (-32602)\n * and auth check; a variable with no completer yields an empty list. Following\n * the SDK's own high-level server, a `ref.uri` that names a registered STATIC\n * resource (not a template) is answered with an empty list rather than an error.\n */\n private async _completeResourceTemplate(\n params: CompleteRequestParams,\n token: AccessToken | undefined,\n ): Promise<CompleteResult> {\n const ref = params.ref as { type: 'ref/resource'; uri: string }\n let template = this._templateResources.get(ref.uri)\n if (!template && this._transforms.length > 0) {\n for (const r of this._templateResources.values()) {\n const view = applyTransformChain<ResourceView>(\n { uri: r.config.uri, name: r.config.name ?? r.config.uri, tags: r.config.tags ?? [], mimeType: r.config.mimeType, title: r.config.title },\n this._transforms,\n (t, v) => t.transformResourceTemplate?.(v),\n )\n if (view && view.uri === ref.uri) { template = r; break }\n }\n }\n\n if (!template || template.config.disabled) {\n // A concrete (non-template) resource URI is a valid ref with nothing to\n // complete — answer empty, matching the SDK's high-level server. But apply\n // resources/read's resolve → not-found → auth gate first, so a disabled or\n // auth-gated static resource is NOT an existence oracle: a hidden resource\n // must be indistinguishable from an unknown URI (task-11's subscribe standard).\n const staticResource = this._staticResources.get(ref.uri)\n if (staticResource && !staticResource.config.disabled) {\n // Enforce the resource's auth guard identically to resources/read (same\n // rejection). Without this, an auth-gated static resource answers `{}` here\n // while read rejects it — a caller could enumerate forbidden URIs.\n if (staticResource.config.auth) await runAuthCheck(staticResource.config.auth, token)\n return { completion: EMPTY_COMPLETION }\n }\n // Disabled or unknown: fall through to the identical not-found rejection, so a\n // disabled static resource is byte-indistinguishable from a URI that was never\n // registered (matches read's not-found code, -32602).\n throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Unknown resource template: \"${ref.uri}\"`)\n }\n if (template.config.auth) await runAuthCheck(template.config.auth, token)\n\n const completer = template.config.complete?.[params.argument.name]\n if (!completer) return { completion: EMPTY_COMPLETION }\n\n const raw = await completer(params.argument.value, params.context)\n return { completion: normalizeCompletion(raw) }\n }\n\n private _notifyToolListChanged(): void {\n this._primaryServer.sendToolListChanged().catch(() => {})\n this._stdioServer?.sendToolListChanged().catch(() => {})\n for (const { server } of this._sessions.values()) {\n server.sendToolListChanged().catch(() => {})\n }\n // Modern (2026-07-28) HTTP requests are stateless per-request — there is no live\n // connection to push an unsolicited notification to. Delivery for subscribed\n // modern clients instead goes through the shared modern handler's own\n // subscriptions/listen bus (see _getModernHandler / FastMCPOptions.eventBus).\n // Optional chaining: a no-op until the first modern HTTP request creates the\n // handler — nothing to notify before then, so there is no reason to force it\n // into existence just to publish to an empty bus.\n this._modernHandler?.notify.toolsChanged()\n }\n\n private _notifyResourceListChanged(): void {\n this._primaryServer.sendResourceListChanged().catch(() => {})\n this._stdioServer?.sendResourceListChanged().catch(() => {})\n for (const { server } of this._sessions.values()) {\n server.sendResourceListChanged().catch(() => {})\n }\n this._modernHandler?.notify.resourcesChanged()\n }\n\n private _notifyPromptListChanged(): void {\n this._primaryServer.sendPromptListChanged().catch(() => {})\n this._stdioServer?.sendPromptListChanged().catch(() => {})\n for (const { server } of this._sessions.values()) {\n server.sendPromptListChanged().catch(() => {})\n }\n this._modernHandler?.notify.promptsChanged()\n }\n\n /**\n * Signal that a resource changed and any subscriber should re-read it. This is\n * the SINGLE change signal for resource updates across both eras — the legacy\n * per-session push and the modern subscriptions/listen bus are driven from here:\n *\n * - Legacy connections (primary / stdio / legacy HTTP sessions) that called\n * `resources/subscribe` for `uri` are pushed `notifications/resources/updated`\n * directly on their live session (subscription set kept in per-session state).\n * - The modern handler's bus (W3) is published to as well; it does its own\n * per-stream filtering, delivering only to `subscriptions/listen` streams that\n * opted in to this URI. Optional chaining keeps it a no-op until the first\n * modern HTTP request has actually built the handler.\n *\n * Unsubscribed sessions (and the modern streams that never opted in) receive\n * nothing, so calling this for a URI with no subscribers is safe and cheap.\n */\n notifyResourceUpdated(uri: string): void {\n const pushIfSubscribed = (server: Server, state: Map<string, unknown> | null): void => {\n const subs = state?.get(RESOURCE_SUBSCRIPTIONS_KEY) as Set<string> | undefined\n if (subs?.has(uri)) server.sendResourceUpdated({ uri }).catch(() => {})\n }\n pushIfSubscribed(this._primaryServer, this._primaryState)\n if (this._stdioServer) pushIfSubscribed(this._stdioServer, this._stdioState)\n for (const { server, state } of this._sessions.values()) pushIfSubscribed(server, state)\n this._modernHandler?.notify.resourceUpdated(uri)\n }\n\n /**\n * Resolve a requested URI to a registered resource, mirroring the lookup order\n * `resources/read` uses: exact static match, then original template match, then\n * (only when transforms are registered) transformed-static and\n * transformed-template matches. Returns the resource plus any template params, or\n * undefined when nothing matches. Disabled static resources are still returned by\n * exact match — callers apply the `disabled` check themselves (as read does), so\n * a hidden-but-known URI is a not-found, not a silent miss.\n */\n private _resolveResource(\n requestedUri: string,\n ): { resource: RegisteredResource; templateParams?: Record<string, string> } | undefined {\n let resource: RegisteredResource | undefined = this._staticResources.get(requestedUri)\n let templateParams: Record<string, string> | undefined\n\n // Direct template matching (original URIs — also handles hidden-but-callable resources)\n if (!resource) {\n for (const r of this._templateResources.values()) {\n if (r.config.disabled) continue\n const params = matchTemplate(r.config.uri, requestedUri)\n if (params !== null) { resource = r; templateParams = params; break }\n }\n }\n\n // Transformed static lookup\n if (!resource && this._transforms.length > 0) {\n for (const r of this._staticResources.values()) {\n if (r.config.disabled) continue\n const view = applyTransformChain<ResourceView>(\n { uri: r.config.uri, name: r.config.name ?? r.config.uri, tags: r.config.tags ?? [], mimeType: r.config.mimeType, title: r.config.title },\n this._transforms,\n (t, v) => t.transformResource?.(v),\n )\n if (view && view.uri === requestedUri) { resource = r; break }\n }\n }\n\n // Transformed template matching\n if (!resource && this._transforms.length > 0) {\n for (const r of this._templateResources.values()) {\n if (r.config.disabled) continue\n const view = applyTransformChain<ResourceView>(\n { uri: r.config.uri, name: r.config.name ?? r.config.uri, tags: r.config.tags ?? [], mimeType: r.config.mimeType, title: r.config.title },\n this._transforms,\n (t, v) => t.transformResourceTemplate?.(v),\n )\n if (view) {\n const params = matchTemplate(view.uri, requestedUri)\n if (params !== null) { resource = r; templateParams = params; break }\n }\n }\n }\n\n if (!resource) return undefined\n return { resource, templateParams }\n }\n\n // Overload: typed handler inferred from input schema\n tool<S extends StandardSchemaV1>(\n config: Omit<ToolConfig, 'input'> & { input: S },\n handler: (args: StandardSchemaV1.InferOutput<S>) => unknown,\n ): void\n // Overload: untyped handler\n tool(config: ToolConfig, handler: (args: Record<string, unknown>) => unknown): void\n // Implementation (handler typed as any to satisfy both overload signatures)\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n tool(config: ToolConfig, handler: (args: any) => any): void {\n const registered: RegisteredTool = { config, handler }\n this._tools.set(config.name, registered)\n this._notifyToolListChanged()\n for (const cb of this._toolRegisteredCallbacks) cb(registered)\n }\n\n prompt(config: PromptConfig, handler: (args?: Record<string, string>) => unknown): void {\n const name = config.name ?? (handler as { name?: string }).name\n if (!name) throw new Error('Prompt name must be provided in config or inferrable from the handler function name')\n const description = config.description ?? inferDescription(name)\n const resolvedConfig: ResolvedPromptConfig = { ...config, name, description }\n const registered: RegisteredPrompt = { config: resolvedConfig, handler }\n this._prompts.set(name, registered)\n this._notifyPromptListChanged()\n for (const cb of this._promptRegisteredCallbacks) cb(registered)\n }\n\n resource(config: ResourceConfig, handler: (params?: Record<string, string>) => unknown): void {\n const registered: RegisteredResource = { config, handler }\n if (isUriTemplate(config.uri)) {\n this._templateResources.set(config.uri, registered)\n } else {\n this._staticResources.set(config.uri, registered)\n }\n this._notifyResourceListChanged()\n for (const cb of this._resourceRegisteredCallbacks) cb(registered)\n }\n\n _removeTool(name: string): boolean {\n if (!this._tools.has(name)) return false\n this._tools.delete(name)\n this._notifyToolListChanged()\n return true\n }\n\n _removeResource(uri: string): boolean {\n if (this._staticResources.has(uri)) {\n this._staticResources.delete(uri)\n this._notifyResourceListChanged()\n return true\n }\n if (this._templateResources.has(uri)) {\n this._templateResources.delete(uri)\n this._notifyResourceListChanged()\n return true\n }\n return false\n }\n\n _removePrompt(name: string): boolean {\n if (!this._prompts.has(name)) return false\n this._prompts.delete(name)\n this._notifyPromptListChanged()\n return true\n }\n\n /** Add a transform to the pipeline. Applied to list responses in registration order. */\n transform(t: Transform): this {\n this._transforms.push(t)\n return this\n }\n\n /**\n * Dispatch a tool call through this server's middleware chain using an inherited context.\n * Used by parent servers to honour child-level middleware when routing mounted tool calls.\n */\n async _dispatchTool(\n name: string,\n rawArgs: unknown,\n ctx: McpContext,\n ) {\n const tool = this._tools.get(name)\n if (!tool || tool.config.disabled) {\n throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Unknown tool: \"${name}\"`)\n }\n if (tool.config.auth) await runAuthCheck(tool.config.auth, ctx.auth)\n\n try {\n return await contextStore.run(ctx, () =>\n runMiddlewareChain(this._middleware, 'tools/call', { name, arguments: rawArgs }, ctx, async () => {\n const args = tool.config.input\n ? await validateInput(tool.config.input, rawArgs, true)\n : rawArgs\n\n let executePromise: Promise<unknown> = Promise.resolve(tool.handler(args))\n if (tool.config.timeout) {\n const ms = tool.config.timeout\n let timer!: ReturnType<typeof setTimeout>\n const timeoutPromise = new Promise<never>((_, reject) => {\n timer = setTimeout(\n () => reject(new Error(`Tool \"${name}\" timed out after ${ms}ms`)),\n ms,\n )\n })\n executePromise = Promise.race([executePromise, timeoutPromise]).finally(() =>\n clearTimeout(timer),\n )\n }\n\n let resultValue = await executePromise\n if (tool.config.output) resultValue = await validateInput(tool.config.output, resultValue)\n // Deliberately no `stateless` argument here: this method has no per-server\n // `opts` in scope (it is only reached via `_mirrorTool`, for a mounted child),\n // and the stateless-ness that matters is the top-level server actually\n // serving the wire request, not this child. `_mirrorTool` passes an\n // InputRequiredResult straight through unwrapped, so it re-enters the\n // mounting parent's own top-level `convertResult(resultValue, opts?.stateless)`\n // call, which applies the guard with the correct flag.\n return convertResult(resultValue)\n }),\n )\n } catch (err) {\n if (err instanceof ProtocolError) throw err\n return {\n content: [{ type: 'text' as const, text: err instanceof Error ? err.message : String(err) }],\n isError: true,\n }\n }\n }\n\n /**\n * Run a resource read through this server's middleware chain using an inherited context.\n * Returns the raw handler result so the parent can apply convertResourceResult with the\n * actual requested URI (important for template resources).\n */\n async _dispatchResource(\n uri: string,\n params: Record<string, string> | undefined,\n ctx: McpContext,\n ): Promise<unknown> {\n const resource = isUriTemplate(uri)\n ? this._templateResources.get(uri)\n : this._staticResources.get(uri)\n\n if (!resource || resource.config.disabled) {\n // See resources/read handler: ResourceNotFoundError carries data.uri so the\n // miss is recognisable per the SDK contract (task-9 Req 3; task-7 F1).\n throw new ResourceNotFoundError(uri, `Unknown resource: \"${uri}\"`)\n }\n if (resource.config.auth) await runAuthCheck(resource.config.auth, ctx.auth)\n\n return contextStore.run(ctx, () =>\n runMiddlewareChain(this._middleware, 'resources/read', { uri }, ctx, async () => {\n let executePromise: Promise<unknown> = Promise.resolve(resource.handler(params))\n if (resource.config.timeout) {\n const ms = resource.config.timeout\n let timer!: ReturnType<typeof setTimeout>\n const timeoutPromise = new Promise<never>((_, reject) => {\n timer = setTimeout(\n () => reject(new Error(`Resource \"${uri}\" timed out after ${ms}ms`)),\n ms,\n )\n })\n executePromise = Promise.race([executePromise, timeoutPromise]).finally(() =>\n clearTimeout(timer),\n ) as Promise<unknown>\n }\n return await executePromise\n }),\n )\n }\n\n /**\n * Dispatch a prompt render through this server's middleware chain using an inherited context.\n */\n async _dispatchPrompt(\n name: string,\n args: Record<string, string>,\n ctx: McpContext,\n ) {\n const prompt = this._prompts.get(name)\n if (!prompt || prompt.config.disabled) {\n throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Unknown prompt: \"${name}\"`)\n }\n if (prompt.config.auth) await runAuthCheck(prompt.config.auth, ctx.auth)\n\n for (const arg of prompt.config.arguments ?? []) {\n if (arg.required && !(arg.name in args)) {\n throw new ProtocolError(\n ProtocolErrorCode.InvalidParams,\n `Missing required argument \"${arg.name}\" for prompt \"${name}\"`,\n )\n }\n }\n\n return contextStore.run(ctx, () =>\n runMiddlewareChain(this._middleware, 'prompts/get', { name, arguments: args }, ctx, async () => {\n let executePromise = Promise.resolve(prompt.handler(args))\n if (prompt.config.timeout) {\n const ms = prompt.config.timeout\n let timer!: ReturnType<typeof setTimeout>\n const timeoutPromise = new Promise<never>((_, reject) => {\n timer = setTimeout(\n () => reject(new Error(`Prompt \"${name}\" timed out after ${ms}ms`)),\n ms,\n )\n })\n executePromise = Promise.race([executePromise, timeoutPromise]).finally(() =>\n clearTimeout(timer),\n )\n }\n // Deliberately no `stateless` argument — see the matching comment in\n // `_dispatchTool` above. `_mirrorPrompt` passes an InputRequiredResult\n // straight through unwrapped, so it re-enters the mounting parent's own\n // top-level `convertPromptResult(await executePromise, opts?.stateless)`\n // call, which applies the guard with the correct top-level flag.\n return convertPromptResult(await executePromise)\n }),\n )\n }\n\n private _mirrorTool(child: FastMCP, tool: RegisteredTool, prefix?: string): void {\n const originalName = tool.config.name\n const key = prefix ? `${prefix}_${originalName}` : originalName\n if (this._tools.has(key)) throw new Error(`Tool name collision on mount: \"${key}\" is already registered`)\n // Strip runtime validators — child's _dispatchTool runs them.\n // inputSchema/outputSchema are kept so clients see the correct JSON Schema.\n const forwardedConfig: ToolConfig = { ...tool.config, name: key, input: undefined, output: undefined }\n this.tool(forwardedConfig, (args: unknown) => {\n const parentCtx = contextStore.getStore()!\n // Inject prefix-aware tool name resolver so toolRef() inside the child resolves correctly.\n const childCtx: typeof parentCtx = prefix\n ? { ...parentCtx, resolveToolName: (name) => `${prefix}_${name}` }\n : parentCtx\n // _dispatchTool already ran the child's own convertResult, so its resolved\n // value is either a finished CallToolResult (wrap in ToolResult so the parent's\n // own convertResult passes it through unchanged) or an InputRequiredResult\n // (multi-round-trip escape hatch — already recognized directly by convertResult,\n // must not be wrapped).\n //\n // LOAD-BEARING for the stateless inputRequests guard: if this ever wraps an\n // InputRequiredResult too, the parent's top-level convertResult takes the\n // `instanceof ToolResult` branch instead of the `isInputRequiredResult` one, which\n // skips assertInputRequestsAllowedStateless (mrtr.ts) entirely — a stateless legacy\n // client would then receive an unusable inputRequests result with no error. See the\n // matching comment on `_dispatchTool` above (this method's counterpart on the other\n // side of the coupling).\n return child._dispatchTool(originalName, args, childCtx).then((result) =>\n isInputRequiredResult(result) ? result : new ToolResult(result),\n )\n })\n }\n\n private _mirrorResource(child: FastMCP, resource: RegisteredResource, prefix?: string): void {\n const name = resource.config.name ?? resource.config.uri\n const originalUri = resource.config.uri\n const targetUri = prefix ? prefixResourceUri(originalUri, prefix) : originalUri\n if (this._staticResources.has(targetUri) || this._templateResources.has(targetUri)) {\n throw new Error(`Resource URI collision on mount: \"${targetUri}\" is already registered`)\n }\n const forwardedConfig: ResourceConfig = {\n ...resource.config,\n uri: targetUri,\n name: prefix ? `${prefix}_${name}` : name,\n }\n // Return the raw handler result so the parent's ReadResource handler can call\n // convertResourceResult with the actual requested URI (correct for template expansions).\n this.resource(forwardedConfig, (params?: Record<string, string>) => {\n const ctx = contextStore.getStore()!\n return child._dispatchResource(originalUri, params, ctx)\n })\n }\n\n private _mirrorPrompt(child: FastMCP, prompt: RegisteredPrompt, prefix?: string): void {\n const originalName = prompt.config.name\n const key = prefix ? `${prefix}_${originalName}` : originalName\n if (this._prompts.has(key)) throw new Error(`Prompt name collision on mount: \"${key}\" is already registered`)\n const forwardedConfig: PromptConfig = { ...(prompt.config as PromptConfig), name: key }\n this.prompt(forwardedConfig, (args?: Record<string, string>) => {\n const ctx = contextStore.getStore()!\n // LOAD-BEARING for the stateless inputRequests guard, same reasoning as _mirrorTool's\n // matching comment above: wrapping an InputRequiredResult here would skip the parent's\n // top-level convertPromptResult -> assertInputRequestsAllowedStateless (mrtr.ts) check,\n // silently handing a stateless legacy client an unusable inputRequests result.\n return child._dispatchPrompt(originalName, args ?? {}, ctx).then((result) =>\n isInputRequiredResult(result) ? result : new PromptResult(result.messages, result.description),\n )\n })\n }\n\n /** Mount a child server onto this server. All tools, resources, and prompts from the child become accessible via this server. Pass a prefix to namespace names and prevent collisions. */\n mount(child: FastMCP, prefix?: string): this {\n if (child === this) throw new Error('Cannot mount a server onto itself')\n if (this._mountedChildren.has(child)) return this\n this._mountedChildren.add(child)\n\n for (const tool of child._tools.values()) this._mirrorTool(child, tool, prefix)\n for (const resource of child._staticResources.values()) this._mirrorResource(child, resource, prefix)\n for (const resource of child._templateResources.values()) this._mirrorResource(child, resource, prefix)\n for (const prompt of child._prompts.values()) this._mirrorPrompt(child, prompt, prefix)\n\n child._toolRegisteredCallbacks.push((tool) => this._mirrorTool(child, tool, prefix))\n child._resourceRegisteredCallbacks.push((resource) => this._mirrorResource(child, resource, prefix))\n child._promptRegisteredCallbacks.push((prompt) => this._mirrorPrompt(child, prompt, prefix))\n\n // When this server closes, drain the child's owned proxy connections\n this._proxyCloseCallbacks.push(async () => {\n await Promise.all(child._proxyCloseCallbacks.map((cb) => cb().catch(() => {})))\n child._proxyCloseCallbacks.length = 0\n })\n\n return this\n }\n\n /** Register a callback invoked when this server is closed — used by proxy connections. */\n _addCloseCallback(cb: () => Promise<void>): void {\n this._proxyCloseCallbacks.push(cb)\n }\n\n /**\n * Register a provider (FastMCPApp or FastMCP) on this server.\n * All tools, resources, and prompts from the provider are mounted without a prefix.\n * For FastMCPApp, pass provider.server; for FastMCP, pass directly.\n */\n addProvider(provider: FastMCP | { server: FastMCP }): this {\n const child = 'server' in provider ? provider.server : provider\n return this.mount(child)\n }\n\n private _applyTransformsToTools(\n tools: RegisteredTool[],\n ): Array<{ name: string; title: string | undefined; description: string; originalName: string; config: ToolConfig; handler: (args: unknown) => unknown }> {\n return tools.flatMap((tool) => {\n const view = applyTransformChain<ToolView>(\n { name: tool.config.name, title: tool.config.title, description: tool.config.description, tags: tool.config.tags ?? [] },\n this._transforms,\n (t, v) => t.transformTool?.(v),\n )\n return view\n ? [{ name: view.name, title: view.title, description: view.description, originalName: tool.config.name, config: tool.config, handler: tool.handler }]\n : []\n })\n }\n\n private _applyTransformsToResources(\n resources: RegisteredResource[],\n ): Array<{ uri: string; name: string; originalUri: string; config: ResourceConfig; handler: (params?: Record<string, string>) => unknown }> {\n return resources.flatMap((r) => {\n const resolvedName = r.config.name ?? r.config.uri\n const view = applyTransformChain<ResourceView>(\n { uri: r.config.uri, name: resolvedName, tags: r.config.tags ?? [], mimeType: r.config.mimeType, title: r.config.title },\n this._transforms,\n (t, v) => t.transformResource?.(v),\n )\n return view\n ? [{ uri: view.uri, name: view.name, originalUri: r.config.uri, config: r.config, handler: r.handler }]\n : []\n })\n }\n\n private _applyTransformsToResourceTemplates(\n templates: RegisteredResource[],\n ): Array<{ uri: string; name: string; originalUri: string; config: ResourceConfig; handler: (params?: Record<string, string>) => unknown }> {\n return templates.flatMap((r) => {\n const resolvedName = r.config.name ?? r.config.uri\n const view = applyTransformChain<ResourceView>(\n { uri: r.config.uri, name: resolvedName, tags: r.config.tags ?? [], mimeType: r.config.mimeType, title: r.config.title },\n this._transforms,\n (t, v) => t.transformResourceTemplate?.(v),\n )\n return view\n ? [{ uri: view.uri, name: view.name, originalUri: r.config.uri, config: r.config, handler: r.handler }]\n : []\n })\n }\n\n private _applyTransformsToPrompts(\n prompts: RegisteredPrompt[],\n ): Array<{ name: string; description: string; originalName: string; config: ResolvedPromptConfig; handler: (args?: Record<string, string>) => unknown }> {\n return prompts.flatMap((p) => {\n const view = applyTransformChain<PromptView>(\n { name: p.config.name, description: p.config.description, tags: p.config.tags ?? [] },\n this._transforms,\n (t, v) => t.transformPrompt?.(v),\n )\n return view\n ? [{ name: view.name, description: view.description, originalName: p.config.name, config: p.config, handler: p.handler }]\n : []\n })\n }\n\n private _buildSynthesizedTools(resourceViews: ResourceView[], promptViews: PromptView[]): SynthesizedTool[] {\n if (this._transforms.length === 0) return []\n const raw = this._transforms.flatMap((t) => t.synthesizeTools?.(resourceViews, promptViews) ?? [])\n return raw.flatMap((s) => {\n const view = applyTransformChain<ToolView>(\n { name: s.name, title: s.title, description: s.description, tags: [] },\n this._transforms,\n (t, v) => t.transformTool?.(v),\n )\n return view ? [{ ...s, name: view.name, title: view.title, description: view.description }] : []\n })\n }\n\n private async _getVisibleViews(\n token: AccessToken | undefined,\n ): Promise<{ resourceViews: ResourceView[]; promptViews: PromptView[] }> {\n const visibleStatic = (\n await Promise.all(\n [...this._staticResources.values()].map(async (r) => {\n if (r.config.disabled) return null\n if (!r.config.auth) return r\n if (!token) return null\n try { await r.config.auth(token); return r } catch { return null }\n }),\n )\n ).filter((r): r is RegisteredResource => r !== null)\n\n const visibleTemplates = (\n await Promise.all(\n [...this._templateResources.values()].map(async (r) => {\n if (r.config.disabled) return null\n if (!r.config.auth) return r\n if (!token) return null\n try { await r.config.auth(token); return r } catch { return null }\n }),\n )\n ).filter((r): r is RegisteredResource => r !== null)\n\n const visiblePrompts = (\n await Promise.all(\n [...this._prompts.values()].map(async (p) => {\n if (p.config.disabled) return null\n if (!p.config.auth) return p\n if (!token) return null\n try { await p.config.auth(token); return p } catch { return null }\n }),\n )\n ).filter((p): p is RegisteredPrompt => p !== null)\n\n const resourceViews: ResourceView[] = [\n ...this._applyTransformsToResources(visibleStatic),\n ...this._applyTransformsToResourceTemplates(visibleTemplates),\n ].map((r) => ({\n uri: r.uri,\n name: r.name,\n tags: r.config.tags ?? [],\n mimeType: r.config.mimeType,\n title: r.config.title,\n }))\n\n const promptViews: PromptView[] = this._applyTransformsToPrompts(visiblePrompts).map((p) => ({\n name: p.name,\n description: p.description,\n tags: p.config.tags ?? [],\n }))\n\n return { resourceViews, promptViews }\n }\n\n /**\n * Add a middleware to the pipeline.\n *\n * Can be called at any point before the first request arrives. `setup()` is\n * called immediately on the primary server so that notification handlers and\n * other server-level side-effects are active before `connect()` / `run()` is\n * called. HTTP sessions created after `use()` will also have `setup()` called\n * via `_makeServer()`.\n */\n use(mw: Middleware): this {\n this._middleware.push(mw)\n mw.setup?.(this._primaryServer)\n return this\n }\n\n getContext(): McpContext {\n const ctx = contextStore.getStore()\n if (!ctx) throw new Error('getContext() called outside of a request handler')\n return ctx\n }\n\n /** The bound address after run() resolves for the http transport. Null for stdio or before run(). */\n get address(): ServerAddress | null {\n return this._address\n }\n\n /**\n * Whether `run()` or `connect()` has been called on this instance. Used by the\n * CLI's entrypoint loader to detect servers that already started themselves via\n * top-level code, so it doesn't attempt to start them a second time.\n */\n get isRunning(): boolean {\n return this._isRunning\n }\n\n async connect(transport: Transport): Promise<void> {\n this._isRunning = true\n // Rebuild so UI extension capability reflects all registered components.\n this._primaryServer = this._makeServer()\n await this._primaryServer.connect(transport)\n }\n\n /**\n * Serve an MCP request through a web-standard, fetch-native HTTP entrypoint.\n *\n * This entrypoint is always stateless and does not require `run()`: legacy\n * (2025-era) requests use a fresh server instance per request, while modern\n * (2026-07-28) requests share the instance's modern handler and event bus.\n * Authentication is deliberately external — `options.authInfo` is trusted and\n * passed unchanged into the protocol handler, where it is exposed as `ctx.auth`.\n * The embedding framework also owns Host/Origin validation and should abort its\n * carrying requests during shutdown; stateless legacy response streams follow\n * that request lifecycle, while `close()` terminates modern exchanges and streams.\n */\n async fetch(request: Request, options?: McpHandlerRequestOptions): Promise<Response> {\n if (request.method.toUpperCase() === 'POST' && !isJsonContentType(request.headers.get('content-type'))) {\n return new Response(\n JSON.stringify({ error: 'Unsupported Media Type: expected application/json' }),\n { status: 415, headers: { 'Content-Type': 'application/json' } },\n )\n }\n\n const legacy = await isLegacyRequest(request, options?.parsedBody)\n if (legacy) return this._getStatelessLegacyHandler()(request, options)\n return this._getModernHandler().fetch(request, options)\n }\n\n /**\n * Modern-era (2026-07-28) in-process fetch entrypoint — the `McpServerLike`\n * duck-type hook `fastmcp-ts/client`'s `Client` looks for when a caller pins\n * modern era for an in-process server (`versionNegotiation: { mode: { pin:\n * '2026-07-28' } } }`). Delegates directly to the same `createMcpHandler`\n * instance the real HTTP modern path uses (`_getModernHandler`), so this is\n * the identical dispatch a real network connection would get — no sockets,\n * same code. Modern-only (`legacy: 'reject'`): a client using `'auto'` or\n * `'legacy'` negotiation instead goes through `connect()` + `InMemoryTransport`\n * (2025-era only), unaffected by this method.\n */\n async _modernFetch(request: Request, options?: McpHandlerRequestOptions): Promise<Response> {\n return this._getModernHandler().fetch(request, options)\n }\n\n async run(options?: RunOptions): Promise<void> {\n this._isRunning = true\n const rawTransport = process.env.MCP_TRANSPORT ?? options?.transport ?? 'stdio'\n if (rawTransport !== 'stdio' && rawTransport !== 'http') {\n throw new Error(`Unknown transport: \"${rawTransport}\". Supported: stdio, http.`)\n }\n const transport = rawTransport as 'stdio' | 'http'\n\n const port = options?.port ?? parseInt(process.env.MCP_PORT ?? process.env.PORT ?? '3000', 10)\n const host = options?.host ?? process.env.MCP_HOST ?? '127.0.0.1'\n const path = options?.path ?? process.env.MCP_PATH ?? '/mcp'\n\n // Resolved for every transport so a malformed value fails loudly at startup\n // regardless of how the server is being served. Only the http path reads it.\n this._stateless = options?.stateless ?? envBool('FASTMCP_STATELESS_HTTP') ?? false\n\n if (transport === 'stdio') {\n const { StdioServerTransport, serveStdio } = await import('@modelcontextprotocol/server/stdio')\n const stdioTransport = new StdioServerTransport(options?.stdin, options?.stdout)\n // serveStdio owns the connection's era decision (from the opening exchange) and\n // pins one instance from the factory for the connection's lifetime — unlike\n // connect(), which is always 2025-era (used by in-process/test transports).\n // The factory may be invoked twice (a discarded server/discover probe instance,\n // then the real pinned one); _stdioServer always ends up holding the latter.\n // The factory receives `ctx.era` because serveStdio always classifies the\n // opening exchange's era before constructing an instance for it (including\n // the discarded probe instance, which is itself a modern-era construction) —\n // so `ctx.era` is used to fork `_makeServer`'s `modern` option the same way\n // `_getModernHandler` does, and a modern connection no longer advertises the\n // legacy-only `resources.subscribe` capability.\n this._stdioHandle = serveStdio(\n (ctx) => {\n // Capture the state Map so the resource-updated fan-out can reach this\n // connection's per-session subscription set (see _notifyResourceUpdated).\n const stdioState = new Map<string, unknown>()\n this._stdioState = stdioState\n this._stdioServer = this._makeServer(stdioState, { modern: ctx.era === 'modern' })\n return this._stdioServer\n },\n { transport: stdioTransport },\n )\n } else if (this._oauth) {\n await this._runHttpOAuth(port, host, path)\n } else {\n await this._runHttpSimple(port, host, path)\n }\n }\n\n /** Lazily builds the modern (2026-07-28) HTTP handler. One per FastMCP instance;\n * builds a fresh Server (via _makeServer) per request, matching createMcpHandler's\n * per-request-factory model. Modern-only (legacy: 'reject') — legacy (2025-era)\n * traffic is routed separately: to the existing sessionful transport by\n * _dispatchHttp, or to the stateless fallback by fetch(). This preserves the\n * session state and server-initiated-request shim for run()'s default HTTP path. */\n private _getModernHandler(): McpHttpHandler {\n if (!this._modernHandler) {\n this._modernHandler = createMcpHandler(() => this._makeServer(new Map(), { modern: true }), {\n legacy: 'reject',\n ...(this._eventBus ? { bus: this._eventBus } : {}),\n })\n }\n return this._modernHandler\n }\n\n /** Lazily builds the stateless legacy (2025-era) HTTP handler. One per FastMCP\n * instance, mirroring _getModernHandler's per-instance, per-request-factory model.\n *\n * The SDK serves each POST from a fresh instance of the factory over a transport\n * built with `sessionIdGenerator: undefined`, and answers GET and DELETE with 405\n * because both are session operations that mean nothing per request.\n *\n * Used unconditionally by fetch(), and by run() only when `_stateless` is on.\n * The sessionful transport in _dispatchLegacyHttp is untouched and remains the\n * default for listener-based HTTP deployments. */\n private _getStatelessLegacyHandler(): LegacyHttpHandler {\n if (!this._statelessLegacyHandler) {\n this._statelessLegacyHandler = legacyStatelessFallback(\n () => this._makeServer(new Map(), { stateless: true }),\n (error) => console.error('[fastmcp] stateless legacy serving failed:', error),\n )\n }\n return this._statelessLegacyHandler\n }\n\n /**\n * Dual-era HTTP dispatch shared by the OAuth and non-OAuth serve paths. Assumes CORS\n * and auth have already been handled by the caller (req.auth already set, if any —\n * both the legacy transport and the modern handler read it as pass-through authInfo).\n */\n private async _dispatchHttp(req: IncomingMessage, res: ServerResponse): Promise<void> {\n // DNS-rebinding protection runs first and is header-only, so it never reads the\n // request body — no contention with the body parsing the legacy/modern branches do\n // below. Each guard writes the SDK's 403 JSON-RPC rejection and returns false when it\n // rejects, covering BOTH the legacy sessionful transport and the modern\n // createMcpHandler path from this one shared choke point.\n if (this._hostGuard && !this._hostGuard(req, res)) return\n if (this._originGuard && !this._originGuard(req, res)) return\n\n const { toNodeHandler, toWebRequest } = await import('@modelcontextprotocol/node')\n\n // Drains the raw Node req stream and builds a web-standard Request from the\n // buffered bytes; req cannot be re-read as a stream after this.\n const request = await toWebRequest(req)\n\n if (req.method === 'POST' && !isJsonContentType(request.headers.get('content-type'))) {\n res\n .writeHead(415, { 'Content-Type': 'application/json' })\n .end(JSON.stringify({ error: 'Unsupported Media Type: expected application/json' }))\n return\n }\n\n // No parsedBody passed here, so isLegacyRequest reads from an internal clone —\n // `request` itself stays fully unread, so we can still read its body below.\n const legacy = await isLegacyRequest(request)\n\n const parsedBody = req.method === 'POST' ? await request.json().catch(() => undefined) : undefined\n\n if (legacy) {\n // Stateless serves 2025-era traffic per request through the SDK's own\n // stateless leg, so consecutive requests may land on different instances.\n // Sessionful serving is the default and keeps the in-memory session map.\n if (this._stateless) {\n // toNodeHandler wants a `{ fetch }`-shaped handler (FetchLikeMcpHandler);\n // LegacyHttpHandler is the bare fetch-shaped function itself, so wrap it\n // rather than widening toNodeHandler's own parameter type.\n await toNodeHandler({ fetch: this._getStatelessLegacyHandler() })(req, res, parsedBody)\n } else {\n await this._dispatchLegacyHttp(req, res, parsedBody)\n }\n } else {\n await toNodeHandler(this._getModernHandler())(req, res, parsedBody)\n }\n }\n\n /** Existing sessionful Streamable HTTP handling for 2025-era clients — unchanged\n * behavior from before the dual-era split, just shared between the OAuth and\n * non-OAuth serve paths instead of duplicated. */\n private async _dispatchLegacyHttp(\n req: IncomingMessage,\n res: ServerResponse,\n parsedBody: unknown,\n ): Promise<void> {\n const { NodeStreamableHTTPServerTransport } = await import('@modelcontextprotocol/node')\n const sessionId = req.headers['mcp-session-id'] as string | undefined\n let mcpTransport: NodeStreamableHTTPServerTransport\n\n if (sessionId) {\n const existing = this._sessions.get(sessionId)\n if (!existing) {\n res.writeHead(404, { 'Content-Type': 'application/json' }).end(JSON.stringify({ error: 'Session not found' }))\n return\n }\n mcpTransport = existing.transport\n } else {\n const sessionState = new Map<string, unknown>()\n const sessionServer = this._makeServer(sessionState)\n mcpTransport = new NodeStreamableHTTPServerTransport({\n sessionIdGenerator: () => randomUUID(),\n // SEP-1699 SSE resumability: a bounded per-session event store makes the\n // transport prime each 2025-11-25+ POST SSE stream with an `id`+empty-`data`\n // event (a Last-Event-ID resume anchor) and a `retry` hint, and lets a client\n // replay missed events after reconnecting. Retention is bounded (see\n // BoundedEventStore); the store is discarded with the session on close.\n eventStore: new BoundedEventStore(),\n retryInterval: LEGACY_SSE_RETRY_MS,\n onsessioninitialized: (id) => {\n this._sessions.set(id, { transport: mcpTransport, server: sessionServer, state: sessionState })\n },\n onsessionclosed: (id) => {\n const session = this._sessions.get(id)\n if (session) {\n const callbacks = (session.state.get(SESSION_CLOSE_CALLBACKS_KEY) as Array<() => void> | undefined) ?? []\n for (const cb of callbacks) cb()\n }\n this._sessions.delete(id)\n },\n })\n await sessionServer.connect(mcpTransport)\n }\n\n await mcpTransport.handleRequest(req, res, parsedBody)\n }\n\n /**\n * Resolve the DNS-rebinding Host/Origin guards for this serve from\n * `FastMCPOptions.dnsRebinding` and the bind `host`. Sets `_hostGuard` / `_originGuard`\n * (null = protection off). See the `dnsRebinding` option doc for the default posture.\n */\n private _resolveDnsRebindingGuards(host: string): void {\n const opt = this._dnsRebindingOptions\n // No config at all + a routable bind = open by default. Warn once so the operator\n // knows the posture; an explicit dnsRebinding (any shape) means they chose it.\n if (opt === undefined && !isLoopbackHost(host) && !_dnsRebindingWarned) {\n _dnsRebindingWarned = true\n console.warn(\n '[fastmcp] This HTTP server accepts requests from any Host or Origin. ' +\n 'Set dnsRebinding in FastMCPOptions to protect local deployments against DNS rebinding.',\n )\n }\n const hasExplicitAllowlist = opt?.allowedHosts !== undefined || opt?.allowedOrigins !== undefined\n // Explicit `enabled` wins; otherwise supplying an allowlist, or binding a loopback\n // host, turns protection on. A routable bind with no config stays off (see option doc).\n const enabled = opt?.enabled ?? (hasExplicitAllowlist || isLoopbackHost(host))\n if (!enabled) {\n this._hostGuard = null\n this._originGuard = null\n return\n }\n this._hostGuard = hostHeaderValidation(opt?.allowedHosts ?? localhostAllowedHostnames())\n this._originGuard = originValidation(opt?.allowedOrigins ?? localhostAllowedOrigins())\n }\n\n private async _runHttpOAuth(port: number, host: string, path: string): Promise<void> {\n this._resolveDnsRebindingGuards(host)\n const express = (await import('express')).default\n const { mcpAuthRouter } = await import('@modelcontextprotocol/server-legacy/auth')\n const { requireBearerAuth } = await import(\n '@modelcontextprotocol/server-legacy/auth'\n )\n\n const oauth = this._oauth!\n const app = express()\n\n // Bind first so we can infer the issuerUrl from the actual bound port (handles port=0)\n const httpServer = await new Promise<HttpServer>((resolve, reject) => {\n const srv = app.listen(port, host, () => resolve(srv))\n srv.on('error', reject)\n })\n\n const bound = httpServer.address() as AddressInfo\n const issuerUrl = oauth.issuerUrl ?? new URL(`http://${bound.address}:${bound.port}`)\n\n // OAuth endpoints (authorize, token, register, metadata)\n app.use(\n mcpAuthRouter({\n provider: oauth.provider,\n issuerUrl,\n scopesSupported: oauth.scopes,\n }),\n )\n\n // MCP endpoint — protected by bearer auth; requireBearerAuth sets req.auth, which\n // both the legacy transport and the modern handler read as pass-through authInfo.\n app.all(\n path,\n requireBearerAuth({ verifier: oauth.provider }),\n async (req, res) => {\n await this._dispatchHttp(req, res)\n },\n )\n\n this._httpServer = httpServer\n this._address = { host: bound.address, port: bound.port, path }\n }\n\n private async _runHttpSimple(port: number, host: string, path: string): Promise<void> {\n this._resolveDnsRebindingGuards(host)\n const { createServer } = await import('node:http')\n\n const auth = this._auth\n\n const corsHeaders = {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, DELETE, OPTIONS',\n // Mcp-Session-Id: legacy (2025-era) session routing, still served alongside\n // modern traffic. MCP-Protocol-Version/Mcp-Method/Mcp-Name: required standard\n // headers for 2026-07-28 requests (SEP-2243). Mcp-Param-* (tool-argument\n // mirroring) is deliberately not listed: browser clients skip that mirroring\n // entirely (dynamically named headers cannot be statically allow-listed for\n // credentialed CORS), so no browser ever needs to send it.\n 'Access-Control-Allow-Headers':\n 'Content-Type, Authorization, Mcp-Session-Id, MCP-Protocol-Version, Mcp-Method, Mcp-Name',\n }\n\n const httpServer = createServer(async (req, res) => {\n // CORS preflight\n if (req.method === 'OPTIONS') {\n res.writeHead(204, corsHeaders).end()\n return\n }\n\n if (req.url?.split('?')[0] !== path) {\n res.writeHead(404).end()\n return\n }\n\n // Attach CORS headers to all responses\n for (const [k, v] of Object.entries(corsHeaders)) res.setHeader(k, v)\n\n // Auth middleware\n if (auth) {\n if (isRequestVerifier(auth)) {\n let accessToken: AccessToken\n try {\n accessToken = await auth.verifyRequest(nodeRequestToHttpContext(req))\n } catch (err) {\n if (err instanceof AuthorizationError) {\n res\n .writeHead(403, { 'Content-Type': 'application/json' })\n .end(JSON.stringify({ error: err.message }))\n } else {\n res\n .writeHead(401, { 'Content-Type': 'application/json' })\n .end(JSON.stringify({ error: err instanceof Error ? err.message : 'Authentication failed' }))\n }\n return\n }\n if (!accessToken.token) {\n // Operator bug, not a client error: an empty token would collapse\n // every header-authenticated caller into one response-cache\n // partition (see CachingMiddleware's auth partitioning).\n console.error(\n '[fastmcp] RequestVerifier.verifyRequest must set AccessToken.token to a stable, non-empty per-identity value. It keys response-cache partitioning and downstream identity.',\n )\n res\n .writeHead(500, { 'Content-Type': 'application/json' })\n .end(JSON.stringify({ error: 'verifyRequest returned an AccessToken with an empty token' }))\n return\n }\n ;(req as IncomingMessage & { auth: AuthInfo }).auth = {\n token: accessToken.token,\n clientId: accessToken.clientId ?? '',\n scopes: accessToken.scopes,\n expiresAt: accessToken.expiresAt,\n extra: accessToken.claims,\n }\n } else {\n const authHeader = req.headers.authorization\n const bearer = authHeader?.startsWith('Bearer ') ? authHeader.slice(7) : null\n\n if (!bearer) {\n res\n .writeHead(401, { 'Content-Type': 'application/json', 'WWW-Authenticate': 'Bearer realm=\"mcp\"' })\n .end(JSON.stringify({ error: 'Missing bearer token' }))\n return\n }\n\n try {\n const accessToken = await auth.verify(bearer)\n ;(req as IncomingMessage & { auth: AuthInfo }).auth = {\n token: accessToken.token,\n clientId: accessToken.clientId ?? '',\n scopes: accessToken.scopes,\n expiresAt: accessToken.expiresAt,\n extra: accessToken.claims,\n }\n } catch (err) {\n if (err instanceof AuthorizationError) {\n res\n .writeHead(403, { 'Content-Type': 'application/json' })\n .end(JSON.stringify({ error: err.message }))\n } else {\n res\n .writeHead(401, { 'Content-Type': 'application/json', 'WWW-Authenticate': 'Bearer realm=\"mcp\"' })\n .end(JSON.stringify({ error: err instanceof Error ? err.message : 'Authentication failed' }))\n }\n return\n }\n }\n }\n\n await this._dispatchHttp(req, res)\n })\n\n this._httpServer = httpServer\n\n await new Promise<void>((resolve, reject) => {\n httpServer.once('error', reject)\n httpServer.listen(port, host, resolve)\n })\n\n const bound = httpServer.address() as AddressInfo\n this._address = { host: bound.address, port: bound.port, path }\n }\n\n async close(): Promise<void> {\n await Promise.all(this._proxyCloseCallbacks.map((cb) => cb().catch(() => {})))\n this._proxyCloseCallbacks.length = 0\n\n await Promise.all(\n [...this._sessions.values()].map(({ transport }) => transport.close().catch(() => {})),\n )\n this._sessions.clear()\n\n if (this._modernHandler) {\n await this._modernHandler.close()\n this._modernHandler = null\n }\n\n // LegacyHttpHandler is a bare fetch-shaped function (no `.close()` to call), but it\n // still gets nulled out here, symmetric with `_modernHandler` above: both are\n // per-instance, lazily-built handlers (see `_getStatelessLegacyHandler`'s doc\n // comment), and leaving this one set after close() would serve a stale handler\n // instance if the server is run() again instead of rebuilding a fresh one.\n this._statelessLegacyHandler = null\n\n if (this._stdioHandle) {\n await this._stdioHandle.close()\n this._stdioHandle = null\n this._stdioServer = null\n this._stdioState = null\n }\n\n if (this._httpServer) {\n await new Promise<void>((resolve, reject) => {\n this._httpServer!.close((err) => (err != null ? reject(err) : resolve()))\n })\n this._httpServer = null\n }\n this._address = null\n await this._primaryServer.close()\n }\n}\n","import type { HttpRequestContext } from '../httpContext'\n\nexport interface AccessToken {\n /** The raw bearer token string. */\n token: string\n /** The subject/client identifier from the token. */\n clientId?: string\n /** Scopes granted to the token. */\n scopes: string[]\n /** Unix timestamp (seconds) when the token expires. */\n expiresAt?: number\n /** All claims from the token payload. */\n claims: Record<string, unknown>\n}\n\nexport interface TokenVerifier {\n verify(token: string): Promise<AccessToken>\n}\n\n/**\n * Request-level verifier for HTTP deployments where identity does not arrive\n * as a bearer token. The typical case is a trusted reverse proxy that\n * authenticates the caller and forwards the resolved identity as request\n * headers.\n *\n * Called once per HTTP request, before dispatch, with that request's own FULL\n * wire headers (no redaction; `request.redactedHeaderNames` is empty here —\n * the verifier is the credential-handling code). Return an AccessToken to\n * admit the request. The result becomes `ctx.auth`, feeds per-item `auth`\n * checks and list filtering, and its `token` (hashed) keys response-cache\n * partitioning. `token` MUST therefore be a stable, non-empty, per-identity\n * value, such as the verified user id. The server rejects an empty `token`\n * with HTTP 500. Throw `AuthorizationError` to produce 403; any other throw\n * produces 401.\n *\n * SECURITY: request headers are forgeable by anyone who can reach this server\n * directly. Trust them only after verifying provenance: a shared secret the\n * proxy injects, mTLS, or network isolation. Add your provenance-secret\n * header to `FastMCPOptions.http.redactHeaders` so it never surfaces in\n * `ctx.http`. See docs: servers/auth/trusted-proxy.\n *\n * HTTP transports only. On stdio there is no HTTP request; configure a\n * TokenVerifier if you need `FASTMCP_CLI_AUTH_TOKEN` support.\n */\nexport interface RequestVerifier {\n verifyRequest(request: HttpRequestContext): Promise<AccessToken>\n}\n\n/** Narrow a `FastMCPOptions.auth` value to the request-level flavor. */\nexport function isRequestVerifier(\n v: TokenVerifier | RequestVerifier,\n): v is RequestVerifier {\n return 'verifyRequest' in v\n}\n\n/**\n * Thrown by authorization checks to produce a 403 response.\n * Any other error thrown during verification produces a 401.\n */\nexport class AuthorizationError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'AuthorizationError'\n }\n}\n","import { randomUUID } from 'node:crypto'\nimport type { EventStore, EventId, StreamId, JSONRPCMessage } from '@modelcontextprotocol/server'\n\n/**\n * Default per-session retention cap for {@link BoundedEventStore}.\n *\n * SEP-1699 resumability without unbounded growth: one store lives per legacy\n * session and holds at most this many most-recent events across all of that\n * session's SSE streams. Older events are evicted FIFO; a client that has fallen\n * further behind than the cap reconnects fresh instead of resuming.\n *\n * This is a COUNT cap (event count), not a byte cap: a burst of large tool results\n * can retain up to 256 large messages, so worst-case bytes scale with message\n * size. A POST tools/call stream normally carries only a handful of events\n * (priming + optional progress + result), so 256 is generous headroom in practice.\n *\n * The store is freed with the session only on GRACEFUL close (client `DELETE` or\n * `mcp.close()`). A client that drops its TCP connection without a `DELETE` leaves\n * the session — and this store — resident until process shutdown; that is the\n * pre-existing legacy-session retention behavior, which an event store makes\n * heavier per session. There is no idle reaper.\n */\nexport const DEFAULT_MAX_EVENTS = 256\n\n/**\n * `retry:` hint (milliseconds) sent in the SSE priming event (SEP-1699).\n *\n * The SDK transport renders a `retry:` field only when this is set, so fastmcp\n * supplies a sane fixed value rather than a tunable option (YAGNI — operators do\n * not normally tune SSE reconnect timing). 1000 ms is a responsive-yet-calm\n * reconnect cadence: fast enough to resume a dropped poll promptly, slow enough\n * to avoid a reconnect storm.\n */\nexport const LEGACY_SSE_RETRY_MS = 1000\n\n/**\n * Bounded in-memory {@link EventStore} for the legacy Streamable HTTP transport's\n * SSE resumability (SEP-1699). Enabling an event store makes the SDK transport\n * emit a priming event (an SSE `id:` with empty `data:`) — plus a `retry:` hint\n * when `retryInterval` is set — at the head of each POST SSE stream, and lets a\n * client replay missed events after reconnecting with `Last-Event-ID`.\n *\n * Retention is bounded to `maxEvents` (default {@link DEFAULT_MAX_EVENTS}): once\n * the cap is exceeded the oldest event is evicted. `Map` preserves insertion\n * order, so eviction and ordered replay are both O(1) amortized off that order.\n * The event id carries a monotonic sequence plus a UUID so ids are unique and\n * stable; stream recovery is a plain map lookup, not id parsing.\n */\nexport class BoundedEventStore implements EventStore {\n private readonly _events = new Map<EventId, { streamId: StreamId; message: JSONRPCMessage }>()\n private _seq = 0\n\n constructor(private readonly _maxEvents: number = DEFAULT_MAX_EVENTS) {}\n\n async storeEvent(streamId: StreamId, message: JSONRPCMessage): Promise<EventId> {\n // seq + uuid make the id unique and per-store ordered. The `streamId` prefix is\n // decorative (aids debugging only) — getStreamIdForEventId reads the stored\n // record, it never parses the id — so an opaque streamId can contain \"::\".\n const eventId = `${streamId}::${(this._seq++).toString(36)}::${randomUUID()}`\n this._events.set(eventId, { streamId, message })\n // FIFO eviction keeps retention bounded. Map iteration order is insertion\n // order, so the first key is always the oldest retained event.\n while (this._events.size > this._maxEvents) {\n const oldest = this._events.keys().next().value as EventId | undefined\n if (oldest === undefined) break\n this._events.delete(oldest)\n }\n return eventId\n }\n\n async getStreamIdForEventId(eventId: EventId): Promise<StreamId | undefined> {\n // Undefined for an unknown/evicted id — the SDK answers 400 rather than\n // silently replaying an empty stream, which is the correct resume error.\n return this._events.get(eventId)?.streamId\n }\n\n async replayEventsAfter(\n lastEventId: EventId,\n { send }: { send: (eventId: EventId, message: JSONRPCMessage) => Promise<void> },\n ): Promise<StreamId> {\n const anchor = this._events.get(lastEventId)\n if (!anchor) return '' // unknown/evicted anchor: nothing to replay\n const { streamId } = anchor\n let pastAnchor = false\n for (const [eventId, stored] of this._events) {\n if (eventId === lastEventId) {\n pastAnchor = true\n continue\n }\n if (pastAnchor && stored.streamId === streamId) await send(eventId, stored.message)\n }\n return streamId\n }\n}\n","import { AsyncLocalStorage } from 'node:async_hooks'\nimport type { Server, ServerContext, RequestStateCodec } from '@modelcontextprotocol/server'\nimport type { AccessToken } from './auth/types'\nimport type { InputResponses } from './mrtr'\nimport { buildHttpRequestContext, resolveSensitiveHeaders } from './httpContext'\nimport type { HttpRequestContext } from './httpContext'\n\n// ---------------------------------------------------------------------------\n// Supporting types\n// ---------------------------------------------------------------------------\n\nexport type LogLevel =\n | 'debug'\n | 'info'\n | 'notice'\n | 'warning'\n | 'error'\n | 'critical'\n | 'alert'\n | 'emergency'\n\nexport interface SamplingMessage {\n role: 'user' | 'assistant'\n content:\n | { type: 'text'; text: string }\n | { type: 'image'; data: string; mimeType: string }\n}\n\nexport interface SamplingParams {\n messages: SamplingMessage[]\n systemPrompt?: string\n /** Maximum tokens to generate. Defaults to 1024. */\n maxTokens?: number\n temperature?: number\n stopSequences?: string[]\n modelPreferences?: {\n hints?: Array<{ name?: string }>\n costPriority?: number\n speedPriority?: number\n intelligencePriority?: number\n }\n}\n\nexport interface SamplingResult {\n role: 'assistant'\n content:\n | { type: 'text'; text: string }\n | { type: 'image'; data: string; mimeType: string }\n model: string\n stopReason?: string\n}\n\n/**\n * Flat JSON Schema object describing fields to collect from the user.\n * Only primitive property types (string, number, boolean) are allowed per the MCP spec.\n */\nexport interface ElicitationSchema {\n type: 'object'\n properties: Record<\n string,\n { type: 'string' | 'number' | 'boolean'; title?: string; description?: string }\n >\n required?: string[]\n}\n\nexport interface ElicitationResult {\n /** How the user responded to the elicitation. */\n action: 'accept' | 'decline' | 'cancel'\n /** Submitted form values. Present only when action is 'accept'. */\n content?: Record<string, string | number | boolean>\n}\n\nexport interface Root {\n uri: string\n name?: string\n}\n\n// ---------------------------------------------------------------------------\n// McpContext — public interface returned by mcp.getContext()\n// ---------------------------------------------------------------------------\n\nexport interface McpContext {\n /** Auth token for the current request, if any. */\n auth: AccessToken | undefined\n /** The MCP request ID for the current call. */\n requestId: string | undefined\n\n /**\n * The HTTP request carrying the current MCP message, when serving over an\n * HTTP transport; `undefined` on stdio. Fresh per request: on a sessionful\n * connection each request's own headers appear here, never the\n * initialize-time ones. Credential headers are withheld by default and\n * listed in `http.redactedHeaderNames` (tune with `FastMCPOptions.http`).\n * Untrusted input; see HttpRequestContext's docs before deriving any\n * authorization from it.\n */\n http: HttpRequestContext | undefined\n\n // --- Logging ---\n\n /** Send a log message to the client at the specified RFC 5424 severity level. */\n log(level: LogLevel, message: string, loggerName?: string): Promise<void>\n debug(message: string, loggerName?: string): Promise<void>\n info(message: string, loggerName?: string): Promise<void>\n notice(message: string, loggerName?: string): Promise<void>\n warning(message: string, loggerName?: string): Promise<void>\n error(message: string, loggerName?: string): Promise<void>\n critical(message: string, loggerName?: string): Promise<void>\n alert(message: string, loggerName?: string): Promise<void>\n emergency(message: string, loggerName?: string): Promise<void>\n\n // --- Progress ---\n\n /**\n * Send a progress notification to the client.\n * No-op if the request did not include a `progressToken` in its `_meta`.\n */\n reportProgress(progress: number, total?: number, message?: string): Promise<void>\n\n // --- Sampling ---\n\n /**\n * Ask the client to perform an LLM inference call and return the result.\n * Throws if the client has not advertised the `sampling` capability.\n *\n * @deprecated Sampling is deprecated as of protocol revision 2026-07-28 (SEP-2577)\n * and this push-style call only works on a legacy (2025-era) connection — calling it\n * on a modern request throws a clear error naming the replacement (return\n * `inputRequired({ inputRequests: { id: inputRequired.createMessage({...}) } })` from\n * the handler instead; see `fastmcp-ts/server`'s re-exported `inputRequired`). A\n * handler written the `inputRequired` way serves both eras unchanged — the SDK's\n * legacy shim fulfils it via a real server→client request on 2025-era connections, so\n * there is rarely a reason to keep calling `ctx.sample()` directly in new code.\n */\n sample(params: SamplingParams): Promise<SamplingResult>\n\n // --- Elicitation ---\n\n /**\n * Ask the client to collect input from the user via a form dialog.\n * Throws if the client has not advertised the `elicitation` capability.\n *\n * @deprecated Throws a clear error naming the replacement when called on a modern\n * (2026-07-28) request — return `inputRequired({ inputRequests: { id:\n * inputRequired.elicit({...}) } })` instead (see `ctx.sample`'s docs; the same\n * write-once, serve-both-eras guidance applies).\n */\n elicit(message: string, schema: ElicitationSchema): Promise<ElicitationResult>\n\n // --- Roots ---\n\n /**\n * Request the list of filesystem roots the client has declared.\n * Throws if the client has not advertised the `roots` capability.\n *\n * @deprecated Roots is deprecated as of protocol revision 2026-07-28 (SEP-2577) —\n * prefer passing paths via tool parameters, resource URIs, or server configuration.\n * Throws a clear error naming `inputRequired(...)` as the multi-round-trip\n * replacement when called on a modern request (see `ctx.sample`'s docs).\n */\n listRoots(): Promise<Root[]>\n\n // --- Multi-round-trip requests (MRTR, protocol revision 2026-07-28) ---\n\n /**\n * The current round's embedded input responses, when this request is a retry of an\n * earlier `inputRequired(...)` return. `undefined` on the flow's first call (no\n * prior round to respond to). Read with the SDK's `acceptedContent(ctx.inputResponses,\n * key)` / `inputResponse(ctx.inputResponses, key)` (re-exported from\n * `fastmcp-ts/server`) rather than indexing this object directly — those readers\n * validate shape and, for `acceptedContent`, optionally the content against a schema.\n */\n inputResponses: InputResponses | undefined\n\n /**\n * Reads the current round's `requestState`, already verified and decoded when\n * `FastMCPOptions.requestState` is configured (the payload `verify` resolved with);\n * the raw, unverified wire string when it is not configured — treat that case as\n * attacker-controlled input. `undefined` when the round carried no state.\n */\n requestState<T = unknown>(): T | undefined\n\n /**\n * Seals `payload` into the opaque `requestState` string to return from\n * `inputRequired({ requestState })`. HMAC-signed via `FastMCPOptions.requestState`\n * when configured; otherwise a plain `JSON.stringify(payload)` with a console\n * warning — the resulting state is unsigned and MUST NOT be trusted for\n * anything that influences authorization, resource access, or business logic (the\n * client can read and tamper with it) unless `FastMCPOptions.requestState` is set.\n */\n mintRequestState<T = unknown>(payload: T): Promise<string>\n\n // --- Session state ---\n\n /** Retrieve a value from session-scoped state. Returns undefined if not set. */\n getState(key: string): unknown\n /** Store a value in session-scoped state. Persists for the lifetime of the session. */\n setState(key: string, value: unknown): void\n /** Remove a value from session-scoped state. */\n deleteState(key: string): void\n\n // --- Apps ---\n\n /**\n * Resolve a logical tool name to its current external name, accounting for\n * any namespace prefix applied when the owning FastMCPApp was mounted.\n * Returns the name unchanged when called outside a mounted context.\n */\n resolveToolName(name: string): string\n\n // --- Session lifecycle ---\n\n /**\n * Register a callback that runs when the current session closes.\n * Useful for releasing per-session resources (e.g. uploaded files).\n * No-op if called outside an active HTTP session.\n */\n onClose(callback: () => void): void\n}\n\n// ---------------------------------------------------------------------------\n// AsyncLocalStorage store\n// ---------------------------------------------------------------------------\n\nexport const contextStore = new AsyncLocalStorage<McpContext>()\n\n/** Internal session-state key for per-session close callbacks. */\nexport const SESSION_CLOSE_CALLBACKS_KEY = '__fastmcp_session_close_callbacks'\n\n/**\n * Pointed error thrown by `ctx.getState` / `ctx.setState` / `ctx.deleteState` on a\n * modern (2026-07-28) HTTP request. Plan §3: session state stays for stdio and legacy\n * HTTP sessions; on modern HTTP every accessor throws instead of silently dropping the\n * read/write/delete against a fresh per-request state map. The message steers to the\n * request-scoped replacement.\n */\nconst SESSION_STATE_MODERN_HTTP_ERROR =\n '[fastmcp] Session state is not available on modern HTTP requests (protocol revision 2026-07-28). ' +\n 'Each request runs statelessly with no shared session store. ' +\n 'Use ctx.requestState() to read per-request state. ' +\n 'Use ctx.mintRequestState() to carry state across a multi-round-trip flow.'\n\n/**\n * Pointed error thrown by the same three accessors on a stateless HTTP request.\n * Distinct from the modern-era message: this one names the switch an operator\n * set, because the cause is deploy configuration rather than protocol revision.\n */\nconst SESSION_STATE_STATELESS_HTTP_ERROR =\n '[fastmcp] Session state is not available on a stateless HTTP server ' +\n '(RunOptions.stateless or FASTMCP_STATELESS_HTTP). ' +\n 'Each request runs against a fresh store that is discarded when the request ends. ' +\n 'Use ctx.requestState() to read per-request state. ' +\n 'Use ctx.mintRequestState() to carry state across a multi-round-trip flow. ' +\n 'Turn stateless off to use session state, or keep state in your own external store.'\n\n/**\n * Pointed error for the server-initiated request APIs on a stateless HTTP\n * request. These need a live session: capabilities are negotiated once at\n * initialize, and the client's reply arrives as a separate request. Neither\n * survives per-request server construction. The default \"Client does not\n * support elicitation\" would blame the client for a server-side choice.\n *\n * Names `inputRequired({ requestState })` as the replacement, because it is the\n * one multi-round-trip form that works without a session; the embedded-request\n * form fails for the same reason these APIs do (see mrtr.ts's\n * INPUT_REQUESTS_STATELESS_HTTP_ERROR). Deliberately avoids the literal\n * \"inputRequests\" so the three stateless messages stay distinguishable by\n * substring in tests: only the mrtr.ts constant contains both \"inputRequests\"\n * and \"requestState\".\n */\nconst SERVER_INITIATED_STATELESS_HTTP_ERROR =\n '[fastmcp] Server-initiated requests (ctx.elicit, ctx.sample, ctx.listRoots) are not available ' +\n 'on a stateless HTTP server (RunOptions.stateless or FASTMCP_STATELESS_HTTP). ' +\n 'They need a session: client capabilities are negotiated once at initialize, and the client ' +\n 'replies on a separate request. Return inputRequired({ requestState }) to carry a ' +\n 'multi-round-trip flow without a session; the embedded-request form of inputRequired needs ' +\n 'a session too. Turn stateless off to use server-initiated requests.'\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Builds a McpContext for a single request.\n *\n * @param server The SDK Server instance for this session.\n * @param sdkCtx The SDK's own per-request ServerContext (the second argument passed to\n * every `server.setRequestHandler` callback). Supplies the request ID,\n * progress token, and — critically — `mcpReq.log` / `mcpReq.notify`, which\n * route era-appropriately: on a legacy (2025-era) connection they behave\n * exactly like the old `server.sendLoggingMessage` / `server.notification`\n * push; on a modern (2026-07-28) request, logging is gated on the\n * per-request `_meta` `logLevel` envelope key (absent = suppressed, not\n * unfiltered — see `ctx.log`'s own docs) and progress/related messages are\n * correctly attached to the current request's response (single JSON body\n * or SSE stream) rather than pushed as a request-agnostic notification.\n * @param auth The verified access token, if any.\n * @param sessionState The per-session state Map (shared across requests in the same session).\n * @param requestStateCodec The HMAC codec built from `FastMCPOptions.requestState`, if\n * configured. Backs `ctx.mintRequestState()`; `ctx.requestState()` itself always reads\n * through `sdkCtx.mcpReq.requestState()`, which already reflects whatever\n * `ServerOptions.requestState.verify` (built from this same codec) resolved.\n * @param stateless Whether this request is being served by a stateless HTTP server\n * (`_makeServer`'s `opts.stateless`). Gates session state and the server-initiated\n * request APIs on the legacy path with a message naming the switch, distinct from the\n * modern era's own established errors for the same APIs.\n */\nexport function createContext(\n server: Server,\n sdkCtx: ServerContext,\n auth: AccessToken | undefined,\n sessionState: Map<string, unknown>,\n requestStateCodec?: RequestStateCodec,\n stateless?: boolean,\n sensitiveHeaders?: ReadonlySet<string>,\n): McpContext {\n const requestId = String(sdkCtx.mcpReq.id)\n const progressToken = (sdkCtx.mcpReq._meta as { progressToken?: string | number } | undefined)\n ?.progressToken\n\n // Per-request era + transport, read from the SDK context:\n // - a modern (2026-07-28) request carries a `_meta` envelope; a legacy one does not.\n // - an HTTP-transport request carries `sdkCtx.http`; a stdio one does not.\n // These back the era gates below. `isModernEra` reorders the sample/elicit/listRoots\n // capability guard (Req 2); `isModernHttpRequest` is one of `sessionlessReason`'s two\n // inputs, which gates session state (Req 1) below.\n const isModernEra = sdkCtx.mcpReq.envelope !== undefined\n const isModernHttpRequest = isModernEra && sdkCtx.http !== undefined\n\n // Why session state is unavailable, or null when it is available. Two HTTP\n // paths are sessionless for different reasons and need different messages:\n // the modern era has no protocol session, and a stateless server discards its\n // store per request.\n const sessionlessReason: 'modern-http' | 'stateless-http' | null = isModernHttpRequest\n ? 'modern-http'\n : stateless && sdkCtx.http !== undefined\n ? 'stateless-http'\n : null\n\n const sessionStateError = (): Error =>\n new Error(\n sessionlessReason === 'modern-http'\n ? SESSION_STATE_MODERN_HTTP_ERROR\n : SESSION_STATE_STATELESS_HTTP_ERROR,\n )\n\n // Route the push-style server→client requests (sampling/createMessage,\n // elicitation/create, roots/list) raised INSIDE this tool call onto the\n // in-flight request's own response stream.\n //\n // These requests carry `relatedRequestId === undefined` by default, which the\n // SDK routes to the STANDALONE server→client stream — on legacy sessionful HTTP\n // the \"_GET_stream\". The sessionful transport DROPS such a message silently when\n // that stream is not yet attached (the client opens it fire-and-forget after\n // `initialize`, and a fresh GET carries no Last-Event-ID so nothing replays it).\n // A real client whose first post-connect operation is a sampling/elicit tool can\n // therefore hang to its timeout, awaiting a reply the server already dropped.\n //\n // Threading the in-flight request id makes the transport pick the POST stream\n // keyed by that id in `_requestToStreamMapping` — the very stream the client is\n // already awaiting the tools/call response on — so the round-trip completes with\n // no dependence on the standalone stream. This is exactly what the SDK's own\n // legacy `inputRequired` shim does for its embedded input-request legs.\n //\n // Threaded unconditionally, which is correct on every combo: the modern era gate\n // (`_assertPushApiInServedEra`) throws before any wire send, and the stdio\n // transport ignores send options entirely (a single bidirectional pipe). Only the\n // legacy sessionful-HTTP transport reads `relatedRequestId` — the path this fixes.\n // (task-25)\n const serverRequestOptions = { relatedRequestId: sdkCtx.mcpReq.id }\n\n async function log(level: LogLevel, message: string, loggerName?: string): Promise<void> {\n await sdkCtx.mcpReq.log(level, message, loggerName)\n }\n\n const httpReq = sdkCtx.http?.req\n // Default to the standard sensitive set if a call site does not pass one:\n // redaction must fail closed, never open.\n const sensitive = sensitiveHeaders ?? resolveSensitiveHeaders()\n\n return {\n auth,\n requestId,\n\n http: httpReq ? buildHttpRequestContext(httpReq, sensitive) : undefined,\n\n log,\n debug: (msg, logger) => log('debug', msg, logger),\n info: (msg, logger) => log('info', msg, logger),\n notice: (msg, logger) => log('notice', msg, logger),\n warning: (msg, logger) => log('warning', msg, logger),\n error: (msg, logger) => log('error', msg, logger),\n critical: (msg, logger) => log('critical', msg, logger),\n alert: (msg, logger) => log('alert', msg, logger),\n emergency: (msg, logger) => log('emergency', msg, logger),\n\n async reportProgress(progress, total, message) {\n if (progressToken === undefined) return\n await sdkCtx.mcpReq.notify({\n method: 'notifications/progress',\n params: {\n progressToken,\n progress,\n ...(total !== undefined ? { total } : {}),\n ...(message !== undefined ? { message } : {}),\n },\n })\n },\n\n async sample(params) {\n if (sessionlessReason === 'stateless-http') throw new Error(SERVER_INITIATED_STATELESS_HTTP_ERROR)\n // On a modern (2026-07-28) request there is no server→client channel: skip the\n // legacy capability guard so the SDK's era gate throws first, naming the\n // inputRequired(...) replacement. On legacy the capability guard stays intact\n // (getClientCapabilities reflects the initialize handshake). (task-9 Req 2)\n if (!isModernEra) {\n const caps = server.getClientCapabilities()\n if (!caps?.sampling) {\n throw new Error(\n '[fastmcp] Client does not support sampling. Ensure the client advertises the sampling capability before calling ctx.sample().',\n )\n }\n }\n const result = await server.createMessage(\n {\n messages: params.messages,\n maxTokens: params.maxTokens ?? 1024,\n ...(params.systemPrompt !== undefined ? { systemPrompt: params.systemPrompt } : {}),\n ...(params.temperature !== undefined ? { temperature: params.temperature } : {}),\n ...(params.stopSequences !== undefined ? { stopSequences: params.stopSequences } : {}),\n ...(params.modelPreferences !== undefined\n ? { modelPreferences: params.modelPreferences }\n : {}),\n },\n serverRequestOptions,\n )\n return {\n role: 'assistant' as const,\n content: result.content as SamplingResult['content'],\n model: result.model,\n stopReason: result.stopReason,\n }\n },\n\n async elicit(message, schema) {\n if (sessionlessReason === 'stateless-http') throw new Error(SERVER_INITIATED_STATELESS_HTTP_ERROR)\n // Modern era: skip the legacy capability guard so the SDK era gate throws first,\n // naming inputRequired(...). Legacy: capability guard intact. (task-9 Req 2)\n if (!isModernEra) {\n const caps = server.getClientCapabilities()\n if (!caps?.elicitation) {\n throw new Error(\n '[fastmcp] Client does not support elicitation. Ensure the client advertises the elicitation capability before calling ctx.elicit().',\n )\n }\n }\n const result = await server.elicitInput(\n {\n message,\n // Cast: our simplified ElicitationSchema is a subset of the SDK's PrimitiveSchemaDefinition union\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n requestedSchema: schema as any,\n },\n serverRequestOptions,\n )\n return {\n action: result.action,\n content: result.content as ElicitationResult['content'],\n }\n },\n\n async listRoots() {\n if (sessionlessReason === 'stateless-http') throw new Error(SERVER_INITIATED_STATELESS_HTTP_ERROR)\n // Modern era: skip the legacy capability guard so the SDK era gate throws first,\n // naming inputRequired(...). Legacy: capability guard intact. (task-9 Req 2)\n if (!isModernEra) {\n const caps = server.getClientCapabilities()\n if (!caps?.roots) {\n throw new Error(\n '[fastmcp] Client does not support roots. Ensure the client advertises the roots capability before calling ctx.listRoots().',\n )\n }\n }\n const result = await server.listRoots(undefined, serverRequestOptions)\n return result.roots\n },\n\n inputResponses: sdkCtx.mcpReq.inputResponses as InputResponses | undefined,\n\n requestState: <T = unknown>() => sdkCtx.mcpReq.requestState<T>(),\n\n async mintRequestState<T = unknown>(payload: T): Promise<string> {\n if (requestStateCodec) return requestStateCodec.mint(payload, sdkCtx)\n console.warn(\n '[fastmcp] ctx.mintRequestState() called without FastMCPOptions.requestState configured — ' +\n 'the resulting requestState is unsigned. Configure FastMCPOptions.requestState for any ' +\n 'state that influences authorization, resource access, or business logic.',\n )\n return JSON.stringify(payload)\n },\n\n getState: (key) => {\n if (sessionlessReason) throw sessionStateError()\n return sessionState.get(key)\n },\n setState: (key, value) => {\n if (sessionlessReason) throw sessionStateError()\n sessionState.set(key, value)\n },\n deleteState: (key) => {\n if (sessionlessReason) throw sessionStateError()\n sessionState.delete(key)\n },\n\n resolveToolName: (name) => name,\n\n onClose(callback) {\n const existing = (sessionState.get(SESSION_CLOSE_CALLBACKS_KEY) as Array<() => void> | undefined) ?? []\n sessionState.set(SESSION_CLOSE_CALLBACKS_KEY, [...existing, callback])\n },\n }\n}\n","import type { IncomingMessage } from 'node:http'\n\n/**\n * Header names whose VALUES are credentials for this hop. Withheld from\n * `ctx.http.headers` by default (observable via `redactedHeaderNames`) and\n * dropped by `forwardableHeaders`. Adjust per deployment with\n * `FastMCPOptions.http.redactHeaders` / `exposeHeaders`.\n */\nexport const DEFAULT_SENSITIVE_HEADERS: readonly string[] = [\n 'authorization',\n 'cookie',\n 'proxy-authorization',\n 'mcp-session-id',\n]\n\n/**\n * Effective sensitive-header set: the defaults, plus `redactHeaders`, minus\n * `exposeHeaders`. Names are compared lowercased (HTTP headers are\n * case-insensitive).\n */\nexport function resolveSensitiveHeaders(options?: {\n redactHeaders?: string[]\n exposeHeaders?: string[]\n}): Set<string> {\n const set = new Set<string>(DEFAULT_SENSITIVE_HEADERS)\n for (const h of options?.redactHeaders ?? []) set.add(h.toLowerCase())\n for (const h of options?.exposeHeaders ?? []) set.delete(h.toLowerCase())\n return set\n}\n\n/**\n * Read-only, per-request snapshot of the HTTP request that carried the current\n * MCP message. Present wherever the server is reached over an HTTP transport;\n * `undefined` on stdio.\n *\n * REDACTION: credential headers (see {@link DEFAULT_SENSITIVE_HEADERS}, tuned\n * by `FastMCPOptions.http`) are withheld from `headers` and listed in\n * `redactedHeaderNames`, so a `null` lookup is never silent. The redaction\n * guards accidental egress: tool results and logs flow into model context by\n * design. A `RequestVerifier` receives the FULL wire headers instead (its\n * `redactedHeaderNames` is empty): the verifier is the credential-handling\n * code.\n *\n * TRUST: every value here is client-controlled input. Nothing in this object\n * is authenticated. Do not derive authorization from it in handlers. For\n * header-established identity (trusted reverse proxy), configure\n * `FastMCPOptions.auth` with a `RequestVerifier` so identity flows through\n * `ctx.auth` like every other authenticated request. See docs:\n * servers/auth/trusted-proxy.\n */\nexport interface HttpRequestContext {\n /** Headers of the carrying HTTP request, minus the sensitive set. A per-request copy; mutations affect nothing. */\n readonly headers: Headers\n /** Names (lowercase, sorted) that were present on the wire but withheld from `headers`. */\n readonly redactedHeaderNames: readonly string[]\n /** HTTP method of the carrying request (e.g. 'POST'). */\n readonly method: string\n /**\n * Origin-form request target (path + query, e.g. '/mcp?tenant=a'). Scheme and\n * authority are deliberately absent: behind a proxy this server cannot know\n * the external URL. Reconstruct it from your proxy's forwarded headers if you\n * need it.\n */\n readonly url: string\n}\n\n/**\n * Build an {@link HttpRequestContext} from a web-standard Request (the SDK's\n * `ctx.http.req`), withholding `sensitiveHeaders`.\n */\nexport function buildHttpRequestContext(\n req: Request,\n sensitiveHeaders: ReadonlySet<string>,\n): HttpRequestContext {\n const headers = new Headers()\n const redacted: string[] = []\n req.headers.forEach((value, name) => {\n // Headers.forEach reports names lowercased.\n if (sensitiveHeaders.has(name)) {\n redacted.push(name)\n return\n }\n headers.append(name, value)\n })\n redacted.sort()\n let url: string\n try {\n const u = new URL(req.url)\n url = u.pathname + u.search\n } catch {\n url = req.url // already origin-form\n }\n return { headers, redactedHeaderNames: redacted, method: req.method, url }\n}\n\n/**\n * Build an {@link HttpRequestContext} from a Node IncomingMessage, with NO\n * redaction. This feeds `RequestVerifier.verifyRequest` at the HTTP auth gate;\n * the verifier is the credential-handling code and must see the wire.\n */\nexport function nodeRequestToHttpContext(req: IncomingMessage): HttpRequestContext {\n const headers = new Headers()\n for (const [name, value] of Object.entries(req.headers)) {\n if (value === undefined) continue\n if (Array.isArray(value)) {\n for (const v of value) headers.append(name, v)\n } else {\n headers.append(name, value)\n }\n }\n return { headers, redactedHeaderNames: [], method: req.method ?? 'GET', url: req.url ?? '/' }\n}\n\nconst UNFORWARDABLE = new Set([\n // credentials (see also DEFAULT_SENSITIVE_HEADERS; kept here too so the\n // helper is safe on Headers that did not come from a redacted ctx.http)\n 'authorization', 'cookie', 'proxy-authorization', 'proxy-authenticate',\n // hop-by-hop (RFC 9110 §7.6.1) and connection management\n 'connection', 'keep-alive', 'te', 'trailer', 'transfer-encoding', 'upgrade', 'proxy-connection',\n // message framing / target-specific\n 'host', 'content-length', 'content-type', 'expect',\n])\n\n/**\n * Copy of `headers` that is safe to attach to an outbound request to another\n * service. Drops credentials (authorization, cookie, proxy-*), hop-by-hop\n * headers, message-framing headers (host, content-length, content-type,\n * expect), and every `mcp-*` protocol header. Deployment-specific credential\n * headers are covered by `FastMCPOptions.http.redactHeaders`: they are already\n * absent from `ctx.http.headers`. `include` re-admits specific names.\n * Re-admitting 'authorization' forwards the caller's credential; the MCP spec\n * forbids passing the inbound token to upstream APIs, so mint your own\n * upstream credential instead.\n */\nexport function forwardableHeaders(\n headers: Headers,\n options?: { include?: string[] },\n): Headers {\n const include = new Set((options?.include ?? []).map((h) => h.toLowerCase()))\n const out = new Headers()\n headers.forEach((value, name) => {\n if (include.has(name)) {\n out.append(name, value)\n return\n }\n if (UNFORWARDABLE.has(name) || name.startsWith('mcp-')) return\n out.append(name, value)\n })\n return out\n}\n","const TRUE_VALUES = new Set(['1', 'true', 'yes', 'on'])\nconst FALSE_VALUES = new Set(['0', 'false', 'no', 'off'])\n\n/**\n * Read a boolean environment variable.\n *\n * Returns `undefined` when the variable is unset or empty so the caller can fall\n * through to its own default. Throws when the variable is set to a value that is\n * not recognised.\n *\n * The throw is deliberate. A misspelled or malformed boolean operations variable\n * must fail loudly at startup rather than silently fall back to its default. A\n * typo in FASTMCP_STATELESS_HTTP that goes unnoticed leaves a fleet sessionful\n * when the operator believes it is stateless, and that class of mistake tends to\n * surface later as a partial failure rate in production rather than as an error\n * at deploy time.\n */\nexport function envBool(name: string): boolean | undefined {\n const raw = process.env[name]\n if (raw === undefined || raw.trim() === '') return undefined\n const normalized = raw.trim().toLowerCase()\n if (TRUE_VALUES.has(normalized)) return true\n if (FALSE_VALUES.has(normalized)) return false\n throw new Error(\n `[fastmcp] ${name} must be one of 1/true/yes/on or 0/false/no/off (case-insensitive). Received: ${JSON.stringify(raw)}`,\n )\n}\n","import { ProtocolError, ProtocolErrorCode, Server } from \"@modelcontextprotocol/server\";\nimport { createHash } from 'node:crypto'\nimport type { McpContext } from './context'\n\n// ---------------------------------------------------------------------------\n// Core types\n// ---------------------------------------------------------------------------\n\nexport interface MiddlewareContext<T = unknown> {\n readonly method: string\n readonly request: T\n readonly mcpContext: McpContext\n}\n\nexport type Next<R = unknown> = () => Promise<R>\n\n/**\n * A middleware hook. Either call `next()` and return (optionally transforming) its\n * result, or short-circuit by returning your own result without calling `next()`.\n * The return is typed `Promise<unknown>` because a hook can substitute any result\n * shape for the method it intercepts; the framework resolves the concrete type at\n * the call boundary.\n */\nexport interface Middleware {\n /** Called once per Server instance. Use to register notification handlers or other server-level setup. */\n setup?(server: Server): void\n\n // Coarse hook — fires for every request that has no more-specific hook on this instance\n onRequest?(ctx: MiddlewareContext, next: Next): Promise<unknown>\n\n // Per-method hooks — take precedence over onRequest for their specific method\n onCallTool?(ctx: MiddlewareContext, next: Next): Promise<unknown>\n onListTools?(ctx: MiddlewareContext, next: Next): Promise<unknown>\n onReadResource?(ctx: MiddlewareContext, next: Next): Promise<unknown>\n onListResources?(ctx: MiddlewareContext, next: Next): Promise<unknown>\n onListResourceTemplates?(ctx: MiddlewareContext, next: Next): Promise<unknown>\n onGetPrompt?(ctx: MiddlewareContext, next: Next): Promise<unknown>\n onListPrompts?(ctx: MiddlewareContext, next: Next): Promise<unknown>\n}\n\n// ---------------------------------------------------------------------------\n// Chain execution\n// ---------------------------------------------------------------------------\n\nconst METHOD_HOOK_KEY: Partial<Record<string, keyof Middleware>> = {\n 'tools/call': 'onCallTool',\n 'tools/list': 'onListTools',\n 'resources/read': 'onReadResource',\n 'resources/list': 'onListResources',\n 'resources/templates/list': 'onListResourceTemplates',\n 'prompts/get': 'onGetPrompt',\n 'prompts/list': 'onListPrompts',\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype AnyHookFn = (ctx: MiddlewareContext<any>, next: Next<any>) => Promise<any>\n\nfunction selectHook(mw: Middleware, method: string): AnyHookFn | null {\n const key = METHOD_HOOK_KEY[method]\n const specific = key ? (mw[key] as AnyHookFn | undefined) : undefined\n if (specific) return specific.bind(mw)\n if (mw.onRequest) return (mw.onRequest as AnyHookFn).bind(mw)\n return null\n}\n\n/** Build and execute the middleware chain, calling `handler` at the innermost level. */\nexport function runMiddlewareChain<R>(\n middleware: Middleware[],\n method: string,\n request: unknown,\n mcpContext: McpContext,\n handler: () => Promise<R>,\n): Promise<R> {\n const hooks: AnyHookFn[] = []\n for (const mw of middleware) {\n const hook = selectHook(mw, method)\n if (hook) hooks.push(hook)\n }\n\n const ctx: MiddlewareContext = { method, request, mcpContext }\n\n function dispatch(i: number): Promise<R> {\n if (i >= hooks.length) return handler()\n return hooks[i](ctx, () => dispatch(i + 1))\n }\n\n return dispatch(0)\n}\n\n// ---------------------------------------------------------------------------\n// Built-in middleware\n// ---------------------------------------------------------------------------\n\n/** Logs every request with method, outcome, and elapsed time. */\nexport class LoggingMiddleware implements Middleware {\n constructor(private readonly emit: (msg: string) => void = console.log) {}\n\n async onRequest(ctx: MiddlewareContext, next: Next): Promise<unknown> {\n const t0 = Date.now()\n this.emit(`[fastmcp] → ${ctx.method}`)\n try {\n const result = await next()\n this.emit(`[fastmcp] ← ${ctx.method} (${Date.now() - t0}ms)`)\n return result\n } catch (err) {\n this.emit(\n `[fastmcp] ✗ ${ctx.method} (${Date.now() - t0}ms): ${err instanceof Error ? err.message : String(err)}`,\n )\n throw err\n }\n }\n}\n\n/**\n * Custom cache key function. Receives the full middleware context so callers can\n * incorporate auth identity or any other dimension into the key.\n *\n * **The default key already partitions by auth identity — you do not need a `keyFn`\n * for auth safety.** The default is\n * `\"method:<auth-partition>:JSON(params)\"`, where the auth partition is `anon` for a\n * request with no bearer token and the SHA-256 hash of the bearer token for an\n * authenticated request. So a result computed under one identity is never served under\n * another (anonymous and authenticated included, both directions), and auth-filtered\n * list results (tools, resources, prompts) stay per identity.\n *\n * **A custom `keyFn` REPLACES the default partitioning entirely — you then own it.**\n * The key you return is used verbatim; the auth partition is not merged in. If your\n * cached values depend on the caller identity, include an identity dimension yourself.\n * Use the same dimension the default uses — the bearer token, HASHED. Never place the\n * raw token in a cache key:\n *\n * ```ts\n * import { createHash } from 'node:crypto'\n *\n * new CachingMiddleware(60_000, (ctx) => {\n * const token = ctx.mcpContext.auth?.token\n * const id = token ? createHash('sha256').update(token).digest('hex') : 'anon'\n * return `${ctx.method}:${id}:${JSON.stringify(ctx.request)}`\n * })\n * ```\n *\n * `clientId` is a coarser alternative (`ctx.mcpContext.auth?.clientId`), but two tokens\n * may share a `clientId` yet differ in scope, so a `clientId` key can merge identities\n * that must stay apart. Prefer the hashed token.\n */\nexport type CacheKeyFn = (ctx: MiddlewareContext) => string\n\n/** TTL-based response cache. The default key is method + auth partition + serialised\n * request params, so a cached result is served only to the identity that produced it\n * (anonymous is its own partition; authenticated requests partition by bearer-token\n * hash). Auth-filtered results (tools/list visibility, resources/read contents,\n * prompts, completion) therefore never cross identities. Pass a custom `keyFn` to\n * replace this partitioning — the caller then owns identity partitioning (see\n * {@link CacheKeyFn}). */\nexport class CachingMiddleware implements Middleware {\n private readonly _cache = new Map<string, { value: unknown; expiresAt: number }>()\n\n /**\n * Side-effectful control RPCs that must never be cached. The cache keys on method\n * + params, but these methods MUTATE per-session state (the resource subscription\n * set) instead of computing a pure function of their params. A repeated\n * `resources/subscribe` sends byte-identical params, so serving the cached `{}`\n * would skip the handler: after subscribe → unsubscribe → subscribe within the\n * TTL the client believes it re-subscribed, but the server never re-added the URI\n * and `notifyResourceUpdated` delivers nothing. Same class as the inputRequired\n * exclusion in `onRequest`.\n *\n * `completion/complete` is deliberately NOT here: it is read-only — a pure\n * function of `ref` + `argument` with no state mutation — so caching it is correct,\n * exactly like `tools/list` or `resources/read`. (Its auth-per-identity concern is\n * the same one every read method has and is handled by the default key's auth\n * partitioning — see _authPartition — not by excluding it here.)\n */\n private static readonly _nonCacheableMethods = new Set<string>([\n 'resources/subscribe',\n 'resources/unsubscribe',\n ])\n\n constructor(\n readonly ttl: number = 60_000,\n private readonly _keyFn?: CacheKeyFn,\n ) {}\n\n /**\n * Auth partition for the default cache key. A cache entry written under one auth\n * identity must never be served under another, so the identity is folded into the\n * key. Anonymous requests (`mcpContext.auth` undefined — a stdio request without a\n * CLI env token, and every request to a server with no auth configured) share the\n * single `anon` partition, matching the pre-partition default. An authenticated request is\n * partitioned by the SHA-256 hash of its bearer token: the token is the identity\n * credential, so two callers can never collide, and its hash — never the raw token —\n * goes in the key. The bearer token is used rather than `clientId` because two tokens\n * may share a `clientId` yet differ in scope, which must NOT share a partition. A\n * 64-char hex hash can never equal the literal `anon`, so anonymous and authenticated\n * partitions are disjoint in both directions.\n */\n private static _authPartition(ctx: MiddlewareContext): string {\n const token = ctx.mcpContext.auth?.token\n if (token === undefined) return 'anon'\n return createHash('sha256').update(token).digest('hex')\n }\n\n async onRequest(ctx: MiddlewareContext, next: Next): Promise<unknown> {\n // Side-effectful control RPC exclusion: never serve or store a method that\n // mutates per-session state (see _nonCacheableMethods).\n if (CachingMiddleware._nonCacheableMethods.has(ctx.method)) return next()\n\n // Multi-round-trip (inputRequired) exclusion. A retry re-sends byte-identical\n // tools/call params — the SDK lifts inputResponses / requestState out of params —\n // so the default cache key is identical across every round. Caching would replay\n // the first round's input_required result forever and the tool could never\n // complete. Rule: never serve/store when the request carries per-round input, and\n // never store an input_required result (each embeds a single-use flow token).\n const mc = ctx.mcpContext\n const carriesRoundInput = mc.inputResponses !== undefined || mc.requestState() !== undefined\n if (carriesRoundInput) return next()\n\n // Default key partitions by auth identity (see _authPartition) so a result cached\n // for one identity is never served to another. A custom keyFn REPLACES this — its\n // owner is then responsible for any identity partitioning (see CacheKeyFn docs).\n const key = this._keyFn\n ? this._keyFn(ctx as MiddlewareContext)\n : `${ctx.method}:${CachingMiddleware._authPartition(ctx)}:${JSON.stringify(ctx.request)}`\n const entry = this._cache.get(key)\n if (entry && entry.expiresAt > Date.now()) return entry.value\n const result = await next()\n if (!isInputRequiredResultValue(result)) {\n this._cache.set(key, { value: result, expiresAt: Date.now() + this.ttl })\n }\n return result\n }\n}\n\n/** True when a handler result is a multi-round-trip `input_required` round (never cacheable). */\nfunction isInputRequiredResultValue(value: unknown): boolean {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { resultType?: unknown }).resultType === 'input_required'\n )\n}\n\n/** Fixed-window counter rate limiter. Resets to full capacity after every windowMs interval. */\nexport class RateLimitingMiddleware implements Middleware {\n private _tokens: number\n private _lastRefill: number\n\n constructor(\n private readonly limit: number,\n private readonly windowMs: number = 60_000,\n ) {\n this._tokens = limit\n this._lastRefill = Date.now()\n }\n\n async onRequest(ctx: MiddlewareContext, next: Next): Promise<unknown> {\n const now = Date.now()\n if (now - this._lastRefill >= this.windowMs) {\n this._tokens = this.limit\n this._lastRefill = now\n }\n if (this._tokens <= 0) {\n throw new ProtocolError(ProtocolErrorCode.InvalidRequest, 'Rate limit exceeded')\n }\n this._tokens--\n return next()\n }\n}\n\n/** Rejects responses whose JSON serialisation exceeds maxBytes. */\nexport class SizeLimitingMiddleware implements Middleware {\n constructor(private readonly maxBytes: number) {}\n\n async onRequest(ctx: MiddlewareContext, next: Next): Promise<unknown> {\n const result = await next()\n const size = Buffer.byteLength(JSON.stringify(result), 'utf8')\n if (size > this.maxBytes) {\n throw new ProtocolError(\n ProtocolErrorCode.InternalError,\n `Response size (${size} bytes) exceeds limit (${this.maxBytes} bytes)`,\n )\n }\n return result\n }\n}\n\n/**\n * Normalises errors thrown by handlers to proper MCP shapes:\n * - tools/call plain errors → { isError: true, content: [...] } (per MCP spec)\n * - tools/call McpError → re-thrown as a protocol-level error\n * - all other methods → McpError(InternalError, message)\n *\n * Re-throwing McpError from onCallTool ensures that middleware-level errors\n * (e.g. from RateLimitingMiddleware or SizeLimitingMiddleware stacked before\n * this middleware) always propagate as protocol errors and are never silently\n * converted to isError:true tool responses.\n */\nexport class ErrorNormalizationMiddleware implements Middleware {\n async onCallTool(ctx: MiddlewareContext, next: Next): Promise<unknown> {\n try {\n return await next()\n } catch (err) {\n if (err instanceof ProtocolError) throw err\n return {\n content: [{ type: 'text' as const, text: err instanceof Error ? err.message : String(err) }],\n isError: true,\n }\n }\n }\n\n async onRequest(ctx: MiddlewareContext, next: Next): Promise<unknown> {\n try {\n return await next()\n } catch (err) {\n if (err instanceof ProtocolError) throw err\n throw new ProtocolError(\n ProtocolErrorCode.InternalError,\n err instanceof Error ? err.message : String(err),\n )\n }\n }\n}\n\n/**\n * Intercepts `notifications/cancelled` from the client and aborts the matching\n * in-flight handler via Promise.race + AbortController.\n *\n * KNOWN GAP (2026-07-28): this only covers legacy (2025-era) and stdio cancellation.\n * On a modern Streamable HTTP connection, the SDK signals cancellation by closing the\n * request's response stream rather than sending `notifications/cancelled` — the client\n * is correctly told the call was cancelled either way, but a handler registered here\n * keeps running server-side to completion on the modern path, since this middleware\n * never observes that stream closure. The SDK exposes it per-request as\n * `ctx.mcpReq.signal` (a `BaseContext` field, present on every era) — unifying this\n * middleware with that signal (so long-running handlers actually stop executing on\n * both eras) is tracked as follow-up work, not yet implemented here.\n */\nexport class CancellationMiddleware implements Middleware {\n private readonly _inFlight = new Map<string, AbortController>()\n\n setup(server: Server): void {\n server.setNotificationHandler('notifications/cancelled', (notification) => {\n const requestId = String(notification.params.requestId)\n this._inFlight.get(requestId)?.abort()\n })\n }\n\n async onRequest(ctx: MiddlewareContext, next: Next): Promise<unknown> {\n const { requestId } = ctx.mcpContext\n if (!requestId) return next()\n\n const controller = new AbortController()\n this._inFlight.set(requestId, controller)\n\n const abortPromise = new Promise<never>((_, reject) => {\n controller.signal.addEventListener('abort', () =>\n reject(new ProtocolError(ProtocolErrorCode.InternalError, 'Request was cancelled by the client')),\n )\n })\n\n try {\n return await Promise.race([next(), abortPromise])\n } finally {\n this._inFlight.delete(requestId)\n }\n }\n}\n","// ---------------------------------------------------------------------------\n// View types — simplified projections passed to transforms\n// ---------------------------------------------------------------------------\n\nexport interface ToolView {\n readonly name: string\n /** Human-readable display name shown in UIs. Takes precedence over `name` for display purposes. */\n readonly title?: string\n readonly description: string\n readonly tags: readonly string[]\n}\n\nexport interface ResourceView {\n readonly uri: string\n readonly name: string\n readonly tags: readonly string[]\n readonly mimeType?: string\n readonly title?: string\n}\n\nexport interface PromptView {\n readonly name: string\n readonly description: string\n readonly tags: readonly string[]\n}\n\n// ---------------------------------------------------------------------------\n// Synthesized tool — produced by a transform from other components\n// ---------------------------------------------------------------------------\n\nexport interface SynthesizedTool {\n readonly name: string\n /** Human-readable display name shown in UIs. Takes precedence over `name` for display purposes. */\n readonly title?: string\n readonly description: string\n readonly inputSchema?: Record<string, unknown>\n readonly auth?: import('./auth/authorization').AuthCheck\n readonly timeout?: number\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly handler: (args: any) => unknown\n}\n\n// ---------------------------------------------------------------------------\n// Transform interface\n// ---------------------------------------------------------------------------\n\nexport interface Transform {\n /**\n * Transform a tool view before it appears in list responses.\n * Return a modified view to rename/redescribe; return null to hide the tool\n * from list responses (it remains callable by its original name).\n */\n transformTool?(view: ToolView): ToolView | null\n\n /** Transform a static resource view. */\n transformResource?(view: ResourceView): ResourceView | null\n\n /** Transform a URI-template resource view. */\n transformResourceTemplate?(view: ResourceView): ResourceView | null\n\n /** Transform a prompt view. */\n transformPrompt?(view: PromptView): PromptView | null\n\n /**\n * Synthesize additional tools derived from the current resource and prompt lists.\n * Called at request time so the snapshot is always fresh.\n */\n synthesizeTools?(resources: ResourceView[], prompts: PromptView[]): SynthesizedTool[]\n}\n\n// ---------------------------------------------------------------------------\n// Internal helper — apply a chain of transforms to a single view\n// ---------------------------------------------------------------------------\n\nexport function applyTransformChain<T>(\n value: T,\n transforms: Transform[],\n pick: (t: Transform, v: T) => T | null | undefined,\n): T | null {\n let current: T | null = value\n for (const t of transforms) {\n if (current === null) break\n const next = pick(t, current)\n if (next !== undefined) current = next\n }\n return current\n}\n\n// ---------------------------------------------------------------------------\n// Built-in transforms\n// ---------------------------------------------------------------------------\n\n/** Rename a single tool. The original name still resolves at call time. */\nexport function renameTool(originalName: string, newName: string): Transform {\n return {\n transformTool: (v) => (v.name === originalName ? { ...v, name: newName } : v),\n }\n}\n\n/** Rewrite the description of a single tool. */\nexport function redescribeTool(toolName: string, description: string): Transform {\n return {\n transformTool: (v) => (v.name === toolName ? { ...v, description } : v),\n }\n}\n\n/**\n * Hide components whose predicate returns false.\n * Hidden items are removed from list responses but remain callable by original name.\n */\nexport class FilterTransform implements Transform {\n constructor(\n private readonly predicates: {\n tools?: (v: ToolView) => boolean\n resources?: (v: ResourceView) => boolean\n /** When omitted, falls back to the `resources` predicate. */\n resourceTemplates?: (v: ResourceView) => boolean\n prompts?: (v: PromptView) => boolean\n },\n ) {}\n\n transformTool(v: ToolView): ToolView | null {\n return (this.predicates.tools?.(v) ?? true) ? v : null\n }\n transformResource(v: ResourceView): ResourceView | null {\n return (this.predicates.resources?.(v) ?? true) ? v : null\n }\n transformResourceTemplate(v: ResourceView): ResourceView | null {\n const pred = this.predicates.resourceTemplates ?? this.predicates.resources\n return (pred?.(v) ?? true) ? v : null\n }\n transformPrompt(v: PromptView): PromptView | null {\n return (this.predicates.prompts?.(v) ?? true) ? v : null\n }\n}\n\n/** Prefix all tool, prompt, and resource names with a string. URIs are left unchanged. */\nexport class NamespaceTransform implements Transform {\n constructor(private readonly prefix: string) {}\n\n transformTool(v: ToolView): ToolView {\n return { ...v, name: `${this.prefix}${v.name}` }\n }\n transformResource(v: ResourceView): ResourceView {\n return { ...v, name: `${this.prefix}${v.name}` }\n }\n transformResourceTemplate(v: ResourceView): ResourceView {\n return { ...v, name: `${this.prefix}${v.name}` }\n }\n transformPrompt(v: PromptView): PromptView {\n return { ...v, name: `${this.prefix}${v.name}` }\n }\n}\n\n/** Expose registered resources as a `list_resources` tool. */\nexport class ResourcesAsTools implements Transform {\n synthesizeTools(resources: ResourceView[]): SynthesizedTool[] {\n return [\n {\n name: 'list_resources',\n description: 'List all available MCP resources',\n inputSchema: { type: 'object', properties: {} },\n handler: () => resources.map((r) => ({ uri: r.uri, name: r.name, mimeType: r.mimeType })),\n },\n ]\n }\n}\n\n/** Expose registered prompts as a `list_prompts` tool. */\nexport class PromptsAsTools implements Transform {\n synthesizeTools(_resources: ResourceView[], prompts: PromptView[]): SynthesizedTool[] {\n return [\n {\n name: 'list_prompts',\n description: 'List all available MCP prompts',\n inputSchema: { type: 'object', properties: {} },\n handler: () => prompts.map((p) => ({ name: p.name, description: p.description })),\n },\n ]\n }\n}\n\n/**\n * Expose only components whose tags include the specified version string.\n * Components with no tags are always excluded.\n */\nexport class VersionFilter implements Transform {\n constructor(private readonly version: string) {}\n\n private _matches(tags: readonly string[]): boolean {\n return tags.includes(this.version)\n }\n\n transformTool(v: ToolView): ToolView | null {\n return this._matches(v.tags) ? v : null\n }\n transformResource(v: ResourceView): ResourceView | null {\n return this._matches(v.tags) ? v : null\n }\n transformResourceTemplate(v: ResourceView): ResourceView | null {\n return this._matches(v.tags) ? v : null\n }\n transformPrompt(v: PromptView): PromptView | null {\n return this._matches(v.tags) ? v : null\n }\n}\n","import { ProtocolError, ProtocolErrorCode } from \"@modelcontextprotocol/server\";\nimport type { CallToolResult } from \"@modelcontextprotocol/server\";\nimport type { StandardSchemaV1 } from '@standard-schema/spec'\nimport { isInputRequiredResult, assertInputRequestsAllowedStateless } from './mrtr'\nimport type { InputRequiredResult } from './mrtr'\n\nexport class Image {\n constructor(\n readonly buffer: Buffer | Uint8Array,\n readonly mimeType: string,\n ) {}\n}\n\nexport class File {\n constructor(\n readonly buffer: Buffer | Uint8Array,\n readonly name: string,\n readonly mimeType: string,\n ) {}\n}\n\nexport class ToolResult {\n constructor(readonly result: CallToolResult) {}\n}\n\nexport function convertResult(\n value: unknown,\n stateless?: boolean,\n): CallToolResult | InputRequiredResult {\n // Multi-round-trip escape hatch (protocol revision 2026-07-28): a handler that\n // needs more input from the client returns inputRequired({ ... }) — passed through\n // untouched, exactly like the ToolResult escape hatch below. See inputRequired /\n // acceptedContent / inputResponse (re-exported from fastmcp-ts/server).\n //\n // `stateless` is undefined for FastMCP.ts's `_dispatchTool` helper (mounted-server\n // dispatch): that call site has no per-server `opts` in scope, and its result flows\n // back up through the mounting parent's own top-level `convertResult` call, which\n // does have `opts.stateless` and applies the guard there — see mrtr.ts's\n // assertInputRequestsAllowedStateless doc for why the check must key off that\n // per-server flag rather than an instance-wide one.\n if (isInputRequiredResult(value)) {\n assertInputRequestsAllowedStateless(value, stateless)\n return value\n }\n if (value instanceof ToolResult) {\n return value.result\n }\n if (value instanceof Image) {\n return {\n content: [\n {\n type: 'image',\n data: Buffer.from(value.buffer).toString('base64'),\n mimeType: value.mimeType,\n },\n ],\n }\n }\n if (value instanceof File) {\n return {\n content: [\n {\n type: 'resource',\n resource: {\n uri: `file://${value.name}`,\n mimeType: value.mimeType,\n blob: Buffer.from(value.buffer).toString('base64'),\n },\n },\n ],\n }\n }\n if (value === undefined || value === null) {\n return { content: [] }\n }\n if (Array.isArray(value)) {\n console.warn(\n '[fastmcp] Tool returned an array — structuredContent will not be set (MCP spec requires a plain object). Wrap in an object or use ToolResult to suppress this warning.',\n )\n return {\n content: [{ type: 'text', text: JSON.stringify(value) }],\n }\n }\n if (typeof value === 'object') {\n const json = JSON.stringify(value)\n return {\n content: [{ type: 'text', text: json }],\n structuredContent: value as Record<string, unknown>,\n }\n }\n // string, number, boolean\n return {\n content: [{ type: 'text', text: String(value) }],\n }\n}\n\nexport async function toJsonSchema(\n schema: StandardSchemaV1,\n context?: string,\n): Promise<Record<string, unknown>> {\n // Strategy 1: schema-native .toJsonSchema() method (ArkType and any library following this convention)\n const maybeNative = schema as { toJsonSchema?: () => unknown }\n if (typeof maybeNative.toJsonSchema === 'function') {\n try {\n const result = maybeNative.toJsonSchema()\n if (result !== null && typeof result === 'object') {\n return result as Record<string, unknown>\n }\n } catch {\n // fall through\n }\n }\n\n // Strategy 2: Zod v4 z.toJSONSchema()\n try {\n const { z } = await import('zod')\n return (z as unknown as { toJSONSchema: (s: unknown) => Record<string, unknown> }).toJSONSchema(\n schema,\n )\n } catch {\n // fall through\n }\n\n const where = context ? ` for ${context}` : ''\n console.warn(\n `[fastmcp] Could not auto-generate JSON schema${where}. Sending { type: 'object' } to clients. Provide an explicit 'inputSchema' in ToolConfig to suppress this warning.`,\n )\n return { type: 'object' }\n}\n\nexport async function validateInput<S extends StandardSchemaV1>(\n schema: S,\n input: unknown,\n throwAsProtocolError = false,\n): Promise<StandardSchemaV1.InferOutput<S>> {\n const result = await schema['~standard'].validate(input)\n if (result.issues) {\n const messages = result.issues.map((i) => i.message).join('; ')\n if (throwAsProtocolError) {\n throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Validation failed: ${messages}`)\n }\n throw new Error(`Validation failed: ${messages}`)\n }\n return result.value as StandardSchemaV1.InferOutput<S>\n}\n","/**\n * Multi Round-Trip Requests (MRTR) — protocol revision 2026-07-28.\n *\n * On the modern era, servers can no longer send server-initiated requests\n * (sampling, elicitation, roots) mid-call — there is no server→client channel.\n * Instead, a `tools/call`, `prompts/get`, or `resources/read` handler that needs\n * more input from the client returns `inputRequired({ ... })`. The client\n * fulfils the embedded requests and retries the original call with\n * `inputResponses` and an echoed `requestState`.\n *\n * These are thin re-exports of the SDK's own generic, already well-designed\n * primitives — fastmcp-ts adds no behavior on top. See `McpContext.inputResponses`\n * / `McpContext.requestState()` / `McpContext.mintRequestState()` for how a\n * handler reads and mints state through fastmcp's own context, and\n * `FastMCPOptions.requestState` / `FastMCPOptions.inputRequired` for server-wide\n * configuration.\n *\n * Handlers written with `inputRequired(...)` work unchanged on legacy (2025-era)\n * connections too: the SDK's legacy shim fulfils them via real server→client\n * requests and re-enters the handler, so this is a write-once, serve-both-eras\n * pattern — `ctx.elicit()` / `ctx.sample()` / `ctx.listRoots()` remain available\n * for legacy-only code, but throw a clear error naming this replacement when\n * called on a modern-era request.\n */\nimport type { InputRequiredResult } from '@modelcontextprotocol/server'\n\nexport { inputRequired, acceptedContent, inputResponse, isInputRequiredResult } from '@modelcontextprotocol/server'\nexport type {\n InputRequiredResult,\n InputRequiredSpec,\n InputRequest,\n InputRequests,\n InputResponse,\n InputResponses,\n InputResponseView,\n} from '@modelcontextprotocol/server'\n\n/**\n * Pointed error thrown when a handler returns `inputRequired({ inputRequests })` while\n * serving a stateless HTTP server (`RunOptions.stateless` / `FASTMCP_STATELESS_HTTP`).\n *\n * Same structural cause as `ctx.elicit()` / `ctx.sample()` / `ctx.listRoots()` — see\n * `SERVER_INITIATED_STATELESS_HTTP_ERROR` in context.ts — but a DIFFERENT constant on\n * purpose: a handler that returns `inputRequired(...)` never called those APIs, so\n * their wording (\"Server-initiated requests (ctx.elicit, ctx.sample, ctx.listRoots)...\")\n * would name the wrong thing to someone debugging this path. `inputRequests` hits the\n * same wall for its own reason: on legacy connections it is fulfilled by the SDK's\n * legacy shim pushing each embedded request over the server→client channel and awaiting\n * the reply — the exact channel `ctx.elicit()` etc. use, and one a stateless server's\n * per-request `Server` instance does not live long enough to keep open.\n *\n * The bare `inputRequired({ requestState })` form (no `inputRequests`) is NOT affected:\n * it is the supported stateless multi-round-trip pattern (the SDK's legacy shim re-enters\n * the handler in-process, inside the same HTTP request, needing no session) — see\n * docs/concepts/input-required.mdx#the-requeststate-only-pattern.\n */\nexport const INPUT_REQUESTS_STATELESS_HTTP_ERROR =\n '[fastmcp] inputRequired({ inputRequests }) is not available on a stateless HTTP server ' +\n '(RunOptions.stateless or FASTMCP_STATELESS_HTTP). ' +\n \"Fulfilling inputRequests needs a session: the client's reply to each embedded request \" +\n 'arrives on a separate request, and a stateless server discards its per-request Server ' +\n 'before that reply could arrive — the same reason ctx.elicit/ctx.sample/ctx.listRoots ' +\n 'are unavailable here. inputRequired({ requestState }), with no inputRequests, remains ' +\n 'available — it carries state across rounds without needing a session. ' +\n 'Turn stateless off to use inputRequests.'\n\n/**\n * Shared guard called from each of the three result converters (tool.ts convertResult,\n * resource.ts convertResourceResult, prompt.ts convertPromptResult) right after they\n * recognize an `InputRequiredResult`. Throws {@link INPUT_REQUESTS_STATELESS_HTTP_ERROR}\n * when `stateless` is true and `value` carries `inputRequests`; a no-op otherwise —\n * including for the `requestState`-only form, which has no `inputRequests` key. Kept in\n * one place rather than duplicated per converter so the message and the condition can\n * only drift once.\n *\n * `stateless` must be the per-server `opts.stateless` a request handler was built with\n * (the same value threaded into `createContext`), NOT an instance-wide flag — a stdio\n * server can carry `_stateless: true` from `FASTMCP_STATELESS_HTTP` while serving every\n * request sessionfully, because the flag is never passed into `_makeServer` on that path.\n */\nexport function assertInputRequestsAllowedStateless(\n value: InputRequiredResult,\n stateless: boolean | undefined,\n): void {\n // Matches the SDK's own notion of \"has inputRequests\" (buildInputRequired in\n // @modelcontextprotocol/server's core-internal/src/shared/inputRequired.ts: `spec.inputRequests\n // !== void 0 && Object.keys(spec.inputRequests).length > 0`), not merely `!== undefined`.\n // Without the length check, the degenerate-but-legal `inputRequired({ inputRequests: {},\n // requestState: <token> })` -- legal because `requestState` alone already satisfies the SDK's\n // at-least-one-of-the-two rule -- would throw here even though there is nothing to fulfil and\n // the requestState mechanism carries it through fine: a false positive on the one pattern this\n // guard exists to keep working.\n const hasInputRequests =\n value.inputRequests !== undefined && Object.keys(value.inputRequests).length > 0\n // Unlike the sibling guard in context.ts:312 (same root cause, the server-initiated request\n // APIs), this does not also check `sdkCtx.http !== undefined`. Today `stateless: true` only\n // ever reaches a request handler via `_getStatelessLegacyHandler` (FastMCP.ts), whose single\n // call site is HTTP-only (`_makeServer(new Map(), { stateless: true })` inside the legacy HTTP\n // dispatch path) — stdio never passes `stateless` into `_makeServer` (see this function's doc\n // comment above). A transport check here would therefore be dead code with no way to exercise\n // it; add one only if a future stateless path over a non-HTTP transport is introduced.\n if (stateless && hasInputRequests) {\n throw new Error(INPUT_REQUESTS_STATELESS_HTTP_ERROR)\n }\n}\n","import type { AuthCheck } from './auth/authorization'\nimport type { ResourceUiMeta } from './apps/types'\nimport { isInputRequiredResult, assertInputRequestsAllowedStateless } from './mrtr'\nimport type { InputRequiredResult } from './mrtr'\nimport type { CompleteCallback } from './completion'\n\nexport interface ResourceAnnotations {\n /** Intended audience(s) — 'user', 'assistant', or both. */\n audience?: Array<'user' | 'assistant'>\n /** Importance hint from 0 (least) to 1 (most). */\n priority?: number\n /** ISO 8601 timestamp of last modification. */\n lastModified?: string\n}\n\nexport interface ResourceConfig {\n /** Static URI (e.g. `file://readme`) or RFC 6570 template (e.g. `user://{id}`). */\n uri: string\n /** Programmatic identifier. Defaults to the uri. */\n name?: string\n /** Human-readable display name shown in UIs. Defaults to `name`. */\n title?: string\n description?: string\n /** MIME type of the resource content. Defaults to 'text/plain' for strings, 'application/octet-stream' for binary. */\n mimeType?: string\n /**\n * Size of the resource content in bytes, if known.\n * Only meaningful for static resources; ignored for URI templates.\n */\n size?: number\n /** Behavioral hints for clients. */\n annotations?: ResourceAnnotations\n /** Execution timeout in milliseconds. No timeout by default. */\n timeout?: number\n /** When true the resource is hidden from list responses and cannot be read. */\n disabled?: boolean\n /** Arbitrary tags for server-side filtering. */\n tags?: string[]\n auth?: AuthCheck\n /** Apps extension metadata. Included as `_meta.ui` on resources/list entries and on every resources/read content item for UI-capable clients. */\n ui?: ResourceUiMeta\n /**\n * Autocompletion callbacks for this resource template's RFC 6570 variables,\n * keyed by variable name. Only meaningful for URI templates. When set, a\n * `completion/complete` request for\n * `{ ref: { type: 'ref/resource', uri: <this template> }, argument: { name, value } }`\n * routes to `complete[name]`.\n */\n complete?: Record<string, CompleteCallback>\n}\n\n/**\n * Escape hatch for full control over resource response content.\n * Return this from a resource handler to specify content directly.\n */\nexport class ResourceResult {\n constructor(\n readonly contents: Array<{\n uri: string\n mimeType?: string\n text?: string\n blob?: string\n _meta?: Record<string, unknown>\n }>,\n ) {}\n}\n\ntype ResourceContent =\n | { uri: string; mimeType?: string; text: string; _meta?: Record<string, unknown> }\n | { uri: string; mimeType?: string; blob: string; _meta?: Record<string, unknown> }\n\n/**\n * Converts a resource handler's return value into the MCP ReadResourceResult shape.\n *\n * - string → text content\n * - Buffer / Uint8Array → base64 blob content\n * - object / array → JSON-serialised text with mimeType application/json\n * - ResourceResult → passthrough\n * - null / undefined → empty text content\n */\nexport function convertResourceResult(\n value: unknown,\n uri: string,\n mimeType?: string,\n stateless?: boolean,\n): { contents: ResourceContent[] } | InputRequiredResult {\n // Multi-round-trip escape hatch (protocol revision 2026-07-28) — see tool.ts's\n // convertResult for the same pattern applied to tools/call, including why\n // `stateless` is a per-call parameter rather than read off an instance field.\n if (isInputRequiredResult(value)) {\n assertInputRequestsAllowedStateless(value, stateless)\n return value\n }\n if (value instanceof ResourceResult) {\n return { contents: value.contents as ResourceContent[] }\n }\n if (value instanceof Buffer || value instanceof Uint8Array) {\n return {\n contents: [\n {\n uri,\n mimeType: mimeType ?? 'application/octet-stream',\n blob: Buffer.from(value).toString('base64'),\n },\n ],\n }\n }\n if (value === null || value === undefined) {\n return { contents: [{ uri, mimeType: mimeType ?? 'text/plain', text: '' }] }\n }\n if (typeof value === 'object') {\n return {\n contents: [{ uri, mimeType: mimeType ?? 'application/json', text: JSON.stringify(value) }],\n }\n }\n // string, number, boolean\n return { contents: [{ uri, mimeType: mimeType ?? 'text/plain', text: String(value) }] }\n}\n\n/**\n * Attaches the resource's declared `ui` config to every content item as\n * `_meta.ui`, mirroring the resources/list gating. SEP-1865 hosts build the\n * sandboxed iframe's CSP from the resources/read response, so the metadata\n * must ride on the read contents, not only on list entries.\n *\n * No-op when the resource declares no `ui`, the client is not UI-capable, or\n * the result is an InputRequiredResult. A handler-provided `_meta` (via\n * ResourceResult) wins key-by-key; an explicit `_meta.ui` overrides the\n * declared config for that item.\n */\nexport function attachResourceUiMeta(\n result: { contents: ResourceContent[] } | InputRequiredResult,\n ui: ResourceUiMeta | undefined,\n uiCapable: boolean,\n): { contents: ResourceContent[] } | InputRequiredResult {\n if (!ui || !uiCapable || isInputRequiredResult(result)) return result\n return {\n contents: result.contents.map((c) => ({ ...c, _meta: { ui, ...c._meta } })),\n }\n}\n\n/** Returns true if the URI string contains RFC 6570 template expressions. */\nexport function isUriTemplate(uri: string): boolean {\n return uri.includes('{')\n}\n\n/**\n * Matches a concrete URI against an RFC 6570 URI template and returns the\n * extracted parameter values, or null if the URI does not match the template.\n *\n * Supports:\n * - Simple path params: {id} → matches a single path segment\n * - Wildcard path params: {path*} → matches multiple segments (including '/')\n * - Query params: {?q,lang} → extracted from the query string\n */\nexport function matchTemplate(\n uriTemplate: string,\n uri: string,\n): Record<string, string> | null {\n // Split URI into base and query string\n const qIdx = uri.indexOf('?')\n const baseUri = qIdx >= 0 ? uri.slice(0, qIdx) : uri\n const queryString = qIdx >= 0 ? uri.slice(qIdx + 1) : ''\n\n // Pull out query param names from {?...} expressions and strip them from the template\n const queryParamNames: string[] = []\n const baseTemplate = uriTemplate.replace(/\\{[?][^}]+\\}/g, (match) => {\n match\n .slice(2, -1)\n .split(',')\n .map((s) => s.trim())\n .forEach((n) => queryParamNames.push(n))\n return ''\n })\n\n // Build a regex from the base template, collecting path param names\n const names: string[] = []\n const segments = baseTemplate.split(/(\\{[^}]+\\})/g)\n let pattern = '^'\n for (const seg of segments) {\n if (seg.startsWith('{') && seg.endsWith('}')) {\n const inner = seg.slice(1, -1)\n if (inner.endsWith('*')) {\n names.push(inner.slice(0, -1))\n pattern += '(.+)'\n } else {\n names.push(inner)\n pattern += '([^/?]+)'\n }\n } else if (seg) {\n // Escape regex metacharacters in literal parts\n pattern += seg.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')\n }\n }\n pattern += '$'\n\n const pathMatch = baseUri.match(new RegExp(pattern))\n if (!pathMatch) return null\n\n const params: Record<string, string> = {}\n names.forEach((name, i) => {\n params[name] = decodeURIComponent(pathMatch[i + 1])\n })\n\n // Extract query parameters\n if (queryParamNames.length > 0 && queryString) {\n const sp = new URLSearchParams(queryString)\n for (const name of queryParamNames) {\n const val = sp.get(name)\n if (val !== null) params[name] = val\n }\n }\n\n return params\n}\n","export const UI_EXTENSION_KEY = 'io.modelcontextprotocol/ui'\nexport const UI_RESOURCE_MIME_TYPE = 'text/html;profile=mcp-app'\n\n/**\n * Checks whether a client has declared MCP Apps support with a `mimeTypes` list\n * that includes the profile fastmcp serves (`UI_RESOURCE_MIME_TYPE`).\n *\n * SEP-1865's Client<>Server Capability Negotiation section requires the client to\n * declare `mimeTypes` (REQUIRED) as the *value* of its `io.modelcontextprotocol/ui`\n * extension entry, and directs servers to check it (the SDK's own\n * `getUiCapability`/`mimeTypes.includes(RESOURCE_MIME_TYPE)` pattern) before\n * registering UI-enabled tools — a bare presence check on the extension key is not\n * sufficient. Used for both `tools/list` UI-meta inclusion and the `tools/call`\n * graceful-degradation check.\n */\nexport function isUiCapable(\n clientCapabilities: { extensions?: Record<string, unknown> } | undefined,\n): boolean {\n const uiCapability = clientCapabilities?.extensions?.[UI_EXTENSION_KEY] as\n | { mimeTypes?: string[] }\n | undefined\n return !!uiCapability?.mimeTypes?.includes(UI_RESOURCE_MIME_TYPE)\n}\n\nexport type Visibility = 'model' | 'app'\n\nexport interface CspPolicy {\n connectDomains?: string[]\n /** Covers img-src, script-src, style-src, font-src, media-src. */\n resourceDomains?: string[]\n frameDomains?: string[]\n baseUriDomains?: string[]\n}\n\nexport interface UiToolMeta {\n /** Explicit resource URI. Auto-derived from tool name when omitted. */\n resourceUri?: string\n /**\n * Who can see and call this tool. Defaults to `['model', 'app']` per SEP-1865\n * (visible to the model, and callable by the app served from this same\n * connection) when omitted.\n */\n visibility?: Visibility[]\n}\n\nexport interface BrowserPermissions {\n camera?: Record<string, never>\n microphone?: Record<string, never>\n geolocation?: Record<string, never>\n clipboardWrite?: Record<string, never>\n}\n\nexport interface ResourceUiMeta {\n csp?: CspPolicy\n permissions?: BrowserPermissions\n domain?: string\n prefersBorder?: boolean\n}\n","import type { AuthCheck } from './auth/authorization'\nimport { isInputRequiredResult, assertInputRequestsAllowedStateless } from './mrtr'\nimport type { InputRequiredResult } from './mrtr'\nimport type { CompleteCallback } from './completion'\n\nexport interface PromptArgument {\n name: string\n description?: string\n /** When true, the client must supply this argument. Defaults to false. */\n required?: boolean\n /**\n * Autocompletion callback for this argument. When set, a `completion/complete`\n * request for `{ ref: { type: 'ref/prompt', name }, argument: { name, value } }`\n * routes here. Not advertised in `prompts/list` — the client discovers it by\n * calling `completion/complete`.\n */\n complete?: CompleteCallback\n}\n\nexport interface PromptConfig {\n /** Unique prompt identifier. Inferred from the handler function name when omitted. */\n name?: string\n /** Human-readable display name shown in UIs. */\n title?: string\n /** Description shown to clients and LLMs. Inferred from name when omitted. */\n description?: string\n /** Declared arguments. Advertised to clients in prompts/list. */\n arguments?: PromptArgument[]\n /** When true the prompt is hidden from list responses and cannot be invoked. */\n disabled?: boolean\n /** Execution timeout in milliseconds. No timeout by default. */\n timeout?: number\n /** Arbitrary tags for server-side filtering and transforms. */\n tags?: string[]\n auth?: AuthCheck\n}\n\n// ---------------------------------------------------------------------------\n// Content and message types\n// ---------------------------------------------------------------------------\n\nexport type TextContent = { type: 'text'; text: string }\nexport type ImageContent = { type: 'image'; data: string; mimeType: string }\nexport type AudioContent = { type: 'audio'; data: string; mimeType: string }\nexport type ResourceLinkContent = {\n type: 'resource_link'\n uri: string\n name?: string\n description?: string\n mimeType?: string\n}\nexport type EmbeddedResource = {\n type: 'resource'\n resource: { uri: string; mimeType?: string } & ({ text: string } | { blob: string })\n}\n\nexport type PromptContent = TextContent | ImageContent | AudioContent | EmbeddedResource | ResourceLinkContent\n\nexport interface PromptMessage {\n role: 'user' | 'assistant'\n content: PromptContent\n}\n\n/**\n * Escape hatch for full control over the prompt response.\n * Return this from a prompt handler to set an explicit description and/or\n * supply a custom multi-turn message sequence.\n */\nexport class PromptResult {\n constructor(\n readonly messages: PromptMessage[],\n readonly description?: string,\n ) {}\n}\n\n// ---------------------------------------------------------------------------\n// Return value conversion\n// ---------------------------------------------------------------------------\n\nfunction isPromptMessage(value: unknown): value is PromptMessage {\n if (value === null || typeof value !== 'object') return false\n const v = value as Record<string, unknown>\n if (v.role !== 'user' && v.role !== 'assistant') return false\n if (!v.content || typeof v.content !== 'object') return false\n return typeof (v.content as Record<string, unknown>).type === 'string'\n}\n\n/**\n * Converts a prompt handler's return value into the MCP GetPromptResult shape.\n *\n * - string → single user text message\n * - PromptMessage → wrapped in a one-element array\n * - PromptMessage[] → used as-is\n * - PromptResult → passthrough (escape hatch)\n */\nexport function convertPromptResult(\n value: unknown,\n stateless?: boolean,\n): { description?: string; messages: PromptMessage[] } | InputRequiredResult {\n // Multi-round-trip escape hatch (protocol revision 2026-07-28) — see tool.ts's\n // convertResult for the same pattern applied to tools/call, including why\n // `stateless` is a per-call parameter rather than read off an instance field.\n if (isInputRequiredResult(value)) {\n assertInputRequestsAllowedStateless(value, stateless)\n return value\n }\n if (value instanceof PromptResult) {\n return { description: value.description, messages: value.messages }\n }\n if (typeof value === 'string') {\n return { messages: [{ role: 'user', content: { type: 'text', text: value } }] }\n }\n if (isPromptMessage(value)) {\n return { messages: [value] }\n }\n if (Array.isArray(value) && value.every(isPromptMessage)) {\n return { messages: value }\n }\n throw new Error(\n `Prompt handler returned an unsupported value. Expected string, PromptMessage, PromptMessage[], or PromptResult.`,\n )\n}\n","/**\n * Argument completion (`completion/complete`) — the callback contract shared by\n * prompt arguments and resource-template variables.\n *\n * A completion callback turns a partial value the user has typed into a set of\n * suggestions. It attaches to a single prompt argument (`PromptArgument.complete`)\n * or a single resource-template variable (`ResourceConfig.complete[variable]`);\n * the server routes each `completion/complete` request to the matching callback\n * by the request's `ref` type. See FastMCP `_completePrompt` /\n * `_completeResourceTemplate`.\n *\n * `completion/complete` lives in BOTH protocol eras' wire registries (the legacy\n * 2025-11-25 registry and the modern 2026-07-28 `dispatchRequestSchemas`), so the\n * handler and the `completions` capability are declared unconditionally — no\n * per-era fork, unlike `resources/subscribe`.\n */\n\n/**\n * Optional context the client forwards with a completion request: the values it\n * has already resolved for the prompt's OTHER arguments (or the template's other\n * variables). Use it to narrow suggestions — e.g. offer cities once a country is\n * chosen.\n */\nexport interface CompletionContext {\n arguments?: Record<string, string>\n}\n\n/**\n * The paginated shape a completion callback MAY return for full control over the\n * `total` / `hasMore` hints. Mirrors the wire `CompleteResult.completion` object.\n * Returning a bare `string[]` instead is the common case.\n */\nexport interface CompletionResult {\n /** Suggested values. Capped to 100 on the wire (the spec's maximum). */\n values: string[]\n /** Total number of matches available, if larger than `values`. */\n total?: number\n /** Whether more matches exist beyond `values`. */\n hasMore?: boolean\n}\n\n/**\n * A completion callback. Receives the partial `value` the user has typed and the\n * optional resolved-argument `context`, and returns suggestions — either a bare\n * `string[]` or a {@link CompletionResult} with explicit pagination hints. May be\n * async.\n */\nexport type CompleteCallback = (\n value: string,\n context?: CompletionContext,\n) => string[] | CompletionResult | Promise<string[] | CompletionResult>\n\n/**\n * Normalise a callback's return value into the wire `completion` object.\n *\n * - Bare `string[]` → matches the SDK's own `createCompletionResult`: `values`\n * sliced to the 100-item wire cap, `total` = the full length, `hasMore` = true\n * when the callback produced more than 100.\n * - {@link CompletionResult} → the author is managing pagination, so `total` and\n * `hasMore` pass through exactly as given (omitted when undefined); `values` is\n * still capped to 100 to satisfy the wire schema.\n */\nexport function normalizeCompletion(\n raw: string[] | CompletionResult,\n): { values: string[]; total?: number; hasMore?: boolean } {\n if (Array.isArray(raw)) {\n return {\n values: raw.slice(0, 100),\n total: raw.length,\n hasMore: raw.length > 100,\n }\n }\n return {\n values: raw.values.slice(0, 100),\n ...(raw.total !== undefined ? { total: raw.total } : {}),\n ...(raw.hasMore !== undefined ? { hasMore: raw.hasMore } : {}),\n }\n}\n\n/** The `completion` object for a ref/argument that has no completer: an empty list. */\nexport const EMPTY_COMPLETION = { values: [] as string[] }\n","import type { AccessToken } from './types'\nimport { AuthorizationError } from './types'\n\nexport type AuthCheck = (token: AccessToken) => void | Promise<void>\n\nexport function requireScopes(...scopes: string[]): AuthCheck {\n return async (token) => {\n for (const scope of scopes) {\n if (!token.scopes.includes(scope)) {\n throw new AuthorizationError(`Missing required scope: \"${scope}\"`)\n }\n }\n }\n}\n","import type { AccessToken, TokenVerifier } from './types'\n\nexport function multiAuth(...verifiers: TokenVerifier[]): TokenVerifier {\n return {\n async verify(token: string): Promise<AccessToken> {\n const errors: string[] = []\n for (const verifier of verifiers) {\n try {\n return await verifier.verify(token)\n } catch (err) {\n errors.push(err instanceof Error ? err.message : String(err))\n }\n }\n throw new Error(`All auth sources rejected the token: ${errors.join('; ')}`)\n },\n }\n}\n","import { createRemoteJWKSet, jwtVerify } from 'jose'\nimport type { AccessToken, TokenVerifier } from '../types'\n\nexport interface JwtVerifierOptions {\n jwksUri: string\n issuer?: string\n audience?: string | string[]\n /** Clock skew tolerance in seconds. Default: 0. */\n leeway?: number\n}\n\nexport function jwtVerifier(options: JwtVerifierOptions): TokenVerifier {\n const JWKS = createRemoteJWKSet(new URL(options.jwksUri))\n\n return {\n async verify(token: string): Promise<AccessToken> {\n const { payload } = await jwtVerify(token, JWKS, {\n issuer: options.issuer,\n audience: options.audience,\n clockTolerance: options.leeway ?? 0,\n })\n\n const scopes =\n typeof payload.scope === 'string'\n ? payload.scope.split(' ').filter(Boolean)\n : Array.isArray(payload.scope)\n ? (payload.scope as string[])\n : []\n\n return {\n token,\n clientId: typeof payload.sub === 'string' ? payload.sub : undefined,\n scopes,\n expiresAt: payload.exp,\n claims: payload as Record<string, unknown>,\n }\n },\n }\n}\n","import type { AccessToken, TokenVerifier } from '../types'\n\nexport interface IntrospectionVerifierOptions {\n endpoint: string\n credentials: { clientId: string; clientSecret: string }\n /** Cache TTL in seconds. Omit or set to 0 to disable caching. */\n cacheTtl?: number\n}\n\ninterface CacheEntry {\n token: AccessToken\n expiresAt: number\n}\n\nexport function introspectionVerifier(options: IntrospectionVerifierOptions): TokenVerifier {\n const cache = options.cacheTtl ? new Map<string, CacheEntry>() : null\n\n return {\n async verify(rawToken: string): Promise<AccessToken> {\n if (cache) {\n const cached = cache.get(rawToken)\n if (cached && Date.now() < cached.expiresAt) {\n return cached.token\n }\n cache.delete(rawToken)\n }\n\n const credentials = Buffer.from(\n `${options.credentials.clientId}:${options.credentials.clientSecret}`,\n ).toString('base64')\n\n const response = await fetch(options.endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n Authorization: `Basic ${credentials}`,\n },\n body: new URLSearchParams({ token: rawToken }),\n })\n\n if (!response.ok) {\n throw new Error(`Introspection endpoint returned ${response.status}`)\n }\n\n const data = (await response.json()) as {\n active: boolean\n scope?: string\n client_id?: string\n exp?: number\n [key: string]: unknown\n }\n\n if (!data.active) {\n throw new Error('Token is not active')\n }\n\n const accessToken: AccessToken = {\n token: rawToken,\n clientId: data.client_id,\n scopes: data.scope ? data.scope.split(' ').filter(Boolean) : [],\n expiresAt: data.exp,\n claims: data as Record<string, unknown>,\n }\n\n if (cache && options.cacheTtl) {\n cache.set(rawToken, {\n token: accessToken,\n expiresAt: Date.now() + options.cacheTtl * 1000,\n })\n }\n\n return accessToken\n },\n }\n}\n","import type { AccessToken, TokenVerifier } from '../types'\n\nexport function staticTokenVerifier(\n map: Record<string, Partial<Omit<AccessToken, 'token'>>>,\n): TokenVerifier {\n return {\n async verify(token: string): Promise<AccessToken> {\n const entry = map[token]\n if (!entry) {\n throw new Error('Unknown token')\n }\n if (entry.expiresAt !== undefined && entry.expiresAt < Math.floor(Date.now() / 1000)) {\n throw new Error('Token has expired')\n }\n return {\n token,\n clientId: entry.clientId,\n scopes: entry.scopes ?? [],\n expiresAt: entry.expiresAt,\n claims: entry.claims ?? {},\n }\n },\n }\n}\n\nexport function debugTokenVerifier(): TokenVerifier {\n console.warn('[fastmcp] debugTokenVerifier() accepts all bearer tokens — never use in production')\n return {\n async verify(token: string): Promise<AccessToken> {\n if (!token) {\n throw new Error('Empty token')\n }\n return { token, scopes: [], claims: {} }\n },\n }\n}\n","import { randomUUID } from 'node:crypto'\nimport type { OAuthClientInformationFull, AuthInfo } from \"@modelcontextprotocol/server\";\nimport { UnsupportedGrantTypeError } from \"@modelcontextprotocol/server-legacy/auth\";\nimport type { OAuthServerProvider, AuthorizationParams, OAuthRegisteredClientsStore } from \"@modelcontextprotocol/server-legacy/auth\";\nimport type { Response } from 'express'\n\nexport interface OAuthProviderOptions {\n /**\n * Called during the authorization step. Implementations must eventually redirect\n * to `params.redirectUri` with a `code` query parameter (and `state` if present).\n *\n * If omitted, all authorization requests are auto-approved immediately — suitable\n * for testing and development only.\n */\n onAuthorize?: (\n client: OAuthClientInformationFull,\n params: AuthorizationParams,\n res: Response,\n ) => Promise<void>\n /** Scopes supported by this server, advertised in OAuth metadata. */\n scopes?: string[]\n /** Access token lifetime in seconds. Default: 3600. */\n tokenTtl?: number\n}\n\n/**\n * Creates an in-memory OAuth 2.1 server provider with Dynamic Client Registration support.\n *\n * Suitable for development, testing, and simple deployments where persistence is not required.\n * All state (clients, codes, tokens) is held in memory and lost on restart.\n */\nexport function oauthProvider(options: OAuthProviderOptions = {}): OAuthServerProvider {\n const clients = new Map<string, OAuthClientInformationFull>()\n const codes = new Map<string, { client: OAuthClientInformationFull; params: AuthorizationParams }>()\n const tokens = new Map<string, { clientId: string; scopes: string[]; expiresAt: number }>()\n\n // The SDK registration handler generates client_id and other fields before calling\n // registerClient, so at runtime the argument is always a full OAuthClientInformationFull.\n const clientsStore: OAuthRegisteredClientsStore = {\n async getClient(clientId) {\n return clients.get(clientId)\n },\n async registerClient(client) {\n const full = client as OAuthClientInformationFull\n clients.set(full.client_id, full)\n return full\n },\n }\n\n return {\n clientsStore,\n\n async authorize(client, params, res) {\n if (options.onAuthorize) {\n return options.onAuthorize(client, params, res)\n }\n // Default: auto-approve — issue code and redirect immediately\n const code = randomUUID()\n codes.set(code, { client, params })\n const redirectUrl = new URL(params.redirectUri)\n redirectUrl.searchParams.set('code', code)\n if (params.state) redirectUrl.searchParams.set('state', params.state)\n res.redirect(redirectUrl.toString())\n },\n\n async challengeForAuthorizationCode(_client, authorizationCode) {\n const data = codes.get(authorizationCode)\n if (!data) throw new Error('Invalid authorization code')\n return data.params.codeChallenge\n },\n\n async exchangeAuthorizationCode(client, authorizationCode) {\n const data = codes.get(authorizationCode)\n if (!data) throw new Error('Invalid authorization code')\n if (data.client.client_id !== client.client_id) {\n throw new Error('Authorization code was not issued to this client')\n }\n codes.delete(authorizationCode)\n\n const token = randomUUID()\n const ttl = options.tokenTtl ?? 3600\n const requestedScopes = data.params.scopes ?? []\n const grantedScopes =\n options.scopes !== undefined\n ? requestedScopes.filter((s) => options.scopes!.includes(s))\n : requestedScopes\n tokens.set(token, {\n clientId: client.client_id,\n scopes: grantedScopes,\n expiresAt: Math.floor(Date.now() / 1000) + ttl,\n })\n return {\n access_token: token,\n token_type: 'bearer',\n expires_in: ttl,\n scope: grantedScopes.join(' '),\n }\n },\n\n async exchangeRefreshToken() {\n throw new UnsupportedGrantTypeError('Refresh tokens are not supported by this provider')\n },\n\n async verifyAccessToken(token): Promise<AuthInfo> {\n const data = tokens.get(token)\n if (!data) throw new Error('Invalid token')\n if (data.expiresAt < Math.floor(Date.now() / 1000)) throw new Error('Token has expired')\n return {\n token,\n clientId: data.clientId,\n scopes: data.scopes,\n expiresAt: data.expiresAt,\n }\n },\n }\n}\n","import type { OAuthClientInformationFull, OAuthTokenRevocationRequest, OAuthTokens, AuthInfo } from \"@modelcontextprotocol/server\";\nimport type { OAuthServerProvider, AuthorizationParams, OAuthRegisteredClientsStore } from \"@modelcontextprotocol/server-legacy/auth\";\n\nexport interface OAuthProxyOptions {\n /** Pre-registered credentials this proxy uses when talking to the upstream server. */\n upstreamCredentials: {\n clientId: string\n clientSecret?: string\n }\n /** Upstream OAuth server endpoint URLs. */\n endpoints: {\n authorizationUrl: string\n tokenUrl: string\n revocationUrl?: string\n }\n /**\n * Verifies an access token issued by the upstream and returns information about it.\n * Called for every MCP request to validate the bearer token.\n */\n verifyAccessToken: (token: string) => Promise<AuthInfo>\n}\n\n/**\n * Creates an OAuth provider that proxies to an existing upstream OAuth server using\n * pre-registered credentials.\n *\n * MCP clients interact with this proxy using Dynamic Client Registration. The proxy\n * presents a DCR-compliant interface while internally using its own fixed credentials\n * (`upstreamCredentials`) when communicating with the upstream authorization server.\n */\nexport function oauthProxy(options: OAuthProxyOptions): OAuthServerProvider {\n const clients = new Map<string, OAuthClientInformationFull>()\n\n const clientsStore: OAuthRegisteredClientsStore = {\n async getClient(clientId) {\n return clients.get(clientId)\n },\n // DCR for incoming MCP clients — stored locally, not proxied upstream\n async registerClient(client) {\n const full = client as OAuthClientInformationFull\n clients.set(full.client_id, full)\n return full\n },\n }\n\n return {\n clientsStore,\n // Let the upstream server validate PKCE — we pass code_verifier through\n skipLocalPkceValidation: true as const,\n\n async authorize(_client, params, res) {\n // Redirect to upstream using the proxy's registered client_id\n const targetUrl = new URL(options.endpoints.authorizationUrl)\n targetUrl.searchParams.set('client_id', options.upstreamCredentials.clientId)\n targetUrl.searchParams.set('response_type', 'code')\n targetUrl.searchParams.set('redirect_uri', params.redirectUri)\n targetUrl.searchParams.set('code_challenge', params.codeChallenge)\n targetUrl.searchParams.set('code_challenge_method', 'S256')\n if (params.state) targetUrl.searchParams.set('state', params.state)\n if (params.scopes?.length) targetUrl.searchParams.set('scope', params.scopes.join(' '))\n res.redirect(targetUrl.toString())\n },\n\n async challengeForAuthorizationCode() {\n // PKCE is validated by the upstream; returning empty string skips local validation\n return ''\n },\n\n async exchangeAuthorizationCode(_client, authorizationCode, codeVerifier, redirectUri): Promise<OAuthTokens> {\n const body = new URLSearchParams({\n grant_type: 'authorization_code',\n client_id: options.upstreamCredentials.clientId,\n code: authorizationCode,\n })\n if (options.upstreamCredentials.clientSecret) {\n body.set('client_secret', options.upstreamCredentials.clientSecret)\n }\n if (codeVerifier) body.set('code_verifier', codeVerifier)\n if (redirectUri) body.set('redirect_uri', redirectUri)\n\n const response = await fetch(options.endpoints.tokenUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: body.toString(),\n })\n if (!response.ok) {\n await response.body?.cancel()\n throw new Error(`Upstream token exchange failed: ${response.status}`)\n }\n return response.json() as Promise<OAuthTokens>\n },\n\n async exchangeRefreshToken(_client, refreshToken, scopes): Promise<OAuthTokens> {\n const body = new URLSearchParams({\n grant_type: 'refresh_token',\n client_id: options.upstreamCredentials.clientId,\n refresh_token: refreshToken,\n })\n if (options.upstreamCredentials.clientSecret) {\n body.set('client_secret', options.upstreamCredentials.clientSecret)\n }\n if (scopes?.length) body.set('scope', scopes.join(' '))\n\n const response = await fetch(options.endpoints.tokenUrl, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: body.toString(),\n })\n if (!response.ok) {\n await response.body?.cancel()\n throw new Error(`Upstream token refresh failed: ${response.status}`)\n }\n return response.json() as Promise<OAuthTokens>\n },\n\n verifyAccessToken: options.verifyAccessToken,\n\n ...(options.endpoints.revocationUrl\n ? {\n async revokeToken(\n _client: OAuthClientInformationFull,\n request: OAuthTokenRevocationRequest,\n ): Promise<void> {\n const body = new URLSearchParams({\n token: request.token,\n client_id: options.upstreamCredentials.clientId,\n })\n if (options.upstreamCredentials.clientSecret) {\n body.set('client_secret', options.upstreamCredentials.clientSecret)\n }\n if (request.token_type_hint) {\n body.set('token_type_hint', request.token_type_hint)\n }\n const response = await fetch(options.endpoints.revocationUrl!, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: body.toString(),\n })\n if (!response.ok) {\n await response.body?.cancel()\n // RFC 7009 §2.2: servers should not signal errors on revocation\n }\n },\n }\n : {}),\n }\n}\n","import { Client } from \"@modelcontextprotocol/client\";\nimport type { CallToolResult } from \"@modelcontextprotocol/client\";\nimport { parseTemplate } from 'url-template'\nimport { FastMCP } from './FastMCP'\nimport { ToolResult } from './tool'\nimport { ResourceResult } from './resource'\nimport { PromptResult } from './prompt'\nimport type { PromptMessage } from './prompt'\n\ntype StdioTransport = {\n type: 'stdio'\n command: string\n args?: string[]\n env?: Record<string, string>\n cwd?: string\n /** How long (ms) before the proxy re-fetches component lists. Default 30 000. Set 0 for notifications-only. */\n cacheTtl?: number\n}\n\ntype HttpTransport = {\n type: 'http'\n url: string\n requestInit?: RequestInit\n /** How long (ms) before the proxy re-fetches component lists. Default 30 000. Set 0 for notifications-only. */\n cacheTtl?: number\n}\n\nexport type ProxyTransport = StdioTransport | HttpTransport\n\n/**\n * Build a FastMCP proxy around an already-connected MCP Client.\n * Exported to enable testing with in-memory transports.\n */\nexport async function buildProxyFromClient(\n client: Client,\n options?: { cacheTtl?: number; name?: string },\n): Promise<FastMCP> {\n const cacheTtl = options?.cacheTtl ?? 30_000\n\n const serverInfo = client.getServerVersion()\n const proxyName = options?.name ?? serverInfo?.name ?? 'proxy'\n const proxyVersion = serverInfo?.version ?? '0.0.1'\n\n const proxy = new FastMCP({ name: proxyName, version: proxyVersion })\n\n // Track which component identifiers were registered by this proxy so we can diff on resync.\n const proxiedTools = new Set<string>()\n const proxiedResources = new Set<string>()\n const proxiedPrompts = new Set<string>()\n\n // Per-type timestamp of last successful sync (0 forces an immediate resync on first list request).\n const lastSync = { tools: 0, resources: 0, prompts: 0 }\n\n async function resyncTools(): Promise<void> {\n // client.listTools() with no cursor auto-aggregates every page for us (v2 SDK\n // behavior — see ClientOptions.listMaxPages, default cap 64 pages).\n const { tools } = await client.listTools()\n\n const incoming = new Set(tools.map((t) => t.name))\n\n for (const name of proxiedTools) {\n if (!incoming.has(name)) {\n proxy._removeTool(name)\n proxiedTools.delete(name)\n }\n }\n\n for (const tool of tools) {\n if (proxiedTools.has(tool.name)) {\n // Update metadata if it changed\n proxy._removeTool(tool.name)\n proxiedTools.delete(tool.name)\n }\n proxy.tool(\n {\n name: tool.name,\n ...(tool.title !== undefined ? { title: tool.title } : {}),\n description: tool.description ?? tool.name,\n inputSchema: (tool.inputSchema as Record<string, unknown>) ?? {},\n },\n async (args: unknown) => {\n const result = await client.callTool(\n { name: tool.name, arguments: args as Record<string, unknown> }\n )\n // Zod infers _meta on content items as Record<string,unknown> but\n // CallToolResult types it more specifically — identical at runtime.\n return new ToolResult(result as unknown as CallToolResult)\n },\n )\n proxiedTools.add(tool.name)\n }\n\n lastSync.tools = Date.now()\n }\n\n async function resyncResources(): Promise<void> {\n const incoming = new Set<string>()\n\n try {\n // client.listResources() with no cursor auto-aggregates every page for us.\n const { resources } = await client.listResources()\n\n for (const resource of resources) {\n incoming.add(resource.uri)\n if (!proxiedResources.has(resource.uri)) {\n proxy.resource(\n {\n uri: resource.uri,\n name: resource.name,\n ...(resource.description !== undefined ? { description: resource.description } : {}),\n ...(resource.mimeType !== undefined ? { mimeType: resource.mimeType } : {}),\n },\n async () => {\n const result = await client.readResource({ uri: resource.uri })\n return new ResourceResult(\n result.contents as Array<{\n uri: string\n mimeType?: string\n text?: string\n blob?: string\n }>,\n )\n },\n )\n proxiedResources.add(resource.uri)\n }\n }\n } catch {\n // server may not support resources\n }\n\n try {\n // client.listResourceTemplates() with no cursor auto-aggregates every page for us.\n const { resourceTemplates } = await client.listResourceTemplates()\n\n for (const template of resourceTemplates) {\n const uriTemplate = template.uriTemplate\n incoming.add(uriTemplate)\n if (!proxiedResources.has(uriTemplate)) {\n const expander = parseTemplate(uriTemplate)\n proxy.resource(\n {\n uri: uriTemplate,\n name: template.name,\n ...(template.description !== undefined\n ? { description: template.description }\n : {}),\n ...(template.mimeType !== undefined ? { mimeType: template.mimeType } : {}),\n },\n async (params?: Record<string, string>) => {\n const actualUri = params ? expander.expand(params) : uriTemplate\n const result = await client.readResource({ uri: actualUri })\n return new ResourceResult(\n result.contents as Array<{\n uri: string\n mimeType?: string\n text?: string\n blob?: string\n }>,\n )\n },\n )\n proxiedResources.add(uriTemplate)\n }\n }\n } catch {\n // server may not support resource templates\n }\n\n for (const uri of proxiedResources) {\n if (!incoming.has(uri)) {\n proxy._removeResource(uri)\n proxiedResources.delete(uri)\n }\n }\n\n lastSync.resources = Date.now()\n }\n\n async function resyncPrompts(): Promise<void> {\n // client.listPrompts() with no cursor auto-aggregates every page for us.\n const { prompts } = await client.listPrompts()\n\n const incoming = new Set(prompts.map((p) => p.name))\n\n for (const name of proxiedPrompts) {\n if (!incoming.has(name)) {\n proxy._removePrompt(name)\n proxiedPrompts.delete(name)\n }\n }\n\n for (const prompt of prompts) {\n if (!proxiedPrompts.has(prompt.name)) {\n proxy.prompt(\n {\n name: prompt.name,\n description: prompt.description,\n ...(prompt.arguments?.length ? { arguments: prompt.arguments } : {}),\n },\n async (args?: Record<string, string>) => {\n const result = await client.getPrompt({ name: prompt.name, arguments: args })\n return new PromptResult(result.messages as PromptMessage[], result.description)\n },\n )\n proxiedPrompts.add(prompt.name)\n }\n }\n\n lastSync.prompts = Date.now()\n }\n\n // Initial sync.\n await Promise.all([\n resyncTools().catch(() => {}),\n resyncResources().catch(() => {}),\n resyncPrompts().catch(() => {}),\n ])\n\n // Subscribe to backend change notifications for immediate resync.\n client.setNotificationHandler('notifications/tools/list_changed', () => {\n resyncTools().catch(() => {})\n })\n client.setNotificationHandler('notifications/resources/list_changed', () => {\n resyncResources().catch(() => {})\n })\n client.setNotificationHandler('notifications/prompts/list_changed', () => {\n resyncPrompts().catch(() => {})\n })\n\n // TTL-based lazy resync: re-fetch on list requests when the cache is stale.\n if (cacheTtl > 0) {\n proxy.use({\n async onListTools(ctx, next) {\n if (Date.now() - lastSync.tools > cacheTtl) await resyncTools().catch(() => {})\n return next()\n },\n async onListResources(ctx, next) {\n if (Date.now() - lastSync.resources > cacheTtl) await resyncResources().catch(() => {})\n return next()\n },\n async onListResourceTemplates(ctx, next) {\n if (Date.now() - lastSync.resources > cacheTtl) await resyncResources().catch(() => {})\n return next()\n },\n async onListPrompts(ctx, next) {\n if (Date.now() - lastSync.prompts > cacheTtl) await resyncPrompts().catch(() => {})\n return next()\n },\n })\n }\n\n proxy._addCloseCallback(async () => {\n await client.close()\n })\n\n return proxy\n}\n\n/**\n * Create a FastMCP instance that proxies all requests to a remote MCP server.\n * The returned instance can be mounted onto a parent server via `parent.mount(proxy)`.\n *\n * Component lists (tools, resources, prompts) are kept in sync via:\n * - Change notifications from the backend (immediate resync)\n * - TTL-based lazy resync on each list request (configurable via `cacheTtl`, default 30 s)\n */\nexport async function createProxy(config: ProxyTransport, name?: string): Promise<FastMCP> {\n let transport: import('@modelcontextprotocol/client').Transport\n\n if (config.type === 'stdio') {\n const { StdioClientTransport } = await import('@modelcontextprotocol/client/stdio')\n transport = new StdioClientTransport({\n command: config.command,\n args: config.args,\n env: config.env,\n cwd: config.cwd,\n })\n } else {\n const { StreamableHTTPClientTransport } = await import(\n '@modelcontextprotocol/client'\n )\n transport = new StreamableHTTPClientTransport(new URL(config.url), {\n requestInit: config.requestInit,\n })\n }\n\n const client = new Client(\n { name: name ?? 'fastmcp-proxy', version: '0.0.1' },\n { capabilities: {} },\n )\n\n await client.connect(transport)\n\n return buildProxyFromClient(client, { cacheTtl: config.cacheTtl, name })\n}\n","/** Small shared helpers for the OpenAPI port. Not exported from the package. */\n\n/**\n * Python-style truthiness: the ported logic from Python FastMCP branches on\n * `if value:` where empty dicts, arrays, and strings are falsy. Faithful\n * branching needs the same notion here.\n */\nexport function truthy(value: unknown): boolean {\n if (value === null || value === undefined || value === false) return false\n if (typeof value === 'number') return value !== 0\n if (typeof value === 'string') return value.length > 0\n if (Array.isArray(value)) return value.length > 0\n if (typeof value === 'object') return Object.keys(value).length > 0\n return true\n}\n\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n/** Structural equality; object key order ignored, array order significant. */\nexport function deepEqual(a: unknown, b: unknown): boolean {\n if (a === b) return true\n if (Array.isArray(a) && Array.isArray(b)) {\n return a.length === b.length && a.every((item, i) => deepEqual(item, b[i]))\n }\n if (isPlainObject(a) && isPlainObject(b)) {\n const aKeys = Object.keys(a)\n const bKeys = Object.keys(b)\n return (\n aKeys.length === bKeys.length &&\n aKeys.every((k) => Object.prototype.hasOwnProperty.call(b, k) && deepEqual(a[k], b[k]))\n )\n }\n return false\n}\n\nexport function warn(message: string): void {\n console.warn(`[fastmcp] ${message}`)\n}\n","/**\n * OpenAPI spec → HTTPRoute parsing.\n *\n * Port of Python FastMCP's `fastmcp.utilities.openapi.parser`, operating on\n * the plain spec object instead of validated pydantic models (the TypeScript\n * side does not validate the spec; malformed pieces are skipped with a\n * warning where Python's per-item error handling does the same). Reference\n * resolution is local-only: an external `$ref` in a request body, response,\n * or component walk throws; one in a parameter skips that parameter, exactly\n * like Python's per-scope error handling.\n */\n\nimport { parse as parseYaml } from 'yaml'\nimport type {\n HTTPRoute,\n HttpMethod,\n JsonSchema,\n ParameterInfo,\n ParameterLocation,\n RequestBodyInfo,\n ResponseInfo,\n} from './types'\nimport { isPlainObject, truthy, warn } from './internal'\nimport { combineSchemasAndMapParams, discriminatorTargetName, isExternalRefError, replaceRefWithDefs } from './schemas'\n\n/**\n * Load an OpenAPI spec from an object or from YAML/JSON text. YAML 1.2 is a\n * superset of JSON, so JSON text parses through the same path.\n */\nexport function loadSpec(spec: Record<string, unknown> | string): Record<string, unknown> {\n if (typeof spec !== 'string') return spec\n const parsed: unknown = parseYaml(spec)\n if (!isPlainObject(parsed)) {\n throw new Error('OpenAPI spec text must parse to an object')\n }\n return parsed\n}\n\nconst HTTP_METHODS_LOWER = [\n 'get',\n 'put',\n 'post',\n 'delete',\n 'options',\n 'head',\n 'patch',\n 'trace',\n] as const\n\nconst PRIMARY_SUCCESS_PRIORITY = ['200', '201', '202', '204', '207'] as const\n\nconst PARAMETER_LOCATIONS: readonly ParameterLocation[] = ['path', 'query', 'header', 'cookie']\n\nfunction isSuccessStatusCode(statusCode: string): boolean {\n if (/^\\s*[+-]?\\d+\\s*$/.test(statusCode)) {\n const code = parseInt(statusCode, 10)\n return code >= 200 && code < 300\n }\n return ['default', '2xx'].includes(statusCode.toLowerCase())\n}\n\n/** Parse an OpenAPI 3.x spec object into a list of HTTPRoute objects. */\nexport function parseOpenAPIToHttpRoutes(spec: Record<string, unknown>): HTTPRoute[] {\n const openapiVersion = typeof spec.openapi === 'string' ? spec.openapi : ''\n return new SpecParser(spec, openapiVersion).parse()\n}\n\nclass SpecParser {\n constructor(\n private readonly spec: Record<string, unknown>,\n private readonly openapiVersion: string,\n ) {}\n\n private toParameterLocation(paramIn: string): ParameterLocation {\n if ((PARAMETER_LOCATIONS as readonly string[]).includes(paramIn)) {\n return paramIn as ParameterLocation\n }\n warn(`Unknown parameter location: ${paramIn}, defaulting to 'query'`)\n return 'query'\n }\n\n /** Resolve a `{$ref}` object to its target within the spec (local only). */\n private resolveRef(item: unknown): unknown {\n if (!isPlainObject(item) || typeof item.$ref !== 'string') return item\n const ref = item.$ref\n try {\n if (!ref.startsWith('#/')) {\n throw new Error(`External or non-local reference not supported: ${ref}`)\n }\n const parts = ref.replace(/^[#/]+/, '').replace(/[#/]+$/, '').split('/')\n let target: unknown = this.spec\n for (const part of parts) {\n if (/^\\d+$/.test(part) && Array.isArray(target)) {\n target = target[Number(part)]\n } else if (isPlainObject(target)) {\n target = target[part]\n } else {\n throw new Error(`Cannot traverse part '${part}' in reference '${ref}'`)\n }\n if (target === null || target === undefined) {\n throw new Error(`Reference part '${part}' not found in path '${ref}'`)\n }\n }\n if (isPlainObject(target) && typeof target.$ref === 'string') {\n return this.resolveRef(target)\n }\n return target\n } catch (error) {\n throw new Error(`Failed to resolve reference '${ref}': ${(error as Error).message}`)\n }\n }\n\n /** Resolve a schema (or ref to one) and return it as a ref-converted copy. */\n private extractSchemaAsDict(schemaObj: unknown): JsonSchema {\n try {\n const resolved = this.resolveRef(schemaObj)\n let result: JsonSchema\n if (isPlainObject(resolved)) {\n // Deep copy: downstream steps mutate schemas in place, and the same\n // spec object may be parsed more than once.\n result = structuredClone(resolved)\n } else {\n warn(`Expected a schema object after resolving, got ${typeof resolved}. Using empty schema.`)\n result = {}\n }\n return replaceRefWithDefs(result)\n } catch (error) {\n if (isExternalRefError(error)) throw error\n warn(`Failed to extract schema: ${(error as Error).message}`)\n return {}\n }\n }\n\n private extractParameters(operationParams: unknown, pathItemParams: unknown): ParameterInfo[] {\n const extracted: ParameterInfo[] = []\n const seen = new Set<string>()\n const all = [\n ...(Array.isArray(operationParams) ? operationParams : []),\n ...(Array.isArray(pathItemParams) ? pathItemParams : []),\n ]\n\n for (const paramOrRef of all) {\n try {\n const parameter = this.resolveRef(paramOrRef)\n if (\n !isPlainObject(parameter) ||\n typeof parameter.name !== 'string' ||\n typeof parameter.in !== 'string'\n ) {\n warn(`Expected a parameter object after resolving. Skipping.`)\n continue\n }\n\n const location = this.toParameterLocation(parameter.in)\n\n // Skip duplicate parameters (same name and location).\n const key = `${parameter.name}\u0000${parameter.in}`\n if (seen.has(key)) continue\n seen.add(key)\n\n let paramSchema: JsonSchema = {}\n if (truthy(parameter.schema)) {\n paramSchema = this.extractSchemaAsDict(parameter.schema)\n } else if (isPlainObject(parameter.content) && truthy(parameter.content)) {\n // Content-based parameter: use the first media type's schema.\n const firstMediaType = Object.values(parameter.content)[0]\n if (isPlainObject(firstMediaType) && truthy(firstMediaType.schema)) {\n paramSchema = this.extractSchemaAsDict(firstMediaType.schema)\n }\n }\n\n extracted.push({\n name: parameter.name,\n location,\n required: Boolean(parameter.required),\n schema: paramSchema,\n ...(typeof parameter.description === 'string'\n ? { description: parameter.description }\n : {}),\n ...(typeof parameter.explode === 'boolean' ? { explode: parameter.explode } : {}),\n ...(typeof parameter.style === 'string' ? { style: parameter.style } : {}),\n })\n } catch (error) {\n // Per-parameter failures (including external refs) skip the parameter.\n warn(`Failed to extract parameter: ${(error as Error).message}`)\n }\n }\n\n return extracted\n }\n\n private extractRequestBody(requestBodyOrRef: unknown): RequestBodyInfo | undefined {\n if (!truthy(requestBodyOrRef)) return undefined\n\n try {\n const requestBody = this.resolveRef(requestBodyOrRef)\n if (!isPlainObject(requestBody)) {\n warn(`Expected a request body object after resolving. Skipping request body.`)\n return undefined\n }\n\n const info: RequestBodyInfo = {\n required: Boolean(requestBody.required),\n contentSchema: {},\n ...(typeof requestBody.description === 'string'\n ? { description: requestBody.description }\n : {}),\n }\n\n if (isPlainObject(requestBody.content)) {\n for (const [mediaType, mediaTypeObj] of Object.entries(requestBody.content)) {\n if (isPlainObject(mediaTypeObj) && truthy(mediaTypeObj.schema)) {\n try {\n info.contentSchema[mediaType] = this.extractSchemaAsDict(mediaTypeObj.schema)\n } catch (error) {\n if (isExternalRefError(error)) throw error\n warn(`Failed to extract schema for media type '${mediaType}': ${(error as Error).message}`)\n }\n }\n }\n }\n\n return info\n } catch (error) {\n if (isExternalRefError(error)) throw error\n warn(`Failed to extract request body: ${(error as Error).message}`)\n return undefined\n }\n }\n\n private getPrimarySuccessResponse(\n operationResponses: Record<string, unknown>,\n ): [string, unknown] | null {\n for (const code of PRIMARY_SUCCESS_PRIORITY) {\n if (code in operationResponses) return [code, operationResponses[code]]\n }\n for (const [statusCode, respOrRef] of Object.entries(operationResponses)) {\n if (isSuccessStatusCode(statusCode)) return [statusCode, respOrRef]\n }\n return null\n }\n\n /** Extract only the primary success response for the MCP component. */\n private extractResponses(operationResponses: unknown): Record<string, ResponseInfo> {\n const extracted: Record<string, ResponseInfo> = {}\n if (!isPlainObject(operationResponses) || !truthy(operationResponses)) return extracted\n\n const primary = this.getPrimarySuccessResponse(operationResponses)\n if (primary === null) return extracted\n\n const [statusCode, respOrRef] = primary\n try {\n const response = this.resolveRef(respOrRef)\n if (!isPlainObject(response)) {\n warn(`Expected a response object after resolving for status code ${statusCode}. Skipping.`)\n return extracted\n }\n\n const respInfo: ResponseInfo = {\n contentSchema: {},\n ...(typeof response.description === 'string' ? { description: response.description } : {}),\n }\n\n if (isPlainObject(response.content)) {\n for (const [mediaType, mediaTypeObj] of Object.entries(response.content)) {\n if (isPlainObject(mediaTypeObj) && truthy(mediaTypeObj.schema)) {\n try {\n // Track whether this was a top-level component ref before resolution.\n let topLevelSchemaName: string | null = null\n const mediaSchema = mediaTypeObj.schema\n if (isPlainObject(mediaSchema) && typeof mediaSchema.$ref === 'string') {\n if (mediaSchema.$ref.startsWith('#/components/schemas/')) {\n topLevelSchemaName = mediaSchema.$ref.split('/').pop() as string\n }\n }\n\n const schemaDict = this.extractSchemaAsDict(mediaSchema)\n if (topLevelSchemaName !== null) {\n schemaDict['x-fastmcp-top-level-schema'] = topLevelSchemaName\n }\n respInfo.contentSchema[mediaType] = schemaDict\n } catch (error) {\n if (isExternalRefError(error)) throw error\n warn(\n `Failed to extract schema for media type '${mediaType}' in response ${statusCode}: ${(error as Error).message}`,\n )\n }\n } else {\n // Record the media type even without a schema so MIME type\n // inference can still use the declared content type.\n respInfo.contentSchema[mediaType] ??= {}\n }\n }\n }\n\n extracted[statusCode] = respInfo\n } catch (error) {\n if (isExternalRefError(error)) throw error\n warn(`Failed to extract response for status code ${statusCode}: ${(error as Error).message}`)\n }\n\n return extracted\n }\n\n /** Collect schema names referenced by `schema`, transitively. */\n private extractSchemaDependencies(\n schema: unknown,\n allSchemas: Record<string, JsonSchema>,\n collected: Set<string> = new Set(),\n followDiscriminator = false,\n ): Set<string> {\n const collect = (schemaName: string): void => {\n if (!collected.has(schemaName) && schemaName in allSchemas) {\n collected.add(schemaName)\n findRefs(allSchemas[schemaName])\n }\n }\n\n const findRefs = (obj: unknown): void => {\n if (isPlainObject(obj)) {\n if (typeof obj.$ref === 'string') {\n const ref = obj.$ref\n if (ref.startsWith('#/$defs/') || ref.startsWith('#/components/schemas/')) {\n collect(ref.split('/').pop() as string)\n }\n }\n\n if (followDiscriminator) {\n const discriminator = obj.discriminator\n if (isPlainObject(discriminator) && isPlainObject(discriminator.mapping)) {\n for (const target of Object.values(discriminator.mapping)) {\n if (typeof target !== 'string') continue\n const name = discriminatorTargetName(target)\n if (name !== null) collect(name)\n }\n }\n }\n\n for (const value of Object.values(obj)) findRefs(value)\n } else if (Array.isArray(obj)) {\n for (const item of obj) findRefs(item)\n }\n }\n\n findRefs(schema)\n return collected\n }\n\n private extractInputSchemaDependencies(\n parameters: ParameterInfo[],\n requestBody: RequestBodyInfo | undefined,\n allSchemas: Record<string, JsonSchema>,\n ): Record<string, JsonSchema> {\n const needed = new Set<string>()\n\n for (const param of parameters) {\n if (truthy(param.schema)) {\n this.extractSchemaDependencies(param.schema, allSchemas, needed)\n }\n }\n\n // Request bodies are flattened into a single object, so discriminated\n // subtypes need to come along.\n if (requestBody && truthy(requestBody.contentSchema)) {\n for (const contentSchema of Object.values(requestBody.contentSchema)) {\n this.extractSchemaDependencies(contentSchema, allSchemas, needed, true)\n }\n }\n\n return Object.fromEntries([...needed].filter((n) => n in allSchemas).map((n) => [n, allSchemas[n]]))\n }\n\n private extractOutputSchemaDependencies(\n responses: Record<string, ResponseInfo>,\n allSchemas: Record<string, JsonSchema>,\n ): Record<string, JsonSchema> {\n if (!truthy(responses) || !truthy(allSchemas)) return {}\n\n const needed = new Set<string>()\n\n for (const response of Object.values(responses)) {\n if (!truthy(response.contentSchema)) continue\n\n for (const contentSchema of Object.values(response.contentSchema)) {\n this.extractSchemaDependencies(contentSchema, allSchemas, needed)\n\n const schemaName = contentSchema['x-fastmcp-top-level-schema']\n if (typeof schemaName === 'string' && schemaName in allSchemas) {\n needed.add(schemaName)\n this.extractSchemaDependencies(allSchemas[schemaName], allSchemas, needed)\n }\n }\n }\n\n return Object.fromEntries([...needed].filter((n) => n in allSchemas).map((n) => [n, allSchemas[n]]))\n }\n\n parse(): HTTPRoute[] {\n const routes: HTTPRoute[] = []\n\n const paths = this.spec.paths\n if (!isPlainObject(paths) || !truthy(paths)) {\n warn('OpenAPI schema has no paths defined.')\n return []\n }\n\n // Extract component schema definitions (per-definition failures skip\n // that definition, external refs included — Python parity).\n const schemaDefinitions: Record<string, JsonSchema> = {}\n const components = this.spec.components\n if (isPlainObject(components) && isPlainObject(components.schemas)) {\n for (const [name, schema] of Object.entries(components.schemas)) {\n try {\n schemaDefinitions[name] = this.extractSchemaAsDict(this.resolveRef(schema))\n } catch (error) {\n warn(`Failed to extract schema definition '${name}': ${(error as Error).message}`)\n }\n }\n }\n for (const [name, schema] of Object.entries(schemaDefinitions)) {\n if (isPlainObject(schema)) {\n schemaDefinitions[name] = replaceRefWithDefs(schema)\n }\n }\n\n for (const [pathStr, pathItemObj] of Object.entries(paths)) {\n if (!isPlainObject(pathItemObj)) {\n warn(`Skipping invalid path item for path '${pathStr}'`)\n continue\n }\n\n const pathLevelParams = pathItemObj.parameters\n\n for (const methodLower of HTTP_METHODS_LOWER) {\n const operation = pathItemObj[methodLower]\n if (!isPlainObject(operation)) continue\n\n const method = methodLower.toUpperCase() as HttpMethod\n\n try {\n const parameters = this.extractParameters(operation.parameters, pathLevelParams)\n const requestBody = this.extractRequestBody(operation.requestBody)\n const responses = this.extractResponses(operation.responses)\n\n const extensions = Object.fromEntries(\n Object.entries(operation).filter(([key]) => key.startsWith('x-')),\n )\n\n const requestSchemas = this.extractInputSchemaDependencies(\n parameters,\n requestBody,\n schemaDefinitions,\n )\n const responseSchemas = this.extractOutputSchemaDependencies(\n responses,\n schemaDefinitions,\n )\n\n const route: HTTPRoute = {\n path: pathStr,\n method,\n ...(typeof operation.operationId === 'string'\n ? { operationId: operation.operationId }\n : {}),\n ...(typeof operation.summary === 'string' ? { summary: operation.summary } : {}),\n ...(typeof operation.description === 'string'\n ? { description: operation.description }\n : {}),\n tags: Array.isArray(operation.tags) ? [...(operation.tags as string[])] : [],\n parameters,\n ...(requestBody !== undefined ? { requestBody } : {}),\n responses,\n requestSchemas,\n responseSchemas,\n extensions,\n openapiVersion: this.openapiVersion,\n flatParamSchema: {},\n parameterMap: {},\n }\n\n // Pre-calculate the flat schema and parameter mapping.\n try {\n const [flatSchema, parameterMap] = combineSchemasAndMapParams(route)\n route.flatParamSchema = flatSchema\n route.parameterMap = parameterMap\n } catch (error) {\n warn(\n `Failed to pre-calculate schema for route ${method} ${pathStr}: ${(error as Error).message}`,\n )\n route.flatParamSchema = { type: 'object', properties: {} }\n route.parameterMap = {}\n }\n routes.push(route)\n } catch (error) {\n if (isExternalRefError(error)) throw error\n const opId =\n typeof operation.operationId === 'string' ? operation.operationId : 'unknown'\n warn(\n `Failed to process operation ${method} ${pathStr} (ID: ${opId}): ${(error as Error).message}`,\n )\n }\n }\n }\n\n return routes\n }\n}\n","/**\n * OpenAPI 3.x schema → JSON Schema conversion.\n *\n * Port of Python FastMCP's `fastmcp.utilities.openapi.json_schema_converter`\n * (plus `require_discriminator_property` from `fastmcp.utilities.json_schema`).\n * The conversion order is part of the parity contract:\n *\n * 1. nullable → type arrays / anyOf-with-null (OpenAPI 3.0 only; 3.1 has no\n * `nullable`, so the keyword is simply stripped there)\n * 2. oneOf → anyOf (all 3.x — overlapping unions must not hard-fail)\n * 3. the discriminator's tag property is forced into each variant's\n * `required` BEFORE the keyword is removed\n * 4. OpenAPI-specific fields removed\n * 5. recurse into nested schemas\n */\n\nimport type { JsonSchema } from './types'\nimport { isPlainObject } from './internal'\n\nconst OPENAPI_SPECIFIC_FIELDS = [\n 'nullable',\n 'discriminator',\n 'readOnly',\n 'writeOnly',\n 'xml',\n 'externalDocs',\n 'deprecated',\n] as const\n\nconst RECURSIVE_MAP_FIELDS = ['properties', '$defs', '$definitions'] as const\nconst RECURSIVE_SINGLE_FIELDS = ['items', 'additionalProperties', 'not'] as const\nconst RECURSIVE_LIST_FIELDS = ['allOf', 'anyOf', 'oneOf'] as const\n\n/** Convert an OpenAPI 3.x schema (and everything nested in it) to JSON Schema. */\nexport function convertOpenAPISchemaToJsonSchema(\n schema: JsonSchema,\n openapiVersion?: string,\n): JsonSchema {\n if (!isPlainObject(schema)) return schema\n\n let result: JsonSchema = { ...schema }\n\n if (openapiVersion?.startsWith('3.0')) {\n result = convertNullableField(result)\n }\n\n if ('oneOf' in result) {\n result.anyOf = result.oneOf\n delete result.oneOf\n }\n\n result = requireDiscriminatorProperty(result)\n\n for (const field of OPENAPI_SPECIFIC_FIELDS) {\n delete result[field]\n }\n\n for (const field of RECURSIVE_MAP_FIELDS) {\n const map = result[field]\n if (isPlainObject(map)) {\n result[field] = Object.fromEntries(\n Object.entries(map).map(([name, sub]) => [\n name,\n isPlainObject(sub) ? convertOpenAPISchemaToJsonSchema(sub, openapiVersion) : sub,\n ]),\n )\n }\n }\n for (const field of RECURSIVE_SINGLE_FIELDS) {\n const sub = result[field]\n if (isPlainObject(sub)) {\n result[field] = convertOpenAPISchemaToJsonSchema(sub, openapiVersion)\n }\n }\n for (const field of RECURSIVE_LIST_FIELDS) {\n const list = result[field]\n if (Array.isArray(list)) {\n result[field] = list.map((item) =>\n isPlainObject(item) ? convertOpenAPISchemaToJsonSchema(item, openapiVersion) : item,\n )\n }\n }\n\n return result\n}\n\n/** Convert OpenAPI 3.0 `nullable: true` into JSON Schema null unions. */\nfunction convertNullableField(schema: JsonSchema): JsonSchema {\n if (!('nullable' in schema)) return schema\n\n const result = { ...schema }\n const nullableValue = result.nullable\n delete result.nullable\n\n if (!nullableValue) return result\n\n const currentType = result.type\n if ('type' in result) {\n if (typeof currentType === 'string') {\n result.type = [currentType, 'null']\n } else if (Array.isArray(currentType) && !currentType.includes('null')) {\n result.type = [...currentType, 'null']\n }\n } else if ('oneOf' in result) {\n result.anyOf = [...(result.oneOf as unknown[]), { type: 'null' }]\n delete result.oneOf\n } else if ('anyOf' in result) {\n const anyOf = result.anyOf as unknown[]\n if (!anyOf.some((item) => isPlainObject(item) && item.type === 'null')) {\n result.anyOf = [...anyOf, { type: 'null' }]\n }\n } else if ('allOf' in result) {\n result.anyOf = [{ allOf: result.allOf }, { type: 'null' }]\n delete result.allOf\n }\n\n if (Array.isArray(result.enum) && !result.enum.includes(null)) {\n result.enum = [...result.enum, null]\n }\n\n return result\n}\n\n/** Return a copy of `schema` with `propertyName` added to `required`. */\nfunction requireProperty(schema: JsonSchema, propertyName: string): JsonSchema {\n const required = schema.required\n if (required === undefined || required === null) {\n return { ...schema, required: [propertyName] }\n }\n if (Array.isArray(required) && !required.includes(propertyName)) {\n return { ...schema, required: [...required, propertyName] }\n }\n return schema\n}\n\n/**\n * Keep an OpenAPI discriminator's tag mandatory after the keyword is dropped:\n * adds `discriminator.propertyName` to each anyOf/oneOf variant's `required`.\n */\nexport function requireDiscriminatorProperty(schema: JsonSchema): JsonSchema {\n const discriminator = schema.discriminator\n if (!isPlainObject(discriminator)) return schema\n const propertyName = discriminator.propertyName\n if (typeof propertyName !== 'string') return schema\n\n const result = { ...schema }\n for (const key of ['anyOf', 'oneOf'] as const) {\n const variants = result[key]\n if (!Array.isArray(variants)) continue\n result[key] = variants.map((variant) =>\n isPlainObject(variant) ? requireProperty(variant, propertyName) : variant,\n )\n }\n return result\n}\n","/**\n * Schema manipulation for OpenAPI operations.\n *\n * Port of Python FastMCP's `fastmcp.utilities.openapi.schemas`. The quirks are\n * deliberate parity: the flat input schema keeps an empty `required: []`, the\n * request-body content schema is mutated IN PLACE (the request director later\n * reads the mutated version to decide body construction), and discriminator\n * subtypes are flattened into optional fields rather than emitted as a\n * top-level union. The snapshots in `tests/fixtures/openapi/` pin all of it.\n */\n\nimport type { HTTPRoute, JsonSchema, ParameterMapping, ResponseInfo } from './types'\nimport { deepEqual, isPlainObject, truthy } from './internal'\nimport { convertOpenAPISchemaToJsonSchema } from './jsonSchema'\n\nexport const EXTERNAL_REF_MESSAGE = 'External or non-local reference not supported'\n\nexport function isExternalRefError(error: unknown): boolean {\n return error instanceof Error && error.message.includes(EXTERNAL_REF_MESSAGE)\n}\n\n/**\n * Replace OpenAPI `#/components/schemas/X` refs with JSON Schema `#/$defs/X`\n * recursively. Throws on external (non-`#/`) references.\n */\nexport function replaceRefWithDefs(info: JsonSchema, description?: string): JsonSchema {\n const schema: JsonSchema = { ...info }\n const refPath = schema.$ref\n if (truthy(refPath)) {\n if (typeof refPath === 'string') {\n if (refPath.startsWith('#/components/schemas/')) {\n schema.$ref = `#/$defs/${refPath.split('/').pop()}`\n } else if (!refPath.startsWith('#/')) {\n throw new Error(\n `${EXTERNAL_REF_MESSAGE}: ${refPath}. FastMCP only supports local schema ` +\n `references starting with '#/'. Please include all schema definitions ` +\n `within the OpenAPI document.`,\n )\n }\n }\n } else if (truthy(schema.properties)) {\n const properties = schema.properties as Record<string, unknown>\n if ('$ref' in properties) {\n // A property literally named \"$ref\": the Python implementation treats the\n // whole properties map as one schema in this case. Same here, for parity.\n schema.properties = replaceRefWithDefs(properties as JsonSchema)\n } else {\n schema.properties = Object.fromEntries(\n Object.entries(properties).map(([name, prop]) => [\n name,\n isPlainObject(prop) ? replaceRefWithDefs(prop) : prop,\n ]),\n )\n }\n } else if (truthy(schema.items)) {\n if (isPlainObject(schema.items)) {\n schema.items = replaceRefWithDefs(schema.items)\n }\n }\n for (const section of ['anyOf', 'allOf', 'oneOf'] as const) {\n const list = schema[section]\n if (Array.isArray(list)) {\n schema[section] = list.map((item) => (isPlainObject(item) ? replaceRefWithDefs(item) : item))\n }\n }\n const additionalProperties = schema.additionalProperties\n if (truthy(additionalProperties) && isPlainObject(additionalProperties)) {\n schema.additionalProperties = replaceRefWithDefs(additionalProperties)\n }\n const propertyNames = schema.propertyNames\n if (truthy(propertyNames) && isPlainObject(propertyNames)) {\n schema.propertyNames = replaceRefWithDefs(propertyNames)\n }\n const patternProperties = schema.patternProperties\n if (truthy(patternProperties) && isPlainObject(patternProperties)) {\n schema.patternProperties = Object.fromEntries(\n Object.entries(patternProperties).map(([pattern, sub]) => [\n pattern,\n isPlainObject(sub) ? replaceRefWithDefs(sub) : sub,\n ]),\n )\n }\n if (info.description === undefined && truthy(description) && !truthy(schema.description)) {\n schema.description = description\n }\n return schema\n}\n\n/** Expand local schema references while collecting `allOf` members. */\nfunction allofMembers(\n schema: JsonSchema,\n schemaDefs: Record<string, JsonSchema>,\n resolving: ReadonlySet<string> = new Set(),\n): JsonSchema[] {\n const ref = schema.$ref\n if (typeof ref === 'string') {\n for (const prefix of ['#/$defs/', '#/components/schemas/']) {\n if (ref.startsWith(prefix)) {\n const name = ref.slice(prefix.length)\n const referenced = schemaDefs[name]\n if (isPlainObject(referenced) && !resolving.has(name)) {\n const siblings = Object.fromEntries(\n Object.entries(schema).filter(([key]) => key !== '$ref'),\n )\n const members = allofMembers(referenced, schemaDefs, new Set([...resolving, name]))\n return truthy(siblings) ? [...members, siblings] : members\n }\n break\n }\n }\n }\n\n const allOf = schema.allOf\n if (Array.isArray(allOf)) {\n const members: JsonSchema[] = []\n for (const member of allOf) {\n if (isPlainObject(member)) {\n members.push(...allofMembers(member, schemaDefs, resolving))\n }\n }\n const siblings = Object.fromEntries(Object.entries(schema).filter(([key]) => key !== 'allOf'))\n return truthy(siblings) ? [...members, siblings] : members\n }\n\n return [schema]\n}\n\n/**\n * Resolve a `discriminator.mapping` value to a local schema name. Mapping\n * values hold \"schema names or references\": a bare `\"Cat\"` means the `Cat`\n * component just as `\"#/components/schemas/Cat\"` does.\n */\nexport function discriminatorTargetName(target: string): string | null {\n for (const prefix of ['#/$defs/', '#/components/schemas/']) {\n if (target.startsWith(prefix)) {\n return target.slice(prefix.length) || null\n }\n }\n if (target.startsWith('#') || target.includes('/')) return null\n return target || null\n}\n\n/**\n * Flatten the subtypes named by an OpenAPI `discriminator.mapping` into the\n * parent's properties. Variant fields merge in as optional; properties that\n * disagree between variants become an anyOf; the tag property's description\n * spells out the accepted values. Returns replacement properties, or null when\n * there is no usable mapping.\n */\nfunction flattenDiscriminatorSubtypes(\n schema: JsonSchema,\n schemaDefs: Record<string, JsonSchema>,\n): Record<string, unknown> | null {\n const discriminator = schema.discriminator\n if (!isPlainObject(discriminator)) return null\n\n const propertyName = discriminator.propertyName\n const mapping = discriminator.mapping\n if (typeof propertyName !== 'string' || !isPlainObject(mapping)) return null\n\n const ownProps = isPlainObject(schema.properties) ? schema.properties : {}\n const alternatives = new Map<string, unknown[]>()\n const values: string[] = []\n const variants: string[] = []\n\n for (const [value, target] of Object.entries(mapping)) {\n if (typeof target !== 'string') continue\n\n const name = discriminatorTargetName(target)\n const subtype = name !== null ? schemaDefs[name] : undefined\n if (!isPlainObject(subtype)) continue\n\n // Fields the parent already declares are shared, not variant-specific.\n const variantFields: string[] = []\n for (const member of allofMembers(subtype, schemaDefs)) {\n const memberProps = isPlainObject(member.properties) ? member.properties : {}\n for (const [propName, propSchema] of Object.entries(memberProps)) {\n if (propName in ownProps) continue\n if (!variantFields.includes(propName)) variantFields.push(propName)\n const seen = alternatives.get(propName) ?? []\n if (!seen.some((existing) => deepEqual(existing, propSchema))) seen.push(propSchema)\n alternatives.set(propName, seen)\n }\n }\n\n values.push(`'${value}'`)\n if (variantFields.length > 0) {\n variants.push(`'${value}' uses ${variantFields.join(', ')}`)\n }\n }\n\n if (values.length === 0) return null\n\n const subtypeProps = Object.fromEntries(\n [...alternatives.entries()].map(([propName, schemas]) => [\n propName,\n schemas.length === 1 ? schemas[0] : { anyOf: schemas },\n ]),\n )\n const properties: Record<string, unknown> = { ...ownProps, ...subtypeProps }\n\n let note = `Selects the variant. Accepted values: ${values.join(', ')}.`\n if (variants.length > 0) {\n note += ` ${variants.join('; ')}. Send only the fields belonging to the selected variant.`\n }\n\n // The discriminator names a property of the payload, so give it a schema even\n // when the parent left it undeclared.\n const existing = properties[propertyName]\n const tagSchema: JsonSchema = isPlainObject(existing) ? existing : { type: 'string' }\n const existingDesc = tagSchema.description\n properties[propertyName] = {\n ...tagSchema,\n description: truthy(existingDesc) ? `${existingDesc as string} ${note}` : note,\n }\n\n return properties\n}\n\nfunction capitalize(text: string): string {\n return text.charAt(0).toUpperCase() + text.slice(1)\n}\n\n/**\n * Combine parameter and request-body schemas into the flat input schema\n * advertised on the MCP tool, and build the parameter map that routes flat\n * arguments back to their OpenAPI locations at request time.\n *\n * Mirrors the Python parser's pre-calculation path (`convert_refs=False`):\n * refs are already converted, `$defs` is attached unpruned, and the body\n * content schema is mutated in place.\n */\nexport function combineSchemasAndMapParams(\n route: HTTPRoute,\n): [JsonSchema, Record<string, ParameterMapping>] {\n const properties: Record<string, unknown> = {}\n const required: string[] = []\n const parameterMap: Record<string, ParameterMapping> = {}\n\n const paramNamesByLocation = {\n path: new Set<string>(),\n query: new Set<string>(),\n header: new Set<string>(),\n cookie: new Set<string>(),\n }\n let bodySchema: JsonSchema = {}\n let bodyProps: Record<string, unknown> = {}\n\n for (const param of route.parameters) {\n paramNamesByLocation[param.location].add(param.name)\n }\n\n const requestBody = route.requestBody\n if (requestBody && truthy(requestBody.contentSchema)) {\n const contentType = Object.keys(requestBody.contentSchema)[0]\n bodySchema = requestBody.contentSchema[contentType]\n\n if (truthy(requestBody.description) && !truthy(bodySchema.description)) {\n bodySchema.description = requestBody.description\n }\n\n if ('allOf' in bodySchema && Array.isArray(bodySchema.allOf)) {\n const mergedProps: Record<string, unknown> = {}\n const mergedRequired: string[] = []\n\n for (const subSchema of allofMembers(bodySchema, route.requestSchemas)) {\n if ('properties' in subSchema && isPlainObject(subSchema.properties)) {\n Object.assign(mergedProps, subSchema.properties)\n }\n if ('required' in subSchema && Array.isArray(subSchema.required)) {\n mergedRequired.push(...(subSchema.required as string[]))\n }\n }\n\n bodySchema.properties = mergedProps\n if (mergedRequired.length > 0) {\n bodySchema.required = [...new Set(mergedRequired)]\n }\n delete bodySchema.allOf\n }\n\n // Merge discriminated subtype fields in as optional. The discriminator\n // itself is dropped: its mapping points at definitions that would leave\n // dangling refs once pruned from $defs.\n const flattenedProps = flattenDiscriminatorSubtypes(bodySchema, route.requestSchemas)\n if (flattenedProps !== null) {\n bodySchema.properties = flattenedProps\n delete bodySchema.discriminator\n }\n\n bodyProps = isPlainObject(bodySchema.properties) ? bodySchema.properties : {}\n }\n\n // Collisions: a name used in more than one non-body location, or shared\n // between body and a parameter location.\n const allNonBodyParams = new Set<string>()\n for (const names of Object.values(paramNamesByLocation)) {\n for (const name of names) allNonBodyParams.add(name)\n }\n const bodyParamNames = new Set(Object.keys(bodyProps))\n const paramCounts = new Map<string, number>()\n for (const param of route.parameters) {\n paramCounts.set(param.name, (paramCounts.get(param.name) ?? 0) + 1)\n }\n const collidingParams = new Set<string>()\n for (const name of allNonBodyParams) {\n if (bodyParamNames.has(name)) collidingParams.add(name)\n }\n for (const [name, count] of paramCounts) {\n if (count > 1) collidingParams.add(name)\n }\n\n for (const param of route.parameters) {\n const paramSchema: JsonSchema = { ...param.schema }\n if (truthy(param.description) && !truthy(paramSchema.description)) {\n paramSchema.description = param.description\n }\n\n if (collidingParams.has(param.name)) {\n const suffixedName = `${param.name}__${param.location}`\n if (param.required) required.push(suffixedName)\n parameterMap[suffixedName] = { location: param.location, openapiName: param.name }\n\n const originalDesc = truthy(paramSchema.description) ? (paramSchema.description as string) : ''\n const locationDesc = `(${capitalize(param.location)} parameter)`\n paramSchema.description = originalDesc ? `${originalDesc} ${locationDesc}` : locationDesc\n\n properties[suffixedName] = paramSchema\n } else {\n if (param.required) required.push(param.name)\n parameterMap[param.name] = { location: param.location, openapiName: param.name }\n properties[param.name] = paramSchema\n }\n }\n\n // Request body properties are added without suffixes.\n if (requestBody && truthy(requestBody.contentSchema)) {\n if ('$ref' in bodySchema && !truthy(bodyProps)) {\n // The entire body is a reference: keep it as a single `body` property.\n properties.body = bodySchema\n if (requestBody.required) required.push('body')\n parameterMap.body = { location: 'body', openapiName: 'body' }\n } else if (truthy(bodyProps)) {\n for (const [propName, propSchema] of Object.entries(bodyProps)) {\n properties[propName] = propSchema\n parameterMap[propName] = { location: 'body', openapiName: propName }\n }\n if (requestBody.required) {\n required.push(...((bodySchema.required as string[] | undefined) ?? []))\n }\n } else {\n // Direct array/primitive body: name the parameter from the schema title.\n let paramName = String(\n typeof bodySchema.title === 'string' ? bodySchema.title : 'body',\n ).toLowerCase()\n paramName = paramName.replace(/[^a-zA-Z0-9_]/g, '_')\n if (!paramName || /^\\d/.test(paramName)) paramName = 'body_data'\n\n properties[paramName] = bodySchema\n if (requestBody.required) required.push(paramName)\n parameterMap[paramName] = { location: 'body', openapiName: paramName }\n }\n }\n\n let result: JsonSchema = { type: 'object', properties, required }\n if (truthy(route.requestSchemas)) {\n result.$defs = route.requestSchemas\n }\n\n if (route.openapiVersion?.startsWith('3')) {\n result = convertOpenAPISchemaToJsonSchema(result, route.openapiVersion)\n }\n\n return [result, parameterMap]\n}\n\nconst SUCCESS_CODE_PRIORITY = ['200', '201', '202', '204'] as const\n\nconst JSON_COMPATIBLE_TYPES = [\n 'application/json',\n 'application/vnd.api+json',\n 'application/hal+json',\n 'application/ld+json',\n 'text/json',\n] as const\n\n/**\n * Extract the MCP tool output schema from OpenAPI responses: first success\n * response, JSON-compatible content type preferred, non-object schemas\n * wrapped in `{result}` with the `x-fastmcp-wrap-result` marker.\n */\nexport function extractOutputSchemaFromResponses(\n responses: Record<string, ResponseInfo>,\n schemaDefinitions?: Record<string, JsonSchema>,\n openapiVersion?: string,\n): JsonSchema | null {\n if (!truthy(responses)) return null\n\n let responseInfo: ResponseInfo | undefined\n for (const statusCode of SUCCESS_CODE_PRIORITY) {\n if (statusCode in responses) {\n responseInfo = responses[statusCode]\n break\n }\n }\n if (responseInfo === undefined) {\n for (const [statusCode, respInfo] of Object.entries(responses)) {\n if (statusCode.startsWith('2')) {\n responseInfo = respInfo\n break\n }\n }\n }\n if (responseInfo === undefined || !truthy(responseInfo.contentSchema)) return null\n\n let schema: JsonSchema | undefined\n for (const contentType of JSON_COMPATIBLE_TYPES) {\n if (contentType in responseInfo.contentSchema) {\n schema = responseInfo.contentSchema[contentType]\n break\n }\n }\n if (schema === undefined) {\n const firstContentType = Object.keys(responseInfo.contentSchema)[0]\n schema = responseInfo.contentSchema[firstContentType]\n }\n\n if (!truthy(schema) || !isPlainObject(schema)) return null\n\n let outputSchema = replaceRefWithDefs(schema)\n\n // A top-level $ref is inlined from the definitions before further handling.\n if (typeof outputSchema.$ref === 'string' && schemaDefinitions && truthy(schemaDefinitions)) {\n const refPath = outputSchema.$ref\n if (refPath.startsWith('#/$defs/')) {\n const schemaName = refPath.split('/').pop() as string\n if (schemaName in schemaDefinitions) {\n outputSchema = replaceRefWithDefs(schemaDefinitions[schemaName])\n }\n }\n }\n\n if (openapiVersion?.startsWith('3')) {\n outputSchema = convertOpenAPISchemaToJsonSchema(outputSchema, openapiVersion)\n }\n\n // MCP requires output schemas to be objects; wrap anything else.\n if (outputSchema.type !== 'object') {\n outputSchema = {\n type: 'object',\n properties: { result: outputSchema },\n required: ['result'],\n 'x-fastmcp-wrap-result': true,\n }\n }\n\n if (schemaDefinitions && truthy(schemaDefinitions)) {\n const processedDefs: Record<string, JsonSchema> = { ...schemaDefinitions }\n for (const [name, defSchema] of Object.entries(processedDefs)) {\n if (isPlainObject(defSchema)) {\n processedDefs[name] = replaceRefWithDefs(defSchema)\n }\n }\n if (openapiVersion?.startsWith('3')) {\n for (const name of Object.keys(processedDefs)) {\n processedDefs[name] = convertOpenAPISchemaToJsonSchema(processedDefs[name], openapiVersion)\n }\n }\n outputSchema.$defs = processedDefs\n }\n\n return outputSchema\n}\n","/**\n * Route mapping: which MCP component type each HTTP route becomes.\n *\n * Port of Python FastMCP's `fastmcp.server.providers.openapi.routing`. User\n * maps are checked in order before the default map (everything becomes a\n * tool); the first map whose methods, pattern, and tags all match wins.\n */\n\nimport type { HTTPRoute, RouteMap } from './types'\n\n/** Default route mapping: every route becomes a tool. */\nexport const DEFAULT_ROUTE_MAPPINGS: readonly RouteMap[] = [{ mcpType: 'tool' }]\n\nfunction patternMatches(pattern: RegExp | string | undefined, path: string): boolean {\n if (pattern === undefined) return true\n if (typeof pattern === 'string') return new RegExp(pattern).test(path)\n // Unanchored search independent of the RegExp's lastIndex state.\n return path.search(pattern) !== -1\n}\n\n/** Find the first route map matching the route. Falls back to tool. */\nexport function determineRouteType(route: HTTPRoute, mappings: readonly RouteMap[]): RouteMap {\n for (const routeMap of mappings) {\n const methods = routeMap.methods ?? '*'\n if (methods !== '*' && !methods.includes(route.method)) continue\n\n if (!patternMatches(routeMap.pattern, route.path)) continue\n\n if (routeMap.tags && routeMap.tags.length > 0) {\n const routeTags = new Set(route.tags ?? [])\n if (!routeMap.tags.every((tag) => routeTags.has(tag))) continue\n }\n\n return routeMap\n }\n\n return { mcpType: 'tool' }\n}\n","/**\n * Component naming for generated MCP components.\n *\n * Port of Python FastMCP's `_slugify`, `_generate_default_name`, and\n * `_get_unique_name`. The order of operations is part of the parity contract:\n * names truncate to 56 characters BEFORE per-type numeric deduplication, so a\n * long name that collides becomes `<56 chars>_2`, not a re-truncated hybrid.\n */\n\nimport type { HTTPRoute } from './types'\n\n/** Slug containing only letters, numbers, and underscores (case preserved). */\nexport function slugify(text: string): string {\n if (!text) return ''\n return text\n .replace(/[\\s\\-.]+/g, '_')\n .replace(/[^a-zA-Z0-9_]/g, '')\n .replace(/_+/g, '_')\n .replace(/^_+|_+$/g, '')\n}\n\n/**\n * Default component name for a route: operationId (before any `__` suffix),\n * overridden by the `names` map, else summary, else `{METHOD}_{path}`.\n */\nexport function generateDefaultName(route: HTTPRoute, names?: Record<string, string>): string {\n let name: string\n if (route.operationId) {\n name = names?.[route.operationId] ?? route.operationId.split('__')[0]\n } else {\n name = route.summary || `${route.method}_${route.path}`\n }\n\n name = slugify(name)\n if (name.length > 56) name = name.slice(0, 56)\n return name\n}\n\nexport type ComponentNameType = 'tool' | 'resource' | 'resourceTemplate' | 'prompt'\n\n/** Per-type name counter that appends `_2`, `_3`, ... on collisions. */\nexport class NameRegistry {\n private readonly counters: Record<ComponentNameType, Map<string, number>> = {\n tool: new Map(),\n resource: new Map(),\n resourceTemplate: new Map(),\n prompt: new Map(),\n }\n\n getUniqueName(name: string, componentType: ComponentNameType): string {\n const counter = this.counters[componentType]\n const count = (counter.get(name) ?? 0) + 1\n counter.set(name, count)\n if (count === 1) return name\n return `${name}_${count}`\n }\n}\n","/**\n * Request building: flat MCP tool arguments → a concrete HTTP request.\n *\n * Port of Python FastMCP's `fastmcp.utilities.openapi.director`\n * (RequestDirector). Handles un-flattening via the parameter map, OpenAPI\n * query style/explode serialization, strict path-parameter percent-encoding\n * (everything encoded, plus `.` → `%2E`), and request-body dispatch on the\n * FIRST declared content type.\n */\n\nimport type { HTTPRoute, ParameterInfo } from './types'\nimport { isPlainObject, warn } from './internal'\n\n/** A fully built HTTP request, ready to hand to fetch. */\nexport interface DirectedRequest {\n method: string\n /** Absolute URL including any query string. */\n url: string\n headers: Record<string, string>\n body?: string | URLSearchParams | FormData\n}\n\n/**\n * Query-string representation of a scalar. Booleans are lowercased to match\n * JSON/OpenAPI conventions (true/false).\n */\nfunction queryScalarToStr(value: unknown): string {\n if (typeof value === 'boolean') return value ? 'true' : 'false'\n return String(value)\n}\n\n/** Delimiter per OpenAPI style when explode=false. */\nconst STYLE_DELIMITERS: Record<string, string> = {\n form: ',',\n spaceDelimited: ' ',\n pipeDelimited: '|',\n}\n\ninterface UnflattenedArguments {\n pathParams: Record<string, unknown>\n queryParams: Record<string, unknown>\n headerParams: Record<string, unknown>\n cookieParams: Record<string, unknown>\n body: unknown\n}\n\n/** Map flat arguments back to their OpenAPI locations via the parameter map. */\nfunction unflattenArguments(route: HTTPRoute, flatArgs: Record<string, unknown>): UnflattenedArguments {\n const pathParams: Record<string, unknown> = {}\n const queryParams: Record<string, unknown> = {}\n const headerParams: Record<string, unknown> = {}\n const cookieParams: Record<string, unknown> = {}\n const bodyProps: Record<string, unknown> = {}\n\n const buckets: Record<string, Record<string, unknown>> = {\n path: pathParams,\n query: queryParams,\n header: headerParams,\n cookie: cookieParams,\n body: bodyProps,\n }\n\n if (Object.keys(route.parameterMap).length > 0) {\n for (const [argName, value] of Object.entries(flatArgs)) {\n if (value === null || value === undefined) continue // optional parameter omitted\n\n const mapping = route.parameterMap[argName]\n if (mapping === undefined) {\n warn(`Argument '${argName}' not found in parameter map for ${route.operationId ?? route.path}`)\n continue\n }\n buckets[mapping.location][mapping.openapiName] = value\n }\n } else {\n // Fallback when pre-calculation failed: suffix parsing, then declared\n // parameter locations, else body.\n const paramLocations = new Map(route.parameters.map((p) => [p.name, p.location]))\n\n for (const [argName, value] of Object.entries(flatArgs)) {\n if (value === null || value === undefined) continue\n\n const suffixIdx = argName.lastIndexOf('__')\n if (suffixIdx !== -1) {\n const baseName = argName.slice(0, suffixIdx)\n const location = argName.slice(suffixIdx + 2)\n if (location in buckets && location !== 'body') {\n buckets[location][baseName] = value\n continue\n }\n }\n\n const location = paramLocations.get(argName)\n if (location !== undefined) {\n buckets[location][argName] = value\n } else {\n bodyProps[argName] = value\n }\n }\n }\n\n // Body construction: an object-typed body schema keeps the property map; a\n // non-object schema with exactly one property sends the value directly.\n let body: unknown\n if (Object.keys(bodyProps).length > 0) {\n const contentSchema = route.requestBody?.contentSchema\n if (contentSchema && Object.keys(contentSchema).length > 0) {\n const contentType = Object.keys(contentSchema)[0]\n const bodySchema = contentSchema[contentType]\n\n if (isPlainObject(bodySchema) && bodySchema.type === 'object') {\n body = bodyProps\n } else if (Object.keys(bodyProps).length === 1) {\n body = Object.values(bodyProps)[0]\n } else {\n body = bodyProps\n }\n } else {\n body = bodyProps\n }\n }\n\n return { pathParams, queryParams, headerParams, cookieParams, body }\n}\n\n/**\n * Serialize query values per their OpenAPI style/explode settings. Exploded\n * arrays stay arrays (the key repeats in the query string); explode=false\n * joins with the style's delimiter; exploded objects fan out into separate\n * keys (bare property names for form style, `key[prop]` for deepObject).\n */\nfunction serializeQueryParams(\n route: HTTPRoute,\n queryParams: Record<string, unknown>,\n): Record<string, unknown> {\n if (Object.keys(queryParams).length === 0) return queryParams\n\n const paramLookup = new Map<string, ParameterInfo>(\n route.parameters.filter((p) => p.location === 'query').map((p) => [p.name, p]),\n )\n\n const serialized: Record<string, unknown> = {}\n for (const [key, value] of Object.entries(queryParams)) {\n const paramInfo = paramLookup.get(key)\n if (paramInfo !== undefined) {\n const explode = paramInfo.explode ?? true\n if (isPlainObject(value)) {\n if (Object.keys(value).length === 0) continue\n if (explode) {\n for (const [propKey, propValue] of Object.entries(value)) {\n const propertyName =\n paramInfo.style === 'deepObject'\n ? `${key}[${queryScalarToStr(propKey)}]`\n : queryScalarToStr(propKey)\n serialized[propertyName] = queryScalarToStr(propValue)\n }\n } else {\n const delimiter = STYLE_DELIMITERS[paramInfo.style ?? 'form'] ?? ','\n // form,explode=false on objects: key,value pairs (R,100,G,200).\n const parts: string[] = []\n for (const [propKey, propValue] of Object.entries(value)) {\n parts.push(queryScalarToStr(propKey), queryScalarToStr(propValue))\n }\n serialized[key] = parts.join(delimiter)\n }\n continue\n }\n if (!explode && Array.isArray(value)) {\n if (value.length === 0) continue\n const delimiter = STYLE_DELIMITERS[paramInfo.style ?? 'form'] ?? ','\n serialized[key] = value.map(queryScalarToStr).join(delimiter)\n continue\n }\n }\n serialized[key] = value\n }\n return serialized\n}\n\n/**\n * Percent-encode a path parameter value. Everything outside [A-Za-z0-9_~-]\n * is encoded (Python `quote(safe=\"\")` parity), and `.` becomes `%2E` so a\n * crafted value can never traverse the path.\n */\nfunction quotePathValue(value: string): string {\n return encodeURIComponent(value)\n .replace(/[!'()*]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`)\n .replace(/\\./g, '%2E')\n}\n\n/** Substitute path parameters into the template and join with the base URL. */\nfunction buildUrl(pathTemplate: string, pathParams: Record<string, unknown>, baseUrl: string): string {\n let urlPath = pathTemplate\n for (const [paramName, paramValue] of Object.entries(pathParams)) {\n const placeholder = `{${paramName}}`\n if (urlPath.includes(placeholder)) {\n urlPath = urlPath.split(placeholder).join(quotePathValue(String(paramValue)))\n }\n }\n const base = `${baseUrl.replace(/\\/+$/, '')}/`\n return new URL(urlPath.replace(/^\\/+/, ''), base).toString()\n}\n\n/**\n * Build the complete HTTP request for a route from flat tool arguments,\n * handling all OpenAPI serialization rules.\n */\nexport function buildRequest(\n route: HTTPRoute,\n flatArgs: Record<string, unknown>,\n baseUrl: string,\n): DirectedRequest {\n const { pathParams, queryParams, headerParams, cookieParams, body } = unflattenArguments(\n route,\n flatArgs,\n )\n\n const serializedQuery = serializeQueryParams(route, queryParams)\n\n const url = new URL(buildUrl(route.path, pathParams, baseUrl))\n for (const [key, value] of Object.entries(serializedQuery)) {\n if (Array.isArray(value)) {\n for (const item of value) url.searchParams.append(key, queryScalarToStr(item))\n } else {\n url.searchParams.append(key, queryScalarToStr(value))\n }\n }\n\n const headers: Record<string, string> = {}\n for (const [key, value] of Object.entries(headerParams)) {\n headers[key] = queryScalarToStr(value)\n }\n const cookiePairs = Object.entries(cookieParams).map(\n ([key, value]) => `${key}=${queryScalarToStr(value)}`,\n )\n if (cookiePairs.length > 0) {\n headers.cookie = cookiePairs.join('; ')\n }\n\n // Declared content type from the spec: raw value for the outgoing header\n // (preserves parameters like charset), normalized for dispatch matching.\n let rawContentType: string | undefined\n let declaredContentType: string | undefined\n const contentSchema = route.requestBody?.contentSchema\n if (contentSchema && Object.keys(contentSchema).length > 0) {\n rawContentType = Object.keys(contentSchema)[0]\n declaredContentType = rawContentType.split(';')[0].trim().toLowerCase()\n }\n\n let requestBody: DirectedRequest['body']\n if (body !== null && body !== undefined) {\n if (declaredContentType === 'multipart/form-data' && isPlainObject(body)) {\n const form = new FormData()\n for (const [key, value] of Object.entries(body)) {\n if (value instanceof Uint8Array) {\n form.append(key, new Blob([value as BlobPart]))\n } else {\n form.append(key, queryScalarToStr(value))\n }\n }\n requestBody = form\n // fetch sets the multipart boundary header itself.\n } else if (declaredContentType === 'application/x-www-form-urlencoded' && isPlainObject(body)) {\n const params = new URLSearchParams()\n for (const [key, value] of Object.entries(body)) {\n params.append(key, queryScalarToStr(value))\n }\n requestBody = params\n } else if (isPlainObject(body) || Array.isArray(body)) {\n requestBody = JSON.stringify(body)\n // JSON-compatible types like application/json-patch+json keep their\n // declared content type; everything else is plain application/json.\n headers['content-type'] =\n declaredContentType !== undefined &&\n declaredContentType !== 'application/json' &&\n declaredContentType.includes('json')\n ? (rawContentType as string)\n : 'application/json'\n } else {\n requestBody = String(body)\n if (rawContentType !== undefined) {\n headers['content-type'] = rawContentType\n }\n }\n }\n\n return {\n method: route.method.toUpperCase(),\n url: url.toString(),\n headers,\n ...(requestBody !== undefined ? { body: requestBody } : {}),\n }\n}\n\n/** @internal Exported for the resource template path-argument reverse lookup. */\nexport function pathArgumentName(route: HTTPRoute, parameterName: string): string {\n for (const [argumentName, mapping] of Object.entries(route.parameterMap)) {\n if (mapping.location === 'path' && mapping.openapiName === parameterName) {\n return argumentName\n }\n }\n return parameterName\n}\n","/**\n * HTTP execution for generated components.\n *\n * Port of Python FastMCP's `OpenAPITool.run` / `OpenAPIResource.read`\n * (`fastmcp.server.providers.openapi.components`): bare fetch with a timeout,\n * Python-compatible error messages (they surface as tool errors, so clients\n * may match on them), JSON responses as structuredContent with the\n * `x-fastmcp-wrap-result` unwrap applied, non-JSON as text.\n */\n\nimport { ToolResult } from '../tool'\nimport { ResourceResult } from '../resource'\nimport type { HTTPRoute, JsonSchema } from './types'\nimport { buildRequest } from './director'\nimport { isPlainObject, truthy } from './internal'\n\nexport const DEFAULT_TIMEOUT_MS = 30_000\n\n/** HTTP client configuration for a generated OpenAPI server. */\nexport interface OpenAPIClientOptions {\n /**\n * Base URL for requests. Defaults to the spec's first `servers` entry\n * (with server variables filled from their defaults). Required when the\n * spec has no absolute server URL.\n */\n baseUrl?: string\n /** Default headers sent on every request. Request-specific headers win. */\n headers?: Record<string, string>\n /** Async header provider, resolved per request (e.g. a token refresher). */\n auth?: { getHeaders(): Promise<Record<string, string>> }\n /** Custom fetch implementation. Defaults to the global fetch. */\n fetch?: typeof globalThis.fetch\n /** Per-request timeout in milliseconds. Default 30 000. */\n timeoutMs?: number\n}\n\n/** @internal Resolved client with all defaults applied. */\nexport interface ResolvedClient {\n baseUrl: string\n headers: Record<string, string>\n auth?: { getHeaders(): Promise<Record<string, string>> }\n fetch: typeof globalThis.fetch\n timeoutMs: number\n}\n\n/** Substitute server variables with their defaults: `{region}` → `us-east-1`. */\nfunction fillServerVariables(url: string, variables: unknown): string {\n if (!isPlainObject(variables)) return url\n let filled = url\n for (const [name, variable] of Object.entries(variables)) {\n const fallback = isPlainObject(variable) ? variable.default : undefined\n filled = filled.split(`{${name}}`).join(typeof fallback === 'string' ? fallback : '')\n }\n return filled\n}\n\n/** @internal Resolve client options against the spec's servers entry. */\nexport function resolveClient(\n options: OpenAPIClientOptions,\n spec: Record<string, unknown>,\n): ResolvedClient {\n let baseUrl = options.baseUrl\n if (baseUrl === undefined) {\n const servers = spec.servers\n const first = Array.isArray(servers) ? servers[0] : undefined\n const serverUrl = isPlainObject(first) && typeof first.url === 'string' ? first.url : undefined\n if (serverUrl === undefined) {\n throw new Error(\n \"No server URL found in OpenAPI spec. Either add a 'servers' entry to the \" +\n 'spec or provide client.baseUrl explicitly.',\n )\n }\n baseUrl = fillServerVariables(serverUrl, first?.variables)\n }\n try {\n new URL(baseUrl)\n } catch {\n throw new Error(\n `OpenAPI base URL must be absolute, got '${baseUrl}'. Provide client.baseUrl explicitly.`,\n )\n }\n\n return {\n baseUrl,\n headers: options.headers ?? {},\n ...(options.auth !== undefined ? { auth: options.auth } : {}),\n fetch: options.fetch ?? globalThis.fetch,\n timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,\n }\n}\n\nfunction isTimeoutError(error: unknown): boolean {\n return (\n error instanceof Error &&\n (error.name === 'TimeoutError' || error.name === 'AbortError')\n )\n}\n\nasync function sendRequest(\n client: ResolvedClient,\n route: HTTPRoute,\n args: Record<string, unknown>,\n): Promise<Response> {\n let url: string\n let init: RequestInit\n try {\n const directed = buildRequest(route, args, client.baseUrl)\n const authHeaders = client.auth ? await client.auth.getHeaders() : {}\n // Client defaults merge under auth headers; directed headers win over\n // both. HTTP header names are case-insensitive, so merge on lowercase\n // keys — otherwise a parameter named X-Trace would ride ALONGSIDE a\n // default x-trace instead of replacing it.\n const headers: Record<string, string> = {}\n for (const source of [client.headers, authHeaders, directed.headers]) {\n for (const [name, value] of Object.entries(source)) {\n headers[name.toLowerCase()] = value\n }\n }\n url = directed.url\n init = {\n method: directed.method,\n headers,\n ...(directed.body !== undefined ? { body: directed.body } : {}),\n signal: AbortSignal.timeout(client.timeoutMs),\n }\n } catch (error) {\n const e = error as Error\n throw new Error(\n `Error building request for ${route.method.toUpperCase()} ${route.path}: ${e.name}: ${e.message}`,\n )\n }\n\n let response: Response\n try {\n response = await client.fetch(url, init)\n } catch (error) {\n if (isTimeoutError(error)) {\n throw new Error(`HTTP request timed out (${(error as Error).name})`)\n }\n const e = error as Error\n throw new Error(`Request error (${e.name}): ${e.message}`)\n }\n\n if (!response.ok) {\n let message = `HTTP error ${response.status}: ${response.statusText}`\n const text = await response.text().catch(() => '')\n if (text) message += ` - ${text}`\n throw new Error(message)\n }\n\n return response\n}\n\n/** Execute a tool call: send the HTTP request and convert the response. */\nexport async function runToolRequest(\n client: ResolvedClient,\n route: HTTPRoute,\n args: Record<string, unknown>,\n outputSchema: JsonSchema | null | undefined,\n): Promise<ToolResult> {\n const response = await sendRequest(client, route, args)\n const text = await response.text()\n\n let result: unknown\n try {\n result = JSON.parse(text)\n } catch {\n // Not JSON: return the raw text.\n return new ToolResult({ content: [{ type: 'text', text }] })\n }\n\n let structured: unknown\n if (outputSchema !== null && outputSchema !== undefined) {\n structured = truthy(outputSchema['x-fastmcp-wrap-result']) ? { result } : result\n } else if (!isPlainObject(result)) {\n structured = { result }\n } else {\n structured = result\n }\n // structuredContent must be a plain object on the wire; wrap anything that\n // slipped through (e.g. a backend returning an array against an object schema).\n if (!isPlainObject(structured)) {\n structured = { result: structured }\n }\n\n return new ToolResult({\n content: [{ type: 'text', text: JSON.stringify(structured) }],\n structuredContent: structured as Record<string, unknown>,\n })\n}\n\n/** Execute a resource read: send the HTTP request and convert the response. */\nexport async function readResourceRequest(\n client: ResolvedClient,\n route: HTTPRoute,\n args: Record<string, unknown>,\n uri: string,\n mimeType: string,\n): Promise<ResourceResult> {\n const response = await sendRequest(client, route, args)\n const contentType = (response.headers.get('content-type') ?? '').toLowerCase()\n\n if (contentType.includes('application/json')) {\n const result: unknown = JSON.parse(await response.text())\n return new ResourceResult([\n { uri, mimeType: 'application/json', text: JSON.stringify(result) },\n ])\n }\n if (contentType.includes('text/') || contentType.includes('application/xml')) {\n return new ResourceResult([{ uri, mimeType, text: await response.text() }])\n }\n const bytes = Buffer.from(await response.arrayBuffer())\n return new ResourceResult([{ uri, mimeType, blob: bytes.toString('base64') }])\n}\n","/**\n * createOpenAPIServer: build a FastMCP server from an OpenAPI 3.x spec.\n *\n * TypeScript port of Python FastMCP's `FastMCP.from_openapi` /\n * `OpenAPIProvider`. Components are generated eagerly: parse the spec into\n * routes, map each route to a component type, name it, derive its schemas,\n * and register it on a plain FastMCP with a forwarding handler that calls the\n * described HTTP API. Generated names and schemas match the Python\n * implementation byte for byte; the snapshots under `tests/fixtures/openapi/`\n * pin that contract.\n */\n\nimport { FastMCP } from '../FastMCP'\nimport type { FastMCPOptions } from '../FastMCP'\nimport type {\n ComponentFn,\n HTTPRoute,\n JsonSchema,\n OpenAPIComponent,\n OpenAPIResourceComponent,\n OpenAPIResourceTemplateComponent,\n OpenAPIToolComponent,\n RouteMap,\n RouteMapFn,\n} from './types'\nimport { isPlainObject, truthy, warn } from './internal'\nimport { loadSpec, parseOpenAPIToHttpRoutes } from './parser'\nimport { extractOutputSchemaFromResponses } from './schemas'\nimport { DEFAULT_ROUTE_MAPPINGS, determineRouteType } from './routing'\nimport { NameRegistry, generateDefaultName } from './naming'\nimport { pathArgumentName } from './director'\nimport {\n readResourceRequest,\n resolveClient,\n runToolRequest,\n} from './execute'\nimport type { OpenAPIClientOptions, ResolvedClient } from './execute'\n\nexport interface OpenAPIServerOptions {\n /** The OpenAPI 3.0/3.1 spec: a parsed object, or YAML/JSON text. */\n spec: Record<string, unknown> | string\n /** Server name. Default 'OpenAPI Server'. */\n name?: string\n /** Server version. Defaults to FastMCP's own default. */\n version?: string\n /** HTTP client configuration (base URL, headers, auth, fetch, timeout). */\n client?: OpenAPIClientOptions\n /** Route maps checked in order before the default (everything → tool). */\n routeMaps?: RouteMap[]\n /** Route-type hook, run after the route maps on every route. */\n routeMapFn?: RouteMapFn\n /** Component customization hook, called before each registration. */\n componentFn?: ComponentFn\n /** Overrides mapping operationId → component name. */\n names?: Record<string, string>\n /** Tags added to every generated component. */\n tags?: string[]\n /**\n * When true (default), tools advertise the output schema extracted from\n * the spec. When false, a permissive schema is advertised instead (the\n * wrap-result marker is preserved).\n */\n validateOutput?: boolean\n /** Remaining FastMCP options (auth, middleware, page sizes, ...). */\n serverOptions?: Omit<FastMCPOptions, 'name' | 'version'>\n}\n\nconst DEFAULT_MIME_TYPE = 'application/json'\n\nconst JSON_COMPATIBLE_TYPES = [\n 'application/json',\n 'application/vnd.api+json',\n 'application/hal+json',\n 'application/ld+json',\n 'text/json',\n] as const\n\n/** Primary MIME type from a route's success response; application/json fallback. */\nfunction extractMimeTypeFromRoute(route: HTTPRoute): string {\n if (!truthy(route.responses)) return DEFAULT_MIME_TYPE\n\n let responseInfo = undefined\n for (const statusCode of ['200', '201', '202', '204']) {\n if (statusCode in route.responses) {\n responseInfo = route.responses[statusCode]\n break\n }\n }\n if (responseInfo === undefined) {\n for (const [statusCode, respInfo] of Object.entries(route.responses)) {\n if (statusCode.startsWith('2')) {\n responseInfo = respInfo\n break\n }\n }\n }\n if (responseInfo === undefined || !truthy(responseInfo.contentSchema)) return DEFAULT_MIME_TYPE\n\n const contentTypes = Object.keys(responseInfo.contentSchema)\n if (contentTypes.length === 1) return contentTypes[0]\n\n for (const contentType of JSON_COMPATIBLE_TYPES) {\n if (contentType in responseInfo.contentSchema) return contentType\n }\n return contentTypes[0]\n}\n\n/** Expand a `resource://name/{a}/{b}` template with matched parameter values. */\nfunction expandTemplateUri(uriTemplate: string, params: Record<string, string>): string {\n let uri = uriTemplate\n for (const [name, value] of Object.entries(params)) {\n uri = uri.split(`{${name}}`).join(encodeURIComponent(value))\n }\n return uri\n}\n\n/** Map matched template params back to flat tool-argument names. */\nfunction templateArguments(\n route: HTTPRoute,\n params: Record<string, string>,\n): Record<string, unknown> {\n const args: Record<string, unknown> = {}\n for (const parameter of route.parameters) {\n if (parameter.location !== 'path') continue\n const argumentName = pathArgumentName(route, parameter.name)\n if (parameter.name in params) {\n args[argumentName] = params[parameter.name]\n continue\n }\n const normalizedName = parameter.name.replace(/-/g, '_')\n if (normalizedName in params) {\n args[argumentName] = params[normalizedName]\n }\n }\n return args\n}\n\n/**\n * Create a FastMCP server from an OpenAPI 3.0/3.1 specification. Every\n * operation becomes an MCP component (tool by default; see `routeMaps`)\n * whose handler calls the described HTTP endpoint.\n */\nexport function createOpenAPIServer(options: OpenAPIServerOptions): FastMCP {\n const spec = loadSpec(options.spec)\n const client = resolveClient(options.client ?? {}, spec)\n const routes = parseOpenAPIToHttpRoutes(spec)\n\n const server = new FastMCP({\n name: options.name ?? 'OpenAPI Server',\n ...(options.version !== undefined ? { version: options.version } : {}),\n ...options.serverOptions,\n })\n\n const routeMaps = [...(options.routeMaps ?? []), ...DEFAULT_ROUTE_MAPPINGS]\n const registry = new NameRegistry()\n const validateOutput = options.validateOutput ?? true\n\n for (const route of routes) {\n const routeMap = determineRouteType(route, routeMaps)\n let routeType = routeMap.mcpType\n\n if (options.routeMapFn !== undefined) {\n try {\n const result = options.routeMapFn(route, routeType)\n if (result !== null && result !== undefined) {\n routeType = result\n }\n } catch (error) {\n warn(\n `Error in routeMapFn for ${route.method} ${route.path}: ${(error as Error).message}. Using mapped type.`,\n )\n }\n }\n\n const componentName = generateDefaultName(route, options.names)\n const componentTags = [\n ...new Set([...route.tags, ...(routeMap.mcpTags ?? []), ...(options.tags ?? [])]),\n ].sort()\n\n if (routeType === 'tool') {\n createTool(server, client, route, componentName, componentTags, registry, validateOutput, options.componentFn)\n } else if (routeType === 'resource') {\n createResource(server, client, route, componentName, componentTags, registry, options.componentFn)\n } else if (routeType === 'resourceTemplate') {\n createTemplate(server, client, route, componentName, componentTags, registry, options.componentFn)\n }\n // 'exclude' routes are skipped.\n }\n\n return server\n}\n\nfunction applyComponentFn(\n componentFn: ComponentFn | undefined,\n route: HTTPRoute,\n component: OpenAPIComponent,\n): void {\n if (componentFn === undefined) return\n try {\n componentFn(route, component)\n } catch (error) {\n warn(\n `Error in componentFn for ${component.kind} '${component.name}': ${(error as Error).message}`,\n )\n }\n}\n\nfunction createTool(\n server: FastMCP,\n client: ResolvedClient,\n route: HTTPRoute,\n name: string,\n tags: string[],\n registry: NameRegistry,\n validateOutput: boolean,\n componentFn: ComponentFn | undefined,\n): void {\n let outputSchema = extractOutputSchemaFromResponses(\n route.responses,\n route.responseSchemas,\n route.openapiVersion,\n )\n\n if (!validateOutput && outputSchema !== null) {\n // Permissive schema: accept any object, but keep the wrap-result flag so\n // non-object responses still get wrapped.\n const permissive: JsonSchema = { type: 'object', additionalProperties: true }\n if (truthy(outputSchema['x-fastmcp-wrap-result'])) {\n permissive['x-fastmcp-wrap-result'] = true\n }\n outputSchema = permissive\n }\n\n const component: OpenAPIToolComponent = {\n kind: 'tool',\n name: registry.getUniqueName(name, 'tool'),\n description: route.description || route.summary || `Executes ${route.method} ${route.path}`,\n inputSchema: route.flatParamSchema,\n ...(outputSchema !== null ? { outputSchema } : {}),\n tags,\n }\n applyComponentFn(componentFn, route, component)\n\n server.tool(\n {\n name: component.name,\n description: component.description,\n inputSchema: component.inputSchema,\n ...(component.outputSchema !== undefined ? { outputSchema: component.outputSchema } : {}),\n tags: component.tags,\n },\n async (args: unknown) =>\n runToolRequest(client, route, isPlainObject(args) ? args : {}, component.outputSchema),\n )\n}\n\nfunction createResource(\n server: FastMCP,\n client: ResolvedClient,\n route: HTTPRoute,\n name: string,\n tags: string[],\n registry: NameRegistry,\n componentFn: ComponentFn | undefined,\n): void {\n const uniqueName = registry.getUniqueName(name, 'resource')\n const component: OpenAPIResourceComponent = {\n kind: 'resource',\n uri: `resource://${uniqueName}`,\n name: uniqueName,\n description: route.description || route.summary || `Represents ${route.path}`,\n mimeType: extractMimeTypeFromRoute(route),\n tags,\n }\n applyComponentFn(componentFn, route, component)\n\n server.resource(\n {\n uri: component.uri,\n name: component.name,\n description: component.description,\n mimeType: component.mimeType,\n tags: component.tags,\n },\n async () => readResourceRequest(client, route, {}, component.uri, component.mimeType),\n )\n}\n\nfunction createTemplate(\n server: FastMCP,\n client: ResolvedClient,\n route: HTTPRoute,\n name: string,\n tags: string[],\n registry: NameRegistry,\n componentFn: ComponentFn | undefined,\n): void {\n const uniqueName = registry.getUniqueName(name, 'resourceTemplate')\n\n // Template path parameters appear in the URI sorted alphabetically.\n const pathParams = route.parameters\n .filter((p) => p.location === 'path')\n .map((p) => p.name)\n .sort()\n let uriTemplate = `resource://${uniqueName}`\n if (pathParams.length > 0) {\n uriTemplate += '/' + pathParams.map((p) => `{${p}}`).join('/')\n }\n\n const parametersSchema: JsonSchema = {\n type: 'object',\n properties: Object.fromEntries(\n route.parameters\n .filter((p) => p.location === 'path')\n .map((p) => [\n p.name,\n {\n ...(isPlainObject(p.schema) ? p.schema : {}),\n ...(truthy(p.description) && !(isPlainObject(p.schema) && 'description' in p.schema)\n ? { description: p.description }\n : {}),\n },\n ]),\n ),\n required: route.parameters\n .filter((p) => p.location === 'path' && p.required)\n .map((p) => p.name),\n }\n\n const component: OpenAPIResourceTemplateComponent = {\n kind: 'resourceTemplate',\n uriTemplate,\n name: uniqueName,\n description: route.description || route.summary || `Template for ${route.path}`,\n mimeType: extractMimeTypeFromRoute(route),\n parameters: parametersSchema,\n tags,\n }\n applyComponentFn(componentFn, route, component)\n\n server.resource(\n {\n uri: component.uriTemplate,\n name: component.name,\n description: component.description,\n mimeType: component.mimeType,\n tags: component.tags,\n },\n async (params?: Record<string, string>) => {\n const matched = params ?? {}\n const concreteUri = expandTemplateUri(component.uriTemplate, matched)\n return readResourceRequest(\n client,\n route,\n templateArguments(route, matched),\n concreteUri,\n component.mimeType,\n )\n },\n )\n}\n\nexport type { OpenAPIClientOptions } from './execute'\nexport type {\n ComponentFn,\n HTTPRoute,\n HttpMethod,\n JsonSchema,\n MCPType,\n OpenAPIComponent,\n OpenAPIResourceComponent,\n OpenAPIResourceTemplateComponent,\n OpenAPIToolComponent,\n ParameterInfo,\n ParameterLocation,\n RequestBodyInfo,\n ResponseInfo,\n RouteMap,\n RouteMapFn,\n} from './types'\n","import { FastMCP } from '../FastMCP'\nimport type { ToolConfig } from '../FastMCP'\nimport { contextStore } from '../context'\nimport type { Component } from './components'\nimport type { Visibility } from './types'\n\nexport interface EntrypointConfig {\n name: string\n description: string\n title?: string\n}\n\nexport interface BackendToolConfig {\n name: string\n description: string\n title?: string\n /** Defaults to ['app']. Pass ['model', 'app'] to also expose to the LLM. */\n visibility?: Visibility[]\n}\n\nexport interface FastMCPAppOptions {\n name: string\n version?: string\n}\n\nexport class FastMCPApp {\n readonly server: FastMCP\n\n constructor(options: FastMCPAppOptions) {\n this.server = new FastMCP({ name: options.name, version: options.version })\n }\n\n /**\n * Register an entry-point tool.\n * Entry-points are visible to the LLM (visibility: ['model', 'app']) and\n * automatically linked to a generated ui:// resource URI.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n entrypoint(config: EntrypointConfig, handler: (args?: any) => Component): void {\n const resourceUri = `ui://${config.name}`\n const toolConfig: ToolConfig = {\n name: config.name,\n description: config.description,\n ...(config.title !== undefined ? { title: config.title } : {}),\n ui: { visibility: ['model', 'app'], resourceUri },\n }\n this.server.tool(toolConfig, handler)\n // Stub resource so resources/read on the ui:// URI doesn't 404.\n // Replaced by the real UI runtime bundle when bundling is implemented.\n this.server.resource(\n { uri: resourceUri, mimeType: 'text/html;profile=mcp-app', name: config.name },\n () => `<!doctype html><html><head><meta charset=\"utf-8\"></head><body><!-- fastmcp ui-runtime placeholder --></body></html>`,\n )\n }\n\n /**\n * Register a backend tool.\n * Backend tools are hidden from listTools by default (visibility: ['app']).\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n backendTool(config: BackendToolConfig, handler: (args: any) => unknown): void {\n const visibility = config.visibility ?? ['app']\n const toolConfig: ToolConfig = {\n name: config.name,\n description: config.description,\n ...(config.title !== undefined ? { title: config.title } : {}),\n ui: { visibility },\n }\n this.server.tool(toolConfig, handler)\n }\n\n /**\n * Returns a reference to a tool that resolves to the correct external name\n * (including any mount prefix) when evaluated inside a request handler.\n * Call inside a handler function — not at definition time.\n */\n toolRef(name: string): string {\n const ctx = contextStore.getStore()\n if (!ctx) return name\n return ctx.resolveToolName(name)\n }\n}\n","import { contextStore } from '../context'\n\n/**\n * Resolve a logical tool name to its current external name inside a request\n * handler, accounting for any mount prefix applied by a parent server.\n *\n * Use this in providers that are built on bare FastMCP (not FastMCPApp) to\n * produce mount-prefix–aware action strings for Button components.\n */\nexport function actionRef(name: string): string {\n return contextStore.getStore()?.resolveToolName(name) ?? name\n}\n","import { runInNewContext } from 'node:vm'\nimport { FastMCP } from '../FastMCP'\nimport { ToolResult } from '../tool'\nimport { COMPONENT_CATALOG } from './components'\nimport * as Components from './components'\n\nexport class GenerativeUI {\n readonly server: FastMCP\n\n constructor() {\n this.server = new FastMCP({ name: 'generative-ui' })\n\n // Regular LLM tool — catalog lookup, always returns structured data\n this.server.tool(\n {\n name: 'search_components',\n description: 'List available UI components with their types and descriptions',\n },\n () => new ToolResult({\n content: [{ type: 'text', text: JSON.stringify(COMPONENT_CATALOG) }],\n }),\n )\n\n // LLM-visible tool — executes component code in an isolated sandbox\n this.server.tool(\n {\n name: 'generate_ui',\n description: 'Execute a UI component expression and return the component tree. Use search_components to discover available component APIs first.',\n inputSchema: {\n type: 'object',\n properties: {\n code: { type: 'string', description: 'A JavaScript expression using the component builders (Column, Text, Button, etc.) that evaluates to a component tree' },\n },\n required: ['code'],\n },\n },\n (args: Record<string, unknown>) => {\n const { code } = args as { code: string }\n // Sandbox: only the component builder functions are in scope — no Node globals\n const sandbox: Record<string, unknown> = { ...Components }\n delete sandbox['COMPONENT_CATALOG']\n\n try {\n // NOTE: vm.runInNewContext is NOT a true security sandbox — prototype chain\n // escapes are possible. Do not execute untrusted code in production.\n return runInNewContext(code, sandbox, { timeout: 2000 })\n } catch (err) {\n throw new Error(`[generate_ui] ${err instanceof Error ? err.message : String(err)}`)\n }\n },\n )\n }\n}\n","// ---------------------------------------------------------------------------\n// Component tree types\n// ---------------------------------------------------------------------------\n\nexport interface Component {\n type: string\n props?: Record<string, unknown>\n children?: Component[]\n}\n\n// If-node carries builder methods but they must be non-enumerable so\n// toEqual/JSON.stringify treat the node as a plain object.\nexport interface IfNode extends Component {\n type: 'if'\n branches: Array<{ condition: string; node: Component }>\n fallback?: Component\n elif(condition: string, node: Component): IfNode\n else(node: Component): Component\n}\n\n// ---------------------------------------------------------------------------\n// Component catalog — used by GenerativeUI.search_components\n// ---------------------------------------------------------------------------\n\nexport interface CatalogEntry {\n type: string\n description: string\n}\n\nexport const COMPONENT_CATALOG: CatalogEntry[] = [\n { type: 'column', description: 'Vertical stack layout. Props: gap, align, padding. Children: any components.' },\n { type: 'row', description: 'Horizontal stack layout. Props: gap, align, justify, wrap. Children: any components.' },\n { type: 'grid', description: 'CSS grid layout. Props: columns, gap. Children: any components.' },\n { type: 'text', description: 'Text display. Props: content (string or Rx), variant (heading|body|caption|code), color.' },\n { type: 'badge', description: 'Status badge. Props: text, color, variant.' },\n { type: 'table', description: 'Data table. Props: columns (string[]), rows (string[][]). No children.' },\n { type: 'chart-bar', description: 'Bar chart. Props: data (object[]), xKey, yKey, title.' },\n { type: 'chart-line', description: 'Line chart. Props: data (object[]), xKey, yKey, title.' },\n { type: 'chart-area', description: 'Area chart. Props: data (object[]), xKey, yKey, title.' },\n { type: 'chart-pie', description: 'Pie chart. Props: data (object[]), labelKey, valueKey, title.' },\n { type: 'input', description: 'Form text input. Props: name, label, type (text|email|number|password), placeholder, required.' },\n { type: 'select', description: 'Dropdown select. Props: name, label, options (string[] or {value,label}[]), required.' },\n { type: 'button', description: 'Clickable button. Props: label, action (tool name string), variant, disabled.' },\n { type: 'if', description: 'Conditional rendering. branches: [{condition, node}], fallback.' },\n { type: 'foreach', description: 'Dynamic list. Props: items (binding expression). Children: [template].' },\n { type: 'rx', description: 'Reactive value. Props: expression (client-side state binding). Embeddable as prop.' },\n]\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction withChildren(type: string, props?: Record<string, unknown>, children?: Component[]): Component {\n const node: Component = { type }\n if (props && Object.keys(props).length > 0) node.props = props\n if (children && children.length > 0) node.children = children\n return node\n}\n\nfunction withProps(type: string, props: Record<string, unknown>): Component {\n return { type, props }\n}\n\n// ---------------------------------------------------------------------------\n// Layout\n// ---------------------------------------------------------------------------\n\nexport function Column(props?: Record<string, unknown>, children?: Component[]): Component {\n return withChildren('column', props, children)\n}\n\nexport function Row(props?: Record<string, unknown>, children?: Component[]): Component {\n return withChildren('row', props, children)\n}\n\nexport function Grid(props?: Record<string, unknown>, children?: Component[]): Component {\n return withChildren('grid', props, children)\n}\n\n// ---------------------------------------------------------------------------\n// Data display\n// ---------------------------------------------------------------------------\n\nexport function Text(content: string | Component, extraProps?: Record<string, unknown>): Component {\n return withProps('text', { content, ...extraProps })\n}\n\nexport function Badge(text: string, extraProps?: Record<string, unknown>): Component {\n return withProps('badge', { text, ...extraProps })\n}\n\nexport function Table(props: { columns: string[]; rows: string[][]; [key: string]: unknown }): Component {\n return withProps('table', props as Record<string, unknown>)\n}\n\n// ---------------------------------------------------------------------------\n// Charts\n// ---------------------------------------------------------------------------\n\nexport function Bar(props: Record<string, unknown>): Component {\n return withProps('chart-bar', props)\n}\n\nexport function Line(props: Record<string, unknown>): Component {\n return withProps('chart-line', props)\n}\n\nexport function Area(props: Record<string, unknown>): Component {\n return withProps('chart-area', props)\n}\n\nexport function Pie(props: Record<string, unknown>): Component {\n return withProps('chart-pie', props)\n}\n\n// ---------------------------------------------------------------------------\n// Forms\n// ---------------------------------------------------------------------------\n\nexport function Input(props: Record<string, unknown>): Component {\n return withProps('input', props)\n}\n\nexport function Select(props: Record<string, unknown>): Component {\n return withProps('select', props)\n}\n\nexport function Button(props: Record<string, unknown>): Component {\n return withProps('button', props)\n}\n\n// ---------------------------------------------------------------------------\n// Control flow — If with non-enumerable builder methods\n// ---------------------------------------------------------------------------\n\nfunction makeIfNode(\n branches: Array<{ condition: string; node: Component }>,\n fallback?: Component,\n): IfNode {\n const node = { type: 'if' as const, branches, ...(fallback !== undefined ? { fallback } : {}) } as IfNode\n\n Object.defineProperty(node, 'elif', {\n enumerable: false,\n value(condition: string, child: Component): IfNode {\n return makeIfNode([...branches, { condition, node: child }], fallback)\n },\n })\n\n Object.defineProperty(node, 'else', {\n enumerable: false,\n value(child: Component): Component {\n return makeIfNode(branches, child)\n },\n })\n\n return node\n}\n\nexport function If(condition: string, then: Component, fallback?: Component): IfNode {\n return makeIfNode([{ condition, node: then }], fallback)\n}\n\n// ---------------------------------------------------------------------------\n// Dynamic list\n// ---------------------------------------------------------------------------\n\nexport function ForEach(items: string, template: Component): Component {\n return { type: 'foreach', props: { items }, children: [template] }\n}\n\n// ---------------------------------------------------------------------------\n// Reactive state binding\n// ---------------------------------------------------------------------------\n\nexport function Rx(expression: string): Component {\n return withProps('rx', { expression })\n}\n","import { FastMCP } from '../../FastMCP'\nimport { actionRef } from '../actionRef'\nimport { Column, Text, Button } from '../components'\n\nexport class Approval {\n readonly server: FastMCP\n\n constructor() {\n this.server = new FastMCP({ name: 'approval' })\n\n this.server.tool(\n {\n name: 'approval_request',\n description: 'Present a confirm/deny approval card to the user',\n inputSchema: {\n type: 'object',\n properties: {\n message: { type: 'string', description: 'The question or action to seek approval for' },\n },\n required: ['message'],\n },\n ui: { visibility: ['model', 'app'] },\n },\n (args: Record<string, unknown>) => {\n const message = (args.message as string) ?? 'Approve?'\n return Column({}, [\n Text(message),\n Button({ label: 'Confirm', action: actionRef('approval_confirm') }),\n Button({ label: 'Deny', action: actionRef('approval_deny'), variant: 'secondary' }),\n ])\n },\n )\n\n this.server.resource(\n { uri: 'ui://approval_request', mimeType: 'text/html;profile=mcp-app', name: 'approval_request' },\n () => `<!doctype html><html><head><meta charset=\"utf-8\"></head><body><!-- fastmcp ui-runtime placeholder --></body></html>`,\n )\n\n this.server.tool(\n {\n name: 'approval_confirm',\n description: 'Record a confirmed approval decision',\n ui: { visibility: ['app'] },\n },\n () => ({ decision: 'approved' as const }),\n )\n\n this.server.tool(\n {\n name: 'approval_deny',\n description: 'Record a denied approval decision',\n ui: { visibility: ['app'] },\n },\n () => ({ decision: 'denied' as const }),\n )\n }\n}\n","import { FastMCP } from '../../FastMCP'\nimport { actionRef } from '../actionRef'\nimport { Row, Button } from '../components'\n\nexport class Choice {\n readonly server: FastMCP\n\n constructor() {\n this.server = new FastMCP({ name: 'choice' })\n\n this.server.tool(\n {\n name: 'choice_present',\n description: 'Present a list of options for the user to choose from',\n inputSchema: {\n type: 'object',\n properties: {\n question: { type: 'string', description: 'The question to ask the user' },\n options: { type: 'array', items: { type: 'string' }, description: 'The options to present' },\n },\n required: ['question', 'options'],\n },\n ui: { visibility: ['model', 'app'] },\n },\n (args: Record<string, unknown>) => {\n const options = (args.options as string[]) ?? []\n return Row(\n {},\n // Each button carries its option value as args so the host can\n // forward it to choice_select without extra state.\n options.map((opt) =>\n Button({ label: opt, action: actionRef('choice_select'), args: { option: opt } }),\n ),\n )\n },\n )\n\n this.server.resource(\n { uri: 'ui://choice_present', mimeType: 'text/html;profile=mcp-app', name: 'choice_present' },\n () => `<!doctype html><html><head><meta charset=\"utf-8\"></head><body><!-- fastmcp ui-runtime placeholder --></body></html>`,\n )\n\n this.server.tool(\n {\n name: 'choice_select',\n description: \"Record the user's selection\",\n ui: { visibility: ['app'] },\n },\n (args: Record<string, unknown>) => ({ selected: args.option as string }),\n )\n }\n}\n","import { randomUUID } from 'node:crypto'\nimport { FastMCP } from '../../FastMCP'\nimport { ResourceResult } from '../../resource'\nimport { contextStore } from '../../context'\nimport { actionRef } from '../actionRef'\nimport { Column, Text, Button } from '../components'\n\nexport interface FileHandle {\n handle: string\n name: string\n mimeType: string\n data: Buffer\n}\n\nexport interface FileStorageAdapter {\n save(handle: string, file: FileHandle): void\n load(handle: string): FileHandle | undefined\n delete(handle: string): void\n}\n\n/**\n * Default in-memory adapter with TTL-based expiry. Expiry is checked lazily on\n * every save/load (no timer), so it costs nothing when idle. This is the\n * era-agnostic cleanup mechanism for uploaded files: unlike session-close\n * cleanup (ctx.onClose, below), which only fires for transports that actually\n * have a session (stdio, legacy HTTP), TTL expiry works uniformly for\n * stateless modern (2026-07-28) HTTP requests too, where there is no session\n * to close.\n */\nfunction makeInMemoryAdapter(ttlMs: number): FileStorageAdapter {\n const store = new Map<string, { file: FileHandle; expiresAt: number }>()\n function sweep(): void {\n const now = Date.now()\n for (const [handle, entry] of store) {\n if (entry.expiresAt <= now) store.delete(handle)\n }\n }\n return {\n save: (handle, file) => {\n sweep()\n store.set(handle, { file, expiresAt: Date.now() + ttlMs })\n },\n load: (handle) => {\n sweep()\n return store.get(handle)?.file\n },\n delete: (handle) => {\n store.delete(handle)\n },\n }\n}\n\nexport interface FileUploadOptions {\n storage?: FileStorageAdapter\n /**\n * How long (ms) an uploaded file is retained by the default in-memory storage\n * adapter before automatic expiry. Only applies when no custom `storage` is\n * supplied. Default: 30 minutes.\n */\n ttlMs?: number\n}\n\nexport class FileUpload {\n readonly server: FastMCP\n private readonly _storage: FileStorageAdapter\n\n constructor(options?: FileUploadOptions) {\n this._storage = options?.storage ?? makeInMemoryAdapter(options?.ttlMs ?? 30 * 60_000)\n this.server = new FastMCP({ name: 'file-upload' })\n\n const storage = this._storage\n\n this.server.tool(\n {\n name: 'file_upload_open',\n description: 'Open a file picker UI for the user to upload a file',\n inputSchema: {\n type: 'object',\n properties: {\n prompt: { type: 'string', description: 'Instructions shown above the file picker' },\n },\n },\n ui: { visibility: ['model', 'app'] },\n },\n (args: Record<string, unknown>) => {\n return Column({}, [\n Text((args.prompt as string | undefined) ?? 'Upload a file'),\n Button({ label: 'Choose file', action: actionRef('file_upload_submit') }),\n ])\n },\n )\n\n this.server.tool(\n {\n name: 'file_upload_submit',\n description: 'Receive and store uploaded file bytes server-side',\n inputSchema: {\n type: 'object',\n properties: {\n name: { type: 'string', description: 'File name' },\n mimeType: { type: 'string', description: 'MIME type of the file' },\n data: { type: 'string', description: 'Base64-encoded file content' },\n },\n required: ['name', 'mimeType', 'data'],\n },\n ui: { visibility: ['app'] },\n },\n (args: Record<string, unknown>) => {\n // The handle is the durable, portable identifier for this upload — it works\n // the same way whether the caller is on a session-based transport (stdio,\n // legacy HTTP) or a stateless modern (2026-07-28) HTTP request: the model\n // threads it back as an ordinary tool argument on later calls (file_upload_delete,\n // reading the ui://files/{handle} resource), the same explicit-handle pattern\n // the spec recommends in place of session state.\n const handle = randomUUID()\n const fileData = Buffer.from(args.data as string, 'base64')\n storage.save(handle, {\n handle,\n name: args.name as string,\n mimeType: args.mimeType as string,\n data: fileData,\n })\n\n // Best-effort early cleanup for transports that actually have a session\n // (stdio, legacy HTTP) — a no-op on stateless modern HTTP, where there is no\n // session to close. The real, era-agnostic cleanup is the storage adapter's\n // own TTL expiry (see makeInMemoryAdapter / FileUploadOptions.ttlMs).\n contextStore.getStore()?.onClose(() => storage.delete(handle))\n\n const uri = `ui://files/${handle}`\n return { handle, uri }\n },\n )\n\n this.server.tool(\n {\n name: 'file_upload_delete',\n description: 'Delete a previously uploaded file by its handle',\n inputSchema: {\n type: 'object',\n properties: {\n handle: { type: 'string', description: 'The file handle returned by file_upload_submit' },\n },\n required: ['handle'],\n },\n ui: { visibility: ['app'] },\n },\n (args: Record<string, unknown>) => {\n const handle = args.handle as string\n storage.delete(handle)\n return { deleted: handle }\n },\n )\n\n this.server.resource(\n { uri: 'ui://files/{handle}', name: 'uploaded-file', mimeType: 'application/octet-stream' },\n (params) => {\n const h = params?.handle\n if (!h) throw new Error('Missing file handle')\n const file = storage.load(h)\n if (!file) throw new Error(`File not found: ${h}`)\n const uri = `ui://files/${h}`\n if (file.mimeType.startsWith('text/')) {\n return new ResourceResult([{ uri, mimeType: file.mimeType, text: file.data.toString('utf8') }])\n }\n return new ResourceResult([{ uri, mimeType: file.mimeType, blob: file.data.toString('base64') }])\n },\n )\n }\n}\n","import type { StandardSchemaV1 } from '@standard-schema/spec'\nimport { FastMCP } from '../../FastMCP'\nimport { toJsonSchema } from '../../tool'\nimport { actionRef } from '../actionRef'\nimport { Column, Input, Select, Button } from '../components'\n\nexport interface FormInputOptions {\n name: string\n description: string\n schema: StandardSchemaV1\n}\n\ntype FieldSchema = Record<string, unknown>\n\nfunction buildField(fieldName: string, fieldSchema: FieldSchema, required: string[]) {\n const isRequired = required.includes(fieldName)\n const type = fieldSchema.type as string | undefined\n if (Array.isArray(fieldSchema.enum)) {\n return Select({ name: fieldName, label: fieldName, options: fieldSchema.enum as string[], required: isRequired })\n }\n if (type === 'number' || type === 'integer') {\n return Input({ name: fieldName, label: fieldName, type: 'number', required: isRequired })\n }\n return Input({ name: fieldName, label: fieldName, type: 'text', required: isRequired })\n}\n\nasync function validateWithSchema(\n schema: StandardSchemaV1,\n data: unknown,\n): Promise<{ valid: true; value: unknown } | { valid: false; errors: Record<string, string> }> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const result = await (schema['~standard'].validate as (v: unknown) => Promise<any>)(data)\n if (result.issues && result.issues.length > 0) {\n const errors: Record<string, string> = {}\n for (const issue of result.issues) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const path = issue.path?.map((p: any) => String(typeof p === 'object' ? p.key : p)).join('.') ?? 'root'\n errors[path] = String(issue.message)\n }\n return { valid: false, errors }\n }\n return { valid: true, value: result.value }\n}\n\nexport class FormInput {\n readonly server: FastMCP\n\n constructor(options: FormInputOptions) {\n this.server = new FastMCP({ name: options.name })\n const { name, description, schema } = options\n const submitName = `${name}_submit`\n\n this.server.resource(\n { uri: `ui://${name}`, mimeType: 'text/html;profile=mcp-app', name },\n () => `<!doctype html><html><head><meta charset=\"utf-8\"></head><body><!-- fastmcp ui-runtime placeholder --></body></html>`,\n )\n\n this.server.tool(\n { name, description, ui: { visibility: ['model', 'app'] } },\n async () => {\n // Use the shared extractor so Zod, Valibot, ArkType, etc. all work.\n const jsonSchema = await toJsonSchema(schema, `form \"${name}\"`)\n const properties = (jsonSchema.properties ?? {}) as Record<string, FieldSchema>\n const required = (jsonSchema.required ?? []) as string[]\n\n const fields = Object.entries(properties).map(([fieldName, fieldSchema]) =>\n buildField(fieldName, fieldSchema, required),\n )\n\n return Column({}, [...fields, Button({ label: 'Submit', action: actionRef(submitName) })])\n },\n )\n\n this.server.tool(\n {\n name: submitName,\n description: `Submit ${name} form data`,\n inputSchema: {\n type: 'object',\n properties: {\n data: { type: 'object', description: 'Form field values keyed by field name' },\n },\n required: ['data'],\n },\n ui: { visibility: ['app'] },\n },\n async (args: Record<string, unknown>) => {\n const result = await validateWithSchema(schema, args.data)\n if (!result.valid) {\n return { errors: result.errors }\n }\n return result.value\n },\n )\n }\n}\n"],"mappings":"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","names":["ProtocolError","ProtocolErrorCode","Server","randomUUID","ProtocolError","ProtocolErrorCode","ProtocolError","ProtocolErrorCode","ProtocolError","ProtocolErrorCode","Server","ctx","randomUUID","randomUUID","existing","location","JSON_COMPATIBLE_TYPES","randomUUID","randomUUID"]}