A CLI tool that generates Vercel AI SDK stubs for Model Context Protocol (MCP) tools. Think of it as "shadcn for MCP".
Why would you do this over using the MCP directly:
- Security: Prevents possible prompt injection from unexpected changes to the MCP server tool definitions.
- Security: Prevents security issues from unexpected new tools (e.g. when the server introduces a new delete function which your agent is not expected to call).
- Security: Allows overridding tool implementations with narrower arguments. E.g. by limiting queries to a single tenant or similar specialization of broad tools.
- Quality/cost: High context usage from unneeded functions.
- Quality: Prevents quality regressions from unexpected changes to the MCP server.
- Quality: Allows tuning of tool call precision in the context of your project.
See samples of generated output.
See sample usage of MCP stubs.
npx mcp-to-ai-sdk@latest <MCP_URL_OR_PATH>
# Generate wrappers for HTTP MCP endpoints (uses StreamableHttp by default)
npx mcp-to-ai-sdk@latest https://mcp.grep.app
# Use Server-Sent Events transport
npx mcp-to-ai-sdk@latest --sse https://example.com/mcp/sse
# Generate wrappers for local MCP servers
npx mcp-to-ai-sdk@latest /path/to/mcp-server.js
# Add authentication headers for protected MCP endpoints
npx mcp-to-ai-sdk@latest -H 'Authorization: Bearer your-token' https://api.example.com/mcp
npx mcp-to-ai-sdk@latest -H 'X-API-Key: your-key' -H 'Authorization: Bearer your-token' https://api.example.com/mcp
mcps/mcp.grep.app/
├── client.ts # Shared MCP client with lazy connection
├── index.ts # Domain-based exports (mcpGrepTools)
└── searchGitHub.ts # Individual tool implementation
import { tool } from "ai";
import { type Client } from "@modelcontextprotocol/sdk/client/index.js";
import { z } from "zod";
// Auto-generated wrapper for MCP tool: searchGitHub
// Source: https://mcp.grep.app
export const searchGitHubToolWithClient = (
getClient: () => Promise<Client> | Client
) =>
tool({
description: "Find real-world code examples from GitHub repositories",
inputSchema: z.object({
query: z.string().describe("Code pattern to search for"),
language: z
.array(z.string())
.optional()
.describe("Programming languages"),
}),
execute: async (args): Promise<string> => {
const client = await getClient();
const result = await client.callTool({
name: "searchGitHub",
arguments: args,
});
// Handle different content types from MCP
if (Array.isArray(result.content)) {
return result.content
.map((item: unknown) =>
typeof item === "string" ? item : JSON.stringify(item)
)
.join("\n");
} else if (typeof result.content === "string") {
return result.content;
} else {
return JSON.stringify(result.content);
}
},
});
The package generates a default client shared between all tools from a given MCP servers.
You may customize connection parameters by editing the generated client.ts
file.
To use the generated output, install the required dependencies in your project:
npm install ai zod @modelcontextprotocol/sdk
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";
import { mcpGrepTools } from "./mcps/mcp.grep.app"; // Domain-based export name
const result = await generateText({
model: openai("gpt-4"),
tools: mcpGrepTools, // Use all tools from the MCP server
prompt: "Find examples of React hooks usage",
});
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";
import { searchGitHubTool } from "./mcps/mcp.grep.app";
const result = await generateText({
model: openai("gpt-4"),
tools: {
searchGitHub: searchGitHubTool,
},
prompt: "Find examples of React hooks usage",
});
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";
import { searchGitHubToolWithClient } from "./mcps/mcp.grep.app/searchGitHub.js";
import { getMcpClient } from "./mcps/mcp.grep.app/client.js";
const result = await generateText({
model: openai("gpt-4"),
tools: {
searchGitHub: searchGitHubToolWithClient(getMcpClient),
},
prompt: "Find examples of React hooks usage",
});
import { generateText } from "ai";
import { openai } from "@ai-sdk/openai";
import { mcpGrepToolsWithClient } from "./mcps/mcp.grep.app/index.js";
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
// Create your custom client
const customClient = new Client(/* ... */);
const result = await generateText({
model: openai("gpt-4"),
tools: mcpGrepToolsWithClient(customClient), // All tools with custom client
prompt: "Find examples of React hooks usage",
});
For MCP servers that require OAuth authentication, the CLI will automatically handle the complete authentication flow:
- Detects when a server requires OAuth authentication
- Spins up a temporary local web server to handle the OAuth callback
- Opens your browser to complete the authentication flow
- Automatically captures the auth tokens and proceeds with tool discovery
- Downloads all available tool definitions after successful authentication
When using -H
flags to pass headers during tool discovery:
- Headers are used to authenticate with the MCP server during discovery
- Generated client files include header placeholders with
TODO
values for security - You'll need to replace the TODO placeholders with actual values in your runtime environment
Important: While the CLI successfully downloads tool definitions from authenticated servers, you'll need to configure authentication in the generated client files for actual tool usage in your agent.
Example generated client with headers:
const transport = new StreamableHTTPClientTransport(
new URL("https://api.example.com/mcp"),
{
requestInit: {
headers: {
Authorization: "TODO: Replace with your actual value",
"X-API-Key": "TODO: Replace with your actual value",
},
},
}
);
- StreamableHttp (default for URLs): Best for most HTTP MCP servers
- Server-Sent Events: Use
--sse
flag for SSE endpoints - Stdio: Automatic for local file paths
# Install dependencies
pnpm install
# Run in development mode
pnpm dev https://mcp.grep.app
# Build for distribution
pnpm build
# Test built version
node dist/mcp-tools-cli.js https://mcp.grep.app