@mcp-ts/sdk 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/README.md +25 -13
  2. package/dist/adapters/agui-adapter.d.mts +21 -44
  3. package/dist/adapters/agui-adapter.d.ts +21 -44
  4. package/dist/adapters/agui-adapter.js +93 -67
  5. package/dist/adapters/agui-adapter.js.map +1 -1
  6. package/dist/adapters/agui-adapter.mjs +93 -68
  7. package/dist/adapters/agui-adapter.mjs.map +1 -1
  8. package/dist/adapters/agui-middleware.d.mts +32 -134
  9. package/dist/adapters/agui-middleware.d.ts +32 -134
  10. package/dist/adapters/agui-middleware.js +314 -350
  11. package/dist/adapters/agui-middleware.js.map +1 -1
  12. package/dist/adapters/agui-middleware.mjs +314 -351
  13. package/dist/adapters/agui-middleware.mjs.map +1 -1
  14. package/dist/adapters/ai-adapter.d.mts +2 -2
  15. package/dist/adapters/ai-adapter.d.ts +2 -2
  16. package/dist/adapters/langchain-adapter.d.mts +2 -2
  17. package/dist/adapters/langchain-adapter.d.ts +2 -2
  18. package/dist/adapters/mastra-adapter.d.mts +2 -2
  19. package/dist/adapters/mastra-adapter.d.ts +2 -2
  20. package/dist/client/index.d.mts +184 -57
  21. package/dist/client/index.d.ts +184 -57
  22. package/dist/client/index.js +535 -130
  23. package/dist/client/index.js.map +1 -1
  24. package/dist/client/index.mjs +535 -131
  25. package/dist/client/index.mjs.map +1 -1
  26. package/dist/client/react.d.mts +40 -6
  27. package/dist/client/react.d.ts +40 -6
  28. package/dist/client/react.js +587 -142
  29. package/dist/client/react.js.map +1 -1
  30. package/dist/client/react.mjs +586 -143
  31. package/dist/client/react.mjs.map +1 -1
  32. package/dist/client/vue.d.mts +5 -5
  33. package/dist/client/vue.d.ts +5 -5
  34. package/dist/client/vue.js +545 -140
  35. package/dist/client/vue.js.map +1 -1
  36. package/dist/client/vue.mjs +545 -141
  37. package/dist/client/vue.mjs.map +1 -1
  38. package/dist/{events-BP6WyRNh.d.mts → events-BgeztGYZ.d.mts} +12 -1
  39. package/dist/{events-BP6WyRNh.d.ts → events-BgeztGYZ.d.ts} +12 -1
  40. package/dist/index.d.mts +4 -4
  41. package/dist/index.d.ts +4 -4
  42. package/dist/index.js +779 -248
  43. package/dist/index.js.map +1 -1
  44. package/dist/index.mjs +775 -245
  45. package/dist/index.mjs.map +1 -1
  46. package/dist/{multi-session-client-DMF3ED2O.d.mts → multi-session-client-CxogNckF.d.mts} +1 -1
  47. package/dist/{multi-session-client-BOFgPypS.d.ts → multi-session-client-cox_WXUj.d.ts} +1 -1
  48. package/dist/server/index.d.mts +44 -40
  49. package/dist/server/index.d.ts +44 -40
  50. package/dist/server/index.js +242 -116
  51. package/dist/server/index.js.map +1 -1
  52. package/dist/server/index.mjs +238 -112
  53. package/dist/server/index.mjs.map +1 -1
  54. package/dist/shared/index.d.mts +2 -2
  55. package/dist/shared/index.d.ts +2 -2
  56. package/dist/shared/index.js.map +1 -1
  57. package/dist/shared/index.mjs.map +1 -1
  58. package/dist/{types-SbDlA2VX.d.mts → types-CLccx9wW.d.mts} +1 -1
  59. package/dist/{types-SbDlA2VX.d.ts → types-CLccx9wW.d.ts} +1 -1
  60. package/package.json +8 -1
  61. package/src/adapters/agui-adapter.ts +121 -107
  62. package/src/adapters/agui-middleware.ts +474 -512
  63. package/src/client/core/app-host.ts +417 -0
  64. package/src/client/core/sse-client.ts +365 -212
  65. package/src/client/core/types.ts +31 -0
  66. package/src/client/index.ts +1 -0
  67. package/src/client/react/index.ts +1 -0
  68. package/src/client/react/use-mcp-app.ts +73 -0
  69. package/src/client/react/useMcp.ts +18 -0
  70. package/src/server/handlers/nextjs-handler.ts +8 -7
  71. package/src/server/handlers/sse-handler.ts +131 -164
  72. package/src/server/mcp/oauth-client.ts +32 -2
  73. package/src/server/storage/index.ts +17 -1
  74. package/src/server/storage/sqlite-backend.ts +185 -0
  75. package/src/server/storage/types.ts +1 -1
  76. package/src/shared/events.ts +12 -0
  77. package/src/shared/types.ts +4 -2
@@ -1,4 +1,50 @@
1
1
  // src/adapters/agui-adapter.ts
