@roostjs/mcp

Model Context Protocol server implementation. Expose application capabilities as tools, resources, and prompts to MCP-compatible AI clients.

Installation

bun add @roostjs/mcp @roostjs/schema

McpServer API

McpServer is an abstract base class. Extend it and declare the tool, resource, and prompt classes to expose.

abstract tools: Array<new () => McpTool>

Array of tool class constructors to register with the server.

abstract resources: Array<new () => McpResource>

Array of resource class constructors to register.

abstract prompts: Array<new () => McpPrompt>

Array of prompt class constructors to register.

abstract serverName(): string

The server name reported in the MCP handshake.

abstract serverVersion(): string

The server version reported in the MCP handshake.

serverInstructions(): string

Optional. Instructions string included in the MCP server info response.

listTools(): ToolDefinition[]

Returns all registered tool definitions in MCP protocol format.

listResources(): ResourceDefinition[]

Returns all registered resource definitions.

listPrompts(): PromptDefinition[]

Returns all registered prompt definitions.

async callTool(name: string, args: Record<string, unknown>): Promise<McpResponse>

Find the tool with the given name and invoke its handle() method.

async readResource(uri: string): Promise<McpResponse>

Find the resource matching the URI and invoke its handle() method.

async runPrompt(name: string, args: Record<string, unknown>): Promise<McpResponse | McpResponse[]>

Find the prompt with the given name and invoke its handle() method.

static async tool(ToolClass: new () => McpTool, args: Record<string, unknown>): Promise<McpResponse>

Directly invoke a tool class without going through the server routing. Used in tests.

McpTool API

Abstract base class for MCP tools.

abstract description(): string

One-sentence description of the tool. Sent to the client in the tools list.

abstract schema(s: typeof schema): Record<string, SchemaBuilder>

Define input parameters using the schema builder from @roostjs/schema.

abstract async handle(request: McpRequest): Promise<McpResponse>

Execute the tool logic and return an McpResponse.

shouldRegister?(): boolean

Optional. Return false to conditionally exclude the tool from registration.

McpResource API

Abstract base class for MCP resources.

abstract uri(): string

The resource URI. Must be unique within the server.

abstract description(): string

Human-readable description of the resource content.

abstract mimeType(): string

MIME type of the resource content (e.g., 'text/plain', 'text/markdown', 'application/json').

abstract async handle(request: McpRequest): Promise<McpResponse>

Return the resource content wrapped in an McpResponse.

McpPrompt API

Abstract base class for MCP prompts.

abstract description(): string

Description of what the prompt does.

abstract schema(s: typeof schema): Record<string, SchemaBuilder>

Define the prompt's input parameters.

abstract async handle(request: McpRequest): Promise<McpResponse | McpResponse[]>

Return the constructed prompt text. May return multiple message objects.

McpRequest API

get<T>(key: string): T

Retrieve a typed parameter value from the invocation arguments.

McpResponse API

static text(content: string): McpResponse

Create a text content response.

static error(message: string): McpResponse

Create an error response.

toJSON(): { content: Array<{ type: string; text: string }> }

Serialize the response to MCP protocol JSON format.

createMcpRequest

createMcpRequest(args: Record<string, unknown>): McpRequest

Create an McpRequest from a plain arguments object. Used internally by McpServer when routing tool calls and prompt invocations. Import directly when testing tools or prompts in isolation without a full server.

AiSearchResource

AiSearchResource is a pre-built McpResource that wraps a Cloudflare AI Search binding, exposing semantic search over an indexed corpus to any MCP client.

Because AiSearchResource requires constructor arguments (the AI Search binding and an instance name), it cannot be used directly in the zero-argument Array<new () => McpResource> pattern. Two registration patterns are supported.

Pattern 1 — Subclass per instance (recommended)

import { AiSearchResource } from '@roostjs/mcp';

export class MyAiSearch extends AiSearchResource {
  constructor() {
    super(env.AI_SEARCH, 'my-docs');
  }
}

Register the subclass on an McpServer as normal:

class AppServer extends McpServer {
  resources = [MyAiSearch];
}

Pattern 2 — Ad-hoc instance

Construct AiSearchResource directly and pass it to McpServer.readResource() without registering it on the server.

Constructor

constructor(
  binding: { run(request: Record<string, unknown>): Promise<Record<string, unknown>> },
  instanceName: string,
)
ParameterDescription
bindingThe Cloudflare AI Search binding (e.g. env.AI_SEARCH).
instanceNameA unique name for this search instance. Used as the URI host: aisearch://{instanceName}.

Methods

uri(): string

Returns aisearch://{instanceName}.

mimeType(): string

Returns 'application/json'.

description(): string

Returns a string describing the instance name and accepted query shape.

shouldRegister(): boolean

Returns true.

async handle(request: McpRequest): Promise<McpResponse>

Accepts query (required string), metadataFilters (optional Record<string, string>), and pathFilters (optional string[]). Returns McpResponse.structured(...) with the search result, or McpResponse.error(...) if query is empty or the binding throws.

Request parameters

ParameterTypeRequiredDescription
querystringYesThe search query text.
metadataFiltersRecord<string, string>NoKey/value metadata filters passed to the AI Search binding.
pathFiltersstring[]NoURL path prefixes to restrict search scope.

Response shape

When the AI Search binding returns an answer field:

interface AiSearchResult {
  answer: string;
  sources: Array<{
    url: string;
    title?: string;
    excerpt?: string;
  }>;
}

Otherwise the raw binding response is returned as structured content.

McpResponse.structured

static structured(content: Record<string, unknown>): McpResponse

Create a structured JSON content response. Used by AiSearchResource and any resource or tool that needs to return machine-readable JSON rather than plain text.

Types

interface McpToolDefinition {
  name: string;
  description: string;
  inputSchema: JsonSchemaOutput;
}

interface McpResourceDefinition {
  uri: string;
  description: string;
  mimeType: string;
}

interface McpPromptDefinition {
  name: string;
  description: string;
  arguments: JsonSchemaOutput;
}

interface PromptArgument {
  name: string;
  description?: string;
  required?: boolean;
}