McpServer
Builds Model Context Protocol (MCP) servers with Effect.
The McpServer service stores the tools, resources, resource templates, prompts, completions, initialized clients, and outgoing notifications exposed by a server. This module also includes the server runner, custom protocol, stdio, and HTTP layers, registration helpers, and APIs that let handlers ask the connected client for structured input or read its advertised capabilities.
Accessors
clientCapabilities
Signature
declare const clientCapabilities: Effect.Effect<ClientCapabilities, never, McpServerClient>;Collects structured input from the current MCP client and decodes the accepted response with schema.
Details
Accepted content is decoded with the supplied schema, declined requests fail with ElicitationDeclined, and canceled requests interrupt the effect.
Signature
declare const elicit: < S extends Schema.ConstraintEncoder<Record<string, unknown>, unknown>,>(options: { readonly message: string; readonly schema: S;}) => Effect.Effect<S["Type"], ElicitationDeclined, McpServerClient | S["DecodingServices"]>;Handlers
registerPrompt
Registers an MCP prompt from an Effect program.
When to use
Use when you are already inside an Effect program with an McpServer service and need to add a prompt handler directly.
Details
Parameters are decoded with the supplied schema, completion handlers encode per-parameter suggestions, and string prompt content is converted into a user text message.
See
promptfor the layer-based prompt registration wrapper
Signature
declare function registerPrompt< E, R, Params extends Fields = {}, Completions extends { [K in string | number | symbol]: ( input: string, context: | { readonly arguments?: { [key: string]: string; }; } | undefined, ) => Effect<Array<Params[K]>, any, any>; } = {},>(options: { readonly annotations?: Context<never>; readonly completion?: ValidateCompletions<Completions, Extract<keyof Params, string>>; readonly content: (params: Params) => Effect<string | Array<PromptMessage>, E, R>; readonly description?: string; readonly name: string; readonly parameters?: Params;}): Effect< void, never, McpServer | Exclude<R, McpServerClient> | Exclude<DecodingServices<Params>, McpServerClient>>;registerResource
Registers an MCP resource or resource template from an Effect program.
When to use
Use when you are already inside an Effect program with an McpServer service and need to add a concrete resource or URI-template resource directly.
See
resourcefor the layer-based resource registration wrapper
Signature
declare const registerResource: { <E, R>(options: { readonly annotations?: Context.Context<never>; readonly audience?: ReadonlyArray<"user" | "assistant">; readonly content: Effect.Effect<typeof ReadResourceResult.Type | string | Uint8Array, E, R>; readonly description?: string; readonly mimeType?: string; readonly name: string; readonly priority?: number; readonly uri: string; }): Effect<void, never, McpServer | Exclude<R, McpServerClient>>; <Schemas extends readonly Array<Constraint>>(segments: TemplateStringsArray, ...schemas: Schemas): <E, R, Completions extends Partial<ResourceCompletions<Schemas>> = {}>(options: { readonly annotations?: Context.Context<never>; readonly audience?: ReadonlyArray<"user" | "assistant">; readonly completion?: ValidateCompletions<Completions, keyof ResourceCompletions<Schemas>>; readonly content: (uri: string, ...params: { [K in keyof Schemas]: Schemas[K]["Type"] }) => Effect.Effect<typeof ReadResourceResult.Type | string | Uint8Array, E, R>; readonly description?: string; readonly mimeType?: string; readonly name: string; readonly priority?: number; }) => Effect<void, never, McpServer | Exclude<R, McpServerClient> | Exclude<Schemas[number]["DecodingServices"], McpServerClient> | Exclude<Schemas[number]["EncodingServices"], McpServerClient> | Exclude<Completions[keyof Completions] extends (input: string) => Ret ? Ret extends Effect<_A, _E, _R> ? _R : never : never, McpServerClient>>;}registerToolkit
Registers a Toolkit with the McpServer.
Signature
declare const registerToolkit: <Tools extends Record<string, Tool.Any>>( toolkit: Toolkit.Toolkit<Tools>,) => Effect.Effect< void, never, McpServer | Tool.HandlersFor<Tools> | Exclude<Tool.HandlerServices<Tools>, McpServerClient>>;Layers
Creates a layer that starts an MCP server over an existing RpcServer.Protocol and provides the McpServer and McpServerClient services.
When to use
Use when you already have a custom or externally provided RpcServer.Protocol and want to start an MCP server as part of a layer graph.
Details
The returned layer forks run(options) in the layer scope and merges McpServer.layer, so registration layers can use the McpServer service while the server is running.
Gotchas
Unlike layerStdio and layerHttp, this layer does not install a concrete transport. The surrounding layer graph must provide RpcServer.Protocol.
See
runfor the effect form used by this layerlayerStdiofor a stdio-backed layer that installs the MCP protocol and NDJSON-RPC serializationlayerHttpfor an HTTP-backed layer that registers withHttpRouterand installs JSON-RPC serialization
Signature
declare function layer(options: { readonly extensions?: Record<`${string}/${string}`, unknown>; readonly name: string; readonly protocols: readonly [ProtocolAdapter, ProtocolAdapter]; readonly version: string;}): Layer<McpServerClient | McpServer, IllegalArgumentError, Protocol>;Registers a Streamable HTTP MCP endpoint at options.path.
When to use
Use to expose an MCP server through an existing HttpRouter.
Details
POST serves JSON-RPC and accepted notification-only requests return 202. Unsupported protocol versions return 400; methods without MCP handlers return 405. Browser Origins are rejected unless listed in allowedOrigins.
See
layerStdiofor exposing the server over stdiolayerfor the base MCP server layer without a transport protocol
Signature
declare function layerHttp(options: { readonly allowedOrigins?: readonly Array<string>; readonly extensions?: Record<`${string}/${string}`, unknown>; readonly name: string; readonly path: PathInput; readonly protocols: readonly [ProtocolAdapter, ProtocolAdapter]; readonly version: string;}): Layer<McpServerClient | McpServer, IllegalArgumentError, HttpRouter>layerStdio
Runs the McpServer, using stdio for input and output.
Signature
declare function layerStdio(options: { readonly extensions?: Record<`${string}/${string}`, unknown>; readonly name: string; readonly protocols: readonly [ProtocolAdapter, ProtocolAdapter]; readonly version: string;}): Layer<McpServerClient | McpServer, IllegalArgumentError, Stdio>;Creates a layer that registers an MCP prompt.
When to use
Use to compose prompt registration into an MCP server layer.
Details
Parameters are decoded with the supplied schema, completion handlers encode per-parameter suggestions, and string prompt content is converted into a user text message.
See
registerPromptfor the Effect-level prompt registration API
Signature
declare function prompt< E, R, Params extends Fields = {}, Completions extends { [K in string | number | symbol]: ( input: string, context: | { readonly arguments?: { [key: string]: string; }; } | undefined, ) => Effect<Array<Params[K]["Type"]>, any, any>; } = {},>(options: { readonly annotations?: Context<never>; readonly completion?: ValidateCompletions<Completions, Extract<keyof Params, string>>; readonly content: (params: View<Params>) => Effect<string | Array<PromptMessage>, E, R>; readonly description?: string; readonly name: string; readonly parameters?: Params;}): Layer< never, never, Exclude<R, McpServerClient> | Exclude<DecodingServices<Params>, McpServerClient>>;Creates a layer that registers an MCP resource or resource template.
When to use
Use to compose resource registration into an MCP server layer.
See
registerResourcefor the Effect-level resource registration API
Signature
declare const resource: { <E, R>(options: { readonly audience?: ReadonlyArray<"user" | "assistant">; readonly content: Effect.Effect<typeof ReadResourceResult.Type | string | Uint8Array, E, R>; readonly description?: string; readonly mimeType?: string; readonly name: string; readonly priority?: number; readonly uri: string; }): Layer<never, never, Exclude<R, McpServerClient>>; <Schemas extends readonly Array<Constraint>>(segments: TemplateStringsArray, ...schemas: Schemas): <E, R, Completions extends Partial<ResourceCompletions<Schemas>> = {}>(options: { readonly audience?: ReadonlyArray<"user" | "assistant">; readonly completion?: ValidateCompletions<Completions, keyof ResourceCompletions<Schemas>>; readonly content: (uri: string, ...params: { [K in keyof Schemas]: Schemas[K]["Type"] }) => Effect.Effect<typeof ReadResourceResult.Type | string | Uint8Array, E, R>; readonly description?: string; readonly mimeType?: string; readonly name: string; readonly priority?: number; }) => Layer<never, never, Exclude<R, McpServerClient> | Exclude<Completions[keyof Completions] extends (input: string) => Ret ? Ret extends Effect<_A, _E, _R> ? _R : never : never, McpServerClient>>;}Registers an AiToolkit with the McpServer.
Signature
declare function toolkit<Tools extends Record<string, Any>>( toolkit: Toolkit<Tools>,): Layer<never, never, HandlersFor<Tools> | Exclude<HandlerServices<Tools>, McpServerClient>>;Models
ResourceCompletions type
Completion-handler map for a resource URI template.
Details
Each schema interpolation contributes a parameter key, using an explicit Param name when present or paramN otherwise, and each handler returns candidate values for that parameter.
Signature
type ResourceCompletions<Schemas extends ReadonlyArray<Schema.Constraint>> = { [K in Extract<keyof Schemas, `${number}`>]: ( input: string, context: CompletionContext, ) => Effect.Effect<Array<Schemas[K]["Type"]>, any, any>;};Running
Runs an MCP server over the current RpcServer.Protocol.
Details
The server performs initialization and session handling, serves registered tools, resources, and prompts, and forwards queued server notifications to initialized clients.
Signature
declare const run: (options: { readonly extensions?: Record<`${string}/${string}`, unknown>; readonly name: string; readonly protocols: Arr.NonEmptyReadonlyArray<McpProtocol.ProtocolAdapter>; readonly version: string;}) => Effect.Effect<never, Cause.IllegalArgumentError, McpServer | RpcServer.Protocol>;Services
Service that stores and serves an MCP server's registered tools, resources, prompts, completions, and outgoing notifications.
Details
Handlers use this service to register capabilities and resolve incoming MCP requests.
Signature
declare class McpServer extends Shape<"effect/ai/McpServer", { readonly addPrompt: (options: { readonly annotations: Context<never>; readonly completions: Record<string, (input: string, context: CompletionContext) => Effect.Effect<CompleteResult, InternalError, McpServerClient>>; readonly handle: (params: Record<string, string>) => Effect<GetPromptResult, InvalidParams | InternalError, McpServerClient>; readonly prompt: Prompt; }) => Effect<void>; readonly addResource: (options: { readonly annotations: Context<never>; readonly handle: Effect<ReadResourceResult, InternalError, McpServerClient>; readonly resource: Resource; }) => Effect<void>; readonly addResourceTemplate: (options: { readonly annotations: Context<never>; readonly completions: Record<string, (input: string, context: CompletionContext) => Effect.Effect<CompleteResult, InternalError>>; readonly handle: (uri: string, params: Array<string>) => Effect<ReadResourceResult, InvalidParams | InternalError, McpServerClient>; readonly routerPath: string; readonly template: ResourceTemplate; }) => Effect<void>; readonly addTool: (options: { readonly annotations: Context<never>; readonly handle: (payload: any) => Effect<CallToolResult, InvalidParams | InternalError, McpServerClient>; readonly tool: Tool; }) => Effect<void>; readonly callTool: (requests: { readonly _meta?: { readonly progressToken?: string | number; }; readonly arguments?: { [key: string]: any; }; readonly name: string; }) => Effect<CallToolResult, InvalidParams | InternalError, McpServerClient>; readonly completion: (complete: { readonly argument: { readonly name: string; readonly value: string; }; readonly context?: { readonly arguments?: { [key: string]: string; }; }; readonly ref: PromptReference | ResourceReference; }) => Effect<CompleteResult, InvalidParams | InternalError, McpServerClient>; readonly findResource: (uri: string) => Effect<ReadResourceResult, McpErrorBase | InvalidParams | InternalError, McpServerClient>; readonly getPromptResult: (request: { readonly _meta?: { readonly progressToken?: string | number; }; readonly arguments?: { [key: string]: string; }; readonly name: string; readonly title?: string; }) => Effect<GetPromptResult, InvalidParams | InternalError, McpServerClient>; readonly initializedClients: Set<number>; readonly notifications: { "notifications/cancelled": <AsQueue extends boolean = false, Discard = false>(input: { readonly _meta?: { [key: string]: unknown; }; readonly reason?: string; readonly requestId: string | number; }, options?: { readonly context?: Context<never>; readonly discard?: Discard; readonly headers?: Input; }) => Effect<Discard extends true ? void : void, Discard extends true ? never : never, never>; "notifications/message": <AsQueue extends boolean = false, Discard = false>(input: { readonly _meta?: { [key: string]: unknown; }; readonly data: any; readonly level: "error" | "debug" | "info" | "notice" | "warning" | "critical" | "alert" | "emergency"; readonly logger?: string; }, options?: { readonly context?: Context<never>; readonly discard?: Discard; readonly headers?: Input; }) => Effect<Discard extends true ? void : void, Discard extends true ? never : never, never>; "notifications/progress": <AsQueue extends boolean = false, Discard = false>(input: { readonly _meta?: { [key: string]: unknown; }; readonly message?: string; readonly progress?: number; readonly progressToken: string | number; readonly total?: number; }, options?: { readonly context?: Context<never>; readonly discard?: Discard; readonly headers?: Input; }) => Effect<Discard extends true ? void : void, Discard extends true ? never : never, never>; "notifications/prompts/list_changed": <AsQueue extends boolean = false, Discard = false>(input: { readonly _meta?: { [key: string]: unknown; }; } | undefined, options?: { readonly context?: Context<never>; readonly discard?: Discard; readonly headers?: Input; }) => Effect<Discard extends true ? void : void, Discard extends true ? never : never, never>; "notifications/resources/list_changed": <AsQueue extends boolean = false, Discard = false>(input: { readonly _meta?: { [key: string]: unknown; }; } | undefined, options?: { readonly context?: Context<never>; readonly discard?: Discard; readonly headers?: Input; }) => Effect<Discard extends true ? void : void, Discard extends true ? never : never, never>; "notifications/resources/updated": <AsQueue extends boolean = false, Discard = false>(input: { readonly _meta?: { [key: string]: unknown; }; readonly uri: string; }, options?: { readonly context?: Context<never>; readonly discard?: Discard; readonly headers?: Input; }) => Effect<Discard extends true ? void : void, Discard extends true ? never : never, never>; "notifications/tools/list_changed": <AsQueue extends boolean = false, Discard = false>(input: { readonly _meta?: { [key: string]: unknown; }; } | undefined, options?: { readonly context?: Context<never>; readonly discard?: Discard; readonly headers?: Input; }) => Effect<Discard extends true ? void : void, Discard extends true ? never : never, never>; }; readonly notificationsQueue: Dequeue<Request<any>>; readonly prompts: readonly Array<{ readonly annotations: Context<never>; readonly prompt: Prompt; }>; readonly resources: readonly Array<{ readonly annotations: Context<never>; readonly resource: Resource; }>; readonly resourceTemplates: readonly Array<{ readonly annotations: Context<never>; readonly template: ResourceTemplate; }>; readonly tools: readonly Array<{ readonly annotations: Context<never>; readonly tool: Tool; }>;}, this> { constructor(_: never); static readonly layer: Layer<McpServerClient | McpServer>; static readonly make: Effect<{ readonly addPrompt: (options: { readonly annotations: Context<never>; readonly completions: Record<string, (input: string, context: CompletionContext) => Effect.Effect<CompleteResult, InternalError, McpServerClient>>; readonly handle: (params: Record<string, string>) => Effect<GetPromptResult, InvalidParams | InternalError, McpServerClient>; readonly prompt: Prompt; }) => Effect<void>; readonly addResource: (options: { readonly annotations: Context<never>; readonly handle: Effect<ReadResourceResult, InternalError, McpServerClient>; readonly resource: Resource; }) => Effect<void>; readonly addResourceTemplate: (options: { readonly annotations: Context<never>; readonly completions: Record<string, (input: string, context: CompletionContext) => Effect.Effect<CompleteResult, InternalError>>; readonly handle: (uri: string, params: Array<string>) => Effect<ReadResourceResult, InvalidParams | InternalError, McpServerClient>; readonly routerPath: string; readonly template: ResourceTemplate; }) => Effect<void>; readonly addTool: (options: { readonly annotations: Context<never>; readonly handle: (payload: any) => Effect<CallToolResult, InvalidParams | InternalError, McpServerClient>; readonly tool: Tool; }) => Effect<void>; readonly callTool: (requests: { readonly _meta?: { readonly progressToken?: string | number; }; readonly arguments?: { [key: string]: any; }; readonly name: string; }) => Effect<CallToolResult, InvalidParams | InternalError, McpServerClient>; readonly completion: (complete: { readonly argument: { readonly name: string; readonly value: string; }; readonly context?: { readonly arguments?: { [key: string]: string; }; }; readonly ref: PromptReference | ResourceReference; }) => Effect<CompleteResult, InvalidParams | InternalError, McpServerClient>; readonly findResource: (uri: string) => Effect<ReadResourceResult, McpErrorBase | InvalidParams | InternalError, McpServerClient>; readonly getPromptResult: (request: { readonly _meta?: { readonly progressToken?: string | number; }; readonly arguments?: { [key: string]: string; }; readonly name: string; readonly title?: string; }) => Effect<GetPromptResult, InvalidParams | InternalError, McpServerClient>; readonly initializedClients: Set<number>; readonly notifications: { "notifications/cancelled": <AsQueue extends boolean = false, Discard = false>(input: { readonly _meta?: { [key: string]: unknown; }; readonly reason?: string; readonly requestId: string | number; }, options?: { readonly context?: Context<never>; readonly discard?: Discard; readonly headers?: Input; }) => Effect<Discard extends true ? void : void, Discard extends true ? never : never, never>; "notifications/message": <AsQueue extends boolean = false, Discard = false>(input: { readonly _meta?: { [key: string]: unknown; }; readonly data: any; readonly level: "error" | "debug" | "info" | "notice" | "warning" | "critical" | "alert" | "emergency"; readonly logger?: string; }, options?: { readonly context?: Context<never>; readonly discard?: Discard; readonly headers?: Input; }) => Effect<Discard extends true ? void : void, Discard extends true ? never : never, never>; "notifications/progress": <AsQueue extends boolean = false, Discard = false>(input: { readonly _meta?: { [key: string]: unknown; }; readonly message?: string; readonly progress?: number; readonly progressToken: string | number; readonly total?: number; }, options?: { readonly context?: Context<never>; readonly discard?: Discard; readonly headers?: Input; }) => Effect<Discard extends true ? void : void, Discard extends true ? never : never, never>; "notifications/prompts/list_changed": <AsQueue extends boolean = false, Discard = false>(input: { readonly _meta?: { [key: string]: unknown; }; } | undefined, options?: { readonly context?: Context<never>; readonly discard?: Discard; readonly headers?: Input; }) => Effect<Discard extends true ? void : void, Discard extends true ? never : never, never>; "notifications/resources/list_changed": <AsQueue extends boolean = false, Discard = false>(input: { readonly _meta?: { [key: string]: unknown; }; } | undefined, options?: { readonly context?: Context<never>; readonly discard?: Discard; readonly headers?: Input; }) => Effect<Discard extends true ? void : void, Discard extends true ? never : never, never>; "notifications/resources/updated": <AsQueue extends boolean = false, Discard = false>(input: { readonly _meta?: { [key: string]: unknown; }; readonly uri: string; }, options?: { readonly context?: Context<never>; readonly discard?: Discard; readonly headers?: Input; }) => Effect<Discard extends true ? void : void, Discard extends true ? never : never, never>; "notifications/tools/list_changed": <AsQueue extends boolean = false, Discard = false>(input: { readonly _meta?: { [key: string]: unknown; }; } | undefined, options?: { readonly context?: Context<never>; readonly discard?: Discard; readonly headers?: Input; }) => Effect<Discard extends true ? void : void, Discard extends true ? never : never, never>; }; readonly notificationsQueue: Dequeue<Request<any>>; readonly prompts: readonly Array<{ readonly annotations: Context<never>; readonly prompt: Prompt; }>; readonly resources: readonly Array<{ readonly annotations: Context<never>; readonly resource: Resource; }>; readonly resourceTemplates: readonly Array<{ readonly annotations: Context<never>; readonly template: ResourceTemplate; }>; readonly tools: readonly Array<{ readonly annotations: Context<never>; readonly tool: Tool; }>; }, never, Scope>;}Utility Types
ValidateCompletions type
Utility type that validates a completion-handler record against the allowed parameter keys.
Signature
type ValidateCompletions<Completions, Keys extends string> = Completions & { [K in keyof Completions]: K extends Keys ? (input: string, context: CompletionContext) => any : never;};
Accesses the current client's capabilities.