2
+ var PYDANTIC_FORBIDDEN_PROPS = [
3
+ // JSON Schema meta-properties
4
+ "$schema",
5
+ "$id",
6
+ "$comment",
7
+ "$defs",
8
+ "definitions",
9
+ // Extended properties used by some MCP servers (e.g., Apify)
10
+ "prefill",
11
+ "examples",
12
+ "enumTitles",
13
+ "enumDescriptions",
14
+ // Other common extensions
15
+ "deprecated",
16
+ "readOnly",
17
+ "writeOnly",
18
+ "contentMediaType",
19
+ "contentEncoding"
20
+ ];
21
+ function cleanSchema(schema) {
22
+ if (!schema) {
23
+ return { type: "object", properties: {} };
24
+ }
25
+ const cleaned = { ...schema };
26
+ for (const prop of PYDANTIC_FORBIDDEN_PROPS) {
27
+ delete cleaned[prop];
28
+ }
29
+ if (cleaned.properties && typeof cleaned.properties === "object") {
30
+ const cleanedProps = {};
31
+ for (const [key, value] of Object.entries(cleaned.properties)) {
32
+ if (typeof value === "object" && value !== null) {
33
+ cleanedProps[key] = cleanSchema(value);
34
+ } else {
35
+ cleanedProps[key] = value;
36
+ }
37
+ }
38
+ cleaned.properties = cleanedProps;
39
+ }
40
+ if (cleaned.items && typeof cleaned.items === "object") {
41
+ cleaned.items = cleanSchema(cleaned.items);
42
+ }
43
+ if (cleaned.additionalProperties && typeof cleaned.additionalProperties === "object") {
44
+ cleaned.additionalProperties = cleanSchema(cleaned.additionalProperties);
45
+ }
46
+ return cleaned;
47
+ }
2
48
  var AguiAdapter = class {
3
49
  constructor(client, options = {}) {
4
50
  this.client = client;
@@ -6,102 +52,81 @@ var AguiAdapter = class {
6
52
  }
7
53
  /**
8
54
  * Get tools with handlers for MCP tool execution.
9
- *
10
- * Each tool includes a handler function that:
11
- * 1. Calls the MCP tool via the client
12
- * 2. Extracts text content from the result
13
- * 3. Returns the result as a string or JSON
14
- *
15
- * @returns Array of AguiTool objects
16
55
  */
17
56
  async getTools() {
18
- const isMultiSession = typeof this.client.getClients === "function";
19
- if (isMultiSession) {
57
+ if (this.isMultiSession()) {
20
58
  const clients = this.client.getClients();
21
59
  const allTools = [];
22
60
  for (const client of clients) {
23
- const tools = await this.transformTools(client);
24
- allTools.push(...tools);
61
+ allTools.push(...await this.transformTools(client));
25
62
  }
26
63
  return allTools;
27
64
  }
28
65
  return this.transformTools(this.client);
29
66
  }
30
- async transformTools(client) {
31
- if (!client.isConnected()) {
32
- return [];
33
- }
34
- const result = await client.listTools();
35
- const prefix = this.options.prefix ?? client.getServerId() ?? "mcp";
36
- const tools = [];
37
- for (const tool of result.tools) {
38
- const toolName = `${prefix}_${tool.name}`;
39
- tools.push({
40
- name: toolName,
41
- description: tool.description || `Execute ${tool.name}`,
42
- parameters: tool.inputSchema || { type: "object", properties: {} },
43
- handler: async (args) => {
44
- console.log(`[AguiAdapter] Executing MCP tool: ${tool.name}`, args);
45
- const result2 = await client.callTool(tool.name, args);
46
- if (result2.content && Array.isArray(result2.content)) {
47
- const textContent = result2.content.filter((c) => c.type === "text").map((c) => c.text).join("\n");
48
- return textContent || result2;
49
- }
50
- return result2;
51
- }
52
- });
53
- }
54
- return tools;
55
- }
56
- /**
57
- * Get tools as a function (for dynamic loading).
58
- *
59
- * @returns Function that returns a Promise of tools
60
- */
61
- getToolsFunction() {
62
- return async () => this.getTools();
63
- }
64
67
  /**
65
68
  * Get tool definitions in JSON Schema format for passing to remote agents.
66
- *
67
- * This format is compatible with:
68
- * - OpenAI's function calling API
69
- * - AG-UI input.tools format
70
- * - Most LLM tool/function calling implementations
71
- *
72
- * @returns Array of AguiToolDefinition objects
73
69
  */
74
70
  async getToolDefinitions() {
75
- const isMultiSession = typeof this.client.getClients === "function";
76
- if (isMultiSession) {
71
+ if (this.isMultiSession()) {
77
72
  const clients = this.client.getClients();
78
73
  const allTools = [];
79
74
  for (const client of clients) {
80
- const tools = await this.transformToolDefinitions(client);
81
- allTools.push(...tools);
75
+ allTools.push(...await this.transformToolDefinitions(client));
82
76
  }
83
77
  return allTools;
84
78
  }
85
79
  return this.transformToolDefinitions(this.client);
86
80
  }
81
+ /**
82
+ * Get tools as a function (for dynamic loading).
83
+ */
84
+ getToolsFunction() {
85
+ return () => this.getTools();
86
+ }
87
+ isMultiSession() {
88
+ return typeof this.client.getClients === "function";
89
+ }
90
+ async transformTools(client) {
91
+ if (!client.isConnected()) return [];
92
+ const result = await client.listTools();
93
+ const serverId = typeof client.getServerId === "function" ? client.getServerId() : void 0;
94
+ const normalizedPrefix = (this.options.prefix ?? serverId ?? "mcp").replace(/-/g, "");
95
+ const prefix = `tool_${normalizedPrefix}`;
96
+ return result.tools.map((tool) => {
97
+ const mcpTool = tool;
98
+ const mcpToolName = tool.name;
99
+ return {
100
+ name: `${prefix}_${tool.name}`,
101
+ description: tool.description || `Execute ${tool.name}`,
102
+ parameters: cleanSchema(tool.inputSchema),
103
+ _meta: { ...mcpTool._meta, sessionId: client.getSessionId?.() },
104
+ handler: async (args) => {
105
+ console.log(`[AguiAdapter] Executing MCP tool: ${mcpToolName}`, args);
106
+ const callResult = await client.callTool(mcpToolName, args ?? {});
107
+ return callResult;
108
+ }
109
+ };
110
+ });
111
+ }
87
112
  async transformToolDefinitions(client) {
88
- if (!client.isConnected()) {
89
- return [];
90
- }
113
+ if (!client.isConnected()) return [];
91
114
  const result = await client.listTools();
92
- const prefix = this.options.prefix ?? client.getServerId() ?? "mcp";
93
- const tools = [];
94
- for (const tool of result.tools) {
95
- tools.push({
115
+ const serverId = typeof client.getServerId === "function" ? client.getServerId() : void 0;
116
+ const normalizedPrefix = (this.options.prefix ?? serverId ?? "mcp").replace(/-/g, "");
117
+ const prefix = `tool_${normalizedPrefix}`;
118
+ return result.tools.map((tool) => {
119
+ const mcpTool = tool;
120
+ return {
96
121
  name: `${prefix}_${tool.name}`,
97
122
  description: tool.description || `Execute ${tool.name}`,
98
- parameters: tool.inputSchema || { type: "object", properties: {} }
99
- });
100
- }
101
- return tools;
123
+ parameters: cleanSchema(tool.inputSchema),
124
+ _meta: { ...mcpTool._meta, sessionId: client.getSessionId?.() }
125
+ };
126
+ });
102
127
  }
103
128
  };
104
129
 
105
- export { AguiAdapter };
130
+ export { AguiAdapter, cleanSchema };
106
131
  //# sourceMappingURL=agui-adapter.mjs.map
107
132
  //# sourceMappingURL=agui-adapter.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/adapters/agui-adapter.ts"],"names":["result"],"mappings":"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","file":"agui-adapter.mjs","sourcesContent":["/**\r\n * MCP Adapter for AG-UI Integration\r\n *\r\n * This adapter transforms MCP tools into formats compatible with AG-UI agents.\r\n * It provides tools with handlers for server-side execution and tool definitions\r\n * in JSON Schema format for passing to remote agents.\r\n *\r\n * @example\r\n * ```typescript\r\n * import { MultiSessionClient } from '@mcp-ts/sdk/server';\r\n * import { AguiAdapter } from '@mcp-ts/sdk/adapters/mcp-adapter';\r\n * import { createMcpMiddleware } from '@mcp-ts/sdk/adapters/agui-middleware';\r\n * import { HttpAgent } from '@ag-ui/client';\r\n *\r\n * // Create MCP client\r\n * const mcpClient = new MultiSessionClient('user_123');\r\n * await mcpClient.connect();\r\n *\r\n * // Create adapter and get tools\r\n * const adapter = new AguiAdapter(mcpClient);\r\n * const tools = await adapter.getTools();\r\n *\r\n * // Use with AG-UI middleware\r\n * const agent = new HttpAgent({ url: 'http://localhost:8000/agent' });\r\n * agent.use(createMcpMiddleware(mcpClient, { tools }));\r\n * ```\r\n */\r\n\r\nimport { MCPClient } from '../server/mcp/oauth-client.js';\r\nimport { MultiSessionClient } from '../server/mcp/multi-session-client.js';\r\n\r\n/**\r\n * Configuration options for AguiAdapter\r\n */\r\nexport interface AguiAdapterOptions {\r\n /**\r\n * Prefix for tool names to avoid collision with other tools.\r\n * @default serverId or 'mcp'\r\n */\r\n prefix?: string;\r\n}\r\n\r\n/**\r\n * AG-UI Tool with handler for server-side execution.\r\n *\r\n * Tools contain:\r\n * - `name`: Unique identifier (prefixed with server ID)\r\n * - `description`: Human-readable description for the LLM\r\n * - `parameters`: JSON Schema defining the input format\r\n * - `handler`: Function that executes the tool via MCP client\r\n */\r\nexport interface AguiTool {\r\n /** Unique tool name (e.g., \"server-abc_get_weather\") */\r\n name: string;\r\n /** Human-readable description for the LLM */\r\n description: string;\r\n /** JSON Schema format parameters */\r\n parameters?: Record<string, any>;\r\n /** Handler function that executes the MCP tool */\r\n handler?: (args: any) => any | Promise<any>;\r\n}\r\n\r\n/**\r\n * Tool definition format for passing to remote agents (without handler).\r\n * Compatible with OpenAI's function calling API.\r\n */\r\nexport interface AguiToolDefinition {\r\n /** Tool name (e.g., \"server-abc_get_weather\") */\r\n name: string;\r\n /** Human-readable description */\r\n description: string;\r\n /** JSON Schema format parameters */\r\n parameters: Record<string, any>;\r\n}\r\n\r\n/**\r\n * Adapter that transforms MCP tools into AG-UI compatible formats.\r\n *\r\n * This adapter provides two main outputs:\r\n * - `getTools()`: Returns tools with handlers for server-side execution\r\n * - `getToolDefinitions()`: Returns tool definitions in JSON Schema format for remote agents\r\n */\r\nexport class AguiAdapter {\r\n constructor(\r\n private client: MCPClient | MultiSessionClient,\r\n private options: AguiAdapterOptions = {}\r\n ) { }\r\n\r\n /**\r\n * Get tools with handlers for MCP tool execution.\r\n *\r\n * Each tool includes a handler function that:\r\n * 1. Calls the MCP tool via the client\r\n * 2. Extracts text content from the result\r\n * 3. Returns the result as a string or JSON\r\n *\r\n * @returns Array of AguiTool objects\r\n */\r\n async getTools(): Promise<AguiTool[]> {\r\n const isMultiSession = typeof (this.client as any).getClients === 'function';\r\n\r\n if (isMultiSession) {\r\n const clients = (this.client as MultiSessionClient).getClients();\r\n const allTools: AguiTool[] = [];\r\n\r\n for (const client of clients) {\r\n const tools = await this.transformTools(client);\r\n allTools.push(...tools);\r\n }\r\n\r\n return allTools;\r\n }\r\n\r\n return this.transformTools(this.client as MCPClient);\r\n }\r\n\r\n private async transformTools(client: MCPClient): Promise<AguiTool[]> {\r\n if (!client.isConnected()) {\r\n return [];\r\n }\r\n\r\n const result = await client.listTools();\r\n const prefix = this.options.prefix ?? client.getServerId() ?? 'mcp';\r\n const tools: AguiTool[] = [];\r\n\r\n for (const tool of result.tools) {\r\n const toolName = `${prefix}_${tool.name}`;\r\n\r\n tools.push({\r\n name: toolName,\r\n description: tool.description || `Execute ${tool.name}`,\r\n parameters: tool.inputSchema || { type: 'object', properties: {} },\r\n handler: async (args: any) => {\r\n console.log(`[AguiAdapter] Executing MCP tool: ${tool.name}`, args);\r\n const result = await client.callTool(tool.name, args);\r\n\r\n // Extract text content from result\r\n if (result.content && Array.isArray(result.content)) {\r\n const textContent = result.content\r\n .filter((c: any) => c.type === 'text')\r\n .map((c: any) => c.text)\r\n .join('\\n');\r\n return textContent || result;\r\n }\r\n\r\n return result;\r\n }\r\n });\r\n }\r\n\r\n return tools;\r\n }\r\n\r\n /**\r\n * Get tools as a function (for dynamic loading).\r\n *\r\n * @returns Function that returns a Promise of tools\r\n */\r\n getToolsFunction(): () => Promise<AguiTool[]> {\r\n return async () => this.getTools();\r\n }\r\n\r\n /**\r\n * Get tool definitions in JSON Schema format for passing to remote agents.\r\n *\r\n * This format is compatible with:\r\n * - OpenAI's function calling API\r\n * - AG-UI input.tools format\r\n * - Most LLM tool/function calling implementations\r\n *\r\n * @returns Array of AguiToolDefinition objects\r\n */\r\n async getToolDefinitions(): Promise<AguiToolDefinition[]> {\r\n const isMultiSession = typeof (this.client as any).getClients === 'function';\r\n\r\n if (isMultiSession) {\r\n const clients = (this.client as MultiSessionClient).getClients();\r\n const allTools: AguiToolDefinition[] = [];\r\n\r\n for (const client of clients) {\r\n const tools = await this.transformToolDefinitions(client);\r\n allTools.push(...tools);\r\n }\r\n\r\n return allTools;\r\n }\r\n\r\n return this.transformToolDefinitions(this.client as MCPClient);\r\n }\r\n\r\n private async transformToolDefinitions(client: MCPClient): Promise<AguiToolDefinition[]> {\r\n if (!client.isConnected()) {\r\n return [];\r\n }\r\n\r\n const result = await client.listTools();\r\n const prefix = this.options.prefix ?? client.getServerId() ?? 'mcp';\r\n const tools: AguiToolDefinition[] = [];\r\n\r\n for (const tool of result.tools) {\r\n tools.push({\r\n name: `${prefix}_${tool.name}`,\r\n description: tool.description || `Execute ${tool.name}`,\r\n parameters: tool.inputSchema || { type: 'object', properties: {} },\r\n });\r\n }\r\n\r\n return tools;\r\n }\r\n}\r\n"]}
1
+ {"version":3,"sources":["../../src/adapters/agui-adapter.ts"],"names":[],"mappings":"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","file":"agui-adapter.mjs","sourcesContent":["/**\r\n * MCP Adapter for AG-UI Integration\r\n *\r\n * This adapter transforms MCP tools into formats compatible with AG-UI agents.\r\n * It provides tools with handlers for server-side execution and tool definitions\r\n * in JSON Schema format for passing to remote agents.\r\n *\r\n * @example\r\n * ```typescript\r\n * import { MultiSessionClient } from '@mcp-ts/sdk/server';\r\n * import { AguiAdapter } from '@mcp-ts/sdk/adapters/agui-adapter';\r\n * import { createMcpMiddleware } from '@mcp-ts/sdk/adapters/agui-middleware';\r\n * import { HttpAgent } from '@ag-ui/client';\r\n *\r\n * // Create MCP client\r\n * const mcpClient = new MultiSessionClient('user_123');\r\n * await mcpClient.connect();\r\n *\r\n * // Create adapter and get tools\r\n * const adapter = new AguiAdapter(mcpClient);\r\n * const tools = await adapter.getTools();\r\n *\r\n * // Use with AG-UI middleware\r\n * const agent = new HttpAgent({ url: 'http://localhost:8000/agent' });\r\n * agent.use(createMcpMiddleware({ tools }));\r\n * ```\r\n */\r\n\r\nimport { MCPClient } from '../server/mcp/oauth-client.js';\r\nimport { MultiSessionClient } from '../server/mcp/multi-session-client.js';\r\n\r\n/**\r\n * Extended JSON Schema properties that Pydantic's strict validation rejects.\r\n * These are valid JSON Schema extensions but not part of the core spec.\r\n */\r\nconst PYDANTIC_FORBIDDEN_PROPS = [\r\n // JSON Schema meta-properties\r\n '$schema', '$id', '$comment', '$defs', 'definitions',\r\n // Extended properties used by some MCP servers (e.g., Apify)\r\n 'prefill', 'examples', 'enumTitles', 'enumDescriptions',\r\n // Other common extensions\r\n 'deprecated', 'readOnly', 'writeOnly', 'contentMediaType', 'contentEncoding',\r\n];\r\n\r\n/**\r\n * Cleans a JSON Schema by removing meta-properties that cause issues with\r\n * strict Pydantic validation (e.g., Google ADK, LangGraph).\r\n *\r\n * @param schema - The JSON Schema to clean\r\n * @returns Cleaned schema without forbidden properties\r\n */\r\nexport function cleanSchema(schema: Record<string, any> | undefined): Record<string, any> {\r\n if (!schema) {\r\n return { type: 'object', properties: {} };\r\n }\r\n\r\n const cleaned = { ...schema };\r\n\r\n // Remove all forbidden properties\r\n for (const prop of PYDANTIC_FORBIDDEN_PROPS) {\r\n delete cleaned[prop];\r\n }\r\n\r\n // Recursively clean nested properties\r\n if (cleaned.properties && typeof cleaned.properties === 'object') {\r\n const cleanedProps: Record<string, any> = {};\r\n for (const [key, value] of Object.entries(cleaned.properties)) {\r\n if (typeof value === 'object' && value !== null) {\r\n cleanedProps[key] = cleanSchema(value as Record<string, any>);\r\n } else {\r\n cleanedProps[key] = value;\r\n }\r\n }\r\n cleaned.properties = cleanedProps;\r\n }\r\n\r\n // Clean items if it's an array schema\r\n if (cleaned.items && typeof cleaned.items === 'object') {\r\n cleaned.items = cleanSchema(cleaned.items);\r\n }\r\n\r\n // Clean additionalProperties if it's an object schema\r\n if (cleaned.additionalProperties && typeof cleaned.additionalProperties === 'object') {\r\n cleaned.additionalProperties = cleanSchema(cleaned.additionalProperties);\r\n }\r\n\r\n return cleaned;\r\n}\r\n\r\n/**\r\n * Configuration options for AguiAdapter\r\n */\r\nexport interface AguiAdapterOptions {\r\n /**\r\n * Prefix for tool names to avoid collision with other tools.\r\n * @default serverId or 'mcp'\r\n */\r\n prefix?: string;\r\n}\r\n\r\n/**\r\n * AG-UI Tool with handler for server-side execution.\r\n */\r\nexport interface AguiTool {\r\n name: string;\r\n description: string;\r\n parameters?: Record<string, any>;\r\n _meta?: Record<string, any>; // Add _meta to AguiTool\r\n handler?: (args: any) => any | Promise<any>;\r\n}\r\n\r\n/**\r\n * Tool definition format for passing to remote agents (without handler).\r\n */\r\nexport interface AguiToolDefinition {\r\n name: string;\r\n description: string;\r\n parameters: Record<string, any>;\r\n _meta?: Record<string, any>; // Add _meta to AguiToolDefinition\r\n}\r\n\r\n/**\r\n * Adapter that transforms MCP tools into AG-UI compatible formats.\r\n */\r\nexport class AguiAdapter {\r\n constructor(\r\n private client: MCPClient | MultiSessionClient,\r\n private options: AguiAdapterOptions = {}\r\n ) { }\r\n\r\n /**\r\n * Get tools with handlers for MCP tool execution.\r\n */\r\n async getTools(): Promise<AguiTool[]> {\r\n if (this.isMultiSession()) {\r\n const clients = (this.client as MultiSessionClient).getClients();\r\n const allTools: AguiTool[] = [];\r\n for (const client of clients) {\r\n allTools.push(...await this.transformTools(client));\r\n }\r\n return allTools;\r\n }\r\n return this.transformTools(this.client as MCPClient);\r\n }\r\n\r\n /**\r\n * Get tool definitions in JSON Schema format for passing to remote agents.\r\n */\r\n async getToolDefinitions(): Promise<AguiToolDefinition[]> {\r\n if (this.isMultiSession()) {\r\n const clients = (this.client as MultiSessionClient).getClients();\r\n const allTools: AguiToolDefinition[] = [];\r\n for (const client of clients) {\r\n allTools.push(...await this.transformToolDefinitions(client));\r\n }\r\n return allTools;\r\n }\r\n return this.transformToolDefinitions(this.client as MCPClient);\r\n }\r\n\r\n /**\r\n * Get tools as a function (for dynamic loading).\r\n */\r\n getToolsFunction(): () => Promise<AguiTool[]> {\r\n return () => this.getTools();\r\n }\r\n\r\n private isMultiSession(): boolean {\r\n return typeof (this.client as any).getClients === 'function';\r\n }\r\n\r\n private async transformTools(client: MCPClient): Promise<AguiTool[]> {\r\n if (!client.isConnected()) return [];\r\n\r\n const result = await client.listTools();\r\n const serverId = (typeof (client as any).getServerId === 'function'\r\n ? (client as any).getServerId()\r\n : undefined) as string | undefined;\r\n const normalizedPrefix = (this.options.prefix ?? serverId ?? 'mcp').replace(/-/g, '');\r\n const prefix = `tool_${normalizedPrefix}`;\r\n\r\n return result.tools.map(tool => {\r\n // Type assertion to access _meta if it exists on the tool object (it comes from MCP SDK)\r\n const mcpTool = tool as any;\r\n const mcpToolName = tool.name;\r\n return {\r\n name: `${prefix}_${tool.name}`,\r\n description: tool.description || `Execute ${tool.name}`,\r\n parameters: cleanSchema(tool.inputSchema),\r\n _meta: { ...mcpTool._meta, sessionId: (client as any).getSessionId?.() },\r\n handler: async (args: any) => {\r\n console.log(`[AguiAdapter] Executing MCP tool: ${mcpToolName}`, args);\r\n\r\n // IMPORTANT: call the actual MCP tool. (Previously this mistakenly returned the listTools() result.)\r\n const callResult = await (client as any).callTool(mcpToolName, args ?? {});\r\n\r\n // Return the raw result object so middleware can inspect `_meta` (e.g. for UI triggers).\r\n return callResult;\r\n }\r\n }\r\n });\r\n }\r\n\r\n private async transformToolDefinitions(client: MCPClient): Promise<AguiToolDefinition[]> {\r\n if (!client.isConnected()) return [];\r\n\r\n const result = await client.listTools();\r\n const serverId = (typeof (client as any).getServerId === 'function'\r\n ? (client as any).getServerId()\r\n : undefined) as string | undefined;\r\n const normalizedPrefix = (this.options.prefix ?? serverId ?? 'mcp').replace(/-/g, '');\r\n const prefix = `tool_${normalizedPrefix}`;\r\n\r\n return result.tools.map(tool => {\r\n const mcpTool = tool as any;\r\n return {\r\n name: `${prefix}_${tool.name}`,\r\n description: tool.description || `Execute ${tool.name}`,\r\n parameters: cleanSchema(tool.inputSchema),\r\n _meta: { ...mcpTool._meta, sessionId: (client as any).getSessionId?.() },\r\n };\r\n });\r\n }\r\n}\r\n"]}
@@ -1,9 +1,9 @@
1
1
  import { Observable } from 'rxjs';
2
2
  import { Middleware, RunAgentInput, AbstractAgent, BaseEvent } from '@ag-ui/client';
3
- export { AbstractAgent, BaseEvent, EventType, Middleware, RunAgentInput, ToolCallEndEvent } from '@ag-ui/client';
4
- import { M as MCPClient, a as MultiSessionClient } from '../multi-session-client-DMF3ED2O.mjs';
3
+ export { AbstractAgent, BaseEvent, EventType, Middleware, RunAgentInput, Tool, ToolCallEndEvent } from '@ag-ui/client';
5
4
  import { AguiTool } from './agui-adapter.mjs';
6
- import '../events-BP6WyRNh.mjs';
5
+ import '../multi-session-client-CxogNckF.mjs';
6
+ import '../events-BgeztGYZ.mjs';
7
7
  import '@modelcontextprotocol/sdk/types.js';
8
8
  import '@modelcontextprotocol/sdk/shared/auth.js';
9
9
  import '@modelcontextprotocol/sdk/client/auth.js';
@@ -11,161 +11,59 @@ import '@modelcontextprotocol/sdk/client/auth.js';
11
11
  /**
12
12
  * AG-UI Middleware for MCP Tool Execution
13
13
  *
14
- * This middleware intercepts tool calls from remote agents (e.g., LangGraph, AutoGen)
15
- * and executes MCP tools server-side, returning results back to the agent.
14
+ * This middleware intercepts tool calls from remote agents and executes
15
+ * MCP tools server-side, returning results back to the agent.
16
16
  *
17
- * ## How It Works
18
- *
19
- * 1. **Tool Injection**: When a run starts, the middleware injects MCP tool definitions
20
- * into `input.tools` so the remote agent knows about available MCP tools.
21
- *
22
- * 2. **Event Interception**: The middleware subscribes to the agent's event stream and
23
- * tracks tool calls using AG-UI events:
24
- * - `TOOL_CALL_START`: Records tool name and ID
25
- * - `TOOL_CALL_ARGS`: Accumulates streamed arguments
26
- * - `TOOL_CALL_END`: Marks tool call as complete
27
- * - `RUN_FINISHED`: Triggers execution of pending MCP tools
28
- *
29
- * 3. **Server-Side Execution**: When `RUN_FINISHED` arrives with pending MCP tool calls,
30
- * the middleware:
31
- * - Executes each MCP tool via the MCP client
32
- * - Emits `TOOL_CALL_RESULT` events with the results
33
- * - Adds results to `input.messages` for context
34
- * - Emits `RUN_FINISHED` to close the current run
35
- * - Triggers a new run so the agent can process tool results
36
- *
37
- * 4. **Recursive Processing**: If the new run makes more MCP tool calls, the cycle
38
- * repeats until the agent completes without pending MCP calls.
39
- *
40
- * ## Tool Identification
41
- *
42
- * MCP tools are identified by a configurable prefix (default: `server-`).
43
- * Tools not matching this prefix are passed through without interception.
44
- *
45
- * @requires @ag-ui/client - This middleware requires @ag-ui/client as a peer dependency
17
+ * @requires @ag-ui/client - Peer dependency for AG-UI types
46
18
  * @requires rxjs - Uses RxJS Observables for event streaming
47
- *
48
- * @example
49
- * ```typescript
50
- * import { HttpAgent } from '@ag-ui/client';
51
- * import { McpMiddleware } from '@mcp-ts/sdk/adapters/agui-middleware';
52
- * import { AguiAdapter } from '@mcp-ts/sdk/adapters/agui-adapter';
53
- *
54
- * // Create MCP client and adapter
55
- * const mcpClient = new MultiSessionClient('user_123');
56
- * await mcpClient.connect();
57
- *
58
- * const adapter = new AguiAdapter(mcpClient);
59
- * const actions = await adapter.getActions();
60
- *
61
- * // Create middleware with pre-loaded actions
62
- * const middleware = new McpMiddleware({
63
- * client: mcpClient,
64
- * actions,
65
- * toolPrefix: 'server-',
66
- * });
67
- *
68
- * // Use with HttpAgent
69
- * const agent = new HttpAgent({ url: 'http://localhost:8000/agent' });
70
- * agent.use(middleware);
71
- * ```
72
19
  */
73
20
 
21
+ /** New event type for MCP UI triggers */
22
+ declare const MCP_APP_UI_EVENT = "mcp-apps-ui";
74
23
  /**
75
- * Tool definition format for AG-UI input.tools
24
+ * MCP Apps UI trigger event.
25
+ *
26
+ * IMPORTANT: This must be emitted as an AG-UI CustomEvent so subscribers
27
+ * (e.g. CopilotKit `onCustomEvent`) can receive it.
76
28
  */
77
- interface AgUiTool {
78
- name: string;
79
- description: string;
80
- parameters?: Record<string, any>;
29
+ interface McpAppUiEventPayload {
30
+ toolCallId: string;
31
+ resourceUri: string;
32
+ sessionId?: string;
33
+ toolName: string;
34
+ result?: any;
81
35
  }
82
36
  /**
83
37
  * Configuration for McpMiddleware
84
38
  */
85
39
  interface McpMiddlewareConfig {
86
- /**
87
- * MCP client or MultiSessionClient for executing tools
88
- */
89
- client: MCPClient | MultiSessionClient;
90
- /**
91
- * Prefix used to identify MCP tool names.
92
- * Tools starting with this prefix will be executed server-side.
93
- * @default 'server-'
94
- */
95
- toolPrefix?: string;
96
- /**
97
- * Pre-loaded tools with handlers for execution.
98
- * If not provided, tools will be loaded from the MCP client on first use.
99
- */
100
- tools?: AguiTool[];
40
+ /** Pre-loaded tools with handlers (required) */
41
+ tools: AguiTool[];
101
42
  }
102
43
  /**
103
44
  * AG-UI Middleware that executes MCP tools server-side.
104
- *
105
- * This middleware intercepts tool calls for MCP tools (identified by prefix),
106
- * executes them via the MCP client, and returns results to the agent.
107
- *
108
- * @see {@link createMcpMiddleware} for a simpler factory function
109
45
  */
110
46
  declare class McpMiddleware extends Middleware {
111
- private client;
112
- private toolPrefix;
113
- private actions;
114
47
  private tools;
115
- private actionsLoaded;
48
+ private toolSchemas;
116
49
  constructor(config: McpMiddlewareConfig);
117
- /**
118
- * Convert actions to AG-UI tool format
119
- */
120
- private actionsToTools;
121
- /**
122
- * Check if a tool name is an MCP tool (matches the configured prefix)
123
- */
124
50
  private isMcpTool;
125
- /**
126
- * Load actions from the MCP client if not already loaded
127
- */
128
- private ensureActionsLoaded;
129
- /**
130
- * Execute an MCP tool and return the result as a string
131
- */
51
+ private parseArgs;
132
52
  private executeTool;
133
- /**
134
- * Generate a unique message ID for tool results
135
- */
136
- private generateMessageId;
137
- /**
138
- * Run the middleware, intercepting and executing MCP tool calls
139
- */
53
+ private generateId;
54
+ private ensureIds;
55
+ /** Process tool call events and update state */
56
+ private handleToolCallEvent;
57
+ /** Execute pending MCP tools and return results */
58
+ private executeTools;
59
+ private emitToolResults;
140
60
  run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent>;
141
- private triggerNewRun;
142
- private handlePendingCalls;
143
61
  }
144
62
  /**
145
63
  * Factory function to create MCP middleware.
146
- *
147
- * This is a convenience wrapper around McpMiddleware that returns a function
148
- * compatible with the AG-UI middleware pattern.
149
- *
150
- * @param client - MCP client or MultiSessionClient
151
- * @param options - Configuration options
152
- * @returns Middleware function
153
- *
154
- * @example
155
- * ```typescript
156
- * import { HttpAgent } from '@ag-ui/client';
157
- * import { createMcpMiddleware } from '@mcp-ts/sdk/adapters/agui-middleware';
158
- *
159
- * const agent = new HttpAgent({ url: 'http://localhost:8000/agent' });
160
- * agent.use(createMcpMiddleware(multiSessionClient, {
161
- * toolPrefix: 'server-',
162
- * actions: mcpActions,
163
- * }));
164
- * ```
165
64
  */
166
- declare function createMcpMiddleware(client: MCPClient | MultiSessionClient, options?: {
167
- toolPrefix?: string;
168
- tools?: AguiTool[];
65
+ declare function createMcpMiddleware(options: {
66
+ tools: AguiTool[];
169
67
  }): (input: RunAgentInput, next: AbstractAgent) => Observable<BaseEvent>;
170
68
 
171
- export { type AgUiTool, McpMiddleware, type McpMiddlewareConfig, McpMiddleware as McpToolExecutorMiddleware, createMcpMiddleware, createMcpMiddleware as createMcpToolMiddleware };
69
+ export { MCP_APP_UI_EVENT, type McpAppUiEventPayload, McpMiddleware, type McpMiddlewareConfig, McpMiddleware as McpToolExecutorMiddleware, createMcpMiddleware, createMcpMiddleware as createMcpToolMiddleware };
@@ -1,9 +1,9 @@
1
1
  import { Observable } from 'rxjs';
2
2
  import { Middleware, RunAgentInput, AbstractAgent, BaseEvent } from '@ag-ui/client';
3
- export { AbstractAgent, BaseEvent, EventType, Middleware, RunAgentInput, ToolCallEndEvent } from '@ag-ui/client';
4
- import { M as MCPClient, a as MultiSessionClient } from '../multi-session-client-BOFgPypS.js';
3
+ export { AbstractAgent, BaseEvent, EventType, Middleware, RunAgentInput, Tool, ToolCallEndEvent } from '@ag-ui/client';
5
4
  import { AguiTool } from './agui-adapter.js';
6
- import '../events-BP6WyRNh.js';
5
+ import '../multi-session-client-cox_WXUj.js';
6
+ import '../events-BgeztGYZ.js';
7
7
  import '@modelcontextprotocol/sdk/types.js';
8
8
  import '@modelcontextprotocol/sdk/shared/auth.js';
9
9
  import '@modelcontextprotocol/sdk/client/auth.js';
@@ -11,161 +11,59 @@ import '@modelcontextprotocol/sdk/client/auth.js';
11
11
  /**
12
12
  * AG-UI Middleware for MCP Tool Execution
13
13
  *
14
- * This middleware intercepts tool calls from remote agents (e.g., LangGraph, AutoGen)
15
- * and executes MCP tools server-side, returning results back to the agent.
14
+ * This middleware intercepts tool calls from remote agents and executes
15
+ * MCP tools server-side, returning results back to the agent.
16
16
  *
17
- * ## How It Works
18
- *
19
- * 1. **Tool Injection**: When a run starts, the middleware injects MCP tool definitions
20
- * into `input.tools` so the remote agent knows about available MCP tools.
21
- *
22
- * 2. **Event Interception**: The middleware subscribes to the agent's event stream and
23
- * tracks tool calls using AG-UI events:
24
- * - `TOOL_CALL_START`: Records tool name and ID
25
- * - `TOOL_CALL_ARGS`: Accumulates streamed arguments
26
- * - `TOOL_CALL_END`: Marks tool call as complete
27
- * - `RUN_FINISHED`: Triggers execution of pending MCP tools
28
- *
29
- * 3. **Server-Side Execution**: When `RUN_FINISHED` arrives with pending MCP tool calls,
30
- * the middleware:
31
- * - Executes each MCP tool via the MCP client
32
- * - Emits `TOOL_CALL_RESULT` events with the results
33
- * - Adds results to `input.messages` for context
34
- * - Emits `RUN_FINISHED` to close the current run
35
- * - Triggers a new run so the agent can process tool results
36
- *
37
- * 4. **Recursive Processing**: If the new run makes more MCP tool calls, the cycle
38
- * repeats until the agent completes without pending MCP calls.
39
- *
40
- * ## Tool Identification
41
- *
42
- * MCP tools are identified by a configurable prefix (default: `server-`).
43
- * Tools not matching this prefix are passed through without interception.
44
- *
45
- * @requires @ag-ui/client - This middleware requires @ag-ui/client as a peer dependency
17
+ * @requires @ag-ui/client - Peer dependency for AG-UI types
46
18
  * @requires rxjs - Uses RxJS Observables for event streaming
47
- *
48
- * @example
49
- * ```typescript
50
- * import { HttpAgent } from '@ag-ui/client';
51
- * import { McpMiddleware } from '@mcp-ts/sdk/adapters/agui-middleware';
52
- * import { AguiAdapter } from '@mcp-ts/sdk/adapters/agui-adapter';
53
- *
54
- * // Create MCP client and adapter
55
- * const mcpClient = new MultiSessionClient('user_123');
56
- * await mcpClient.connect();
57
- *
58
- * const adapter = new AguiAdapter(mcpClient);
59
- * const actions = await adapter.getActions();
60
- *
61
- * // Create middleware with pre-loaded actions
62
- * const middleware = new McpMiddleware({
63
- * client: mcpClient,
64
- * actions,
65
- * toolPrefix: 'server-',
66
- * });
67
- *
68
- * // Use with HttpAgent
69
- * const agent = new HttpAgent({ url: 'http://localhost:8000/agent' });
70
- * agent.use(middleware);
71
- * ```
72
19
  */
73
20
 
21
+ /** New event type for MCP UI triggers */
22
+ declare const MCP_APP_UI_EVENT = "mcp-apps-ui";
74
23
  /**
75
- * Tool definition format for AG-UI input.tools
24
+ * MCP Apps UI trigger event.
25
+ *
26
+ * IMPORTANT: This must be emitted as an AG-UI CustomEvent so subscribers
27
+ * (e.g. CopilotKit `onCustomEvent`) can receive it.
76
28
  */
77
- interface AgUiTool {
78
- name: string;
79
- description: string;
80
- parameters?: Record<string, any>;
29
+ interface McpAppUiEventPayload {
30
+ toolCallId: string;
31
+ resourceUri: string;
32
+ sessionId?: string;
33
+ toolName: string;
34
+ result?: any;
81
35
  }
82
36
  /**
83
37
  * Configuration for McpMiddleware
84
38
  */
85
39
  interface McpMiddlewareConfig {
86
- /**
87
- * MCP client or MultiSessionClient for executing tools
88
- */
89
- client: MCPClient | MultiSessionClient;
90
- /**
91
- * Prefix used to identify MCP tool names.
92
- * Tools starting with this prefix will be executed server-side.
93
- * @default 'server-'
94
- */
95
- toolPrefix?: string;
96
- /**
97
- * Pre-loaded tools with handlers for execution.
98
- * If not provided, tools will be loaded from the MCP client on first use.
99
- */
100
- tools?: AguiTool[];
40
+ /** Pre-loaded tools with handlers (required) */
41
+ tools: AguiTool[];
101
42
  }
102
43
  /**
103
44
  * AG-UI Middleware that executes MCP tools server-side.
104
- *
105
- * This middleware intercepts tool calls for MCP tools (identified by prefix),
106
- * executes them via the MCP client, and returns results to the agent.
107
- *
108
- * @see {@link createMcpMiddleware} for a simpler factory function
109
45
  */
110
46
  declare class McpMiddleware extends Middleware {
111
- private client;
112
- private toolPrefix;
113
- private actions;
114
47
  private tools;
115
- private actionsLoaded;
48
+ private toolSchemas;
116
49
  constructor(config: McpMiddlewareConfig);
117
- /**
118
- * Convert actions to AG-UI tool format
119
- */
120
- private actionsToTools;
121
- /**
122
- * Check if a tool name is an MCP tool (matches the configured prefix)
123
- */
124
50
  private isMcpTool;
125
- /**
126
- * Load actions from the MCP client if not already loaded
127
- */
128
- private ensureActionsLoaded;
129
- /**
130
- * Execute an MCP tool and return the result as a string
131
- */
51
+ private parseArgs;
132
52
  private executeTool;
133
- /**
134
- * Generate a unique message ID for tool results
135
- */
136
- private generateMessageId;
137
- /**
138
- * Run the middleware, intercepting and executing MCP tool calls
139
- */
53
+ private generateId;
54
+ private ensureIds;
55
+ /** Process tool call events and update state */
56
+ private handleToolCallEvent;
57
+ /** Execute pending MCP tools and return results */
58
+ private executeTools;
59
+ private emitToolResults;
140
60
  run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent>;
141
- private triggerNewRun;
142
- private handlePendingCalls;
143
61
  }
144
62
  /**
145
63
  * Factory function to create MCP middleware.
146
- *
147
- * This is a convenience wrapper around McpMiddleware that returns a function
148
- * compatible with the AG-UI middleware pattern.
149
- *
150
- * @param client - MCP client or MultiSessionClient
151
- * @param options - Configuration options
152
- * @returns Middleware function
153
- *
154
- * @example
155
- * ```typescript
156
- * import { HttpAgent } from '@ag-ui/client';
157
- * import { createMcpMiddleware } from '@mcp-ts/sdk/adapters/agui-middleware';
158
- *
159
- * const agent = new HttpAgent({ url: 'http://localhost:8000/agent' });
160
- * agent.use(createMcpMiddleware(multiSessionClient, {
161
- * toolPrefix: 'server-',
162
- * actions: mcpActions,
163
- * }));
164
- * ```
165
64
  */
166
- declare function createMcpMiddleware(client: MCPClient | MultiSessionClient, options?: {
167
- toolPrefix?: string;
168
- tools?: AguiTool[];
65
+ declare function createMcpMiddleware(options: {
66
+ tools: AguiTool[];
169
67
  }): (input: RunAgentInput, next: AbstractAgent) => Observable<BaseEvent>;
170
68
 
171
- export { type AgUiTool, McpMiddleware, type McpMiddlewareConfig, McpMiddleware as McpToolExecutorMiddleware, createMcpMiddleware, createMcpMiddleware as createMcpToolMiddleware };
69
+ export { MCP_APP_UI_EVENT, type McpAppUiEventPayload, McpMiddleware, type McpMiddlewareConfig, McpMiddleware as McpToolExecutorMiddleware, createMcpMiddleware, createMcpMiddleware as createMcpToolMiddleware };