Skip to content

Add mcpTools() helper for ToolProvider #1126

@mattzcarey

Description

@mattzcarey

Summary

Add an mcpTools() helper that connects to an MCP server and returns a ToolProvider, so MCP servers can be composed alongside aiTools() and stateTools() in createCodeTool.

Usage

import { createCodeTool } from "@cloudflare/codemode";
import { aiTools } from "@cloudflare/codemode/ai";
import { mcpTools } from "@cloudflare/codemode/mcp";
import { stateTools } from "@cloudflare/shell/workers";

const github = await mcpTools(githubMcpServer, "github");

const codeTool = createCodeTool({
  tools: [github, stateTools(workspace), aiTools(myTools)],
  executor,
});
// sandbox: github.listIssues({ repo: "..." }), state.readFile("/path"), codemode.search({ query: "..." })

Pseudo-code

export async function mcpTools(
  server: McpServer,
  name?: string
): Promise<ToolProvider> {
  const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
  await server.connect(serverTransport);

  const client = new Client({ name: "codemode-mcp-proxy", version: "1.0.0" });
  await client.connect(clientTransport);

  const { tools } = await client.listTools();

  // Build type declarations for the LLM (needs generateTypesFromJsonSchema to accept a namespace param)
  const toolDescriptors: JsonSchemaToolDescriptors = {};
  for (const tool of tools) {
    toolDescriptors[tool.name] = {
      description: tool.description,
      inputSchema: tool.inputSchema as JSONSchema7,
    };
  }
  const types = generateTypesFromJsonSchema(toolDescriptors, name);

  // Wrap each MCP tool as a simple execute fn
  const fns: SimpleToolRecord = {};
  for (const tool of tools) {
    fns[sanitizeToolName(tool.name)] = {
      description: tool.description,
      execute: async (args) => {
        return client.callTool({ name: tool.name, arguments: args });
      },
    };
  }

  return { name, tools: fns, types };
}

Notes

  • generateTypesFromJsonSchema needs a namespace parameter (currently hardcodes "codemode")
  • Should be exported from @cloudflare/codemode/mcp
  • Follows the same pattern as stateTools(workspace) and aiTools(tools)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions