Skip to main content
createMcpToolset connects to a Model Context Protocol server over stdio, lists its tools once, and returns an AI SDK-compatible tools record for an SDK agent. This is the inbound MCP integration path: use any MCP server as an agent tool provider without writing one wrapper per external service. For the opposite direction, where an MCP-aware client drives Smithers workflows, see MCP Server.

Import

import { AnthropicAgent } from "smithers-orchestrator";
import {
  createMcpToolset,
  type McpServerConfig,
  type McpToolset,
  type McpToolsetOptions,
} from "@smithers-orchestrator/agents/mcp/createMcpToolset";
createMcpToolset is intentionally a deep import from @smithers-orchestrator/agents/mcp/createMcpToolset; it is not re-exported from the top-level smithers-orchestrator facade.

Quick Start

const mcp = await createMcpToolset({
  command: "npx",
  args: ["-y", "@modelcontextprotocol/server-github"],
  env: { GITHUB_PERSONAL_ACCESS_TOKEN: process.env.GITHUB_TOKEN ?? "" },
});

try {
  const agent = new AnthropicAgent({
    model: "claude-fable-5",
    instructions: "Use the available tools when they are relevant.",
    tools: mcp.tools,
  });

  // Pass `agent` to a <Task>.
} finally {
  await mcp.close();
}
Call close() in a finally block when the workflow process owns the connection. The MCP client and spawned server process stay open until close() resolves.

API

type McpServerConfig = {
  command: string;
  args?: string[];
  env?: Record<string, string>;
  cwd?: string;
};

type McpToolsetOptions = {
  include?: string[];
  exclude?: string[];
  namePrefix?: string;
  clientName?: string;
  clientVersion?: string;
};

type McpToolset = {
  tools: Record<string, import("ai").Tool>;
  toolNames: string[];
  close: () => Promise<void>;
};

declare function createMcpToolset(
  config: McpServerConfig,
  options?: McpToolsetOptions,
): Promise<McpToolset>;
command, args, env, and cwd are passed to the MCP SDK stdio transport. The Smithers client identity defaults to clientName: "smithers-mcp-toolset" and clientVersion: "0.0.0".

Tool Curation

const github = await createMcpToolset(
  {
    command: "npx",
    args: ["-y", "@modelcontextprotocol/server-github"],
    env: { GITHUB_PERSONAL_ACCESS_TOKEN: process.env.GITHUB_TOKEN ?? "" },
  },
  {
    include: ["get_issue", "create_pull_request"],
    exclude: ["create_pull_request"],
    namePrefix: "github_",
  },
);
include and exclude match the original MCP server tool names before namePrefix is applied. If both match a tool, exclude wins. toolNames contains the final names after filtering and prefixing.

Runtime Behavior

On connect, Smithers calls tools/list once and wraps every selected MCP tool with AI SDK dynamicTool. When an agent invokes one of those tools, the wrapper calls MCP tools/call with the original server tool name and the model-provided arguments. Response handling is intentionally simple:
  • Successful calls return structuredContent when the server provides it.
  • Otherwise successful calls return the joined text content blocks.
  • MCP tool errors return { error: true, message, status: "failed" } so the agent can inspect and recover inside its tool loop.
Schema handling follows the MCP server’s advertised inputSchema. If a server omits it, Smithers uses an empty object JSON schema.

CLI Agents

CLI agents consume MCP through their native configuration surfaces, not through createMcpToolset. Claude Code, Kimi, and Amp expose MCP config flags; Codex reads MCP servers from ~/.codex/config.toml or codex mcp add. Use createMcpToolset when you are building an SDK-agent workflow with AnthropicAgent, OpenAIAgent, HermesAgent, or a raw AI SDK tool-loop agent.

See Also