|
| 1 | +import { useEffect, useState } from "react"; |
| 2 | +import { createRoot } from "react-dom/client"; |
| 3 | + |
1 | 4 | import { Client } from "@modelcontextprotocol/sdk/client/index.js"; |
2 | 5 | import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js"; |
3 | 6 | import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js"; |
4 | 7 | import { Tool } from "@modelcontextprotocol/sdk/types.js"; |
5 | | -import { useEffect, useState } from "react"; |
6 | | -import { createRoot } from "react-dom/client"; |
7 | | -import { UIActionResult } from "../src/mcp-ui-types.js"; |
8 | | -import { UITemplatedToolCallRenderer } from "../src/react/UITemplatedToolCallRenderer.js"; |
| 8 | +import { AppRenderer,AppRendererProps } from "../src/AppRenderer"; |
| 9 | +import { AppBridge } from "../../../dist/src/app-bridge"; |
9 | 10 |
|
10 | | -const SANDBOX_PROXY_URL = URL.parse("/sandbox.html", location.href); |
| 11 | +const SANDBOX_PROXY_URL = URL.parse("/sandbox.html", location.href)!; |
11 | 12 |
|
12 | 13 | /** |
13 | | - * Example React application demonstrating the UITemplatedToolCallRenderer component. |
| 14 | + * Example React application demonstrating the AppRenderer component. |
14 | 15 | * |
15 | 16 | * This shows how to: |
16 | 17 | * - Connect to an MCP server |
17 | 18 | * - List available tools |
18 | | - * - Render tool UIs using UITemplatedToolCallRenderer |
| 19 | + * - Render tool UIs using AppRenderer |
19 | 20 | * - Handle UI actions from the tool |
20 | 21 | */ |
21 | 22 | function ExampleApp() { |
@@ -93,23 +94,19 @@ function ExampleApp() { |
93 | 94 | setActiveTools((prev) => prev.filter((t) => t.id !== id)); |
94 | 95 | }; |
95 | 96 |
|
96 | | - const handleUIAction = async (toolId: string, action: UIActionResult) => { |
97 | | - console.log(`[React Host] UI Action from ${toolId}:`, action); |
98 | | - |
99 | | - if (action.type === "intent") { |
100 | | - console.log( |
101 | | - "[React Host] Intent:", |
102 | | - action.payload.intent, |
103 | | - action.payload.params, |
104 | | - ); |
105 | | - } else if (action.type === "link") { |
106 | | - console.log("[React Host] Opening link:", action.payload.url); |
107 | | - window.open(action.payload.url, "_blank", "noopener,noreferrer"); |
108 | | - } else if (action.type === "prompt") { |
109 | | - console.log("[React Host] Prompt:", action.payload.prompt); |
110 | | - } else if (action.type === "notify") { |
111 | | - console.log("[React Host] Notification:", action.payload.message); |
112 | | - } |
| 97 | + const handleMessage: AppRendererProps["onmessage"] = async (params, _extra) => { |
| 98 | + console.log("[React Host] Message:", params); |
| 99 | + return {}; |
| 100 | + }; |
| 101 | + |
| 102 | + const handleLoggingMessage: AppRendererProps["onloggingmessage"] = (params) => { |
| 103 | + console.log("[React Host] Logging message:", params); |
| 104 | + }; |
| 105 | + |
| 106 | + const handleOpenLink: AppRendererProps["onopenlink"] = async (params, _extra) => { |
| 107 | + console.log("[React Host] Open link request:", params); |
| 108 | + window.open(params.url, "_blank", "noopener,noreferrer"); |
| 109 | + return { isError: false }; |
113 | 110 | }; |
114 | 111 |
|
115 | 112 | const handleError = (toolId: string, err: Error) => { |
@@ -223,13 +220,15 @@ function ExampleApp() { |
223 | 220 | </button> |
224 | 221 | </div> |
225 | 222 |
|
226 | | - <UITemplatedToolCallRenderer |
| 223 | + <AppRenderer |
227 | 224 | sandboxProxyUrl={SANDBOX_PROXY_URL} |
228 | 225 | client={client} |
229 | 226 | toolName={tool.name} |
230 | 227 | toolInput={tool.input} |
231 | | - onUIAction={(action) => handleUIAction(tool.id, action)} |
232 | | - onError={(err) => handleError(tool.id, err)} |
| 228 | + onmessage={handleMessage} |
| 229 | + onloggingmessage={handleLoggingMessage} |
| 230 | + onopenlink={handleOpenLink} |
| 231 | + onerror={(err) => handleError(tool.id, err)} |
233 | 232 | /> |
234 | 233 | </div> |
235 | 234 | ))} |
|
0 commit comments