{"version":3,"sources":["../src/server.ts"],"sourcesContent":["/**\n * Copyright 2024 Google LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { Server } from '@modelcontextprotocol/sdk/server/index.js' with { 'resolution-mode': 'import' };\nimport type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js' with { 'resolution-mode': 'import' };\nimport type {\n  CallToolRequest,\n  CallToolResult,\n  GetPromptRequest,\n  GetPromptResult,\n  ListPromptsRequest,\n  ListPromptsResult,\n  ListResourceTemplatesResult,\n  ListToolsRequest,\n  ListToolsResult,\n  Prompt,\n  PromptMessage,\n  Tool,\n} from '@modelcontextprotocol/sdk/types.js' with { 'resolution-mode': 'import' };\nimport {\n  ListResourceTemplatesRequest,\n  ListResourcesRequest,\n  ListResourcesResult,\n  ReadResourceRequest,\n  ReadResourceResult,\n  Resource,\n  ResourceTemplate,\n} from '@modelcontextprotocol/sdk/types.js';\nimport {\n  GenkitError,\n  Message,\n  type Genkit,\n  type MessageData,\n  type Part,\n  type PromptAction,\n  type ResourceAction,\n} from 'genkit';\nimport { logger } from 'genkit/logging';\nimport { toJsonSchema } from 'genkit/schema';\nimport { toToolDefinition, type ToolAction } from 'genkit/tool';\nimport type { McpServerOptions } from './index.mjs';\n\n/**\n * Represents an MCP (Model Context Protocol) server that exposes Genkit tools\n * and prompts. This class wraps a Genkit instance and makes its registered\n * actions (tools, prompts) available to MCP clients. It handles the translation\n * between Genkit's action definitions and MCP's expected formats.\n */\nexport class GenkitMcpServer {\n  ai: Genkit;\n  options: McpServerOptions;\n  server?: Server;\n  actionsResolved = false;\n  toolActions: ToolAction[] = [];\n  promptActions: PromptAction[] = [];\n  resourceActions: ResourceAction[] = [];\n\n  /**\n   * Creates an instance of GenkitMcpServer.\n   * @param ai The Genkit instance whose actions will be exposed.\n   * @param options Configuration options for the MCP server, like its name and version.\n   */\n  constructor(ai: Genkit, options: McpServerOptions) {\n    this.ai = ai;\n    this.options = options;\n  }\n\n  /**\n   * Initializes the MCP server instance and registers request handlers. It\n   * dynamically imports MCP SDK components and sets up handlers for listing\n   * tools, calling tools, listing prompts, and getting prompts. It also\n   * resolves and stores all tool and prompt actions from the Genkit instance.\n   *\n   * This method is called by the constructor and ensures the server is ready\n   * before any requests are handled. It's idempotent.\n   */\n  async setup(): Promise<void> {\n    if (this.actionsResolved) return;\n    const { Server } = await import(\n      '@modelcontextprotocol/sdk/server/index.js'\n    );\n\n    this.server = new Server(\n      { name: this.options.name, version: this.options.version || '1.0.0' },\n      {\n        capabilities: {\n          prompts: {},\n          tools: {},\n          resources: {},\n        },\n      }\n    );\n\n    const {\n      CallToolRequestSchema,\n      GetPromptRequestSchema,\n      ListPromptsRequestSchema,\n      ListToolsRequestSchema,\n      ListResourcesRequestSchema,\n      ListResourceTemplatesRequestSchema,\n      ReadResourceRequestSchema,\n    } = await import('@modelcontextprotocol/sdk/types.js');\n\n    this.server.setRequestHandler(\n      ListToolsRequestSchema,\n      this.listTools.bind(this)\n    );\n    this.server.setRequestHandler(\n      CallToolRequestSchema,\n      this.callTool.bind(this)\n    );\n    this.server.setRequestHandler(\n      ListPromptsRequestSchema,\n      this.listPrompts.bind(this)\n    );\n    this.server.setRequestHandler(\n      ListResourcesRequestSchema,\n      this.listResources.bind(this)\n    );\n    this.server.setRequestHandler(\n      ListResourceTemplatesRequestSchema,\n      this.listResourceTemplates.bind(this)\n    );\n    this.server.setRequestHandler(\n      ReadResourceRequestSchema,\n      this.readResource.bind(this)\n    );\n    this.server.setRequestHandler(\n      GetPromptRequestSchema,\n      this.getPrompt.bind(this)\n    );\n\n    // TODO -- use listResolvableActions.\n    const allActions = await this.ai.registry.listActions();\n    const toolList: ToolAction[] = [];\n    const promptList: PromptAction[] = [];\n    const resourceList: ResourceAction[] = [];\n    for (const k in allActions) {\n      if (k.startsWith('/tool/')) {\n        toolList.push(allActions[k] as ToolAction);\n      } else if (k.startsWith('/prompt/')) {\n        promptList.push(allActions[k] as PromptAction);\n      } else if (k.startsWith('/resource/')) {\n        resourceList.push(allActions[k] as ResourceAction);\n      }\n    }\n    this.toolActions = toolList;\n    this.promptActions = promptList;\n    this.resourceActions = resourceList;\n    this.actionsResolved = true;\n  }\n\n  /**\n   * Handles MCP requests to list available tools.\n   * It maps the resolved Genkit tool actions to the MCP Tool format.\n   * @param req The MCP ListToolsRequest.\n   * @returns A Promise resolving to an MCP ListToolsResult.\n   */\n  async listTools(req: ListToolsRequest): Promise<ListToolsResult> {\n    await this.setup();\n    return {\n      tools: this.toolActions.map((t): Tool => {\n        const def = toToolDefinition(t);\n        return {\n          name: def.name,\n          inputSchema: (def.inputSchema as any) || { type: 'object' },\n          description: def.description,\n          _meta: t.__action.metadata?.mcp?._meta,\n        };\n      }),\n    };\n  }\n\n  /**\n   * Handles MCP requests to call a specific tool. It finds the corresponding\n   * Genkit tool action and executes it with the provided arguments. The result\n   * is then formatted as an MCP CallToolResult.\n   * @param req The MCP CallToolRequest containing the tool name and arguments.\n   * @returns A Promise resolving to an MCP CallToolResult.\n   * @throws GenkitError if the requested tool is not found.\n   */\n  async callTool(req: CallToolRequest): Promise<CallToolResult> {\n    await this.setup();\n    const tool = this.toolActions.find(\n      (t) => t.__action.name === req.params.name\n    );\n    if (!tool)\n      throw new GenkitError({\n        status: 'NOT_FOUND',\n        message: `Tried to call tool '${req.params.name}' but it could not be found.`,\n      });\n    const result = await tool(req.params.arguments);\n    return {\n      content: [\n        {\n          type: 'text',\n          text: typeof result === 'string' ? result : JSON.stringify(result),\n        },\n      ],\n    };\n  }\n\n  /**\n   * Handles MCP requests to list available prompts.\n   * It maps the resolved Genkit prompt actions to the MCP Prompt format,\n   * including converting input schemas to MCP argument definitions.\n   * @param req The MCP ListPromptsRequest.\n   * @returns A Promise resolving to an MCP ListPromptsResult.\n   */\n  async listPrompts(req: ListPromptsRequest): Promise<ListPromptsResult> {\n    await this.setup();\n    return {\n      prompts: this.promptActions.map((p): Prompt => {\n        return {\n          name: p.__action.name,\n          description: p.__action.description,\n          arguments: toMcpPromptArguments(p),\n          _meta: p.__action.metadata?.mcp?._meta,\n        };\n      }),\n    };\n  }\n\n  /**\n   * Handles MCP requests to list available resources.\n   * It maps the resolved Genkit resource actions to the MCP Resource format.\n   * @param req The MCP ListResourcesRequest.\n   * @returns A Promise resolving to an MCP ListResourcesResult.\n   */\n  async listResources(req: ListResourcesRequest): Promise<ListResourcesResult> {\n    await this.setup();\n    return {\n      resources: this.resourceActions\n        .filter((r) => r.__action.metadata?.resource.uri)\n        .map((r): Resource => {\n          return {\n            name: r.__action.name,\n            description: r.__action.description,\n            uri: r.__action.metadata?.resource.uri,\n            _meta: r.__action.metadata?.mcp?._meta,\n          };\n        }),\n    };\n  }\n\n  /**\n   * Handles MCP requests to list available resources.\n   * It maps the resolved Genkit resource actions to the MCP Resource format.\n   * @param req The MCP ListResourcesRequest.\n   * @returns A Promise resolving to an MCP ListResourcesResult.\n   */\n  async listResourceTemplates(\n    req: ListResourceTemplatesRequest\n  ): Promise<ListResourceTemplatesResult> {\n    await this.setup();\n    return {\n      resourceTemplates: this.resourceActions\n        .filter((r) => r.__action.metadata?.resource.template)\n        .map((r): ResourceTemplate => {\n          return {\n            name: r.__action.name,\n            description: r.__action.description,\n            uriTemplate: r.__action.metadata?.resource.template,\n            _meta: r.__action.metadata?.mcp?._meta,\n          };\n        }),\n    };\n  }\n\n  /**\n   * Handles MCP requests to list available resources.\n   * It maps the resolved Genkit resource actions to the MCP Resource format.\n   * @param req The MCP ListResourcesRequest.\n   * @returns A Promise resolving to an MCP ListResourcesResult.\n   */\n  async readResource(req: ReadResourceRequest): Promise<ReadResourceResult> {\n    await this.setup();\n    const resource = this.resourceActions.find((r) =>\n      r.matches({ uri: req.params.uri })\n    );\n    if (!resource) {\n      throw new GenkitError({\n        status: 'NOT_FOUND',\n        message: `Tried to call resource '${req.params.uri}' but it could not be found.`,\n      });\n    }\n    const result = await resource({ uri: req.params.uri });\n    return {\n      contents: toMcpResourceMessage(req.params.uri, result.content),\n    };\n  }\n\n  /**\n   * Handles MCP requests to get (render) a specific prompt. It finds the\n   * corresponding Genkit prompt action, executes it with the provided\n   * arguments, and then formats the resulting messages into the MCP\n   * PromptMessage format.\n   * @param req The MCP GetPromptRequest containing the prompt name and\n   * arguments.\n   * @returns A Promise resolving to an MCP GetPromptResult.\n   * @throws GenkitError if the requested prompt is not found.\n   */\n  async getPrompt(req: GetPromptRequest): Promise<GetPromptResult> {\n    await this.setup();\n    const prompt = this.promptActions.find(\n      (p) => p.__action.name === req.params.name\n    );\n    if (!prompt)\n      throw new GenkitError({\n        status: 'NOT_FOUND',\n        message: `[MCP Server] Tried to call prompt '${req.params.name}' but it could not be found.`,\n      });\n    const result = await prompt(req.params.arguments);\n    return {\n      description: prompt.__action.description,\n      messages: result.messages.map(toMcpPromptMessage),\n    };\n  }\n\n  /**\n   * Starts the MCP server with the specified transport or a default\n   * StdioServerTransport. Ensures the server is set up before connecting the\n   * transport.\n   * @param transport Optional MCP transport instance. If not provided, a\n   * StdioServerTransport will be created and used.\n   */\n  async start(transport?: Transport) {\n    if (!transport) {\n      const { StdioServerTransport } = await import(\n        '@modelcontextprotocol/sdk/server/stdio.js'\n      );\n      transport = new StdioServerTransport();\n    }\n    await this.setup();\n    await this.server!.connect(transport);\n    logger.debug(\n      `[MCP Server] MCP server '${this.options.name}' started successfully.`\n    );\n  }\n}\n\n/**\n * Converts a Genkit prompt's input schema to an array of MCP prompt arguments.\n * MCP prompts currently only support string arguments.\n * @param p The Genkit PromptAction.\n * @returns An array of MCP prompt arguments, or undefined if the schema is not defined.\n * @throws GenkitError if the input schema is not an object or if any property is not a string.\n */\nfunction toMcpPromptArguments(\n  p: PromptAction\n): Prompt['arguments'] | undefined {\n  const jsonSchema = toJsonSchema({\n    schema: p.__action.inputSchema,\n    jsonSchema: p.__action.inputJsonSchema,\n  });\n\n  if (!jsonSchema) return undefined;\n  if (!jsonSchema.properties)\n    throw new GenkitError({\n      status: 'FAILED_PRECONDITION',\n      message: '[MCP Server] MCP prompts must take objects as input schema.',\n    });\n\n  const args: Prompt['arguments'] = [];\n  for (const k in jsonSchema.properties) {\n    const { type, description } = jsonSchema.properties[k];\n    if (\n      type !== 'string' &&\n      (!Array.isArray(type) || !type.includes('string'))\n    ) {\n      throw new GenkitError({\n        status: 'FAILED_PRECONDITION',\n        message: `[MCP Server] MCP prompts may only take string arguments, but ${p.__action.name} has property '${k}' of type '${type}'.`,\n      });\n    }\n    args.push({\n      name: k,\n      description,\n      required: jsonSchema.required?.includes(k),\n    });\n  }\n  return args;\n}\n\nconst ROLE_MAP = { model: 'assistant', user: 'user' } as const;\n\n/**\n * Converts a Genkit MessageData object to an MCP PromptMessage.\n * Handles mapping of roles and content types (text, image).\n * MCP only supports 'user' and 'assistant' (model) roles and base64 data images.\n * @param messageData The Genkit MessageData object.\n * @returns An MCP PromptMessage.\n * @throws GenkitError if the role is unsupported or if media is not a data URL.\n */\nfunction toMcpPromptMessage(messageData: MessageData): PromptMessage {\n  if (messageData.role !== 'model' && messageData.role !== 'user') {\n    throw new GenkitError({\n      status: 'UNIMPLEMENTED',\n      message: `[MCP Server] MCP prompt messages do not support role '${messageData.role}'. Only 'user' and 'model' messages are supported.`,\n    });\n  }\n  const message = new Message(messageData);\n  const common = { role: ROLE_MAP[messageData.role] };\n  if (message.media) {\n    const { url, contentType } = message.media;\n    if (!url.startsWith('data:'))\n      throw new GenkitError({\n        status: 'UNIMPLEMENTED',\n        message: `[MCP Server] MCP prompt messages only support base64 data images.`,\n      });\n    const mimeType =\n      contentType || url.substring(url.indexOf(':')! + 1, url.indexOf(';'));\n    const data = url.substring(url.indexOf(',') + 1);\n    return { ...common, content: { type: 'image', mimeType, data } };\n  } else {\n    return { ...common, content: { type: 'text', text: message.text } };\n  }\n}\n\n/**\n * Converts a Genkit Parts to an MCP resource content.\n * Handles mapping of roles and content types (text, image).\n */\nfunction toMcpResourceMessage(\n  uri: string,\n  content: Part[]\n): ReadResourceResult['contents'] {\n  return content.map((p) => {\n    if (p.media) {\n      const { url, contentType } = p.media;\n      if (!url.startsWith('data:'))\n        throw new GenkitError({\n          status: 'UNIMPLEMENTED',\n          message: `[MCP Server] MCP resource messages only support base64 data images.`,\n        });\n      const mimeType =\n        contentType || url.substring(url.indexOf(':')! + 1, url.indexOf(';'));\n      const data = url.substring(url.indexOf(',') + 1);\n      return { uri, mimeType, blob: data };\n    } else if (p.text) {\n      return { uri, text: p.text };\n    } else {\n      throw new GenkitError({\n        status: 'UNIMPLEMENTED',\n        message: `[MCP Server] MCP resource messages only support media and text parts.`,\n      });\n    }\n  });\n}\n"],"mappings":"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","names":[]}