@mcp-ts/sdk 1.2.0 → 1.3.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.
package/README.md CHANGED
@@ -22,6 +22,9 @@
22
22
  <a href="https://www.npmjs.com/package/@mcp-ts/sdk">
23
23
  <img src="https://img.shields.io/npm/v/@mcp-ts/sdk.svg" alt="npm version" />
24
24
  </a>
25
+ <a href="https://zonlabs.github.io/mcp-ts/">
26
+ <img src="https://img.shields.io/badge/docs-website-brightgreen.svg" alt="Documentation" />
27
+ </a>
25
28
  <a href="https://opensource.org/licenses/MIT">
26
29
  <img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT" />
27
30
  </a>
@@ -119,15 +122,11 @@ import { openai } from '@ai-sdk/openai';
119
122
 
120
123
  export async function POST(req: Request) {
121
124
  const { messages, identity } = await req.json();
122
-
123
125
  const client = new MultiSessionClient(identity);
124
126
 
125
127
  try {
126
128
  await client.connect();
127
-
128
129
  const tools = await AIAdapter.getTools(client);
129
-
130
-
131
130
  const result = streamText({
132
131
  model: openai('gpt-4'),
133
132
  messages,
@@ -136,7 +135,6 @@ export async function POST(req: Request) {
136
135
  await mcp.disconnect();
137
136
  }
138
137
  });
139
-
140
138
  return result.toDataStreamResponse();
141
139
  } catch (error) {
142
140
  await mcp.disconnect();
@@ -145,41 +143,47 @@ export async function POST(req: Request) {
145
143
  }
146
144
  ```
147
145
 
148
- ### Client-Side (React)
149
-
150
- ```typescript
151
- 'use client';
152
- import { useMcp } from '@mcp-ts/sdk/client';
153
-
154
- function App() {
155
- const { connections, connect, status } = useMcp({
156
- url: '/api/mcp',
157
- identity: 'user-123',
158
- });
159
-
160
- return (
161
- <div>
162
- <p>Status: {status}</p>
163
- <button onClick={() => connect({
164
- serverId: 'my-server',
165
- serverName: 'My MCP Server',
166
- serverUrl: 'https://mcp.example.com',
167
- callbackUrl: window.location.origin + '/callback',
168
- })}>
169
- Connect
170
- </button>
171
-
172
- {connections.map(conn => (
173
- <div key={conn.sessionId}>
174
- <h3>{conn.serverName}</h3>
175
- <p>State: {conn.state}</p>
176
- <p>Tools: {conn.tools.length}</p>
177
- </div>
178
- ))}
179
- </div>
180
- );
181
- }
182
- ```
146
+ ### Client-Side (React)
147
+
148
+ ```typescript
149
+ 'use client';
150
+
151
+ import { useMcp } from '@mcp-ts/sdk/client/react';
152
+
153
+ function App() {
154
+ const { connections, connect, status } = useMcp({
155
+ url: '/api/mcp',
156
+ identity: 'user-123',
157
+ });
158
+
159
+ return (
160
+ <>
161
+ <p>Status: {status}</p>
162
+
163
+ <button
164
+ onClick={() =>
165
+ connect({
166
+ serverId: 'my-server',
167
+ serverName: 'My MCP Server',
168
+ serverUrl: 'https://mcp.example.com',
169
+ callbackUrl: `${window.location.origin}/callback`,
170
+ })
171
+ }
172
+ >
173
+ Connect
174
+ </button>
175
+
176
+ {connections.map((conn) => (
177
+ <div key={conn.sessionId}>
178
+ <h3>{conn.serverName}</h3>
179
+ <p>State: {conn.state}</p>
180
+ <p>Tools: {conn.tools.length}</p>
181
+ </div>
182
+ ))}
183
+ </>
184
+ );
185
+ }
186
+ ```
183
187
 
184
188
  ### <img src="docs/static/img/agent-framework/agui.webp" width="20" height="20" align="center" /> AG-UI Middleware
185
189
 
@@ -18,21 +18,6 @@ import '@modelcontextprotocol/sdk/client/auth.js';
18
18
  * @requires rxjs - Uses RxJS Observables for event streaming
19
19
  */
20
20
 
21
- /** New event type for MCP UI triggers */
22
- declare const MCP_APP_UI_EVENT = "mcp-apps-ui";
23
- /**
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.
28
- */
29
- interface McpAppUiEventPayload {
30
- toolCallId: string;
31
- resourceUri: string;
32
- sessionId?: string;
33
- toolName: string;
34
- result?: any;
35
- }
36
21
  /**
37
22
  * Configuration for McpMiddleware
38
23
  */
@@ -47,11 +32,6 @@ declare class McpMiddleware extends Middleware {
47
32
  private tools;
48
33
  private toolSchemas;
49
34
  constructor(config: McpMiddlewareConfig);
50
- /**
51
- * Extract base tool name from prefixed format for event emission
52
- * e.g., "tool_abc123_get-time" -> "get-time"
53
- */
54
- private getBaseToolName;
55
35
  private isMcpTool;
56
36
  private parseArgs;
57
37
  private executeTool;
@@ -61,6 +41,7 @@ declare class McpMiddleware extends Middleware {
61
41
  private handleToolCallEvent;
62
42
  /** Execute pending MCP tools and return results */
63
43
  private executeTools;
44
+ /** Emit tool results (without RUN_FINISHED - that's emitted when truly done) */
64
45
  private emitToolResults;
65
46
  run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent>;
66
47
  }
@@ -71,4 +52,4 @@ declare function createMcpMiddleware(options: {
71
52
  tools: AguiTool[];
72
53
  }): (input: RunAgentInput, next: AbstractAgent) => Observable<BaseEvent>;
73
54
 
74
- export { MCP_APP_UI_EVENT, type McpAppUiEventPayload, McpMiddleware, type McpMiddlewareConfig, McpMiddleware as McpToolExecutorMiddleware, createMcpMiddleware, createMcpMiddleware as createMcpToolMiddleware };
55
+ export { McpMiddleware, type McpMiddlewareConfig, McpMiddleware as McpToolExecutorMiddleware, createMcpMiddleware, createMcpMiddleware as createMcpToolMiddleware };
@@ -18,21 +18,6 @@ import '@modelcontextprotocol/sdk/client/auth.js';
18
18
  * @requires rxjs - Uses RxJS Observables for event streaming
19
19
  */
20
20
 
21
- /** New event type for MCP UI triggers */
22
- declare const MCP_APP_UI_EVENT = "mcp-apps-ui";
23
- /**
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.
28
- */
29
- interface McpAppUiEventPayload {
30
- toolCallId: string;
31
- resourceUri: string;
32
- sessionId?: string;
33
- toolName: string;
34
- result?: any;
35
- }
36
21
  /**
37
22
  * Configuration for McpMiddleware
38
23
  */
@@ -47,11 +32,6 @@ declare class McpMiddleware extends Middleware {
47
32
  private tools;
48
33
  private toolSchemas;
49
34
  constructor(config: McpMiddlewareConfig);
50
- /**
51
- * Extract base tool name from prefixed format for event emission
52
- * e.g., "tool_abc123_get-time" -> "get-time"
53
- */
54
- private getBaseToolName;
55
35
  private isMcpTool;
56
36
  private parseArgs;
57
37
  private executeTool;
@@ -61,6 +41,7 @@ declare class McpMiddleware extends Middleware {
61
41
  private handleToolCallEvent;
62
42
  /** Execute pending MCP tools and return results */
63
43
  private executeTools;
44
+ /** Emit tool results (without RUN_FINISHED - that's emitted when truly done) */
64
45
  private emitToolResults;
65
46
  run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent>;
66
47
  }
@@ -71,4 +52,4 @@ declare function createMcpMiddleware(options: {
71
52
  tools: AguiTool[];
72
53
  }): (input: RunAgentInput, next: AbstractAgent) => Observable<BaseEvent>;
73
54
 
74
- export { MCP_APP_UI_EVENT, type McpAppUiEventPayload, McpMiddleware, type McpMiddlewareConfig, McpMiddleware as McpToolExecutorMiddleware, createMcpMiddleware, createMcpMiddleware as createMcpToolMiddleware };
55
+ export { McpMiddleware, type McpMiddlewareConfig, McpMiddleware as McpToolExecutorMiddleware, createMcpMiddleware, createMcpMiddleware as createMcpToolMiddleware };
@@ -56,7 +56,6 @@ function cleanSchema(schema) {
56
56
  }
57
57
 
58
58
  // src/adapters/agui-middleware.ts
59
- var MCP_APP_UI_EVENT = "mcp-apps-ui";
60
59
  var McpMiddleware = class extends client.Middleware {
61
60
  constructor(config) {
62
61
  super();
@@ -66,19 +65,9 @@ var McpMiddleware = class extends client.Middleware {
66
65
  this.toolSchemas = this.tools.map((t) => ({
67
66
  name: t.name,
68
67
  description: t.description,
69
- parameters: cleanSchema(t.parameters),
70
- _meta: t._meta
71
- // Include _meta in the tool definition passed to the agent
68
+ parameters: cleanSchema(t.parameters)
72
69
  }));
73
70
  }
74
- /**
75
- * Extract base tool name from prefixed format for event emission
76
- * e.g., "tool_abc123_get-time" -> "get-time"
77
- */
78
- getBaseToolName(toolName) {
79
- const match = toolName.match(/^tool_[^_]+_(.+)$/);
80
- return match ? match[1] : toolName;
81
- }
82
71
  isMcpTool(toolName) {
83
72
  return this.tools.some((t) => t.name === toolName);
84
73
  }
@@ -103,22 +92,17 @@ var McpMiddleware = class extends client.Middleware {
103
92
  async executeTool(toolName, args) {
104
93
  const tool = this.tools.find((t) => t.name === toolName);
105
94
  if (!tool?.handler) {
106
- return { resultStr: `Error: Tool ${tool ? "has no handler" : "not found"}: ${toolName}` };
95
+ return `Error: Tool ${tool ? "has no handler" : "not found"}: ${toolName}`;
107
96
  }
108
97
  try {
98
+ console.log(`[McpMiddleware] Executing tool: ${toolName}`, args);
109
99
  const result = await tool.handler(args);
110
- let resultStr;
111
- if (typeof result === "string") {
112
- resultStr = result;
113
- } else if (result && typeof result === "object") {
114
- resultStr = JSON.stringify(result);
115
- } else {
116
- resultStr = String(result);
117
- }
118
- return { resultStr, rawResult: result };
100
+ const resultStr = typeof result === "string" ? result : JSON.stringify(result);
101
+ console.log(`[McpMiddleware] Tool result:`, resultStr.slice(0, 200));
102
+ return resultStr;
119
103
  } catch (error) {
120
104
  console.error(`[McpMiddleware] Error executing tool:`, error);
121
- return { resultStr: `Error: ${error.message || String(error)}` };
105
+ return `Error: ${error.message || String(error)}`;
122
106
  }
123
107
  }
124
108
  generateId(prefix) {
@@ -145,6 +129,7 @@ var McpMiddleware = class extends client.Middleware {
145
129
  if (this.isMcpTool(e.toolCallName)) {
146
130
  pendingMcpCalls.add(e.toolCallId);
147
131
  }
132
+ console.log(`[McpMiddleware] TOOL_CALL_START: ${e.toolCallName} (id: ${e.toolCallId}, isMCP: ${this.isMcpTool(e.toolCallName)})`);
148
133
  }
149
134
  }
150
135
  if (event.type === client.EventType.TOOL_CALL_ARGS) {
@@ -154,7 +139,10 @@ var McpMiddleware = class extends client.Middleware {
154
139
  toolCallArgsBuffer.set(e.toolCallId, existing + e.delta);
155
140
  }
156
141
  }
157
- if (event.type === client.EventType.TOOL_CALL_END) ;
142
+ if (event.type === client.EventType.TOOL_CALL_END) {
143
+ const e = event;
144
+ console.log(`[McpMiddleware] TOOL_CALL_END: ${toolCallNames.get(e.toolCallId) ?? "unknown"} (id: ${e.toolCallId})`);
145
+ }
158
146
  if (event.type === client.EventType.MESSAGES_SNAPSHOT) {
159
147
  const messages = event.messages || [];
160
148
  if (messages.length > 0) {
@@ -172,6 +160,7 @@ var McpMiddleware = class extends client.Middleware {
172
160
  toolCallArgsBuffer.set(tc.id, tc.function.arguments || "{}");
173
161
  if (this.isMcpTool(tc.function.name)) {
174
162
  pendingMcpCalls.add(tc.id);
163
+ console.log(`[McpMiddleware] MESSAGES_SNAPSHOT: Discovered ${tc.function.name} (id: ${tc.id})`);
175
164
  }
176
165
  }
177
166
  }
@@ -189,12 +178,12 @@ var McpMiddleware = class extends client.Middleware {
189
178
  const toolName = toolCallNames.get(toolCallId);
190
179
  if (!toolName) return;
191
180
  const args = this.parseArgs(toolCallArgsBuffer.get(toolCallId) || "{}");
192
- const { resultStr, rawResult } = await this.executeTool(toolName, args);
181
+ console.log(`[McpMiddleware] Executing pending tool: ${toolName}`);
182
+ const result = await this.executeTool(toolName, args);
193
183
  results.push({
194
184
  toolCallId,
195
185
  toolName,
196
- result: resultStr,
197
- rawResult,
186
+ result,
198
187
  messageId: this.generateId("mcp_result")
199
188
  });
200
189
  pendingMcpCalls.delete(toolCallId);
@@ -202,29 +191,9 @@ var McpMiddleware = class extends client.Middleware {
202
191
  await Promise.all(promises);
203
192
  return results;
204
193
  }
194
+ /** Emit tool results (without RUN_FINISHED - that's emitted when truly done) */
205
195
  emitToolResults(observer, results) {
206
- for (const { toolCallId, toolName, result, rawResult, messageId } of results) {
207
- const toolDef = this.tools.find((t) => t.name === toolName);
208
- const sessionId = toolDef?._meta?.sessionId;
209
- const resourceUri = rawResult?._meta?.ui?.resourceUri ?? rawResult?._meta?.["ui/resourceUri"] ?? toolDef?._meta?.ui?.resourceUri ?? toolDef?._meta?.["ui/resourceUri"];
210
- if (resourceUri) {
211
- const baseToolName = this.getBaseToolName(toolName);
212
- const payload = {
213
- toolCallId,
214
- resourceUri,
215
- sessionId,
216
- toolName: baseToolName,
217
- // Use base name to match metadata
218
- result: rawResult ?? result
219
- };
220
- observer.next({
221
- type: client.EventType.CUSTOM,
222
- name: MCP_APP_UI_EVENT,
223
- value: payload,
224
- timestamp: Date.now(),
225
- role: "tool"
226
- });
227
- }
196
+ for (const { toolCallId, toolName, result, messageId } of results) {
228
197
  observer.next({
229
198
  type: client.EventType.TOOL_CALL_RESULT,
230
199
  toolCallId,
@@ -233,6 +202,7 @@ var McpMiddleware = class extends client.Middleware {
233
202
  role: "tool",
234
203
  timestamp: Date.now()
235
204
  });
205
+ console.log(`[McpMiddleware] Emitting TOOL_CALL_RESULT for: ${toolName}`);
236
206
  }
237
207
  }
238
208
  run(input, next) {
@@ -246,8 +216,12 @@ var McpMiddleware = class extends client.Middleware {
246
216
  };
247
217
  this.ensureIds(input);
248
218
  const anyInput = input;
219
+ console.log(`[McpMiddleware] === NEW RUN ===`);
220
+ console.log(`[McpMiddleware] threadId: ${anyInput.threadId}, runId: ${anyInput.runId}`);
221
+ console.log(`[McpMiddleware] messages: ${input.messages?.length ?? 0}, tools: ${this.tools?.length ?? 0}`);
249
222
  if (this.toolSchemas?.length) {
250
223
  input.tools = [...input.tools || [], ...this.toolSchemas];
224
+ console.log(`[McpMiddleware] Injected ${this.toolSchemas.length} tools:`, this.toolSchemas.map((t) => t.name));
251
225
  }
252
226
  const handleRunFinished = async () => {
253
227
  if (state.error) return;
@@ -261,6 +235,7 @@ var McpMiddleware = class extends client.Middleware {
261
235
  observer.complete();
262
236
  return;
263
237
  }
238
+ console.log(`[McpMiddleware] RUN_FINISHED with ${state.pendingMcpCalls.size} pending calls`);
264
239
  const toolCalls = [];
265
240
  for (const toolCallId of state.pendingMcpCalls) {
266
241
  const name = state.toolCallNames.get(toolCallId);
@@ -282,9 +257,11 @@ var McpMiddleware = class extends client.Middleware {
282
257
  tool_calls: toolCalls.length > 0 ? toolCalls : void 0
283
258
  };
284
259
  input.messages.push(assistantMsg);
260
+ console.log(`[McpMiddleware] Added assistant message to history before tools: ${state.textContent?.slice(0, 50)}... [${toolCalls.length} tools]`);
285
261
  }
286
262
  const results = await this.executeTools(state);
287
263
  this.emitToolResults(observer, results);
264
+ console.log(`[McpMiddleware] Triggering continuation with ${results.length} results`);
288
265
  for (const { toolCallId, result, messageId } of results) {
289
266
  input.messages.push({
290
267
  id: messageId,
@@ -297,17 +274,20 @@ var McpMiddleware = class extends client.Middleware {
297
274
  state.toolCallNames.clear();
298
275
  state.textContent = "";
299
276
  anyInput.runId = this.generateId("mcp_run");
277
+ console.log(`[McpMiddleware] === CONTINUATION RUN === messages: ${input.messages.length}`);
300
278
  next.run(input).subscribe({
301
279
  next: (event) => {
302
280
  if (state.error) return;
303
281
  this.handleToolCallEvent(event, state);
304
282
  if (event.type === client.EventType.RUN_ERROR) {
283
+ console.log(`[McpMiddleware] RUN_ERROR received in continuation`);
305
284
  state.error = true;
306
285
  observer.next(event);
307
286
  observer.complete();
308
287
  return;
309
288
  }
310
289
  if (event.type === client.EventType.RUN_STARTED) {
290
+ console.log(`[McpMiddleware] Filtering RUN_STARTED from continuation`);
311
291
  return;
312
292
  }
313
293
  if (event.type === client.EventType.RUN_FINISHED) {
@@ -335,6 +315,7 @@ var McpMiddleware = class extends client.Middleware {
335
315
  if (state.error) return;
336
316
  this.handleToolCallEvent(event, state);
337
317
  if (event.type === client.EventType.RUN_ERROR) {
318
+ console.log(`[McpMiddleware] RUN_ERROR received`);
338
319
  state.error = true;
339
320
  observer.next(event);
340
321
  observer.complete();
@@ -373,7 +354,6 @@ Object.defineProperty(exports, "Middleware", {
373
354
  enumerable: true,
374
355
  get: function () { return client.Middleware; }
375
356
  });
376
- exports.MCP_APP_UI_EVENT = MCP_APP_UI_EVENT;
377
357
  exports.McpMiddleware = McpMiddleware;
378
358
  exports.McpToolExecutorMiddleware = McpMiddleware;
379
359
  exports.createMcpMiddleware = createMcpMiddleware;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/adapters/agui-adapter.ts","../../src/adapters/agui-middleware.ts"],"names":["Middleware","EventType","Observable"],"mappings":"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","file":"agui-middleware.js","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 // Call the actual MCP tool\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","/**\r\n * AG-UI Middleware for MCP Tool Execution\r\n *\r\n * This middleware intercepts tool calls from remote agents and executes\r\n * MCP tools server-side, returning results back to the agent.\r\n *\r\n * @requires @ag-ui/client - Peer dependency for AG-UI types\r\n * @requires rxjs - Uses RxJS Observables for event streaming\r\n */\r\n\r\nimport { Observable, Subscriber } from 'rxjs';\r\nimport {\r\n Middleware,\r\n EventType,\r\n type AbstractAgent,\r\n type RunAgentInput,\r\n type BaseEvent,\r\n type ToolCallEndEvent,\r\n type Tool,\r\n} from '@ag-ui/client';\r\nimport { type AguiTool, cleanSchema } from './agui-adapter.js';\r\n\r\n/** New event type for MCP UI triggers */\r\nexport const MCP_APP_UI_EVENT = 'mcp-apps-ui';\r\n/**\r\n * MCP Apps UI trigger event.\r\n *\r\n * IMPORTANT: This must be emitted as an AG-UI CustomEvent so subscribers\r\n * (e.g. CopilotKit `onCustomEvent`) can receive it.\r\n */\r\nexport interface McpAppUiEventPayload {\r\n toolCallId: string;\r\n resourceUri: string;\r\n sessionId?: string;\r\n toolName: string;\r\n result?: any;\r\n}\r\n\r\n/** Tool execution result for continuation */\r\ninterface ToolResult {\r\n toolCallId: string;\r\n toolName: string;\r\n result: string;\r\n /**\r\n * Raw result object (if available).\r\n * Used to preserve metadata (e.g. `_meta`) that is lost in the stringified `result`.\r\n */\r\n rawResult?: any;\r\n messageId: string;\r\n}\r\n\r\n/** State for tracking tool calls during a run */\r\ninterface RunState {\r\n toolCallArgsBuffer: Map<string, string>;\r\n toolCallNames: Map<string, string>;\r\n pendingMcpCalls: Set<string>;\r\n textContent?: string;\r\n error: boolean;\r\n}\r\n\r\n/**\r\n * Configuration for McpMiddleware\r\n */\r\nexport interface McpMiddlewareConfig {\r\n /** Pre-loaded tools with handlers (required) */\r\n tools: AguiTool[];\r\n}\r\n\r\n/**\r\n * AG-UI Middleware that executes MCP tools server-side.\r\n */\r\nexport class McpMiddleware extends Middleware {\r\n private tools: AguiTool[];\r\n private toolSchemas: Tool[];\r\n\r\n constructor(config: McpMiddlewareConfig) {\r\n super();\r\n this.tools = config.tools;\r\n this.toolSchemas = this.tools.map((t: AguiTool) => ({\r\n name: t.name,\r\n description: t.description,\r\n parameters: cleanSchema(t.parameters),\r\n _meta: t._meta, // Include _meta in the tool definition passed to the agent\r\n }));\r\n }\r\n\r\n /**\r\n * Extract base tool name from prefixed format for event emission\r\n * e.g., \"tool_abc123_get-time\" -> \"get-time\"\r\n */\r\n private getBaseToolName(toolName: string): string {\r\n const match = toolName.match(/^tool_[^_]+_(.+)$/);\r\n return match ? match[1] : toolName;\r\n }\r\n\r\n private isMcpTool(toolName: string): boolean {\r\n // Direct comparison - tool names should match as-is\r\n return this.tools.some(t => t.name === toolName);\r\n }\r\n\r\n private parseArgs(argsString: string): Record<string, any> {\r\n if (!argsString?.trim()) return {};\r\n\r\n try {\r\n return JSON.parse(argsString);\r\n } catch {\r\n // Handle duplicated JSON from streaming issues: {...}{...}\r\n const trimmed = argsString.trim();\r\n if (trimmed.includes('}{')) {\r\n const firstObject = trimmed.slice(0, trimmed.indexOf('}{') + 1);\r\n try {\r\n return JSON.parse(firstObject);\r\n } catch {\r\n console.error(`[McpMiddleware] Failed to parse JSON:`, firstObject);\r\n }\r\n }\r\n console.error(`[McpMiddleware] Failed to parse args:`, argsString);\r\n return {};\r\n }\r\n }\r\n\r\n private async executeTool(toolName: string, args: Record<string, any>): Promise<{ resultStr: string, rawResult?: any }> {\r\n const tool = this.tools.find(t => t.name === toolName);\r\n if (!tool?.handler) {\r\n return { resultStr: `Error: Tool ${tool ? 'has no handler' : 'not found'}: ${toolName}` };\r\n }\r\n\r\n try {\r\n // Result can be a string (legacy) or an object (MCP Result with content array)\r\n const result = await tool.handler(args);\r\n\r\n let resultStr: string;\r\n\r\n if (typeof result === 'string') {\r\n resultStr = result;\r\n } else if (result && typeof result === 'object') {\r\n // Determine if we should preserve the object structure (e.g. for MCP Tool Results)\r\n resultStr = JSON.stringify(result);\r\n } else {\r\n resultStr = String(result);\r\n }\r\n\r\n return { resultStr, rawResult: result };\r\n } catch (error: any) {\r\n console.error(`[McpMiddleware] Error executing tool:`, error);\r\n return { resultStr: `Error: ${error.message || String(error)}` };\r\n }\r\n }\r\n\r\n private generateId(prefix: string): string {\r\n return `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;\r\n }\r\n\r\n private ensureIds(input: RunAgentInput): void {\r\n const anyInput = input as any;\r\n if (!anyInput.threadId) anyInput.threadId = this.generateId('mcp_thread');\r\n if (!anyInput.runId) anyInput.runId = this.generateId('mcp_run');\r\n }\r\n\r\n /** Process tool call events and update state */\r\n private handleToolCallEvent(event: BaseEvent, state: RunState): void {\r\n const { toolCallArgsBuffer, toolCallNames, pendingMcpCalls } = state;\r\n\r\n // Accumulate text content for reconstruction\r\n if (event.type === EventType.TEXT_MESSAGE_CHUNK) {\r\n const e = event as any;\r\n if (e.delta) {\r\n state.textContent = (state.textContent || '') + e.delta;\r\n }\r\n }\r\n\r\n if (event.type === EventType.TOOL_CALL_START) {\r\n const e = event as any;\r\n if (e.toolCallId && e.toolCallName) {\r\n toolCallNames.set(e.toolCallId, e.toolCallName);\r\n if (this.isMcpTool(e.toolCallName)) {\r\n pendingMcpCalls.add(e.toolCallId);\r\n }\r\n }\r\n }\r\n\r\n if (event.type === EventType.TOOL_CALL_ARGS) {\r\n const e = event as any;\r\n if (e.toolCallId && e.delta) {\r\n const existing = toolCallArgsBuffer.get(e.toolCallId) || '';\r\n toolCallArgsBuffer.set(e.toolCallId, existing + e.delta);\r\n }\r\n }\r\n\r\n if (event.type === EventType.TOOL_CALL_END) {\r\n // Track tool call end event\r\n }\r\n\r\n // Workaround: Extract parallel tool calls from MESSAGES_SNAPSHOT\r\n if (event.type === EventType.MESSAGES_SNAPSHOT) {\r\n const messages = (event as any).messages || [];\r\n if (messages.length > 0) {\r\n const lastMsg = messages[messages.length - 1];\r\n // Update text content from snapshot if available (often more reliable)\r\n if (lastMsg.role === 'assistant' && lastMsg.content) {\r\n state.textContent = lastMsg.content;\r\n }\r\n\r\n // Discover tools\r\n for (let i = messages.length - 1; i >= 0; i--) {\r\n const msg = messages[i];\r\n const tools = Array.isArray(msg.toolCalls) ? msg.toolCalls :\r\n (Array.isArray(msg.tool_calls) ? msg.tool_calls : []);\r\n\r\n if (msg.role === 'assistant' && tools.length > 0) {\r\n for (const tc of tools) {\r\n if (tc.id && tc.function?.name && !toolCallNames.has(tc.id)) {\r\n toolCallNames.set(tc.id, tc.function.name);\r\n toolCallArgsBuffer.set(tc.id, tc.function.arguments || '{}');\r\n if (this.isMcpTool(tc.function.name)) {\r\n pendingMcpCalls.add(tc.id);\r\n }\r\n }\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /** Execute pending MCP tools and return results */\r\n private async executeTools(state: RunState): Promise<ToolResult[]> {\r\n const { toolCallArgsBuffer, toolCallNames, pendingMcpCalls } = state;\r\n const results: ToolResult[] = [];\r\n\r\n const promises = [...pendingMcpCalls].map(async (toolCallId) => {\r\n const toolName = toolCallNames.get(toolCallId);\r\n if (!toolName) return;\r\n\r\n const args = this.parseArgs(toolCallArgsBuffer.get(toolCallId) || '{}');\r\n const { resultStr, rawResult } = await this.executeTool(toolName, args);\r\n results.push({\r\n toolCallId,\r\n toolName,\r\n result: resultStr,\r\n rawResult,\r\n messageId: this.generateId('mcp_result'),\r\n });\r\n pendingMcpCalls.delete(toolCallId);\r\n });\r\n\r\n await Promise.all(promises);\r\n return results;\r\n }\r\n\r\n private emitToolResults(observer: Subscriber<BaseEvent>, results: ToolResult[]): void {\r\n for (const { toolCallId, toolName, result, rawResult, messageId } of results) {\r\n // UI metadata may appear either on the tool CALL result (rawResult._meta)\r\n // or only on the tool DEFINITION (listTools result). We support both.\r\n const toolDef = this.tools.find(t => t.name === toolName);\r\n const sessionId = toolDef?._meta?.sessionId;\r\n const resourceUri =\r\n rawResult?._meta?.ui?.resourceUri ??\r\n rawResult?._meta?.['ui/resourceUri'] ??\r\n toolDef?._meta?.ui?.resourceUri ??\r\n toolDef?._meta?.['ui/resourceUri'];\r\n\r\n if (resourceUri) {\r\n // Extract base name for event emission to match metadata\r\n const baseToolName = this.getBaseToolName(toolName);\r\n\r\n const payload: McpAppUiEventPayload = {\r\n toolCallId,\r\n resourceUri,\r\n sessionId,\r\n toolName: baseToolName, // Use base name to match metadata\r\n result: rawResult ?? result,\r\n };\r\n\r\n observer.next({\r\n type: EventType.CUSTOM,\r\n name: MCP_APP_UI_EVENT,\r\n value: payload,\r\n timestamp: Date.now(),\r\n role: 'tool',\r\n } as any);\r\n }\r\n\r\n observer.next({\r\n type: EventType.TOOL_CALL_RESULT,\r\n toolCallId,\r\n messageId,\r\n content: result,\r\n role: 'tool',\r\n timestamp: Date.now(),\r\n } as any);\r\n }\r\n }\r\n\r\n run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent> {\r\n return new Observable<BaseEvent>((observer: Subscriber<BaseEvent>) => {\r\n const state: RunState = {\r\n toolCallArgsBuffer: new Map(),\r\n toolCallNames: new Map(),\r\n pendingMcpCalls: new Set(),\r\n textContent: '',\r\n error: false,\r\n };\r\n\r\n this.ensureIds(input);\r\n const anyInput = input as any;\r\n\r\n // Inject MCP tools\r\n if (this.toolSchemas?.length) {\r\n input.tools = [...(input.tools || []), ...this.toolSchemas];\r\n }\r\n\r\n const handleRunFinished = async () => {\r\n if (state.error) return; // Don't continue after error\r\n\r\n if (state.pendingMcpCalls.size === 0) {\r\n observer.next({\r\n type: EventType.RUN_FINISHED,\r\n threadId: anyInput.threadId,\r\n runId: anyInput.runId,\r\n timestamp: Date.now(),\r\n } as any);\r\n observer.complete();\r\n return;\r\n }\r\n\r\n // Reconstruct the Assistant Message that triggered these tools\r\n const toolCalls = [];\r\n for (const toolCallId of state.pendingMcpCalls) {\r\n const name = state.toolCallNames.get(toolCallId);\r\n const args = state.toolCallArgsBuffer.get(toolCallId) || '{}';\r\n if (name) {\r\n toolCalls.push({\r\n id: toolCallId,\r\n type: 'function',\r\n function: { name, arguments: args }\r\n });\r\n }\r\n }\r\n\r\n // Add the Assistant Message to history FIRST\r\n if (toolCalls.length > 0 || state.textContent) {\r\n const assistantMsg = {\r\n id: this.generateId('msg_ast'),\r\n role: 'assistant',\r\n content: state.textContent || null, // Ensure null if empty string for strict LLMs\r\n tool_calls: toolCalls.length > 0 ? toolCalls : undefined\r\n };\r\n input.messages.push(assistantMsg as any);\r\n }\r\n\r\n // Execute tools and emit results (no RUN_FINISHED yet - continuation follows)\r\n const results = await this.executeTools(state);\r\n this.emitToolResults(observer, results);\r\n\r\n // Add tool result messages to history\r\n for (const { toolCallId, result, messageId } of results) {\r\n input.messages.push({\r\n id: messageId,\r\n role: 'tool',\r\n tool_call_id: toolCallId,\r\n content: result,\r\n } as any);\r\n }\r\n\r\n // Reset state for next turn\r\n state.toolCallArgsBuffer.clear();\r\n state.toolCallNames.clear();\r\n state.textContent = ''; // Clear text content for next turn\r\n\r\n anyInput.runId = this.generateId('mcp_run');\r\n\r\n // Subscribe to continuation\r\n next.run(input).subscribe({\r\n next: (event) => {\r\n if (state.error) return;\r\n\r\n this.handleToolCallEvent(event, state);\r\n\r\n if (event.type === EventType.RUN_ERROR) {\r\n state.error = true;\r\n observer.next(event);\r\n observer.complete();\r\n return;\r\n }\r\n\r\n if (event.type === EventType.RUN_STARTED) {\r\n return;\r\n }\r\n\r\n if (event.type === EventType.RUN_FINISHED) {\r\n if (state.pendingMcpCalls.size > 0) {\r\n handleRunFinished();\r\n } else {\r\n observer.next(event);\r\n observer.complete();\r\n }\r\n return;\r\n }\r\n observer.next(event);\r\n },\r\n error: (err) => {\r\n state.error = true;\r\n observer.error(err);\r\n },\r\n complete: () => {\r\n if (!state.error && state.pendingMcpCalls.size === 0) observer.complete();\r\n },\r\n });\r\n };\r\n\r\n const subscription = next.run(input).subscribe({\r\n next: (event) => {\r\n if (state.error) return;\r\n\r\n this.handleToolCallEvent(event, state);\r\n\r\n if (event.type === EventType.RUN_ERROR) {\r\n state.error = true;\r\n observer.next(event);\r\n observer.complete();\r\n return;\r\n }\r\n\r\n if (event.type === EventType.RUN_FINISHED) {\r\n handleRunFinished();\r\n return;\r\n }\r\n observer.next(event);\r\n },\r\n error: (err) => {\r\n state.error = true;\r\n observer.error(err);\r\n },\r\n complete: () => {\r\n if (!state.error && state.pendingMcpCalls.size === 0) observer.complete();\r\n },\r\n });\r\n\r\n return () => subscription.unsubscribe();\r\n });\r\n }\r\n}\r\n\r\n/**\r\n * Factory function to create MCP middleware.\r\n */\r\nexport function createMcpMiddleware(options: { tools: AguiTool[] }) {\r\n const middleware = new McpMiddleware(options);\r\n return (input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent> => {\r\n return middleware.run(input, next);\r\n };\r\n}\r\n\r\n// Legacy exports\r\nexport { McpMiddleware as McpToolExecutorMiddleware };\r\nexport { createMcpMiddleware as createMcpToolMiddleware };\r\n\r\n// Re-exports\r\nexport { Middleware, EventType };\r\nexport type { RunAgentInput, BaseEvent, AbstractAgent, ToolCallEndEvent, Tool };\r\n"]}
1
+ {"version":3,"sources":["../../src/adapters/agui-adapter.ts","../../src/adapters/agui-middleware.ts"],"names":["Middleware","EventType","Observable"],"mappings":"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","file":"agui-middleware.js","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 // Call the actual MCP tool\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","/**\r\n * AG-UI Middleware for MCP Tool Execution\r\n *\r\n * This middleware intercepts tool calls from remote agents and executes\r\n * MCP tools server-side, returning results back to the agent.\r\n *\r\n * @requires @ag-ui/client - Peer dependency for AG-UI types\r\n * @requires rxjs - Uses RxJS Observables for event streaming\r\n */\r\n\r\nimport { Observable, Subscriber } from 'rxjs';\r\nimport {\r\n Middleware,\r\n EventType,\r\n type AbstractAgent,\r\n type RunAgentInput,\r\n type BaseEvent,\r\n type ToolCallEndEvent,\r\n type Tool,\r\n} from '@ag-ui/client';\r\nimport { type AguiTool, cleanSchema } from './agui-adapter.js';\r\n\r\n/** Tool execution result for continuation */\r\ninterface ToolResult {\r\n toolCallId: string;\r\n toolName: string;\r\n result: string;\r\n messageId: string;\r\n}\r\n\r\n/** State for tracking tool calls during a run */\r\ninterface RunState {\r\n toolCallArgsBuffer: Map<string, string>;\r\n toolCallNames: Map<string, string>;\r\n pendingMcpCalls: Set<string>;\r\n textContent?: string;\r\n error: boolean;\r\n}\r\n\r\n/**\n * Configuration for McpMiddleware\n */\nexport interface McpMiddlewareConfig {\n /** Pre-loaded tools with handlers (required) */\n tools: AguiTool[];\n}\n\r\n/**\r\n * AG-UI Middleware that executes MCP tools server-side.\r\n */\r\nexport class McpMiddleware extends Middleware {\n private tools: AguiTool[];\n private toolSchemas: Tool[];\n\n constructor(config: McpMiddlewareConfig) {\n super();\n this.tools = config.tools;\n this.toolSchemas = this.tools.map((t: AguiTool) => ({\n name: t.name,\n description: t.description,\n parameters: cleanSchema(t.parameters),\n }));\n }\n\r\n private isMcpTool(toolName: string): boolean {\r\n return this.tools.some(t => t.name === toolName);\r\n }\r\n\r\n private parseArgs(argsString: string): Record<string, any> {\r\n if (!argsString?.trim()) return {};\r\n\r\n try {\r\n return JSON.parse(argsString);\r\n } catch {\r\n // Handle duplicated JSON from streaming issues: {...}{...}\r\n const trimmed = argsString.trim();\r\n if (trimmed.includes('}{')) {\r\n const firstObject = trimmed.slice(0, trimmed.indexOf('}{') + 1);\r\n try {\r\n return JSON.parse(firstObject);\r\n } catch {\r\n console.error(`[McpMiddleware] Failed to parse JSON:`, firstObject);\r\n }\r\n }\r\n console.error(`[McpMiddleware] Failed to parse args:`, argsString);\r\n return {};\r\n }\r\n }\r\n\r\n private async executeTool(toolName: string, args: Record<string, any>): Promise<string> {\r\n const tool = this.tools.find(t => t.name === toolName);\r\n if (!tool?.handler) {\r\n return `Error: Tool ${tool ? 'has no handler' : 'not found'}: ${toolName}`;\r\n }\r\n\r\n try {\n console.log(`[McpMiddleware] Executing tool: ${toolName}`, args);\n const result = await tool.handler(args);\n const resultStr = typeof result === 'string' ? result : JSON.stringify(result);\n\n console.log(`[McpMiddleware] Tool result:`, resultStr.slice(0, 200));\n return resultStr;\n } catch (error: any) {\r\n console.error(`[McpMiddleware] Error executing tool:`, error);\r\n return `Error: ${error.message || String(error)}`;\r\n }\r\n }\r\n\r\n private generateId(prefix: string): string {\r\n return `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;\r\n }\r\n\r\n private ensureIds(input: RunAgentInput): void {\r\n const anyInput = input as any;\r\n if (!anyInput.threadId) anyInput.threadId = this.generateId('mcp_thread');\r\n if (!anyInput.runId) anyInput.runId = this.generateId('mcp_run');\r\n }\r\n\r\n /** Process tool call events and update state */\r\n private handleToolCallEvent(event: BaseEvent, state: RunState): void {\r\n const { toolCallArgsBuffer, toolCallNames, pendingMcpCalls } = state;\r\n\r\n // Accumulate text content for reconstruction\r\n if (event.type === EventType.TEXT_MESSAGE_CHUNK) {\r\n const e = event as any;\r\n if (e.delta) {\r\n state.textContent = (state.textContent || '') + e.delta;\r\n }\r\n }\r\n\r\n if (event.type === EventType.TOOL_CALL_START) {\r\n const e = event as any;\r\n if (e.toolCallId && e.toolCallName) {\r\n toolCallNames.set(e.toolCallId, e.toolCallName);\r\n if (this.isMcpTool(e.toolCallName)) {\r\n pendingMcpCalls.add(e.toolCallId);\r\n }\r\n console.log(`[McpMiddleware] TOOL_CALL_START: ${e.toolCallName} (id: ${e.toolCallId}, isMCP: ${this.isMcpTool(e.toolCallName)})`);\r\n }\r\n }\r\n\r\n if (event.type === EventType.TOOL_CALL_ARGS) {\r\n const e = event as any;\r\n if (e.toolCallId && e.delta) {\r\n const existing = toolCallArgsBuffer.get(e.toolCallId) || '';\r\n toolCallArgsBuffer.set(e.toolCallId, existing + e.delta);\r\n }\r\n }\r\n\r\n if (event.type === EventType.TOOL_CALL_END) {\r\n const e = event as ToolCallEndEvent;\r\n console.log(`[McpMiddleware] TOOL_CALL_END: ${toolCallNames.get(e.toolCallId) ?? 'unknown'} (id: ${e.toolCallId})`);\r\n }\r\n\r\n // Workaround: Extract parallel tool calls from MESSAGES_SNAPSHOT\r\n if (event.type === EventType.MESSAGES_SNAPSHOT) {\r\n const messages = (event as any).messages || [];\r\n if (messages.length > 0) {\r\n const lastMsg = messages[messages.length - 1];\r\n // Update text content from snapshot if available (often more reliable)\r\n if (lastMsg.role === 'assistant' && lastMsg.content) {\r\n state.textContent = lastMsg.content;\r\n }\r\n\r\n // Discover tools\r\n for (let i = messages.length - 1; i >= 0; i--) {\r\n const msg = messages[i];\r\n const tools = Array.isArray(msg.toolCalls) ? msg.toolCalls :\r\n (Array.isArray(msg.tool_calls) ? msg.tool_calls : []);\r\n\r\n if (msg.role === 'assistant' && tools.length > 0) {\r\n for (const tc of tools) {\r\n if (tc.id && tc.function?.name && !toolCallNames.has(tc.id)) {\r\n toolCallNames.set(tc.id, tc.function.name);\r\n toolCallArgsBuffer.set(tc.id, tc.function.arguments || '{}');\r\n if (this.isMcpTool(tc.function.name)) {\r\n pendingMcpCalls.add(tc.id);\r\n console.log(`[McpMiddleware] MESSAGES_SNAPSHOT: Discovered ${tc.function.name} (id: ${tc.id})`);\r\n }\r\n }\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n /** Execute pending MCP tools and return results */\r\n private async executeTools(state: RunState): Promise<ToolResult[]> {\r\n const { toolCallArgsBuffer, toolCallNames, pendingMcpCalls } = state;\r\n const results: ToolResult[] = [];\r\n\r\n const promises = [...pendingMcpCalls].map(async (toolCallId) => {\r\n const toolName = toolCallNames.get(toolCallId);\r\n if (!toolName) return;\r\n\r\n const args = this.parseArgs(toolCallArgsBuffer.get(toolCallId) || '{}');\r\n console.log(`[McpMiddleware] Executing pending tool: ${toolName}`);\r\n\r\n const result = await this.executeTool(toolName, args);\r\n results.push({\r\n toolCallId,\r\n toolName,\r\n result,\r\n messageId: this.generateId('mcp_result'),\r\n });\r\n pendingMcpCalls.delete(toolCallId);\r\n });\r\n\r\n await Promise.all(promises);\r\n return results;\r\n }\r\n\r\n /** Emit tool results (without RUN_FINISHED - that's emitted when truly done) */\r\n private emitToolResults(observer: Subscriber<BaseEvent>, results: ToolResult[]): void {\r\n for (const { toolCallId, toolName, result, messageId } of results) {\r\n observer.next({\r\n type: EventType.TOOL_CALL_RESULT,\r\n toolCallId,\r\n messageId,\r\n content: result,\r\n role: 'tool',\r\n timestamp: Date.now(),\r\n } as any);\r\n console.log(`[McpMiddleware] Emitting TOOL_CALL_RESULT for: ${toolName}`);\r\n }\r\n }\r\n\r\n run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent> {\r\n return new Observable<BaseEvent>((observer: Subscriber<BaseEvent>) => {\r\n const state: RunState = {\r\n toolCallArgsBuffer: new Map(),\r\n toolCallNames: new Map(),\r\n pendingMcpCalls: new Set(),\r\n textContent: '',\r\n error: false,\r\n };\r\n\r\n this.ensureIds(input);\r\n const anyInput = input as any;\r\n\r\n console.log(`[McpMiddleware] === NEW RUN ===`);\r\n console.log(`[McpMiddleware] threadId: ${anyInput.threadId}, runId: ${anyInput.runId}`);\r\n console.log(`[McpMiddleware] messages: ${input.messages?.length ?? 0}, tools: ${this.tools?.length ?? 0}`);\r\n\r\n // Inject MCP tools\r\n if (this.toolSchemas?.length) {\r\n input.tools = [...(input.tools || []), ...this.toolSchemas];\r\n console.log(`[McpMiddleware] Injected ${this.toolSchemas.length} tools:`, this.toolSchemas.map((t: Tool) => t.name));\r\n }\r\n\r\n const handleRunFinished = async () => {\r\n if (state.error) return; // Don't continue after error\r\n\r\n if (state.pendingMcpCalls.size === 0) {\r\n observer.next({\r\n type: EventType.RUN_FINISHED,\r\n threadId: anyInput.threadId,\r\n runId: anyInput.runId,\r\n timestamp: Date.now(),\r\n } as any);\r\n observer.complete();\r\n return;\r\n }\r\n\r\n console.log(`[McpMiddleware] RUN_FINISHED with ${state.pendingMcpCalls.size} pending calls`);\r\n\r\n // Reconstruct the Assistant Message that triggered these tools\r\n const toolCalls = [];\r\n for (const toolCallId of state.pendingMcpCalls) {\r\n const name = state.toolCallNames.get(toolCallId);\r\n const args = state.toolCallArgsBuffer.get(toolCallId) || '{}';\r\n if (name) {\r\n toolCalls.push({\r\n id: toolCallId,\r\n type: 'function',\r\n function: { name, arguments: args }\r\n });\r\n }\r\n }\r\n\r\n // Add the Assistant Message to history FIRST\r\n if (toolCalls.length > 0 || state.textContent) {\r\n const assistantMsg = {\r\n id: this.generateId('msg_ast'),\r\n role: 'assistant',\r\n content: state.textContent || null, // Ensure null if empty string for strict LLMs\r\n tool_calls: toolCalls.length > 0 ? toolCalls : undefined\r\n };\r\n input.messages.push(assistantMsg as any);\r\n console.log(`[McpMiddleware] Added assistant message to history before tools: ${state.textContent?.slice(0, 50)}... [${toolCalls.length} tools]`);\r\n }\r\n\r\n // Execute tools and emit results (no RUN_FINISHED yet - continuation follows)\r\n const results = await this.executeTools(state);\r\n this.emitToolResults(observer, results);\r\n\r\n // Prepare continuation\r\n console.log(`[McpMiddleware] Triggering continuation with ${results.length} results`);\r\n\r\n // Add tool result messages to history\r\n for (const { toolCallId, result, messageId } of results) {\r\n input.messages.push({\r\n id: messageId,\r\n role: 'tool',\r\n tool_call_id: toolCallId,\r\n content: result,\r\n } as any);\r\n }\r\n\r\n // Reset state for next turn\r\n state.toolCallArgsBuffer.clear();\r\n state.toolCallNames.clear();\r\n state.textContent = ''; // Clear text content for next turn\r\n\r\n anyInput.runId = this.generateId('mcp_run');\r\n console.log(`[McpMiddleware] === CONTINUATION RUN === messages: ${input.messages.length}`);\r\n\r\n // Subscribe to continuation\r\n next.run(input).subscribe({\r\n next: (event) => {\r\n if (state.error) return;\r\n\r\n this.handleToolCallEvent(event, state);\r\n\r\n if (event.type === EventType.RUN_ERROR) {\r\n console.log(`[McpMiddleware] RUN_ERROR received in continuation`);\r\n state.error = true;\r\n observer.next(event);\r\n observer.complete();\r\n return;\r\n }\r\n\r\n if (event.type === EventType.RUN_STARTED) {\r\n console.log(`[McpMiddleware] Filtering RUN_STARTED from continuation`);\r\n return;\r\n }\r\n\r\n if (event.type === EventType.RUN_FINISHED) {\r\n if (state.pendingMcpCalls.size > 0) {\r\n handleRunFinished();\r\n } else {\r\n observer.next(event);\r\n observer.complete();\r\n }\r\n return;\r\n }\r\n observer.next(event);\r\n },\r\n error: (err) => {\r\n state.error = true;\r\n observer.error(err);\r\n },\r\n complete: () => {\r\n if (!state.error && state.pendingMcpCalls.size === 0) observer.complete();\r\n },\r\n });\r\n };\r\n\r\n const subscription = next.run(input).subscribe({\r\n next: (event) => {\r\n if (state.error) return;\r\n\r\n this.handleToolCallEvent(event, state);\r\n\r\n if (event.type === EventType.RUN_ERROR) {\r\n console.log(`[McpMiddleware] RUN_ERROR received`);\r\n state.error = true;\r\n observer.next(event);\r\n observer.complete();\r\n return;\r\n }\r\n\r\n if (event.type === EventType.RUN_FINISHED) {\r\n handleRunFinished();\r\n return;\r\n }\r\n observer.next(event);\r\n },\r\n error: (err) => {\r\n state.error = true;\r\n observer.error(err);\r\n },\r\n complete: () => {\r\n if (!state.error && state.pendingMcpCalls.size === 0) observer.complete();\r\n },\r\n });\r\n\r\n return () => subscription.unsubscribe();\r\n });\r\n }\r\n}\r\n\r\n/**\r\n * Factory function to create MCP middleware.\r\n */\r\nexport function createMcpMiddleware(\n options: { tools: AguiTool[] }\n) {\n const middleware = new McpMiddleware(options);\r\n return (input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent> => {\r\n return middleware.run(input, next);\r\n };\r\n}\r\n\r\n// Legacy exports\r\nexport { McpMiddleware as McpToolExecutorMiddleware };\r\nexport { createMcpMiddleware as createMcpToolMiddleware };\r\n\r\n// Re-exports\r\nexport { Middleware, EventType };\r\nexport type { RunAgentInput, BaseEvent, AbstractAgent, ToolCallEndEvent, Tool };"]}