Some checks failed
Monorepo Pipeline / ⚡ Prioritize Release (push) Successful in 2s
Monorepo Pipeline / 🧪 Test (push) Successful in 1m20s
Monorepo Pipeline / 🧹 Lint (push) Successful in 4m27s
Monorepo Pipeline / 🏗️ Build (push) Successful in 2m35s
Monorepo Pipeline / 🐳 Build Gatekeeper (Product) (push) Failing after 17s
Monorepo Pipeline / 🐳 Build Build-Base (push) Failing after 17s
Monorepo Pipeline / 🐳 Build Production Runtime (push) Failing after 17s
Monorepo Pipeline / 🚀 Release (push) Successful in 1m33s
66 lines
2.6 KiB
TypeScript
66 lines
2.6 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 } from 'ai'
|
|
import { z } from 'zod'
|
|
|
|
/**
|
|
* 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: z.any().describe('JSON matching the original MCP input_schema'), // Simplify for prototype
|
|
// @ts-ignore - 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 }
|
|
}
|