@agent-native/core 0.72.3 → 0.72.4

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 (136) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/core/CHANGELOG.md +10 -0
  3. package/corpus/core/package.json +6 -6
  4. package/corpus/core/src/a2a/client.ts +7 -3
  5. package/corpus/core/src/client/api-path.ts +28 -0
  6. package/corpus/core/src/client/embed-auth.ts +26 -0
  7. package/corpus/core/src/client/mcp-app-host.ts +6 -0
  8. package/corpus/core/src/client/mcp-apps/McpAppRenderer.tsx +227 -33
  9. package/corpus/core/src/client/resources/use-mcp-servers.ts +1 -0
  10. package/corpus/core/src/client/settings/DemoModeSection.tsx +3 -1
  11. package/corpus/core/src/demo/fetch-interceptor.ts +1 -1
  12. package/corpus/core/src/embedding/agent.ts +6 -1
  13. package/corpus/core/src/embedding/bridge.ts +34 -1
  14. package/corpus/core/src/mcp/build-server.ts +38 -10
  15. package/corpus/core/src/mcp/embed-app.ts +120 -45
  16. package/corpus/core/src/mcp/index.ts +5 -0
  17. package/corpus/core/src/mcp/org-directory.ts +70 -11
  18. package/corpus/core/src/mcp/server.ts +14 -0
  19. package/corpus/core/src/mcp-client/config.ts +12 -0
  20. package/corpus/core/src/mcp-client/index.ts +2 -0
  21. package/corpus/core/src/mcp-client/manager.ts +268 -9
  22. package/corpus/core/src/mcp-client/remote-store.ts +154 -0
  23. package/corpus/core/src/mcp-client/routes.ts +2 -0
  24. package/corpus/core/src/server/agent-chat-plugin.ts +8 -0
  25. package/corpus/core/src/server/index.ts +1 -0
  26. package/corpus/core/src/shared/mcp-embed-headers.ts +44 -3
  27. package/corpus/core/src/vite/client.ts +53 -0
  28. package/corpus/templates/assets/.agents/skills/a2a-assets/SKILL.md +17 -10
  29. package/corpus/templates/assets/.agents/skills/asset-generation/SKILL.md +15 -6
  30. package/corpus/templates/assets/AGENTS.md +7 -5
  31. package/corpus/templates/assets/actions/generate-asset.ts +161 -0
  32. package/corpus/templates/assets/actions/list-assets.ts +4 -2
  33. package/corpus/templates/assets/actions/open-asset-picker.ts +84 -3
  34. package/corpus/templates/assets/app/routes/library.tsx +243 -40
  35. package/corpus/templates/clips/desktop/src-tauri/src/native_speech.rs +9 -0
  36. package/corpus/templates/design/AGENTS.md +10 -5
  37. package/corpus/templates/design/actions/connect-assets-mcp.ts +131 -0
  38. package/corpus/templates/design/actions/insert-asset.ts +219 -0
  39. package/corpus/templates/design/actions/view-screen.ts +3 -1
  40. package/corpus/templates/design/app/components/editor/PromptDialog.tsx +1 -1
  41. package/corpus/templates/design/app/pages/DesignEditor.tsx +53 -0
  42. package/corpus/templates/design/server/plugins/agent-chat.ts +5 -1
  43. package/corpus/templates/design/server/plugins/assets-mcp.ts +60 -0
  44. package/dist/a2a/client.d.ts +1 -0
  45. package/dist/a2a/client.d.ts.map +1 -1
  46. package/dist/a2a/client.js +5 -3
  47. package/dist/a2a/client.js.map +1 -1
  48. package/dist/client/api-path.d.ts.map +1 -1
  49. package/dist/client/api-path.js +27 -0
  50. package/dist/client/api-path.js.map +1 -1
  51. package/dist/client/embed-auth.d.ts.map +1 -1
  52. package/dist/client/embed-auth.js +27 -0
  53. package/dist/client/embed-auth.js.map +1 -1
  54. package/dist/client/mcp-app-host.d.ts.map +1 -1
  55. package/dist/client/mcp-app-host.js +5 -0
  56. package/dist/client/mcp-app-host.js.map +1 -1
  57. package/dist/client/mcp-apps/McpAppRenderer.d.ts +1 -0
  58. package/dist/client/mcp-apps/McpAppRenderer.d.ts.map +1 -1
  59. package/dist/client/mcp-apps/McpAppRenderer.js +179 -33
  60. package/dist/client/mcp-apps/McpAppRenderer.js.map +1 -1
  61. package/dist/client/resources/use-mcp-servers.d.ts +1 -0
  62. package/dist/client/resources/use-mcp-servers.d.ts.map +1 -1
  63. package/dist/client/resources/use-mcp-servers.js.map +1 -1
  64. package/dist/client/settings/DemoModeSection.d.ts.map +1 -1
  65. package/dist/client/settings/DemoModeSection.js +3 -1
  66. package/dist/client/settings/DemoModeSection.js.map +1 -1
  67. package/dist/demo/fetch-interceptor.js +1 -1
  68. package/dist/demo/fetch-interceptor.js.map +1 -1
  69. package/dist/embedding/agent.d.ts +1 -1
  70. package/dist/embedding/agent.d.ts.map +1 -1
  71. package/dist/embedding/agent.js +1 -1
  72. package/dist/embedding/agent.js.map +1 -1
  73. package/dist/embedding/bridge.d.ts.map +1 -1
  74. package/dist/embedding/bridge.js +27 -1
  75. package/dist/embedding/bridge.js.map +1 -1
  76. package/dist/extensions/schema.d.ts +2 -2
  77. package/dist/mcp/build-server.d.ts +2 -0
  78. package/dist/mcp/build-server.d.ts.map +1 -1
  79. package/dist/mcp/build-server.js +32 -9
  80. package/dist/mcp/build-server.js.map +1 -1
  81. package/dist/mcp/embed-app.d.ts.map +1 -1
  82. package/dist/mcp/embed-app.js +120 -45
  83. package/dist/mcp/embed-app.js.map +1 -1
  84. package/dist/mcp/index.d.ts +1 -0
  85. package/dist/mcp/index.d.ts.map +1 -1
  86. package/dist/mcp/index.js +1 -0
  87. package/dist/mcp/index.js.map +1 -1
  88. package/dist/mcp/org-directory.d.ts +1 -0
  89. package/dist/mcp/org-directory.d.ts.map +1 -1
  90. package/dist/mcp/org-directory.js +59 -11
  91. package/dist/mcp/org-directory.js.map +1 -1
  92. package/dist/mcp/server.d.ts.map +1 -1
  93. package/dist/mcp/server.js +9 -0
  94. package/dist/mcp/server.js.map +1 -1
  95. package/dist/mcp-client/config.d.ts +12 -0
  96. package/dist/mcp-client/config.d.ts.map +1 -1
  97. package/dist/mcp-client/config.js.map +1 -1
  98. package/dist/mcp-client/index.d.ts +1 -1
  99. package/dist/mcp-client/index.d.ts.map +1 -1
  100. package/dist/mcp-client/index.js +1 -1
  101. package/dist/mcp-client/index.js.map +1 -1
  102. package/dist/mcp-client/manager.d.ts +2 -0
  103. package/dist/mcp-client/manager.d.ts.map +1 -1
  104. package/dist/mcp-client/manager.js +201 -9
  105. package/dist/mcp-client/manager.js.map +1 -1
  106. package/dist/mcp-client/remote-store.d.ts +27 -0
  107. package/dist/mcp-client/remote-store.d.ts.map +1 -1
  108. package/dist/mcp-client/remote-store.js +105 -0
  109. package/dist/mcp-client/remote-store.js.map +1 -1
  110. package/dist/mcp-client/routes.d.ts +1 -0
  111. package/dist/mcp-client/routes.d.ts.map +1 -1
  112. package/dist/mcp-client/routes.js +1 -0
  113. package/dist/mcp-client/routes.js.map +1 -1
  114. package/dist/provider-api/actions/github-repo-files.d.ts +2 -2
  115. package/dist/provider-api/actions/query-staged-dataset.d.ts +3 -3
  116. package/dist/provider-api/corpus-jobs.d.ts +8 -8
  117. package/dist/server/agent-chat-plugin.d.ts +2 -0
  118. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  119. package/dist/server/agent-chat-plugin.js +8 -0
  120. package/dist/server/agent-chat-plugin.js.map +1 -1
  121. package/dist/server/index.d.ts +1 -1
  122. package/dist/server/index.d.ts.map +1 -1
  123. package/dist/server/index.js +1 -1
  124. package/dist/server/index.js.map +1 -1
  125. package/dist/shared/mcp-embed-headers.d.ts +3 -1
  126. package/dist/shared/mcp-embed-headers.d.ts.map +1 -1
  127. package/dist/shared/mcp-embed-headers.js +40 -3
  128. package/dist/shared/mcp-embed-headers.js.map +1 -1
  129. package/dist/sharing/actions/list-resource-shares.d.ts +1 -1
  130. package/dist/sharing/actions/set-resource-visibility.d.ts +2 -2
  131. package/dist/sharing/actions/share-resource.d.ts +1 -1
  132. package/dist/sharing/schema.d.ts +1 -1
  133. package/dist/vite/client.d.ts.map +1 -1
  134. package/dist/vite/client.js +44 -0
  135. package/dist/vite/client.js.map +1 -1
  136. package/package.json +6 -6
@@ -1,18 +1,22 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useCallback, useEffect, useMemo, useRef, useState } from "react";
2
+ import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, } from "react";
3
3
  import { AppBridge, PostMessageTransport, buildAllowAttribute, } from "@modelcontextprotocol/ext-apps/app-bridge";
4
4
  import { IconAlertTriangle, IconLoader2 } from "@tabler/icons-react";
5
+ import { AGENT_NATIVE_EMBED_MESSAGE_TYPES, AGENT_NATIVE_EMBED_PROTOCOL, AGENT_NATIVE_EMBED_VERSION, } from "../../embedding/protocol.js";
5
6
  import { agentNativePath } from "../api-path.js";
7
+ import { sendToAgentChat } from "../agent-chat.js";
6
8
  import { cn } from "../utils.js";
7
9
  export const DEFAULT_MCP_APP_IFRAME_HEIGHT = 650;
8
10
  export const MCP_APP_INITIALIZE_TIMEOUT_MS = 8000;
9
11
  const MIN_IFRAME_HEIGHT = 220;
10
12
  const VIEWPORT_MARGIN = 16;
11
13
  const SANDBOX_FLAGS = "allow-scripts allow-forms allow-popups";
