69 lines
2.3 KiB
TypeScript
69 lines
2.3 KiB
TypeScript
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|||
|
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
||
|
|
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
|
||
|
|
import { Type } from "typebox";
|
||
|
|
|
||
|
|
export default function (pi: ExtensionAPI) {
|
||
|
|
pi.on("session_start", async (_event, ctx) => {
|
||
|
|
const token = process.env.NANOCLAW_MCP_TOKEN;
|
||
|
|
const serverUrl = process.env.NANOCLAW_MCP_URL || "http://localhost:3002/mcp";
|
||
|
|
|
||
|
|
if (!token) {
|
||
|
|
ctx.ui.notify("NANOCLAW_MCP_TOKEN environment variable is missing. MCP tools won't be loaded.", "warning");
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
ctx.ui.notify(`Connecting to nanoclaw MCP server at ${serverUrl}...`, "info");
|
||
|
|
try {
|
||
|
|
const transport = new StreamableHTTPClientTransport(new URL(serverUrl), {
|
||
|
|
requestInit: {
|
||
|
|
headers: {
|
||
|
|
"Authorization": `Bearer ${token}`
|
||
|
|
}
|
||
|
|
}
|
||
|
|
});
|
||
|
|
|
||
|
|
const client = new Client(
|
||
|
|
{ name: "pi-mcp-client", version: "1.0.0" },
|
||
|
|
{ capabilities: { tools: {} } }
|
||
|
|
);
|
||
|
|
|
||
|
|
await client.connect(transport);
|
||
|
|
const { tools } = await client.listTools();
|
||
|
|
|
||
|
|
for (const tool of tools) {
|
||
|
|
pi.registerTool({
|
||
|
|
name: tool.name,
|
||
|
|
description: tool.description || `MCP Tool: ${tool.name}`,
|
||
|
|
parameters: Type.Any(),
|
||
|
|
async execute(id, params) {
|
||
|
|
try {
|
||
|
|
const result = await client.callTool({
|
||
|
|
name: tool.name,
|
||
|
|
arguments: params as any
|
||
|
|
});
|
||
|
|
|
||
|
|
if (result.isError) {
|
||
|
|
throw new Error(result.content.map((c: any) => c.text).join("\n"));
|
||
|
|
}
|
||
|
|
|
||
|
|
return {
|
||
|
|
content: result.content.map((c: any) => ({
|
||
|
|
type: "text",
|
||
|
|
text: c.text || JSON.stringify(c)
|
||
|
|
}))
|
||
|
|
};
|
||
|
|
} catch (err: any) {
|
||
|
|
throw new Error(`MCP Tool Error: ${err.message}`);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
ctx.ui.notify(`Connected to nanoclaw MCP server. Loaded ${tools.length} tools: ${tools.map(t => t.name).join(', ')}`, "success");
|
||
|
|
} catch (error: any) {
|
||
|
|
ctx.ui.notify(`Failed to connect to nanoclaw MCP server: ${error.message}`, "error");
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|