{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import {\n  Middleware,\n  RunAgentInput,\n  AbstractAgent,\n  BaseEvent,\n  Tool,\n  EventType,\n  Message,\n  ToolCall,\n  ToolCallResultEvent,\n  ActivitySnapshotEvent,\n  RunStartedEvent,\n  RunFinishedEvent,\n} from \"@ag-ui/client\";\nimport { Observable, from, switchMap } from \"rxjs\";\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport { SSEClientTransport } from \"@modelcontextprotocol/sdk/client/sse.js\";\nimport { StreamableHTTPClientTransport } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport { randomUUID, createHash } from \"crypto\";\n\n/**\n * Activity type for MCP Apps events\n */\nexport const MCPAppsActivityType = \"mcp-apps\";\n\n/**\n * Proxied MCP request structure from the frontend iframe\n */\nexport interface ProxiedMCPRequest {\n  /** Server hash (MD5 hash of config) */\n  serverHash: string;\n  /** Server name (optional, for lookup by name) */\n  serverId?: string;\n  /** The JSON-RPC method to call */\n  method: string;\n  /** The JSON-RPC params */\n  params?: Record<string, unknown>;\n}\n\n/**\n * Extract EventWithState type from Middleware.runNextWithState return type\n */\ntype ExtractObservableType<T> = T extends Observable<infer U> ? U : never;\ntype RunNextWithStateReturn = ReturnType<Middleware[\"runNextWithState\"]>;\nexport type EventWithState = ExtractObservableType<RunNextWithStateReturn>;\n\n/**\n * UI Tool with its source server config and resource URI\n */\ninterface UIToolInfo {\n  tool: Tool;\n  serverConfig: MCPClientConfig;\n  resourceUri: string;\n}\n\n/**\n * MCP Client configuration for HTTP transport\n */\nexport interface MCPClientConfigHTTP {\n  type: \"http\";\n  url: string;\n  serverId?: string;\n}\n\n/**\n * MCP Client configuration for SSE transport\n */\nexport interface MCPClientConfigSSE {\n  type: \"sse\";\n  url: string;\n  headers?: Record<string, string>;\n  serverId?: string;\n}\n\n/**\n * MCP Client configuration\n */\nexport type MCPClientConfig = MCPClientConfigHTTP | MCPClientConfigSSE;\n\n/**\n * Generate a stable server hash from config using MD5 hash.\n * This allows the frontend to reference servers without knowing their URLs.\n */\nexport function getServerHash(config: MCPClientConfig): string {\n  const serialized = JSON.stringify({\n    type: config.type,\n    url: config.url,\n    headers: config.type === \"sse\" ? (config as MCPClientConfigSSE).headers : undefined,\n  });\n  return createHash(\"md5\").update(serialized).digest(\"hex\");\n}\n\n/**\n * Configuration for MCPAppsMiddleware\n */\nexport interface MCPAppsMiddlewareConfig {\n  /**\n   * List of MCP server configurations\n   */\n  mcpServers?: MCPClientConfig[];\n}\n\n/**\n * Check if a tool has a UI resource attached (per SEP-1865)\n */\nfunction hasUIResource(tool: { _meta?: Record<string, unknown> }): boolean {\n  return typeof tool._meta?.[\"ui/resourceUri\"] === \"string\";\n}\n\n/**\n * Extended tool type that includes MCP Apps metadata\n */\nexport interface MCPAppTool extends Tool {\n  /** UI resource URI from SEP-1865 */\n  uiResourceUri?: string;\n}\n\n/**\n * Convert MCP tool to AG-UI tool format, preserving UI resource info\n */\nfunction convertMCPToolToAGUITool(mcpTool: {\n  name: string;\n  description?: string;\n  inputSchema?: Record<string, unknown>;\n  _meta?: Record<string, unknown>;\n}): Tool {\n  const tool: Tool = {\n    name: mcpTool.name,\n    description: mcpTool.description || \"\",\n    parameters: mcpTool.inputSchema || { type: \"object\", properties: {} },\n  };\n\n  // Store UI resource URI in the description for now\n  // TODO: Once AG-UI Tool type supports _meta, use that instead\n  const uiResourceUri = mcpTool._meta?.[\"ui/resourceUri\"];\n  if (typeof uiResourceUri === \"string\") {\n    tool.description = `${tool.description}\\n[UI Resource: ${uiResourceUri}]`;\n  }\n\n  return tool;\n}\n\n/**\n * MCP Apps middleware - fetches UI-enabled tools from MCP servers.\n */\nexport class MCPAppsMiddleware extends Middleware {\n  private config: MCPAppsMiddlewareConfig;\n  /** Map of serverHash -> server config for proxied requests */\n  private serverConfigMapByHash: Map<string, MCPClientConfig> = new Map();\n  /** Map of serverId -> server config for proxied requests */\n  private serverConfigMapById: Map<string, MCPClientConfig> = new Map();\n\n  constructor(config: MCPAppsMiddlewareConfig = {}) {\n    super();\n    this.config = config;\n    // Build server config maps for proxied requests\n    for (const serverConfig of config.mcpServers || []) {\n      const serverHash = getServerHash(serverConfig);\n      this.serverConfigMapByHash.set(serverHash, serverConfig);\n      if (serverConfig.serverId) {\n        this.serverConfigMapById.set(serverConfig.serverId, serverConfig);\n      }\n    }\n  }\n\n  run(input: RunAgentInput, next: AbstractAgent): Observable<BaseEvent> {\n    // Check for proxied MCP request mode\n    const proxiedRequest = input.forwardedProps\n      ?.__proxiedMCPRequest as ProxiedMCPRequest | undefined;\n    if (proxiedRequest) {\n      return this.handleProxiedMCPRequest(input.runId, proxiedRequest);\n    }\n\n    // If no MCP servers configured, pass through using runNextWithState\n    if (!this.config.mcpServers?.length) {\n      return this.processStream(\n        this.runNextWithState(input, next),\n        new Map()\n      );\n    }\n\n    // Fetch UI tools from MCP servers and inject them\n    return from(this.fetchUITools()).pipe(\n      switchMap((uiToolInfos) => {\n        // Build map of tool name -> UIToolInfo\n        const uiToolsMap = new Map<string, UIToolInfo>();\n        for (const info of uiToolInfos) {\n          uiToolsMap.set(info.tool.name, info);\n        }\n\n        // Merge UI tools with existing input tools\n        const enhancedInput: RunAgentInput = {\n          ...input,\n          tools: [...input.tools, ...uiToolInfos.map((info) => info.tool)],\n        };\n\n        // Use runNextWithState to get state with each event\n        return this.processStream(\n          this.runNextWithState(enhancedInput, next),\n          uiToolsMap\n        );\n      })\n    );\n  }\n\n  /**\n   * Handle a proxied MCP request from the frontend iframe.\n   * This bypasses the normal agent flow and directly executes the MCP request.\n   */\n  private handleProxiedMCPRequest(\n    runId: string,\n    request: ProxiedMCPRequest\n  ): Observable<BaseEvent> {\n    return new Observable<BaseEvent>((subscriber) => {\n      // Look up server config - prefer serverId, fallback to serverHash\n      let serverConfig: MCPClientConfig | undefined;\n      if (request.serverId) {\n        serverConfig = this.serverConfigMapById.get(request.serverId);\n      }\n      if (!serverConfig) {\n        serverConfig = this.serverConfigMapByHash.get(request.serverHash);\n      }\n\n      // Emit RunStarted\n      const runStartedEvent: RunStartedEvent = {\n        type: EventType.RUN_STARTED,\n        runId,\n        threadId: runId,\n      };\n      subscriber.next(runStartedEvent);\n\n      // Handle unknown server\n      if (!serverConfig) {\n        const runFinishedEvent: RunFinishedEvent = {\n          type: EventType.RUN_FINISHED,\n          runId,\n          threadId: runId,\n          result: { error: `Unknown server: ${request.serverId || request.serverHash}` },\n        };\n        subscriber.next(runFinishedEvent);\n        subscriber.complete();\n        return;\n      }\n\n      // Execute the MCP request\n      this.executeMCPRequest(serverConfig, request.method, request.params)\n        .then((result) => {\n          // Emit RunFinished with the MCP result\n          const runFinishedEvent: RunFinishedEvent = {\n            type: EventType.RUN_FINISHED,\n            runId,\n            threadId: runId,\n            result,\n          };\n          subscriber.next(runFinishedEvent);\n          subscriber.complete();\n        })\n        .catch((error) => {\n          // Emit RunFinished with error\n          const runFinishedEvent: RunFinishedEvent = {\n            type: EventType.RUN_FINISHED,\n            runId,\n            threadId: runId,\n            result: { error: String(error) },\n          };\n          subscriber.next(runFinishedEvent);\n          subscriber.complete();\n        });\n    });\n  }\n\n  /**\n   * Execute a generic MCP request (tools/call, resources/read, etc.)\n   */\n  private async executeMCPRequest(\n    serverConfig: MCPClientConfig,\n    method: string,\n    params?: Record<string, unknown>\n  ): Promise<unknown> {\n    let transport;\n\n    if (serverConfig.type === \"sse\") {\n      transport = new SSEClientTransport(new URL(serverConfig.url));\n    } else {\n      transport = new StreamableHTTPClientTransport(new URL(serverConfig.url));\n    }\n\n    const client = new Client(\n      { name: \"mcp-apps-middleware\", version: \"1.0.0\" },\n      {\n        capabilities: {\n          extensions: {\n            \"io.modelcontextprotocol/ui\": {\n              mimeTypes: [\"text/html+mcp\"],\n            },\n          },\n        },\n      }\n    );\n\n    try {\n      await client.connect(transport);\n\n      // Per SEP-1865: Forward any method that doesn't start with \"ui/\"\n      // Methods starting with \"ui/\" are handled by the host, not the MCP server\n      switch (method) {\n        case \"tools/call\":\n          return await client.callTool(\n            params as { name: string; arguments?: Record<string, unknown> }\n          );\n        case \"resources/read\":\n          return await client.readResource(params as { uri: string });\n        case \"notifications/message\":\n          // notifications/message is a one-way notification (no response expected)\n          await client.notification({\n            method: \"notifications/message\",\n            params,\n          });\n          return { success: true };\n        case \"ping\":\n          return await client.ping();\n        default:\n          throw new Error(\n            `MCP method not allowed for UI proxy: ${method}`\n          );\n      }\n    } finally {\n      await client.close();\n    }\n  }\n\n  /**\n   * Process the event stream, holding back RunFinished events until either:\n   * a) Another event comes -> flush the held RunFinished immediately\n   * b) Stream ends -> do special processing, then flush RunFinished and complete\n   */\n  private processStream(\n    source: Observable<EventWithState>,\n    uiToolsMap: Map<string, UIToolInfo>\n  ): Observable<BaseEvent> {\n    return new Observable<BaseEvent>((subscriber) => {\n      let heldRunFinished: EventWithState | null = null;\n      let isProcessing = false;\n\n      const subscription = source.subscribe({\n        next: (eventWithState) => {\n          const event = eventWithState.event;\n\n          // If we have a held RunFinished and a new event comes, flush it first\n          if (heldRunFinished) {\n            subscriber.next(heldRunFinished.event);\n            heldRunFinished = null;\n          }\n\n          // If this is a RunFinished event, hold it back\n          if (event.type === EventType.RUN_FINISHED) {\n            heldRunFinished = eventWithState;\n          } else {\n            subscriber.next(event);\n          }\n        },\n        error: (err) => {\n          // On error, flush any held event and propagate error\n          if (heldRunFinished) {\n            subscriber.next(heldRunFinished.event);\n            heldRunFinished = null;\n          }\n          subscriber.error(err);\n        },\n        complete: async () => {\n          // Stream ended - do special processing if we have a held RunFinished\n          if (heldRunFinished && !isProcessing) {\n            isProcessing = true;\n\n            try {\n              // Find tool calls that don't have a corresponding result message\n              const pendingToolCalls = this.findPendingToolCalls(\n                heldRunFinished.messages\n              );\n\n              // Filter for UI tool calls (tools we injected from MCP servers)\n              const pendingUIToolCalls = pendingToolCalls.filter((tc) =>\n                uiToolsMap.has(tc.function.name)\n              );\n\n              // Execute pending UI tool calls and emit results\n              for (const toolCall of pendingUIToolCalls) {\n                const toolInfo = uiToolsMap.get(toolCall.function.name)!;\n                try {\n                  const args = JSON.parse(toolCall.function.arguments || \"{}\");\n                  const mcpResult = await this.executeToolCall(\n                    toolInfo.serverConfig,\n                    toolCall.function.name,\n                    args\n                  );\n\n                  // Emit tool result event\n                  const resultEvent: ToolCallResultEvent = {\n                    type: EventType.TOOL_CALL_RESULT,\n                    messageId: randomUUID(),\n                    toolCallId: toolCall.id,\n                    content: this.extractTextContent(mcpResult),\n                  };\n                  subscriber.next(resultEvent);\n\n                  // Emit activity snapshot with MCP result and resourceUri (frontend fetches resource)\n                  const activityEvent: ActivitySnapshotEvent = {\n                    type: EventType.ACTIVITY_SNAPSHOT,\n                    messageId: randomUUID(),\n                    activityType: MCPAppsActivityType,\n                    content: {\n                      result: mcpResult,\n                      resourceUri: toolInfo.resourceUri,\n                      serverHash: getServerHash(toolInfo.serverConfig),\n                      serverId: toolInfo.serverConfig.serverId,\n                      toolInput: args,\n                    },\n                    replace: true,\n                  };\n                  subscriber.next(activityEvent);\n                } catch (error) {\n                  console.error(\n                    `Failed to execute UI tool call ${toolCall.function.name}:`,\n                    error\n                  );\n                  // Emit error result\n                  const errorResult: ToolCallResultEvent = {\n                    type: EventType.TOOL_CALL_RESULT,\n                    messageId: randomUUID(),\n                    toolCallId: toolCall.id,\n                    content: JSON.stringify({ error: String(error) }),\n                  };\n                  subscriber.next(errorResult);\n                }\n              }\n\n              subscriber.next(heldRunFinished.event);\n            } finally {\n              heldRunFinished = null;\n              isProcessing = false;\n            }\n          }\n          subscriber.complete();\n        },\n      });\n\n      return () => subscription.unsubscribe();\n    });\n  }\n\n  /**\n   * Execute a tool call on the MCP server and return the raw result\n   */\n  private async executeToolCall(\n    serverConfig: MCPClientConfig,\n    toolName: string,\n    args: Record<string, unknown>\n  ): Promise<unknown> {\n    let transport;\n\n    if (serverConfig.type === \"sse\") {\n      transport = new SSEClientTransport(new URL(serverConfig.url));\n    } else {\n      transport = new StreamableHTTPClientTransport(new URL(serverConfig.url));\n    }\n\n    const client = new Client(\n      { name: \"mcp-apps-middleware\", version: \"1.0.0\" },\n      {\n        capabilities: {\n          extensions: {\n            \"io.modelcontextprotocol/ui\": {\n              mimeTypes: [\"text/html+mcp\"],\n            },\n          },\n        },\n      }\n    );\n\n    try {\n      await client.connect(transport);\n\n      const result = await client.callTool({\n        name: toolName,\n        arguments: args,\n      });\n\n      return result;\n    } finally {\n      await client.close();\n    }\n  }\n\n  /**\n   * Extract text content from MCP result, fallback to JSON stringified content\n   */\n  private extractTextContent(mcpResult: unknown): string {\n    const result = mcpResult as { content?: unknown };\n    if (Array.isArray(result.content)) {\n      const textContent = result.content\n        .filter(\n          (c): c is { type: \"text\"; text: string } =>\n            c &&\n            typeof c === \"object\" &&\n            c.type === \"text\" &&\n            typeof c.text === \"string\"\n        )\n        .map((c) => c.text)\n        .join(\"\\n\");\n      return textContent || JSON.stringify(result.content);\n    }\n    return JSON.stringify(result.content);\n  }\n\n  /**\n   * Find tool calls that don't have a corresponding result (role: \"tool\") message\n   */\n  private findPendingToolCalls(messages: Message[]): ToolCall[] {\n    // Collect all tool calls from assistant messages\n    const allToolCalls: ToolCall[] = [];\n    for (const message of messages) {\n      if (\n        message.role === \"assistant\" &&\n        \"toolCalls\" in message &&\n        message.toolCalls\n      ) {\n        allToolCalls.push(...message.toolCalls);\n      }\n    }\n\n    // Collect all tool call IDs that have results\n    const resolvedToolCallIds = new Set<string>();\n    for (const message of messages) {\n      if (message.role === \"tool\" && \"toolCallId\" in message) {\n        resolvedToolCallIds.add(message.toolCallId);\n      }\n    }\n\n    // Return tool calls that don't have results\n    return allToolCalls.filter((tc) => !resolvedToolCallIds.has(tc.id));\n  }\n\n  /**\n   * Connect to all configured MCP servers and fetch tools with UI resources\n   */\n  private async fetchUITools(): Promise<UIToolInfo[]> {\n    const allUITools: UIToolInfo[] = [];\n\n    for (const serverConfig of this.config.mcpServers || []) {\n      try {\n        const tools = await this.fetchToolsFromServer(serverConfig);\n        allUITools.push(...tools);\n      } catch (error) {\n        console.error(\n          `Failed to fetch tools from MCP server ${serverConfig.url}:`,\n          error\n        );\n      }\n    }\n\n    return allUITools;\n  }\n\n  /**\n   * Connect to a single MCP server and fetch its UI-enabled tools\n   */\n  private async fetchToolsFromServer(\n    serverConfig: MCPClientConfig\n  ): Promise<UIToolInfo[]> {\n    let transport;\n\n    if (serverConfig.type === \"sse\") {\n      transport = new SSEClientTransport(new URL(serverConfig.url));\n    } else {\n      transport = new StreamableHTTPClientTransport(new URL(serverConfig.url));\n    }\n\n    const client = new Client(\n      { name: \"mcp-apps-middleware\", version: \"1.0.0\" },\n      {\n        capabilities: {\n          // Advertise MCP Apps UI support per SEP-1865\n          extensions: {\n            \"io.modelcontextprotocol/ui\": {\n              mimeTypes: [\"text/html+mcp\"],\n            },\n          },\n        },\n      }\n    );\n\n    try {\n      await client.connect(transport);\n\n      // Fetch tools from the server\n      const response = await client.listTools();\n\n      // Filter for tools with UI resources and convert to AG-UI format with server config\n      const uiTools = response.tools\n        .filter(hasUIResource)\n        .map((mcpTool) => ({\n          tool: convertMCPToolToAGUITool(mcpTool),\n          serverConfig,\n          resourceUri: mcpTool._meta![\"ui/resourceUri\"] as string,\n        }));\n\n      return uiTools;\n    } finally {\n      // Always close the connection\n      await client.close();\n    }\n  }\n}\n"],"mappings":"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","names":["Middleware","EventType","Observable","from","switchMap","Client","SSEClientTransport","StreamableHTTPClientTransport","randomUUID","createHash","MCPAppsActivityType","getServerHash","config","serialized","createHash","hasUIResource","tool","_a","convertMCPToolToAGUITool","mcpTool","uiResourceUri","MCPAppsMiddleware","Middleware","serverConfig","serverHash","input","next","_b","proxiedRequest","from","switchMap","uiToolInfos","uiToolsMap","info","enhancedInput","__spreadProps","__spreadValues","runId","request","Observable","subscriber","runStartedEvent","EventType","runFinishedEvent","result","error","method","params","transport","SSEClientTransport","StreamableHTTPClientTransport","client","Client","source","heldRunFinished","isProcessing","subscription","eventWithState","event","err","pendingUIToolCalls","tc","toolCall","toolInfo","args","mcpResult","resultEvent","randomUUID","activityEvent","errorResult","toolName","c","messages","allToolCalls","message","resolvedToolCallIds","allUITools","tools"]}