Some checks failed
Monorepo Pipeline / ⚡ Prioritize Release (push) Successful in 2s
Monorepo Pipeline / 🧹 Lint (push) Failing after 18s
Monorepo Pipeline / 🧪 Test (push) Failing after 10s
Monorepo Pipeline / 🏗️ Build (push) Failing after 10s
Monorepo Pipeline / 🚀 Release (push) Has been skipped
Monorepo Pipeline / 🐳 Build Gatekeeper (Product) (push) Has been skipped
Monorepo Pipeline / 🐳 Build Build-Base (push) Has been skipped
Monorepo Pipeline / 🐳 Build Production Runtime (push) Has been skipped
69 lines
2.4 KiB
TypeScript
69 lines
2.4 KiB
TypeScript
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
|
|
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
import { tool, jsonSchema } from "ai";
|
|
/**
|
|
* Connects to an external MCP Server and maps its tools to Vercel AI SDK Tools.
|
|
*/
|
|
export async function createMcpTools(mcpConfig: {
|
|
name: string;
|
|
url?: string;
|
|
command?: string;
|
|
args?: string[];
|
|
}) {
|
|
let transport;
|
|
|
|
// Support both HTTP/SSE and STDIO transports
|
|
if (mcpConfig.url) {
|
|
transport = new SSEClientTransport(new URL(mcpConfig.url));
|
|
} else if (mcpConfig.command) {
|
|
transport = new StdioClientTransport({
|
|
command: mcpConfig.command,
|
|
args: mcpConfig.args || [],
|
|
});
|
|
} else {
|
|
throw new Error("Invalid MCP config: Must provide either URL or Command.");
|
|
}
|
|
|
|
const client = new Client(
|
|
{ name: `payload-ai-client-${mcpConfig.name}`, version: "1.0.0" },
|
|
{ capabilities: {} },
|
|
);
|
|
|
|
await client.connect(transport);
|
|
|
|
// Fetch available tools from the external MCP server
|
|
const toolListResult = await client.listTools();
|
|
const externalTools = toolListResult.tools || [];
|
|
|
|
const aiSdkTools: Record<string, any> = {};
|
|
|
|
// Map each external tool to a Vercel AI SDK Tool
|
|
for (const extTool of externalTools) {
|
|
// Basic conversion of JSON Schema to Zod for the AI SDK
|
|
// Note: For a production ready adapter, you might need a more robust jsonSchemaToZod converter
|
|
// or use AI SDK's new experimental generateSchema feature if available.
|
|
// Here we use a generic `z.any()` as a fallback since AI SDK requires a Zod schema.
|
|
const toolSchema = extTool.inputSchema as Record<string, any>;
|
|
|
|
// We create a simplified parameter parser.
|
|
// An ideal approach uses `jsonSchemaToZod` library or native AI SDK JSON schema support
|
|
// (introduced recently in `ai` package).
|
|
|
|
aiSdkTools[`${mcpConfig.name}_${extTool.name}`] = tool({
|
|
description: `[From ${mcpConfig.name}] ${extTool.description || extTool.name}`,
|
|
parameters: jsonSchema(toolSchema as any),
|
|
// @ts-expect-error - AI strict mode overload bug with implicit zod inferences
|
|
execute: async (args: any) => {
|
|
const result = await client.callTool({
|
|
name: extTool.name,
|
|
arguments: args,
|
|
});
|
|
return result;
|
|
},
|
|
});
|
|
}
|
|
|
|
return { tools: aiSdkTools, client };
|
|
}
|