14
+ const useBrowserLayoutEffect = typeof window === "undefined" ? useEffect : useLayoutEffect;
12
15
  export function McpAppRenderer({ app, className }) {
13
16
  const iframeRef = useRef(null);
14
17
  const desiredHeightRef = useRef(DEFAULT_MCP_APP_IFRAME_HEIGHT);
15
- const [loadedSrcDoc, setLoadedSrcDoc] = useState(null);
18
+ const modelContextRef = useRef(null);
19
+ const readyRef = useRef(false);
16
20
  const [height, setHeight] = useState(DEFAULT_MCP_APP_IFRAME_HEIGHT);
17
21
  const [error, setError] = useState(null);
18
22
  const [ready, setReady] = useState(false);
@@ -22,13 +26,35 @@ export function McpAppRenderer({ app, className }) {
22
26
  const csp = buildMcpAppCsp(uiMeta.csp);
23
27
  const srcDoc = useMemo(() => (resourceHtml ? injectCsp(resourceHtml, csp) : ""), [resourceHtml, csp]);
24
28
  const externalOpenUrl = useMemo(() => openUrlFromMcpApp(app), [app]);
29
+ // Keep the latest payload/permissions/csp reachable from the bridge effect
30
+ // without making them effect dependencies. The embedded resource identity is
31
+ // fully captured by `srcDoc`. The bridge effect must NOT re-run when a benign
32
+ // parent re-render hands us a new `app` object reference with identical
33
+ // content (common during chat streaming/polling): re-running tears down a
34
+ // live, already-initialized MCP App (teardownResource) and re-arms the
35
+ // initialize watchdog against a fresh host AppBridge that the embed shell
36
+ // will never re-handshake (its connect promise is memoized), surfacing a
37
+ // false "MCP App did not finish initializing." error after the app is
38
+ // visibly working.
39
+ const appRef = useRef(app);
40
+ const supportedPermissionsRef = useRef(supportedPermissions);
41
+ const uiCspRef = useRef(uiMeta.csp);
42
+ appRef.current = app;
43
+ supportedPermissionsRef.current = supportedPermissions;
44
+ uiCspRef.current = uiMeta.csp;
25
45
  useEffect(() => {
26
46
  desiredHeightRef.current = DEFAULT_MCP_APP_IFRAME_HEIGHT;
27
47
  setHeight(clampMcpAppHeight(DEFAULT_MCP_APP_IFRAME_HEIGHT, availableMcpAppHeight(iframeRef.current)));
28
- setLoadedSrcDoc(null);
48
+ readyRef.current = false;
29
49
  setReady(false);
30
50
  setError(null);
51
+ modelContextRef.current = null;
31
52
  }, [srcDoc]);
53
+ const markReady = useCallback(() => {
54
+ readyRef.current = true;
55
+ setReady(true);
56
+ setError(null);
57
+ }, []);
32
58
  const applyHeight = useCallback((desiredHeight) => {
33
59
  if (typeof desiredHeight === "number" &&
34
60
  Number.isFinite(desiredHeight) &&
@@ -71,11 +97,27 @@ export function McpAppRenderer({ app, className }) {
71
97
  }, [applyHeight, srcDoc]);
72
98
  useEffect(() => {
73
99
  const iframe = iframeRef.current;
74
- if (!iframe?.contentWindow || !srcDoc || loadedSrcDoc !== srcDoc)
100
+ if (!iframe?.contentWindow || !srcDoc)
101
+ return;
102
+ const frameWindow = iframe.contentWindow;
103
+ const listener = (event) => {
104
+ if (event.source !== frameWindow)
105
+ return;
106
+ if (isMcpAppReadyMessage(event.data)) {
107
+ markReady();
108
+ }
109
+ };
110
+ window.addEventListener("message", listener);
111
+ return () => window.removeEventListener("message", listener);
112
+ }, [markReady, srcDoc]);
113
+ useBrowserLayoutEffect(() => {
114
+ const iframe = iframeRef.current;
115
+ if (!iframe?.contentWindow || !srcDoc)
75
116
  return;
117
+ const currentApp = appRef.current;
76
118
  let closed = false;
77
119
  const initializeTimer = window.setTimeout(() => {
78
- if (closed)
120
+ if (closed || readyRef.current)
79
121
  return;
80
122
  setReady(false);
81
123
  setError("MCP App did not finish initializing.");
@@ -86,11 +128,11 @@ export function McpAppRenderer({ app, className }) {
86
128
  serverResources: {},
87
129
  logging: {},
88
130
  sandbox: {
89
- permissions: supportedPermissions,
90
- csp: uiMeta.csp ?? {},
131
+ permissions: supportedPermissionsRef.current,
132
+ csp: uiCspRef.current ?? {},
91
133
  },
92
134
  }, {
93
- hostContext: buildHostContext(app, availableMcpAppHeight(iframe)),
135
+ hostContext: buildHostContext(currentApp, availableMcpAppHeight(iframe)),
94
136
  });
95
137
  bridge.addEventListener("sizechange", ({ height: nextHeight }) => {
96
138
  if (typeof nextHeight !== "number" || !Number.isFinite(nextHeight)) {
@@ -102,12 +144,9 @@ export function McpAppRenderer({ app, className }) {
102
144
  if (closed)
103
145
  return;
104
146
  clearTimeout(initializeTimer);
105
- setReady(true);
106
- // Clear any error the initialize timeout may have set before a slow app
107
- // finished — otherwise the error overlay stays stuck over a working app.
108
- setError(null);
109
- void bridge.sendToolInput({ arguments: app.toolInput });
110
- void bridge.sendToolResult(app.toolResult);
147
+ markReady();
148
+ void bridge.sendToolInput({ arguments: appRef.current.toolInput });
149
+ void bridge.sendToolResult(appRef.current.toolResult);
111
150
  });
112
151
  bridge.addEventListener("loggingmessage", ({ level, data }) => {
113
152
  if (level === "error" || level === "critical" || level === "alert") {
@@ -121,13 +160,13 @@ export function McpAppRenderer({ app, className }) {
121
160
  return {};
122
161
  };
123
162
  bridge.oncalltool = async ({ name, arguments: toolArguments }) => {
124
- const toolName = normalizeSameServerToolName(app.serverId, name);
163
+ const toolName = normalizeSameServerToolName(appRef.current.serverId, name);
125
164
  if (!toolName) {
126
165
  return errorToolResult("Cross-server MCP App tool calls are blocked.");
127
166
  }
128
167
  try {
129
168
  return await postMcpAppEndpoint("call-tool", {
130
- serverId: app.serverId,
169
+ serverId: appRef.current.serverId,
131
170
  toolName,
132
171
  arguments: toolArguments && typeof toolArguments === "object"
133
172
  ? toolArguments
@@ -138,17 +177,36 @@ export function McpAppRenderer({ app, className }) {
138
177
  return errorToolResult(err?.message ?? "MCP App tool call failed.");
139
178
  }
140
179
  };
141
- bridge.onlisttools = async () => postMcpAppEndpoint("list-tools", { serverId: app.serverId });
142
- bridge.onreadresource = async ({ uri }) => postMcpAppEndpoint("read-resource", { serverId: app.serverId, uri });
180
+ bridge.onlisttools = async () => postMcpAppEndpoint("list-tools", { serverId: appRef.current.serverId });
181
+ bridge.onreadresource = async ({ uri }) => postMcpAppEndpoint("read-resource", {
182
+ serverId: appRef.current.serverId,
183
+ uri,
184
+ });
143
185
  bridge.onlistresources = async () => ({ resources: [] });
144
186
  bridge.onlistresourcetemplates = async () => ({ resourceTemplates: [] });
145
187
  bridge.ondownloadfile = async () => ({ isError: true });
146
- bridge.onmessage = async () => ({ isError: true });
147
- bridge.onupdatemodelcontext = async () => ({});
188
+ bridge.onmessage = async (params) => {
189
+ const message = messageTextFromMcpUiMessage(params);
190
+ if (!message.trim())
191
+ return { isError: true };
192
+ const mode = requestModeFromMcpUiMessage(params);
193
+ sendToAgentChat({
194
+ message,
195
+ context: contextTextFromMcpModelContext(modelContextRef.current),
196
+ images: imageDataUrlsFromMcpContent(params.content),
197
+ submit: true,
198
+ openSidebar: true,
199
+ ...(mode ? { mode } : {}),
200
+ });
201
+ return {};
202
+ };
203
+ bridge.onupdatemodelcontext = async (params) => {
204
+ modelContextRef.current = params;
205
+ return {};
206
+ };
148
207
  const transport = new PostMessageTransport(iframe.contentWindow, iframe.contentWindow);
149
- setReady(false);
150
208
  setError(null);
151
- bridge.connect(transport).catch((err) => {
209
+ void bridge.connect(transport).catch((err) => {
152
210
  if (!closed) {
153
211
  clearTimeout(initializeTimer);
154
212
  setError(err?.message ?? "Failed to initialize MCP App.");
@@ -156,8 +214,8 @@ export function McpAppRenderer({ app, className }) {
156
214
  });
157
215
  return () => {
158
216
  closed = true;
217
+ modelContextRef.current = null;
159
218
  clearTimeout(initializeTimer);
160
- setReady(false);
161
219
  void bridge
162
220
  .teardownResource({}, { timeout: 500 })
163
221
  .catch(() => undefined)
@@ -165,18 +223,77 @@ export function McpAppRenderer({ app, className }) {
165
223
  void bridge.close?.().catch?.(() => undefined);
166
224
  });
167
225
  };
168
- }, [
169
- app,
170
- applyHeight,
171
- loadedSrcDoc,
172
- srcDoc,
173
- supportedPermissions,
174
- uiMeta.csp,
175
- ]);
226
+ // The embedded resource identity is captured by `srcDoc`; `app`,
227
+ // `supportedPermissions`, and `uiMeta.csp` are read via refs so a
228
+ // new-but-equal `app` object reference does not tear down a live bridge.
229
+ }, [applyHeight, markReady, srcDoc]);
176
230
  if (!resourceHtml) {
177
231
  return (_jsxs("div", { className: cn("agent-mcp-app agent-mcp-app--error", className), children: [_jsx(IconAlertTriangle, { size: 15 }), _jsx("span", { children: "MCP App resource was not available." })] }));
178
232
  }
179
- return (_jsxs("div", { className: cn("agent-mcp-app", uiMeta.prefersBorder === false && "agent-mcp-app--flush", className), children: [!ready && !error && (_jsxs("div", { className: "agent-mcp-app__loading", children: [_jsx(IconLoader2, { size: 14, className: "agent-conversation-spin" }), _jsx("span", { children: "Loading MCP App" })] })), error && (_jsxs("div", { className: "agent-mcp-app__error", children: [_jsx(IconAlertTriangle, { size: 15 }), _jsx("span", { children: error }), externalOpenUrl && (_jsx("button", { type: "button", className: "agent-mcp-app__open", onClick: () => window.open(externalOpenUrl, "_blank", "noopener,noreferrer"), children: "Open in new tab" }))] })), _jsx("iframe", { ref: iframeRef, title: app.tool?.title ?? app.originalToolName, srcDoc: srcDoc, sandbox: SANDBOX_FLAGS, allow: buildAllowAttribute(supportedPermissions), style: { height }, onLoad: () => setLoadedSrcDoc(srcDoc) })] }));
233
+ return (_jsxs("div", { className: cn("agent-mcp-app", uiMeta.prefersBorder === false && "agent-mcp-app--flush", className), children: [!ready && !error && (_jsxs("div", { className: "agent-mcp-app__loading", children: [_jsx(IconLoader2, { size: 14, className: "agent-conversation-spin" }), _jsx("span", { children: "Loading MCP App" })] })), error && (_jsxs("div", { className: "agent-mcp-app__error", children: [_jsx(IconAlertTriangle, { size: 15 }), _jsx("span", { children: error }), externalOpenUrl && (_jsx("button", { type: "button", className: "agent-mcp-app__open", onClick: () => window.open(externalOpenUrl, "_blank", "noopener,noreferrer"), children: "Open in new tab" }))] })), _jsx("iframe", { ref: iframeRef, title: app.tool?.title ?? app.originalToolName, srcDoc: srcDoc, sandbox: SANDBOX_FLAGS, allow: buildAllowAttribute(supportedPermissions), style: { height } })] }));
234
+ }
235
+ function messageTextFromMcpUiMessage(params) {
236
+ return textPartsFromMcpContent(params.content).join("\n\n").trim();
237
+ }
238
+ function requestModeFromMcpUiMessage(params) {
239
+ const record = params && typeof params === "object" && !Array.isArray(params)
240
+ ? params
241
+ : {};
242
+ const mode = record.requestMode ?? record.mode;
243
+ return mode === "act" || mode === "plan" ? mode : undefined;
244
+ }
245
+ function contextTextFromMcpModelContext(context) {
246
+ if (!context)
247
+ return undefined;
248
+ const parts = textPartsFromMcpContent(context.content);
249
+ if (context.structuredContent !== undefined) {
250
+ parts.push(JSON.stringify(context.structuredContent, null, 2));
251
+ }
252
+ const text = parts.join("\n\n").trim();
253
+ return text || undefined;
254
+ }
255
+ function textPartsFromMcpContent(content) {
256
+ if (!Array.isArray(content))
257
+ return [];
258
+ return content
259
+ .map((part) => {
260
+ const record = contentPartRecord(part);
261
+ if (!record ||
262
+ record.type !== "text" ||
263
+ typeof record.text !== "string") {
264
+ return null;
265
+ }
266
+ const text = record.text.trim();
267
+ return text || null;
268
+ })
269
+ .filter((text) => Boolean(text));
270
+ }
271
+ function imageDataUrlsFromMcpContent(content) {
272
+ if (!Array.isArray(content))
273
+ return undefined;
274
+ const images = content
275
+ .map((part) => {
276
+ const record = contentPartRecord(part);
277
+ if (!record || record.type !== "image")
278
+ return null;
279
+ if (typeof record.url === "string" && record.url.trim()) {
280
+ return record.url;
281
+ }
282
+ if (typeof record.data !== "string" || !record.data.trim())
283
+ return null;
284
+ const mimeType = typeof record.mimeType === "string" &&
285
+ record.mimeType.startsWith("image/")
286
+ ? record.mimeType
287
+ : "image/png";
288
+ return `data:${mimeType};base64,${record.data}`;
289
+ })
290
+ .filter((image) => Boolean(image));
291
+ return images.length ? images : undefined;
292
+ }
293
+ function contentPartRecord(part) {
294
+ return part && typeof part === "object" && !Array.isArray(part)
295
+ ? part
296
+ : null;
180
297
  }
181
298
  function resourceUiMeta(app) {
182
299
  const meta = app.resource?._meta;
@@ -229,8 +346,21 @@ function openUrlFromMcpApp(app) {
229
346
  export function supportedMcpAppPermissions(permissions) {
230
347
  return permissions?.clipboardWrite ? { clipboardWrite: {} } : {};
231
348
  }
349
+ export function isMcpAppReadyMessage(data) {
350
+ if (!data || typeof data !== "object" || Array.isArray(data))
351
+ return false;
352
+ const record = data;
353
+ if (record.protocol === AGENT_NATIVE_EMBED_PROTOCOL &&
354
+ record.version === AGENT_NATIVE_EMBED_VERSION &&
355
+ record.type === AGENT_NATIVE_EMBED_MESSAGE_TYPES.READY) {
356
+ return true;
357
+ }
358
+ const type = record.type;
359
+ return (type === "agentNative.embeddedAppReady" ||
360
+ type === "agentNative.frameOrigin");
361
+ }
232
362
  export function buildMcpAppCsp(csp) {
233
- const connect = sanitizeCspSources(csp?.connectDomains);
363
+ const connect = withLocalWebSocketSources(sanitizeCspSources(csp?.connectDomains));
234
364
  const resources = sanitizeCspSources(csp?.resourceDomains);
235
365
  const frames = sanitizeCspSources(csp?.frameDomains);
236
366
  const base = sanitizeCspSources(csp?.baseUriDomains);
@@ -256,6 +386,22 @@ function sanitizeCspSources(values) {
256
386
  }
257
387
  return [...new Set(out)];
258
388
  }
389
+ function withLocalWebSocketSources(sources) {
390
+ const out = [...sources];
391
+ for (const source of sources) {
392
+ try {
393
+ const url = new URL(source);
394
+ if (url.protocol === "http:" &&
395
+ ["localhost", "127.0.0.1", "::1"].includes(url.hostname)) {
396
+ out.push(`ws://${url.host}`);
397
+ }
398
+ }
399
+ catch {
400
+ // Ignore non-URL CSP source expressions.
401
+ }
402
+ }
403
+ return [...new Set(out)];
404
+ }
259
405
  function sanitizeCspSource(value) {
260
406
  const source = value.trim();
261
407
  if (!source || source.includes("'") || /[\s;]/.test(source))
@@ -1 +1 @@
1
- {"version":3,"file":"McpAppRenderer.js","sourceRoot":"","sources":["../../../src/client/mcp-apps/McpAppRenderer.tsx"],"names":[],"mappings":"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","sourcesContent":["import { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport {\n AppBridge,\n PostMessageTransport,\n buildAllowAttribute,\n type McpUiResourceCsp,\n type McpUiResourcePermissions,\n} from \"@modelcontextprotocol/ext-apps/app-bridge\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { IconAlertTriangle, IconLoader2 } from \"@tabler/icons-react\";\nimport type { AgentMcpAppPayload } from \"../../mcp-client/app-result.js\";\nimport { agentNativePath } from \"../api-path.js\";\nimport { cn } from \"../utils.js\";\n\nexport const DEFAULT_MCP_APP_IFRAME_HEIGHT = 650;\nexport const MCP_APP_INITIALIZE_TIMEOUT_MS = 8000;\nconst MIN_IFRAME_HEIGHT = 220;\nconst VIEWPORT_MARGIN = 16;\nconst SANDBOX_FLAGS = \"allow-scripts allow-forms allow-popups\";\n\nexport interface McpAppRendererProps {\n app: AgentMcpAppPayload;\n className?: string;\n}\n\ntype ResourceUiMeta = {\n csp?: McpUiResourceCsp;\n permissions?: McpUiResourcePermissions;\n prefersBorder?: boolean;\n};\n\nexport function McpAppRenderer({ app, className }: McpAppRendererProps) {\n const iframeRef = useRef<HTMLIFrameElement | null>(null);\n const desiredHeightRef = useRef(DEFAULT_MCP_APP_IFRAME_HEIGHT);\n const [loadedSrcDoc, setLoadedSrcDoc] = useState<string | null>(null);\n const [height, setHeight] = useState(DEFAULT_MCP_APP_IFRAME_HEIGHT);\n const [error, setError] = useState<string | null>(null);\n const [ready, setReady] = useState(false);\n const resourceHtml = app.resource ? htmlFromResource(app.resource) : \"\";\n const uiMeta = useMemo(() => resourceUiMeta(app), [app]);\n const supportedPermissions = useMemo(\n () => supportedMcpAppPermissions(uiMeta.permissions),\n [uiMeta.permissions],\n );\n const csp = buildMcpAppCsp(uiMeta.csp);\n const srcDoc = useMemo(\n () => (resourceHtml ? injectCsp(resourceHtml, csp) : \"\"),\n [resourceHtml, csp],\n );\n const externalOpenUrl = useMemo(() => openUrlFromMcpApp(app), [app]);\n\n useEffect(() => {\n desiredHeightRef.current = DEFAULT_MCP_APP_IFRAME_HEIGHT;\n setHeight(\n clampMcpAppHeight(\n DEFAULT_MCP_APP_IFRAME_HEIGHT,\n availableMcpAppHeight(iframeRef.current),\n ),\n );\n setLoadedSrcDoc(null);\n setReady(false);\n setError(null);\n }, [srcDoc]);\n\n const applyHeight = useCallback((desiredHeight?: number) => {\n if (\n typeof desiredHeight === \"number\" &&\n Number.isFinite(desiredHeight) &&\n desiredHeight > 0\n ) {\n desiredHeightRef.current = desiredHeight;\n }\n setHeight(\n clampMcpAppHeight(\n desiredHeightRef.current,\n availableMcpAppHeight(iframeRef.current),\n ),\n );\n }, []);\n\n useEffect(() => {\n let frame = 0;\n const update = () => {\n if (frame) cancelAnimationFrame(frame);\n frame = requestAnimationFrame(() => {\n frame = 0;\n applyHeight();\n });\n };\n\n update();\n window.addEventListener(\"resize\", update, { passive: true });\n window.visualViewport?.addEventListener(\"resize\", update, {\n passive: true,\n });\n document.addEventListener(\"scroll\", update, true);\n\n const observer =\n typeof ResizeObserver !== \"undefined\" ? new ResizeObserver(update) : null;\n if (observer) {\n observer.observe(document.documentElement);\n const parent = iframeRef.current?.parentElement;\n if (parent) observer.observe(parent);\n }\n\n return () => {\n if (frame) cancelAnimationFrame(frame);\n window.removeEventListener(\"resize\", update);\n window.visualViewport?.removeEventListener(\"resize\", update);\n document.removeEventListener(\"scroll\", update, true);\n observer?.disconnect();\n };\n }, [applyHeight, srcDoc]);\n\n useEffect(() => {\n const iframe = iframeRef.current;\n if (!iframe?.contentWindow || !srcDoc || loadedSrcDoc !== srcDoc) return;\n\n let closed = false;\n const initializeTimer = window.setTimeout(() => {\n if (closed) return;\n setReady(false);\n setError(\"MCP App did not finish initializing.\");\n }, MCP_APP_INITIALIZE_TIMEOUT_MS);\n const bridge = new AppBridge(\n null,\n { name: \"Agent Native\", version: \"1.0.0\" },\n {\n openLinks: {},\n serverTools: {},\n serverResources: {},\n logging: {},\n sandbox: {\n permissions: supportedPermissions,\n csp: uiMeta.csp ?? {},\n },\n },\n {\n hostContext: buildHostContext(\n app,\n availableMcpAppHeight(iframe),\n ) as any,\n },\n );\n\n bridge.addEventListener(\"sizechange\", ({ height: nextHeight }) => {\n if (typeof nextHeight !== \"number\" || !Number.isFinite(nextHeight)) {\n return;\n }\n applyHeight(nextHeight);\n });\n bridge.addEventListener(\"initialized\", () => {\n if (closed) return;\n clearTimeout(initializeTimer);\n setReady(true);\n // Clear any error the initialize timeout may have set before a slow app\n // finished — otherwise the error overlay stays stuck over a working app.\n setError(null);\n void bridge.sendToolInput({ arguments: app.toolInput });\n void bridge.sendToolResult(app.toolResult as CallToolResult);\n });\n bridge.addEventListener(\"loggingmessage\", ({ level, data }) => {\n if (level === \"error\" || level === \"critical\" || level === \"alert\") {\n console.warn(\"[mcp-app]\", data);\n }\n });\n bridge.onopenlink = async ({ url }) => {\n if (!isSafeExternalUrl(url)) return { isError: true };\n window.open(url, \"_blank\", \"noopener,noreferrer\");\n return {};\n };\n bridge.oncalltool = async ({ name, arguments: toolArguments }) => {\n const toolName = normalizeSameServerToolName(app.serverId, name);\n if (!toolName) {\n return errorToolResult(\"Cross-server MCP App tool calls are blocked.\");\n }\n try {\n return await postMcpAppEndpoint<CallToolResult>(\"call-tool\", {\n serverId: app.serverId,\n toolName,\n arguments:\n toolArguments && typeof toolArguments === \"object\"\n ? toolArguments\n : {},\n });\n } catch (err: any) {\n return errorToolResult(err?.message ?? \"MCP App tool call failed.\");\n }\n };\n (bridge as any).onlisttools = async () =>\n postMcpAppEndpoint(\"list-tools\", { serverId: app.serverId });\n bridge.onreadresource = async ({ uri }) =>\n postMcpAppEndpoint(\"read-resource\", { serverId: app.serverId, uri });\n bridge.onlistresources = async () => ({ resources: [] });\n bridge.onlistresourcetemplates = async () => ({ resourceTemplates: [] });\n bridge.ondownloadfile = async () => ({ isError: true });\n bridge.onmessage = async () => ({ isError: true });\n bridge.onupdatemodelcontext = async () => ({});\n\n const transport = new PostMessageTransport(\n iframe.contentWindow,\n iframe.contentWindow,\n );\n setReady(false);\n setError(null);\n bridge.connect(transport).catch((err: any) => {\n if (!closed) {\n clearTimeout(initializeTimer);\n setError(err?.message ?? \"Failed to initialize MCP App.\");\n }\n });\n\n return () => {\n closed = true;\n clearTimeout(initializeTimer);\n setReady(false);\n void bridge\n .teardownResource({}, { timeout: 500 })\n .catch(() => undefined)\n .finally(() => {\n void (bridge as any).close?.().catch?.(() => undefined);\n });\n };\n }, [\n app,\n applyHeight,\n loadedSrcDoc,\n srcDoc,\n supportedPermissions,\n uiMeta.csp,\n ]);\n\n if (!resourceHtml) {\n return (\n <div className={cn(\"agent-mcp-app agent-mcp-app--error\", className)}>\n <IconAlertTriangle size={15} />\n <span>MCP App resource was not available.</span>\n </div>\n );\n }\n\n return (\n <div\n className={cn(\n \"agent-mcp-app\",\n uiMeta.prefersBorder === false && \"agent-mcp-app--flush\",\n className,\n )}\n >\n {!ready && !error && (\n <div className=\"agent-mcp-app__loading\">\n <IconLoader2 size={14} className=\"agent-conversation-spin\" />\n <span>Loading MCP App</span>\n </div>\n )}\n {error && (\n <div className=\"agent-mcp-app__error\">\n <IconAlertTriangle size={15} />\n <span>{error}</span>\n {externalOpenUrl && (\n <button\n type=\"button\"\n className=\"agent-mcp-app__open\"\n onClick={() =>\n window.open(externalOpenUrl, \"_blank\", \"noopener,noreferrer\")\n }\n >\n Open in new tab\n </button>\n )}\n </div>\n )}\n <iframe\n ref={iframeRef}\n title={app.tool?.title ?? app.originalToolName}\n srcDoc={srcDoc}\n sandbox={SANDBOX_FLAGS}\n allow={buildAllowAttribute(supportedPermissions)}\n style={{ height }}\n onLoad={() => setLoadedSrcDoc(srcDoc)}\n />\n </div>\n );\n}\n\nfunction resourceUiMeta(app: AgentMcpAppPayload): ResourceUiMeta {\n const meta = app.resource?._meta;\n const ui =\n meta?.ui && typeof meta.ui === \"object\" && !Array.isArray(meta.ui)\n ? (meta.ui as ResourceUiMeta)\n : {};\n return ui;\n}\n\nfunction htmlFromResource(\n resource: NonNullable<AgentMcpAppPayload[\"resource\"]>,\n): string {\n if (typeof resource.text === \"string\") return resource.text;\n if (typeof resource.blob !== \"string\") return \"\";\n try {\n if (typeof atob !== \"function\") return \"\";\n return atob(resource.blob);\n } catch {\n return \"\";\n }\n}\n\nfunction recordValue(value: unknown): Record<string, unknown> | null {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\nfunction openUrlRecordValue(value: unknown): string | null {\n const record = recordValue(value);\n const webUrl = record?.webUrl;\n return typeof webUrl === \"string\" && isSafeExternalUrl(webUrl)\n ? webUrl\n : null;\n}\n\nfunction openUrlFromMcpApp(app: AgentMcpAppPayload): string | null {\n const result = recordValue(app.toolResult);\n const meta = recordValue(result?._meta);\n const fromMeta = openUrlRecordValue(meta?.[\"agent-native/openLink\"]);\n if (fromMeta) return fromMeta;\n\n const structuredContent = recordValue(result?.structuredContent);\n const fromStructured = openUrlRecordValue(structuredContent?.openLink);\n if (fromStructured) return fromStructured;\n\n const directUrl = structuredContent?.url ?? result?.url;\n return typeof directUrl === \"string\" && isSafeExternalUrl(directUrl)\n ? directUrl\n : null;\n}\n\nexport function supportedMcpAppPermissions(\n permissions: McpUiResourcePermissions | undefined,\n): McpUiResourcePermissions {\n return permissions?.clipboardWrite ? { clipboardWrite: {} } : {};\n}\n\nexport function buildMcpAppCsp(csp: McpUiResourceCsp | undefined): string {\n const connect = sanitizeCspSources(csp?.connectDomains);\n const resources = sanitizeCspSources(csp?.resourceDomains);\n const frames = sanitizeCspSources(csp?.frameDomains);\n const base = sanitizeCspSources(csp?.baseUriDomains);\n return [\n \"default-src 'none'\",\n `base-uri ${base.length ? base.join(\" \") : \"'none'\"}`,\n \"form-action 'none'\",\n `connect-src ${connect.length ? connect.join(\" \") : \"'none'\"}`,\n `img-src data: blob:${resources.length ? ` ${resources.join(\" \")}` : \"\"}`,\n `media-src data: blob:${resources.length ? ` ${resources.join(\" \")}` : \"\"}`,\n `font-src data:${resources.length ? ` ${resources.join(\" \")}` : \"\"}`,\n `style-src 'unsafe-inline'${resources.length ? ` ${resources.join(\" \")}` : \"\"}`,\n `script-src 'unsafe-inline'${resources.length ? ` ${resources.join(\" \")}` : \"\"}`,\n `frame-src ${frames.length ? frames.join(\" \") : \"'none'\"}`,\n ].join(\"; \");\n}\n\nfunction sanitizeCspSources(values: string[] | undefined): string[] {\n const out: string[] = [];\n for (const value of values ?? []) {\n const source = sanitizeCspSource(value);\n if (source) out.push(source);\n }\n return [...new Set(out)];\n}\n\nfunction sanitizeCspSource(value: string): string | null {\n const source = value.trim();\n if (!source || source.includes(\"'\") || /[\\s;]/.test(source)) return null;\n if (source === \"https:\") return source;\n if (/^http:\\/\\/(?:localhost|127\\.0\\.0\\.1|\\[::1\\]):\\*$/i.test(source)) {\n return source;\n }\n if (/^https:\\/\\/\\*\\.[a-z0-9.-]+(?::\\d+)?$/i.test(source)) return source;\n try {\n const url = new URL(source);\n if (url.protocol === \"https:\") return url.origin;\n if (\n url.protocol === \"http:\" &&\n [\"localhost\", \"127.0.0.1\", \"::1\"].includes(url.hostname)\n ) {\n return url.origin;\n }\n } catch {\n return null;\n }\n return null;\n}\n\nfunction injectCsp(html: string, csp: string): string {\n const meta = `<meta http-equiv=\"Content-Security-Policy\" content=\"${escapeAttribute(csp)}\">`;\n if (/<head\\b[^>]*>/i.test(html)) {\n return html.replace(/<head\\b[^>]*>/i, (head) => `${head}${meta}`);\n }\n if (/<html\\b[^>]*>/i.test(html)) {\n return html.replace(\n /<html\\b[^>]*>/i,\n (htmlTag) => `${htmlTag}<head>${meta}</head>`,\n );\n }\n return `<!doctype html><html><head>${meta}</head><body>${html}</body></html>`;\n}\n\nfunction escapeAttribute(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/</g, \"&lt;\");\n}\n\nfunction buildHostContext(app: AgentMcpAppPayload, maxHeight: number) {\n const root =\n typeof window !== \"undefined\"\n ? getComputedStyle(document.documentElement)\n : null;\n const cssVar = (name: string) => root?.getPropertyValue(name).trim() || \"\";\n const theme =\n typeof document !== \"undefined\" &&\n (document.documentElement.classList.contains(\"dark\") ||\n window.matchMedia?.(\"(prefers-color-scheme: dark)\").matches)\n ? \"dark\"\n : \"light\";\n return {\n toolInfo: app.tool\n ? {\n tool: {\n name: app.originalToolName,\n description: app.tool.description,\n inputSchema: app.tool.inputSchema ?? {\n type: \"object\",\n properties: {},\n },\n ...(app.tool._meta ? { _meta: app.tool._meta } : {}),\n },\n }\n : undefined,\n theme,\n displayMode: \"inline\",\n availableDisplayModes: [\"inline\"],\n platform: \"web\",\n userAgent: \"agent-native\",\n locale: typeof navigator !== \"undefined\" ? navigator.language : undefined,\n timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n containerDimensions: {\n maxHeight,\n maxWidth: typeof window !== \"undefined\" ? window.innerWidth : undefined,\n },\n styles: {\n variables: {\n \"--color-background-primary\": hslVar(cssVar(\"--background\")),\n \"--color-background-secondary\": hslVar(cssVar(\"--muted\")),\n \"--color-text-primary\": hslVar(cssVar(\"--foreground\")),\n \"--color-text-secondary\": hslVar(cssVar(\"--muted-foreground\")),\n \"--color-border-primary\": hslVar(cssVar(\"--border\")),\n \"--font-sans\": cssVar(\"--font-sans\") || \"ui-sans-serif, system-ui\",\n \"--font-mono\":\n cssVar(\"--font-mono\") ||\n \"ui-monospace, SFMono-Regular, Menlo, monospace\",\n \"--border-radius-md\": cssVar(\"--radius\") || \"8px\",\n },\n },\n };\n}\n\nfunction hslVar(value: string): string | undefined {\n return value ? `hsl(${value})` : undefined;\n}\n\nfunction normalizeSameServerToolName(\n serverId: string,\n rawName: string,\n): string | null {\n if (!rawName.trim()) return null;\n const prefix = `mcp__${serverId}__`;\n if (rawName.startsWith(\"mcp__\")) {\n return rawName.startsWith(prefix) ? rawName.slice(prefix.length) : null;\n }\n return rawName;\n}\n\nasync function postMcpAppEndpoint<T>(\n endpoint: \"call-tool\" | \"list-tools\" | \"read-resource\",\n body: Record<string, unknown>,\n): Promise<T> {\n const response = await fetch(\n agentNativePath(`/_agent-native/mcp/apps/${endpoint}`),\n {\n method: \"POST\",\n credentials: \"same-origin\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n },\n );\n if (!response.ok) {\n let message = `MCP App request failed (${response.status})`;\n try {\n const json = await response.json();\n if (typeof json?.error === \"string\") message = json.error;\n } catch {\n // ignore\n }\n throw new Error(message);\n }\n return (await response.json()) as T;\n}\n\nfunction errorToolResult(message: string): CallToolResult {\n return {\n content: [{ type: \"text\", text: `Error: ${message}` }],\n isError: true,\n };\n}\n\nfunction finitePositiveNumber(value: unknown): number | null {\n return typeof value === \"number\" && Number.isFinite(value) && value > 0\n ? value\n : null;\n}\n\nexport function availableMcpAppHeight(\n element: HTMLElement | null | undefined,\n): number {\n if (typeof window === \"undefined\") return DEFAULT_MCP_APP_IFRAME_HEIGHT;\n\n const viewportHeight =\n finitePositiveNumber(window.visualViewport?.height) ??\n finitePositiveNumber(window.innerHeight) ??\n DEFAULT_MCP_APP_IFRAME_HEIGHT;\n\n if (!element) {\n return Math.max(1, Math.floor(viewportHeight - VIEWPORT_MARGIN * 2));\n }\n\n const rect = element.getBoundingClientRect();\n const top = Number.isFinite(rect.top)\n ? Math.max(VIEWPORT_MARGIN, rect.top)\n : VIEWPORT_MARGIN;\n return Math.max(1, Math.floor(viewportHeight - top - VIEWPORT_MARGIN));\n}\n\nexport function clampMcpAppHeight(\n desiredHeight: number,\n maxVisibleHeight: number,\n): number {\n const maxHeight =\n finitePositiveNumber(maxVisibleHeight) ?? DEFAULT_MCP_APP_IFRAME_HEIGHT;\n const desired =\n finitePositiveNumber(desiredHeight) ?? DEFAULT_MCP_APP_IFRAME_HEIGHT;\n const minimum = Math.min(MIN_IFRAME_HEIGHT, maxHeight);\n return Math.max(minimum, Math.min(maxHeight, Math.ceil(desired)));\n}\n\nfunction isSafeExternalUrl(value: string): boolean {\n try {\n const url = new URL(value);\n return url.protocol === \"http:\" || url.protocol === \"https:\";\n } catch {\n return false;\n }\n}\n"]}
1
+ {"version":3,"file":"McpAppRenderer.js","sourceRoot":"","sources":["../../../src/client/mcp-apps/McpAppRenderer.tsx"],"names":[],"mappings":"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","sourcesContent":["import {\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport {\n AppBridge,\n PostMessageTransport,\n buildAllowAttribute,\n type McpUiResourceCsp,\n type McpUiResourcePermissions,\n} from \"@modelcontextprotocol/ext-apps/app-bridge\";\nimport type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { IconAlertTriangle, IconLoader2 } from \"@tabler/icons-react\";\nimport {\n AGENT_NATIVE_EMBED_MESSAGE_TYPES,\n AGENT_NATIVE_EMBED_PROTOCOL,\n AGENT_NATIVE_EMBED_VERSION,\n} from \"../../embedding/protocol.js\";\nimport type { AgentMcpAppPayload } from \"../../mcp-client/app-result.js\";\nimport { agentNativePath } from \"../api-path.js\";\nimport { sendToAgentChat, type AgentChatRequestMode } from \"../agent-chat.js\";\nimport { cn } from \"../utils.js\";\n\nexport const DEFAULT_MCP_APP_IFRAME_HEIGHT = 650;\nexport const MCP_APP_INITIALIZE_TIMEOUT_MS = 8000;\nconst MIN_IFRAME_HEIGHT = 220;\nconst VIEWPORT_MARGIN = 16;\nconst SANDBOX_FLAGS = \"allow-scripts allow-forms allow-popups\";\nconst useBrowserLayoutEffect =\n typeof window === \"undefined\" ? useEffect : useLayoutEffect;\n\nexport interface McpAppRendererProps {\n app: AgentMcpAppPayload;\n className?: string;\n}\n\ntype ResourceUiMeta = {\n csp?: McpUiResourceCsp;\n permissions?: McpUiResourcePermissions;\n prefersBorder?: boolean;\n};\n\ntype McpContentPart = {\n type?: unknown;\n text?: unknown;\n data?: unknown;\n mimeType?: unknown;\n url?: unknown;\n};\n\ntype McpAppModelContext = {\n content?: unknown;\n structuredContent?: unknown;\n};\n\nexport function McpAppRenderer({ app, className }: McpAppRendererProps) {\n const iframeRef = useRef<HTMLIFrameElement | null>(null);\n const desiredHeightRef = useRef(DEFAULT_MCP_APP_IFRAME_HEIGHT);\n const modelContextRef = useRef<McpAppModelContext | null>(null);\n const readyRef = useRef(false);\n const [height, setHeight] = useState(DEFAULT_MCP_APP_IFRAME_HEIGHT);\n const [error, setError] = useState<string | null>(null);\n const [ready, setReady] = useState(false);\n const resourceHtml = app.resource ? htmlFromResource(app.resource) : \"\";\n const uiMeta = useMemo(() => resourceUiMeta(app), [app]);\n const supportedPermissions = useMemo(\n () => supportedMcpAppPermissions(uiMeta.permissions),\n [uiMeta.permissions],\n );\n const csp = buildMcpAppCsp(uiMeta.csp);\n const srcDoc = useMemo(\n () => (resourceHtml ? injectCsp(resourceHtml, csp) : \"\"),\n [resourceHtml, csp],\n );\n const externalOpenUrl = useMemo(() => openUrlFromMcpApp(app), [app]);\n\n // Keep the latest payload/permissions/csp reachable from the bridge effect\n // without making them effect dependencies. The embedded resource identity is\n // fully captured by `srcDoc`. The bridge effect must NOT re-run when a benign\n // parent re-render hands us a new `app` object reference with identical\n // content (common during chat streaming/polling): re-running tears down a\n // live, already-initialized MCP App (teardownResource) and re-arms the\n // initialize watchdog against a fresh host AppBridge that the embed shell\n // will never re-handshake (its connect promise is memoized), surfacing a\n // false \"MCP App did not finish initializing.\" error after the app is\n // visibly working.\n const appRef = useRef(app);\n const supportedPermissionsRef = useRef(supportedPermissions);\n const uiCspRef = useRef(uiMeta.csp);\n appRef.current = app;\n supportedPermissionsRef.current = supportedPermissions;\n uiCspRef.current = uiMeta.csp;\n\n useEffect(() => {\n desiredHeightRef.current = DEFAULT_MCP_APP_IFRAME_HEIGHT;\n setHeight(\n clampMcpAppHeight(\n DEFAULT_MCP_APP_IFRAME_HEIGHT,\n availableMcpAppHeight(iframeRef.current),\n ),\n );\n readyRef.current = false;\n setReady(false);\n setError(null);\n modelContextRef.current = null;\n }, [srcDoc]);\n\n const markReady = useCallback(() => {\n readyRef.current = true;\n setReady(true);\n setError(null);\n }, []);\n\n const applyHeight = useCallback((desiredHeight?: number) => {\n if (\n typeof desiredHeight === \"number\" &&\n Number.isFinite(desiredHeight) &&\n desiredHeight > 0\n ) {\n desiredHeightRef.current = desiredHeight;\n }\n setHeight(\n clampMcpAppHeight(\n desiredHeightRef.current,\n availableMcpAppHeight(iframeRef.current),\n ),\n );\n }, []);\n\n useEffect(() => {\n let frame = 0;\n const update = () => {\n if (frame) cancelAnimationFrame(frame);\n frame = requestAnimationFrame(() => {\n frame = 0;\n applyHeight();\n });\n };\n\n update();\n window.addEventListener(\"resize\", update, { passive: true });\n window.visualViewport?.addEventListener(\"resize\", update, {\n passive: true,\n });\n document.addEventListener(\"scroll\", update, true);\n\n const observer =\n typeof ResizeObserver !== \"undefined\" ? new ResizeObserver(update) : null;\n if (observer) {\n observer.observe(document.documentElement);\n const parent = iframeRef.current?.parentElement;\n if (parent) observer.observe(parent);\n }\n\n return () => {\n if (frame) cancelAnimationFrame(frame);\n window.removeEventListener(\"resize\", update);\n window.visualViewport?.removeEventListener(\"resize\", update);\n document.removeEventListener(\"scroll\", update, true);\n observer?.disconnect();\n };\n }, [applyHeight, srcDoc]);\n\n useEffect(() => {\n const iframe = iframeRef.current;\n if (!iframe?.contentWindow || !srcDoc) return;\n const frameWindow = iframe.contentWindow;\n const listener = (event: MessageEvent) => {\n if (event.source !== frameWindow) return;\n if (isMcpAppReadyMessage(event.data)) {\n markReady();\n }\n };\n window.addEventListener(\"message\", listener);\n return () => window.removeEventListener(\"message\", listener);\n }, [markReady, srcDoc]);\n\n useBrowserLayoutEffect(() => {\n const iframe = iframeRef.current;\n if (!iframe?.contentWindow || !srcDoc) return;\n\n const currentApp = appRef.current;\n let closed = false;\n const initializeTimer = window.setTimeout(() => {\n if (closed || readyRef.current) return;\n setReady(false);\n setError(\"MCP App did not finish initializing.\");\n }, MCP_APP_INITIALIZE_TIMEOUT_MS);\n const bridge = new AppBridge(\n null,\n { name: \"Agent Native\", version: \"1.0.0\" },\n {\n openLinks: {},\n serverTools: {},\n serverResources: {},\n logging: {},\n sandbox: {\n permissions: supportedPermissionsRef.current,\n csp: uiCspRef.current ?? {},\n },\n },\n {\n hostContext: buildHostContext(\n currentApp,\n availableMcpAppHeight(iframe),\n ) as any,\n },\n );\n\n bridge.addEventListener(\"sizechange\", ({ height: nextHeight }) => {\n if (typeof nextHeight !== \"number\" || !Number.isFinite(nextHeight)) {\n return;\n }\n applyHeight(nextHeight);\n });\n bridge.addEventListener(\"initialized\", () => {\n if (closed) return;\n clearTimeout(initializeTimer);\n markReady();\n void bridge.sendToolInput({ arguments: appRef.current.toolInput });\n void bridge.sendToolResult(appRef.current.toolResult as CallToolResult);\n });\n bridge.addEventListener(\"loggingmessage\", ({ level, data }) => {\n if (level === \"error\" || level === \"critical\" || level === \"alert\") {\n console.warn(\"[mcp-app]\", data);\n }\n });\n bridge.onopenlink = async ({ url }) => {\n if (!isSafeExternalUrl(url)) return { isError: true };\n window.open(url, \"_blank\", \"noopener,noreferrer\");\n return {};\n };\n bridge.oncalltool = async ({ name, arguments: toolArguments }) => {\n const toolName = normalizeSameServerToolName(\n appRef.current.serverId,\n name,\n );\n if (!toolName) {\n return errorToolResult(\"Cross-server MCP App tool calls are blocked.\");\n }\n try {\n return await postMcpAppEndpoint<CallToolResult>(\"call-tool\", {\n serverId: appRef.current.serverId,\n toolName,\n arguments:\n toolArguments && typeof toolArguments === \"object\"\n ? toolArguments\n : {},\n });\n } catch (err: any) {\n return errorToolResult(err?.message ?? \"MCP App tool call failed.\");\n }\n };\n (bridge as any).onlisttools = async () =>\n postMcpAppEndpoint(\"list-tools\", { serverId: appRef.current.serverId });\n bridge.onreadresource = async ({ uri }) =>\n postMcpAppEndpoint(\"read-resource\", {\n serverId: appRef.current.serverId,\n uri,\n });\n bridge.onlistresources = async () => ({ resources: [] });\n bridge.onlistresourcetemplates = async () => ({ resourceTemplates: [] });\n bridge.ondownloadfile = async () => ({ isError: true });\n bridge.onmessage = async (params) => {\n const message = messageTextFromMcpUiMessage(params);\n if (!message.trim()) return { isError: true };\n const mode = requestModeFromMcpUiMessage(params);\n sendToAgentChat({\n message,\n context: contextTextFromMcpModelContext(modelContextRef.current),\n images: imageDataUrlsFromMcpContent(params.content),\n submit: true,\n openSidebar: true,\n ...(mode ? { mode } : {}),\n });\n return {};\n };\n bridge.onupdatemodelcontext = async (params) => {\n modelContextRef.current = params as McpAppModelContext;\n return {};\n };\n\n const transport = new PostMessageTransport(\n iframe.contentWindow,\n iframe.contentWindow,\n );\n setError(null);\n void bridge.connect(transport).catch((err: any) => {\n if (!closed) {\n clearTimeout(initializeTimer);\n setError(err?.message ?? \"Failed to initialize MCP App.\");\n }\n });\n\n return () => {\n closed = true;\n modelContextRef.current = null;\n clearTimeout(initializeTimer);\n void bridge\n .teardownResource({}, { timeout: 500 })\n .catch(() => undefined)\n .finally(() => {\n void (bridge as any).close?.().catch?.(() => undefined);\n });\n };\n // The embedded resource identity is captured by `srcDoc`; `app`,\n // `supportedPermissions`, and `uiMeta.csp` are read via refs so a\n // new-but-equal `app` object reference does not tear down a live bridge.\n }, [applyHeight, markReady, srcDoc]);\n\n if (!resourceHtml) {\n return (\n <div className={cn(\"agent-mcp-app agent-mcp-app--error\", className)}>\n <IconAlertTriangle size={15} />\n <span>MCP App resource was not available.</span>\n </div>\n );\n }\n\n return (\n <div\n className={cn(\n \"agent-mcp-app\",\n uiMeta.prefersBorder === false && \"agent-mcp-app--flush\",\n className,\n )}\n >\n {!ready && !error && (\n <div className=\"agent-mcp-app__loading\">\n <IconLoader2 size={14} className=\"agent-conversation-spin\" />\n <span>Loading MCP App</span>\n </div>\n )}\n {error && (\n <div className=\"agent-mcp-app__error\">\n <IconAlertTriangle size={15} />\n <span>{error}</span>\n {externalOpenUrl && (\n <button\n type=\"button\"\n className=\"agent-mcp-app__open\"\n onClick={() =>\n window.open(externalOpenUrl, \"_blank\", \"noopener,noreferrer\")\n }\n >\n Open in new tab\n </button>\n )}\n </div>\n )}\n <iframe\n ref={iframeRef}\n title={app.tool?.title ?? app.originalToolName}\n srcDoc={srcDoc}\n sandbox={SANDBOX_FLAGS}\n allow={buildAllowAttribute(supportedPermissions)}\n style={{ height }}\n />\n </div>\n );\n}\n\nfunction messageTextFromMcpUiMessage(params: { content?: unknown }): string {\n return textPartsFromMcpContent(params.content).join(\"\\n\\n\").trim();\n}\n\nfunction requestModeFromMcpUiMessage(\n params: unknown,\n): AgentChatRequestMode | undefined {\n const record =\n params && typeof params === \"object\" && !Array.isArray(params)\n ? (params as { mode?: unknown; requestMode?: unknown })\n : {};\n const mode = record.requestMode ?? record.mode;\n return mode === \"act\" || mode === \"plan\" ? mode : undefined;\n}\n\nfunction contextTextFromMcpModelContext(\n context: McpAppModelContext | null,\n): string | undefined {\n if (!context) return undefined;\n const parts = textPartsFromMcpContent(context.content);\n if (context.structuredContent !== undefined) {\n parts.push(JSON.stringify(context.structuredContent, null, 2));\n }\n const text = parts.join(\"\\n\\n\").trim();\n return text || undefined;\n}\n\nfunction textPartsFromMcpContent(content: unknown): string[] {\n if (!Array.isArray(content)) return [];\n return content\n .map((part): string | null => {\n const record = contentPartRecord(part);\n if (\n !record ||\n record.type !== \"text\" ||\n typeof record.text !== \"string\"\n ) {\n return null;\n }\n const text = record.text.trim();\n return text || null;\n })\n .filter((text): text is string => Boolean(text));\n}\n\nfunction imageDataUrlsFromMcpContent(content: unknown): string[] | undefined {\n if (!Array.isArray(content)) return undefined;\n const images = content\n .map((part): string | null => {\n const record = contentPartRecord(part);\n if (!record || record.type !== \"image\") return null;\n if (typeof record.url === \"string\" && record.url.trim()) {\n return record.url;\n }\n if (typeof record.data !== \"string\" || !record.data.trim()) return null;\n const mimeType =\n typeof record.mimeType === \"string\" &&\n record.mimeType.startsWith(\"image/\")\n ? record.mimeType\n : \"image/png\";\n return `data:${mimeType};base64,${record.data}`;\n })\n .filter((image): image is string => Boolean(image));\n return images.length ? images : undefined;\n}\n\nfunction contentPartRecord(part: unknown): McpContentPart | null {\n return part && typeof part === \"object\" && !Array.isArray(part)\n ? (part as McpContentPart)\n : null;\n}\n\nfunction resourceUiMeta(app: AgentMcpAppPayload): ResourceUiMeta {\n const meta = app.resource?._meta;\n const ui =\n meta?.ui && typeof meta.ui === \"object\" && !Array.isArray(meta.ui)\n ? (meta.ui as ResourceUiMeta)\n : {};\n return ui;\n}\n\nfunction htmlFromResource(\n resource: NonNullable<AgentMcpAppPayload[\"resource\"]>,\n): string {\n if (typeof resource.text === \"string\") return resource.text;\n if (typeof resource.blob !== \"string\") return \"\";\n try {\n if (typeof atob !== \"function\") return \"\";\n return atob(resource.blob);\n } catch {\n return \"\";\n }\n}\n\nfunction recordValue(value: unknown): Record<string, unknown> | null {\n return value && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\nfunction openUrlRecordValue(value: unknown): string | null {\n const record = recordValue(value);\n const webUrl = record?.webUrl;\n return typeof webUrl === \"string\" && isSafeExternalUrl(webUrl)\n ? webUrl\n : null;\n}\n\nfunction openUrlFromMcpApp(app: AgentMcpAppPayload): string | null {\n const result = recordValue(app.toolResult);\n const meta = recordValue(result?._meta);\n const fromMeta = openUrlRecordValue(meta?.[\"agent-native/openLink\"]);\n if (fromMeta) return fromMeta;\n\n const structuredContent = recordValue(result?.structuredContent);\n const fromStructured = openUrlRecordValue(structuredContent?.openLink);\n if (fromStructured) return fromStructured;\n\n const directUrl = structuredContent?.url ?? result?.url;\n return typeof directUrl === \"string\" && isSafeExternalUrl(directUrl)\n ? directUrl\n : null;\n}\n\nexport function supportedMcpAppPermissions(\n permissions: McpUiResourcePermissions | undefined,\n): McpUiResourcePermissions {\n return permissions?.clipboardWrite ? { clipboardWrite: {} } : {};\n}\n\nexport function isMcpAppReadyMessage(data: unknown): boolean {\n if (!data || typeof data !== \"object\" || Array.isArray(data)) return false;\n const record = data as {\n protocol?: unknown;\n version?: unknown;\n type?: unknown;\n };\n if (\n record.protocol === AGENT_NATIVE_EMBED_PROTOCOL &&\n record.version === AGENT_NATIVE_EMBED_VERSION &&\n record.type === AGENT_NATIVE_EMBED_MESSAGE_TYPES.READY\n ) {\n return true;\n }\n const type = record.type;\n return (\n type === \"agentNative.embeddedAppReady\" ||\n type === \"agentNative.frameOrigin\"\n );\n}\n\nexport function buildMcpAppCsp(csp: McpUiResourceCsp | undefined): string {\n const connect = withLocalWebSocketSources(\n sanitizeCspSources(csp?.connectDomains),\n );\n const resources = sanitizeCspSources(csp?.resourceDomains);\n const frames = sanitizeCspSources(csp?.frameDomains);\n const base = sanitizeCspSources(csp?.baseUriDomains);\n return [\n \"default-src 'none'\",\n `base-uri ${base.length ? base.join(\" \") : \"'none'\"}`,\n \"form-action 'none'\",\n `connect-src ${connect.length ? connect.join(\" \") : \"'none'\"}`,\n `img-src data: blob:${resources.length ? ` ${resources.join(\" \")}` : \"\"}`,\n `media-src data: blob:${resources.length ? ` ${resources.join(\" \")}` : \"\"}`,\n `font-src data:${resources.length ? ` ${resources.join(\" \")}` : \"\"}`,\n `style-src 'unsafe-inline'${resources.length ? ` ${resources.join(\" \")}` : \"\"}`,\n `script-src 'unsafe-inline'${resources.length ? ` ${resources.join(\" \")}` : \"\"}`,\n `frame-src ${frames.length ? frames.join(\" \") : \"'none'\"}`,\n ].join(\"; \");\n}\n\nfunction sanitizeCspSources(values: string[] | undefined): string[] {\n const out: string[] = [];\n for (const value of values ?? []) {\n const source = sanitizeCspSource(value);\n if (source) out.push(source);\n }\n return [...new Set(out)];\n}\n\nfunction withLocalWebSocketSources(sources: string[]): string[] {\n const out = [...sources];\n for (const source of sources) {\n try {\n const url = new URL(source);\n if (\n url.protocol === \"http:\" &&\n [\"localhost\", \"127.0.0.1\", \"::1\"].includes(url.hostname)\n ) {\n out.push(`ws://${url.host}`);\n }\n } catch {\n // Ignore non-URL CSP source expressions.\n }\n }\n return [...new Set(out)];\n}\n\nfunction sanitizeCspSource(value: string): string | null {\n const source = value.trim();\n if (!source || source.includes(\"'\") || /[\\s;]/.test(source)) return null;\n if (source === \"https:\") return source;\n if (/^http:\\/\\/(?:localhost|127\\.0\\.0\\.1|\\[::1\\]):\\*$/i.test(source)) {\n return source;\n }\n if (/^https:\\/\\/\\*\\.[a-z0-9.-]+(?::\\d+)?$/i.test(source)) return source;\n try {\n const url = new URL(source);\n if (url.protocol === \"https:\") return url.origin;\n if (\n url.protocol === \"http:\" &&\n [\"localhost\", \"127.0.0.1\", \"::1\"].includes(url.hostname)\n ) {\n return url.origin;\n }\n } catch {\n return null;\n }\n return null;\n}\n\nfunction injectCsp(html: string, csp: string): string {\n const meta = `<meta http-equiv=\"Content-Security-Policy\" content=\"${escapeAttribute(csp)}\">`;\n if (/<head\\b[^>]*>/i.test(html)) {\n return html.replace(/<head\\b[^>]*>/i, (head) => `${head}${meta}`);\n }\n if (/<html\\b[^>]*>/i.test(html)) {\n return html.replace(\n /<html\\b[^>]*>/i,\n (htmlTag) => `${htmlTag}<head>${meta}</head>`,\n );\n }\n return `<!doctype html><html><head>${meta}</head><body>${html}</body></html>`;\n}\n\nfunction escapeAttribute(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/</g, \"&lt;\");\n}\n\nfunction buildHostContext(app: AgentMcpAppPayload, maxHeight: number) {\n const root =\n typeof window !== \"undefined\"\n ? getComputedStyle(document.documentElement)\n : null;\n const cssVar = (name: string) => root?.getPropertyValue(name).trim() || \"\";\n const theme =\n typeof document !== \"undefined\" &&\n (document.documentElement.classList.contains(\"dark\") ||\n window.matchMedia?.(\"(prefers-color-scheme: dark)\").matches)\n ? \"dark\"\n : \"light\";\n return {\n toolInfo: app.tool\n ? {\n tool: {\n name: app.originalToolName,\n description: app.tool.description,\n inputSchema: app.tool.inputSchema ?? {\n type: \"object\",\n properties: {},\n },\n ...(app.tool._meta ? { _meta: app.tool._meta } : {}),\n },\n }\n : undefined,\n theme,\n displayMode: \"inline\",\n availableDisplayModes: [\"inline\"],\n platform: \"web\",\n userAgent: \"agent-native\",\n locale: typeof navigator !== \"undefined\" ? navigator.language : undefined,\n timeZone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n containerDimensions: {\n maxHeight,\n maxWidth: typeof window !== \"undefined\" ? window.innerWidth : undefined,\n },\n styles: {\n variables: {\n \"--color-background-primary\": hslVar(cssVar(\"--background\")),\n \"--color-background-secondary\": hslVar(cssVar(\"--muted\")),\n \"--color-text-primary\": hslVar(cssVar(\"--foreground\")),\n \"--color-text-secondary\": hslVar(cssVar(\"--muted-foreground\")),\n \"--color-border-primary\": hslVar(cssVar(\"--border\")),\n \"--font-sans\": cssVar(\"--font-sans\") || \"ui-sans-serif, system-ui\",\n \"--font-mono\":\n cssVar(\"--font-mono\") ||\n \"ui-monospace, SFMono-Regular, Menlo, monospace\",\n \"--border-radius-md\": cssVar(\"--radius\") || \"8px\",\n },\n },\n };\n}\n\nfunction hslVar(value: string): string | undefined {\n return value ? `hsl(${value})` : undefined;\n}\n\nfunction normalizeSameServerToolName(\n serverId: string,\n rawName: string,\n): string | null {\n if (!rawName.trim()) return null;\n const prefix = `mcp__${serverId}__`;\n if (rawName.startsWith(\"mcp__\")) {\n return rawName.startsWith(prefix) ? rawName.slice(prefix.length) : null;\n }\n return rawName;\n}\n\nasync function postMcpAppEndpoint<T>(\n endpoint: \"call-tool\" | \"list-tools\" | \"read-resource\",\n body: Record<string, unknown>,\n): Promise<T> {\n const response = await fetch(\n agentNativePath(`/_agent-native/mcp/apps/${endpoint}`),\n {\n method: \"POST\",\n credentials: \"same-origin\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n },\n );\n if (!response.ok) {\n let message = `MCP App request failed (${response.status})`;\n try {\n const json = await response.json();\n if (typeof json?.error === \"string\") message = json.error;\n } catch {\n // ignore\n }\n throw new Error(message);\n }\n return (await response.json()) as T;\n}\n\nfunction errorToolResult(message: string): CallToolResult {\n return {\n content: [{ type: \"text\", text: `Error: ${message}` }],\n isError: true,\n };\n}\n\nfunction finitePositiveNumber(value: unknown): number | null {\n return typeof value === \"number\" && Number.isFinite(value) && value > 0\n ? value\n : null;\n}\n\nexport function availableMcpAppHeight(\n element: HTMLElement | null | undefined,\n): number {\n if (typeof window === \"undefined\") return DEFAULT_MCP_APP_IFRAME_HEIGHT;\n\n const viewportHeight =\n finitePositiveNumber(window.visualViewport?.height) ??\n finitePositiveNumber(window.innerHeight) ??\n DEFAULT_MCP_APP_IFRAME_HEIGHT;\n\n if (!element) {\n return Math.max(1, Math.floor(viewportHeight - VIEWPORT_MARGIN * 2));\n }\n\n const rect = element.getBoundingClientRect();\n const top = Number.isFinite(rect.top)\n ? Math.max(VIEWPORT_MARGIN, rect.top)\n : VIEWPORT_MARGIN;\n return Math.max(1, Math.floor(viewportHeight - top - VIEWPORT_MARGIN));\n}\n\nexport function clampMcpAppHeight(\n desiredHeight: number,\n maxVisibleHeight: number,\n): number {\n const maxHeight =\n finitePositiveNumber(maxVisibleHeight) ?? DEFAULT_MCP_APP_IFRAME_HEIGHT;\n const desired =\n finitePositiveNumber(desiredHeight) ?? DEFAULT_MCP_APP_IFRAME_HEIGHT;\n const minimum = Math.min(MIN_IFRAME_HEIGHT, maxHeight);\n return Math.max(minimum, Math.min(maxHeight, Math.ceil(desired)));\n}\n\nfunction isSafeExternalUrl(value: string): boolean {\n try {\n const url = new URL(value);\n return url.protocol === \"http:\" || url.protocol === \"https:\";\n } catch {\n return false;\n }\n}\n"]}
@@ -17,6 +17,7 @@ export interface McpServer {
17
17
  set: true;
18
18
  }>;
19
19
  description?: string;
20
+ firstParty?: boolean;
20
21
  createdAt: number;
21
22
  mergedId: string;
22
23
  status: {
@@ -1 +1 @@
1
- {"version":3,"file":"use-mcp-servers.d.ts","sourceRoot":"","sources":["../../../src/client/resources/use-mcp-servers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,KAAK,CAAC;AAE5C,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,cAAc,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,IAAI,CAAA;KAAE,CAAC,CAAC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EACF;QAAE,KAAK,EAAE,WAAW,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GACzC;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GACjC;QAAE,KAAK,EAAE,SAAS,CAAA;KAAE,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,GAAG,EAAE,SAAS,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAKD,wBAAgB,aAAa,0EAU5B;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,cAAc,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,kBAAkB,sGAsBjC;AAED,wBAAgB,kBAAkB;QAGC,MAAM;WAAS,cAAc;YAmB/D;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAmBtE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAoC3D;AAED,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,OAAO,CAAC,gBAAgB,CAAC,CAmB3B;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5E;AAED,wBAAgB,iBAAiB,CAC/B,EAAE,EAAE,MAAM,GACT;IAAE,KAAK,EAAE,cAAc,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAIpD"}
1
+ {"version":3,"file":"use-mcp-servers.d.ts","sourceRoot":"","sources":["../../../src/client/resources/use-mcp-servers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,KAAK,CAAC;AAE5C,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,cAAc,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,IAAI,CAAA;KAAE,CAAC,CAAC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EACF;QAAE,KAAK,EAAE,WAAW,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GACzC;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GACjC;QAAE,KAAK,EAAE,SAAS,CAAA;KAAE,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,GAAG,EAAE,SAAS,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAKD,wBAAgB,aAAa,0EAU5B;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,cAAc,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,kBAAkB,sGAsBjC;AAED,wBAAgB,kBAAkB;QAGC,MAAM;WAAS,cAAc;YAmB/D;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAmBtE;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAoC3D;AAED,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,OAAO,CAAC,gBAAgB,CAAC,CAmB3B;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5E;AAED,wBAAgB,iBAAiB,CAC/B,EAAE,EAAE,MAAM,GACT;IAAE,KAAK,EAAE,cAAc,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAIpD"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-mcp-servers.js","sourceRoot":"","sources":["../../../src/client/resources/use-mcp-servers.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * React-query hooks for remote MCP servers surfaced inside the Workspace\n * tab as a virtual `mcp-servers/` folder.\n *\n * MCP servers live in the settings store (user- and org-scope), not the\n * resources table. These hooks wrap the existing `/_agent-native/mcp/servers`\n * endpoints so the Workspace UI can list, create, and delete them with the\n * same keys/invalidations the old Settings panel used.\n */\n\nimport { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { agentNativePath } from \"../api-path.js\";\n\nexport type McpServerScope = \"user\" | \"org\";\n\nexport interface McpServer {\n id: string;\n scope: McpServerScope;\n name: string;\n url: string;\n headers?: Record<string, { set: true }>;\n description?: string;\n createdAt: number;\n mergedId: string;\n status:\n | { state: \"connected\"; toolCount: number }\n | { state: \"error\"; error: string }\n | { state: \"unknown\" };\n}\n\nexport interface McpServersList {\n user: McpServer[];\n org: McpServer[];\n orgId: string | null;\n role: string | null;\n}\n\nconst ENDPOINT = agentNativePath(\"/_agent-native/mcp/servers\");\nconst LIST_KEY = [\"mcp-servers\"] as const;\n\nexport function useMcpServers() {\n return useQuery<McpServersList>({\n queryKey: LIST_KEY,\n queryFn: async () => {\n const res = await fetch(ENDPOINT, { credentials: \"include\" });\n if (!res.ok) throw new Error(`Failed to load (${res.status})`);\n return (await res.json()) as McpServersList;\n },\n staleTime: 10_000,\n });\n}\n\nexport interface CreateMcpServerArgs {\n scope: McpServerScope;\n name: string;\n url: string;\n headers?: Record<string, string>;\n description?: string;\n}\n\nexport function useCreateMcpServer() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: async (args: CreateMcpServerArgs) => {\n const res = await fetch(ENDPOINT, {\n method: \"POST\",\n credentials: \"include\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(args),\n });\n const body = (await res.json().catch(() => ({}))) as {\n ok?: boolean;\n error?: string;\n server?: McpServer;\n };\n if (!res.ok || !body.ok) {\n throw new Error(body.error || `Create failed (${res.status})`);\n }\n return body.server!;\n },\n onSuccess: () => qc.invalidateQueries({ queryKey: LIST_KEY }),\n });\n}\n\nexport function useDeleteMcpServer() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: async (args: { id: string; scope: McpServerScope }) => {\n const res = await fetch(\n `${ENDPOINT}/${encodeURIComponent(args.id)}?scope=${args.scope}`,\n {\n method: \"DELETE\",\n credentials: \"include\",\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n const body = (await res.json().catch(() => ({}))) as {\n ok?: boolean;\n error?: string;\n };\n if (!res.ok || !body.ok) {\n throw new Error(body.error || `Delete failed (${res.status})`);\n }\n },\n onSuccess: () => qc.invalidateQueries({ queryKey: LIST_KEY }),\n });\n}\n\nexport interface TestMcpUrlResult {\n ok: boolean;\n error?: string;\n toolCount?: number;\n tools?: string[];\n}\n\nexport function getMcpUrlValidationError(rawUrl: string): string | null {\n const trimmed = rawUrl.trim();\n if (!trimmed) return \"Enter the Streamable HTTP MCP server URL.\";\n let url: URL;\n try {\n url = new URL(trimmed);\n } catch {\n return \"Enter a full URL, including https://.\";\n }\n if (url.protocol !== \"https:\" && url.protocol !== \"http:\") {\n return \"MCP server URLs must start with https://.\";\n }\n if (\n url.protocol === \"http:\" &&\n ![\"localhost\", \"127.0.0.1\"].includes(url.hostname)\n ) {\n return \"Use https:// for remote MCP servers. Plain http:// is only allowed for localhost.\";\n }\n return null;\n}\n\nexport function formatMcpServerError(error: unknown): string {\n const raw =\n typeof error === \"string\"\n ? error\n : error instanceof Error\n ? error.message\n : String(error ?? \"\");\n const text = raw.trim();\n if (!text) return \"Could not connect to that MCP server.\";\n if (\n /<!doctype|<html[\\s>]|<\\/html>|unexpected token '<'|is not valid json/i.test(\n text,\n )\n ) {\n return \"That URL returned a web page instead of an MCP response. Check that you pasted the Streamable HTTP endpoint, often ending in /mcp.\";\n }\n if (\n /streamable http/i.test(text) &&\n /error|failed|non-200|status/i.test(text)\n ) {\n return \"The server did not complete the Streamable HTTP MCP handshake. Check the URL and any required authorization headers.\";\n }\n if (\n /failed to fetch|fetch failed|networkerror|econnrefused|enotfound|timed out/i.test(\n text,\n )\n ) {\n return \"Could not reach that MCP server. Check the URL and make sure it is publicly reachable from this app.\";\n }\n if (/401|403|unauthorized|forbidden/i.test(text)) {\n return \"The MCP server rejected the request. Add or update the required Authorization header.\";\n }\n if (/404|not found|405|method not allowed/i.test(text)) {\n return \"That URL is reachable, but it does not look like the MCP endpoint. Check the server's Streamable HTTP path.\";\n }\n return text.length > 240 ? `${text.slice(0, 237).trimEnd()}...` : text;\n}\n\nexport async function testMcpServerUrl(\n url: string,\n headers?: Record<string, string>,\n): Promise<TestMcpUrlResult> {\n const validationError = getMcpUrlValidationError(url);\n if (validationError) return { ok: false, error: validationError };\n const res = await fetch(`${ENDPOINT}/test`, {\n method: \"POST\",\n credentials: \"include\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ url, headers }),\n });\n const body = (await res.json().catch(() => ({}))) as TestMcpUrlResult;\n if (!res.ok) {\n return {\n ok: false,\n error: formatMcpServerError(body.error || \"Test failed\"),\n };\n }\n return body.ok === false\n ? { ...body, error: formatMcpServerError(body.error) }\n : body;\n}\n\n/**\n * Virtual tree-node id used when a server is surfaced in the Workspace tree.\n * Shape: `mcp:<scope>:<serverId>`. Not a real resource row; purely a handle\n * the panel uses to route clicks/delete back to the MCP endpoints.\n */\nexport function mcpVirtualId(scope: McpServerScope, serverId: string): string {\n return `mcp:${scope}:${serverId}`;\n}\n\nexport function parseMcpVirtualId(\n id: string,\n): { scope: McpServerScope; serverId: string } | null {\n const m = /^mcp:(user|org):(.+)$/.exec(id);\n if (!m) return null;\n return { scope: m[1] as McpServerScope, serverId: m[2] };\n}\n"]}
1
+ {"version":3,"file":"use-mcp-servers.js","sourceRoot":"","sources":["../../../src/client/resources/use-mcp-servers.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * React-query hooks for remote MCP servers surfaced inside the Workspace\n * tab as a virtual `mcp-servers/` folder.\n *\n * MCP servers live in the settings store (user- and org-scope), not the\n * resources table. These hooks wrap the existing `/_agent-native/mcp/servers`\n * endpoints so the Workspace UI can list, create, and delete them with the\n * same keys/invalidations the old Settings panel used.\n */\n\nimport { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { agentNativePath } from \"../api-path.js\";\n\nexport type McpServerScope = \"user\" | \"org\";\n\nexport interface McpServer {\n id: string;\n scope: McpServerScope;\n name: string;\n url: string;\n headers?: Record<string, { set: true }>;\n description?: string;\n firstParty?: boolean;\n createdAt: number;\n mergedId: string;\n status:\n | { state: \"connected\"; toolCount: number }\n | { state: \"error\"; error: string }\n | { state: \"unknown\" };\n}\n\nexport interface McpServersList {\n user: McpServer[];\n org: McpServer[];\n orgId: string | null;\n role: string | null;\n}\n\nconst ENDPOINT = agentNativePath(\"/_agent-native/mcp/servers\");\nconst LIST_KEY = [\"mcp-servers\"] as const;\n\nexport function useMcpServers() {\n return useQuery<McpServersList>({\n queryKey: LIST_KEY,\n queryFn: async () => {\n const res = await fetch(ENDPOINT, { credentials: \"include\" });\n if (!res.ok) throw new Error(`Failed to load (${res.status})`);\n return (await res.json()) as McpServersList;\n },\n staleTime: 10_000,\n });\n}\n\nexport interface CreateMcpServerArgs {\n scope: McpServerScope;\n name: string;\n url: string;\n headers?: Record<string, string>;\n description?: string;\n}\n\nexport function useCreateMcpServer() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: async (args: CreateMcpServerArgs) => {\n const res = await fetch(ENDPOINT, {\n method: \"POST\",\n credentials: \"include\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(args),\n });\n const body = (await res.json().catch(() => ({}))) as {\n ok?: boolean;\n error?: string;\n server?: McpServer;\n };\n if (!res.ok || !body.ok) {\n throw new Error(body.error || `Create failed (${res.status})`);\n }\n return body.server!;\n },\n onSuccess: () => qc.invalidateQueries({ queryKey: LIST_KEY }),\n });\n}\n\nexport function useDeleteMcpServer() {\n const qc = useQueryClient();\n return useMutation({\n mutationFn: async (args: { id: string; scope: McpServerScope }) => {\n const res = await fetch(\n `${ENDPOINT}/${encodeURIComponent(args.id)}?scope=${args.scope}`,\n {\n method: \"DELETE\",\n credentials: \"include\",\n headers: { \"Content-Type\": \"application/json\" },\n },\n );\n const body = (await res.json().catch(() => ({}))) as {\n ok?: boolean;\n error?: string;\n };\n if (!res.ok || !body.ok) {\n throw new Error(body.error || `Delete failed (${res.status})`);\n }\n },\n onSuccess: () => qc.invalidateQueries({ queryKey: LIST_KEY }),\n });\n}\n\nexport interface TestMcpUrlResult {\n ok: boolean;\n error?: string;\n toolCount?: number;\n tools?: string[];\n}\n\nexport function getMcpUrlValidationError(rawUrl: string): string | null {\n const trimmed = rawUrl.trim();\n if (!trimmed) return \"Enter the Streamable HTTP MCP server URL.\";\n let url: URL;\n try {\n url = new URL(trimmed);\n } catch {\n return \"Enter a full URL, including https://.\";\n }\n if (url.protocol !== \"https:\" && url.protocol !== \"http:\") {\n return \"MCP server URLs must start with https://.\";\n }\n if (\n url.protocol === \"http:\" &&\n ![\"localhost\", \"127.0.0.1\"].includes(url.hostname)\n ) {\n return \"Use https:// for remote MCP servers. Plain http:// is only allowed for localhost.\";\n }\n return null;\n}\n\nexport function formatMcpServerError(error: unknown): string {\n const raw =\n typeof error === \"string\"\n ? error\n : error instanceof Error\n ? error.message\n : String(error ?? \"\");\n const text = raw.trim();\n if (!text) return \"Could not connect to that MCP server.\";\n if (\n /<!doctype|<html[\\s>]|<\\/html>|unexpected token '<'|is not valid json/i.test(\n text,\n )\n ) {\n return \"That URL returned a web page instead of an MCP response. Check that you pasted the Streamable HTTP endpoint, often ending in /mcp.\";\n }\n if (\n /streamable http/i.test(text) &&\n /error|failed|non-200|status/i.test(text)\n ) {\n return \"The server did not complete the Streamable HTTP MCP handshake. Check the URL and any required authorization headers.\";\n }\n if (\n /failed to fetch|fetch failed|networkerror|econnrefused|enotfound|timed out/i.test(\n text,\n )\n ) {\n return \"Could not reach that MCP server. Check the URL and make sure it is publicly reachable from this app.\";\n }\n if (/401|403|unauthorized|forbidden/i.test(text)) {\n return \"The MCP server rejected the request. Add or update the required Authorization header.\";\n }\n if (/404|not found|405|method not allowed/i.test(text)) {\n return \"That URL is reachable, but it does not look like the MCP endpoint. Check the server's Streamable HTTP path.\";\n }\n return text.length > 240 ? `${text.slice(0, 237).trimEnd()}...` : text;\n}\n\nexport async function testMcpServerUrl(\n url: string,\n headers?: Record<string, string>,\n): Promise<TestMcpUrlResult> {\n const validationError = getMcpUrlValidationError(url);\n if (validationError) return { ok: false, error: validationError };\n const res = await fetch(`${ENDPOINT}/test`, {\n method: \"POST\",\n credentials: \"include\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ url, headers }),\n });\n const body = (await res.json().catch(() => ({}))) as TestMcpUrlResult;\n if (!res.ok) {\n return {\n ok: false,\n error: formatMcpServerError(body.error || \"Test failed\"),\n };\n }\n return body.ok === false\n ? { ...body, error: formatMcpServerError(body.error) }\n : body;\n}\n\n/**\n * Virtual tree-node id used when a server is surfaced in the Workspace tree.\n * Shape: `mcp:<scope>:<serverId>`. Not a real resource row; purely a handle\n * the panel uses to route clicks/delete back to the MCP endpoints.\n */\nexport function mcpVirtualId(scope: McpServerScope, serverId: string): string {\n return `mcp:${scope}:${serverId}`;\n}\n\nexport function parseMcpVirtualId(\n id: string,\n): { scope: McpServerScope; serverId: string } | null {\n const m = /^mcp:(user|org):(.+)$/.exec(id);\n if (!m) return null;\n return { scope: m[1] as McpServerScope, serverId: m[2] };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"DemoModeSection.d.ts","sourceRoot":"","sources":["../../../src/client/settings/DemoModeSection.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAiBH,wBAAgB,eAAe,4CA0F9B;AAED,wBAAgB,YAAY,4CAE3B"}
1
+ {"version":3,"file":"DemoModeSection.d.ts","sourceRoot":"","sources":["../../../src/client/settings/DemoModeSection.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAiBH,wBAAgB,eAAe,4CA4F9B;AAED,wBAAgB,YAAY,4CAE3B"}
@@ -23,7 +23,9 @@ export function DemoModeSection() {
23
23
  const { data } = useQuery({
24
24
  queryKey: ["agent-native", "demo-mode"],
25
25
  queryFn: async () => {
26
- const res = await fetch(DEMO_STATUS_URL, { credentials: "include" });
26
+ const res = await fetch(DEMO_STATUS_URL, {
27
+ credentials: "same-origin",
28
+ });
27
29
  if (!res.ok)
28
30
  return null;
29
31
  return (await res.json());