@agent-native/core 0.22.10 → 0.22.11

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.
@@ -1 +1 @@
1
- {"version":3,"file":"build-server.d.ts","sourceRoot":"","sources":["../../src/mcp/build-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAuBhE,MAAM,WAAW,SAAS;IACxB,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACrC;;;;;;;;;;;OAWG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAChD,qEAAqE;IACrE,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD;;;;;;OAMG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;;kEAGkE;AAClE,MAAM,WAAW,cAAc;IAC7B,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,MAAM,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;IAC5C;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAwBD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,MAAM,EAAE,GAAG,EACX,IAAI,EAAE,cAAc,GAAG,SAAS,GAC/B;IACD,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC,CAyBA;AAyJD;;;;;;;GAOG;AACH,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,iBAAiB,GAAG,SAAS,EACvC,WAAW,CAAC,EAAE,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAgU7B;AAOD,wBAAgB,eAAe,IAAI,MAAM,EAAE,CAc1C;AAyCD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,UAAU,CAC9B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,EACrC,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7D,OAAO,CAAC;IACT,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC,CAkHD;AAED,wBAAsB,sBAAsB,CAC1C,SAAS,EAAE,MAAM,GAAG,SAAS,GAC5B,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAS7B"}
1
+ {"version":3,"file":"build-server.d.ts","sourceRoot":"","sources":["../../src/mcp/build-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAuBhE,MAAM,WAAW,SAAS;IACxB,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACrC;;;;;;;;;;;OAWG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAChD,qEAAqE;IACrE,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD;;;;;;OAMG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;;kEAGkE;AAClE,MAAM,WAAW,cAAc;IAC7B,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,MAAM,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,UAAU,CAAC;IAC5C;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AA+CD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACzB,MAAM,EAAE,GAAG,EACX,IAAI,EAAE,cAAc,GAAG,SAAS,GAC/B;IACD,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC,CAyBA;AA2QD;;;;;;;GAOG;AACH,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,iBAAiB,GAAG,SAAS,EACvC,WAAW,CAAC,EAAE,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAiX7B;AAOD,wBAAgB,eAAe,IAAI,MAAM,EAAE,CAc1C;AAyCD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,UAAU,CAC9B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,gBAAgB,CAAC,EAAE,MAAM,GAAG,SAAS,EACrC,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7D,OAAO,CAAC;IACT,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC,CAkHD;AAED,wBAAsB,sBAAsB,CAC1C,SAAS,EAAE,MAAM,GAAG,SAAS,GAC5B,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAS7B"}
@@ -32,6 +32,25 @@ function isActionVisibleForOAuthScope(entry, scopes) {
32
32
  const required = entry.readOnly === true ? "mcp:read" : "mcp:write";
33
33
  return hasMcpOAuthScope(scopes, required);
34
34
  }
35
+ const COMPACT_MCP_APP_CATALOG_BUILTINS = new Set([
36
+ "list_apps",
37
+ "open_app",
38
+ "create_embed_session",
39
+ ]);
40
+ function isDispatchConfig(config) {
41
+ const id = (config.appId ?? "").toLowerCase();
42
+ const name = (config.name ?? "").toLowerCase();
43
+ return id === "dispatch" || name.includes("dispatch");
44
+ }
45
+ function isActionAdvertisedInCompactMcpAppCatalog(config, name, entry) {
46
+ if (COMPACT_MCP_APP_CATALOG_BUILTINS.has(name))
47
+ return true;
48
+ if (name === "ask_app" && isDispatchConfig(config))
49
+ return true;
50
+ if (entry.mcpApp?.resource)
51
+ return true;
52
+ return entry.publicAgent?.expose === true;
53
+ }
35
54
  /**
36
55
  * Build the deep-link content block + structured `_meta` for a tool result.
37
56
  * Best-effort: any throw / nullish link is swallowed so a bad `link` builder
@@ -108,7 +127,22 @@ function expandRequestOriginSources(sources, requestMeta) {
108
127
  ? [origin]
109
128
  : [source]);
110
129
  }
111
- function mcpAppUiMeta(resource, requestMeta) {
130
+ function openAiWidgetCsp(resource, requestMeta) {
131
+ if (!resource.csp)
132
+ return undefined;
133
+ const csp = {};
134
+ const connectDomains = expandRequestOriginSources(resource.csp.connectDomains, requestMeta);
135
+ const resourceDomains = expandRequestOriginSources(resource.csp.resourceDomains, requestMeta);
136
+ const frameDomains = expandRequestOriginSources(resource.csp.frameDomains, requestMeta);
137
+ if (connectDomains?.length)
138
+ csp.connect_domains = connectDomains;
139
+ if (resourceDomains?.length)
140
+ csp.resource_domains = resourceDomains;
141
+ if (frameDomains?.length)
142
+ csp.frame_domains = frameDomains;
143
+ return Object.keys(csp).length > 0 ? csp : undefined;
144
+ }
145
+ function mcpAppUiMeta(resource, requestMeta, description) {
112
146
  const base = resource._meta && typeof resource._meta === "object"
113
147
  ? { ...resource._meta }
114
148
  : {};
@@ -134,6 +168,17 @@ function mcpAppUiMeta(resource, requestMeta) {
134
168
  }
135
169
  if (Object.keys(ui).length > 0)
136
170
  base.ui = ui;
171
+ if (description && base["openai/widgetDescription"] == null) {
172
+ base["openai/widgetDescription"] = description;
173
+ }
174
+ if (typeof resource.prefersBorder === "boolean" &&
175
+ base["openai/widgetPrefersBorder"] == null) {
176
+ base["openai/widgetPrefersBorder"] = resource.prefersBorder;
177
+ }
178
+ const openAiCsp = openAiWidgetCsp(resource, requestMeta);
179
+ if (openAiCsp && base["openai/widgetCSP"] == null) {
180
+ base["openai/widgetCSP"] = openAiCsp;
181
+ }
137
182
  return Object.keys(base).length > 0 ? base : undefined;
138
183
  }
139
184
  function resolveMcpAppResource(config, actionName, entry, requestMeta) {
@@ -143,14 +188,13 @@ function resolveMcpAppResource(config, actionName, entry, requestMeta) {
143
188
  const uri = resource.uri?.trim() || defaultMcpAppUri(config, actionName);
144
189
  if (!uri.startsWith("ui://"))
145
190
  return null;
146
- const resourceMeta = mcpAppUiMeta(resource, requestMeta);
191
+ const description = resource.description ?? entry.tool.description;
192
+ const resourceMeta = mcpAppUiMeta(resource, requestMeta, description);
147
193
  return {
148
194
  uri,
149
195
  name: resource.name?.trim() || actionName,
150
196
  ...(resource.title ? { title: resource.title } : {}),
151
- ...((resource.description ?? entry.tool.description)
152
- ? { description: resource.description ?? entry.tool.description }
153
- : {}),
197
+ ...(description ? { description } : {}),
154
198
  html: resource.html,
155
199
  mimeType: resource.mimeType ?? MCP_APP_MIME_TYPE,
156
200
  ...(resourceMeta ? { _meta: resourceMeta } : {}),
@@ -172,6 +216,66 @@ function renderMcpAppHtml(resource, actionName, config, requestMeta) {
172
216
  }
173
217
  return resource.html;
174
218
  }
219
+ function openAiToolDescriptorMeta(resource) {
220
+ const label = resource.title ?? resource.name;
221
+ return {
222
+ "openai/outputTemplate": resource.uri,
223
+ "openai/toolInvocation/invoking": `Opening ${label}`,
224
+ "openai/toolInvocation/invoked": `${label} ready`,
225
+ "openai/widgetAccessible": true,
226
+ };
227
+ }
228
+ function openAiToolResultMeta(resource) {
229
+ const label = resource.title ?? resource.name;
230
+ return {
231
+ "openai/outputTemplate": resource.uri,
232
+ "openai/toolInvocation/invoking": `Opening ${label}`,
233
+ "openai/toolInvocation/invoked": `${label} ready`,
234
+ "openai/widgetAccessible": true,
235
+ };
236
+ }
237
+ function primitiveValue(value) {
238
+ return (typeof value === "string" ||
239
+ typeof value === "number" ||
240
+ typeof value === "boolean");
241
+ }
242
+ function mcpAppStructuredContent(result, meta) {
243
+ const out = result && typeof result === "object" && !Array.isArray(result)
244
+ ? { ...result }
245
+ : primitiveValue(result)
246
+ ? { result }
247
+ : {};
248
+ const openLink = meta?.["agent-native/openLink"];
249
+ if (openLink && typeof openLink === "object" && !Array.isArray(openLink)) {
250
+ out.openLink = openLink;
251
+ const webUrl = openLink.webUrl;
252
+ if (typeof webUrl === "string" && !out.url)
253
+ out.url = webUrl;
254
+ }
255
+ return Object.keys(out).length > 0 ? out : { status: "ok" };
256
+ }
257
+ function truncateToolText(value, max = 2000) {
258
+ if (value.length <= max)
259
+ return value;
260
+ return `${value.slice(0, max - 1)}…`;
261
+ }
262
+ function conciseMcpAppToolText(name, result, structuredContent) {
263
+ if (typeof result === "string")
264
+ return truncateToolText(result);
265
+ const message = structuredContent.message;
266
+ if (typeof message === "string" && message.trim()) {
267
+ return truncateToolText(message.trim());
268
+ }
269
+ const title = structuredContent.title ?? structuredContent.name;
270
+ if (typeof title === "string" && title.trim()) {
271
+ return `${title.trim()} is ready.`;
272
+ }
273
+ const id = structuredContent.id;
274
+ if (typeof id === "string" && id.trim()) {
275
+ return `${name} completed for ${id.trim()}.`;
276
+ }
277
+ return `${name} completed.`;
278
+ }
175
279
  // ---------------------------------------------------------------------------
176
280
  // MCP Server creation — converts ActionEntry registry to MCP tools
177
281
  // ---------------------------------------------------------------------------
@@ -213,8 +317,13 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
213
317
  : config.actions;
214
318
  const actions = mergeBuiltinTools(config, baseActions, requestMeta);
215
319
  const visibleActions = Object.fromEntries(Object.entries(actions).filter(([, entry]) => isActionVisibleForOAuthScope(entry, effectiveIdentity?.oauthScopes)));
216
- const mcpAppResources = hasMcpOAuthScope(effectiveIdentity?.oauthScopes, "mcp:apps")
217
- ? getMcpAppResources(config, visibleActions, requestMeta)
320
+ const compactMcpAppCatalog = Array.isArray(effectiveIdentity?.oauthScopes) &&
321
+ hasMcpOAuthScope(effectiveIdentity.oauthScopes, "mcp:apps");
322
+ const advertisedActions = compactMcpAppCatalog
323
+ ? Object.fromEntries(Object.entries(visibleActions).filter(([name, entry]) => isActionAdvertisedInCompactMcpAppCatalog(config, name, entry)))
324
+ : visibleActions;
325
+ const mcpAppResources = compactMcpAppCatalog
326
+ ? getMcpAppResources(config, advertisedActions, requestMeta)
218
327
  : [];
219
328
  const supportsMcpApps = mcpAppResources.length > 0;
220
329
  const server = new Server({ name: config.name, version: config.version ?? "1.0.0" }, {
@@ -262,7 +371,7 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
262
371
  // applies to the listing too.
263
372
  server.setRequestHandler(ListToolsRequestSchema, async () => {
264
373
  return withCallerContext(async () => {
265
- const tools = Object.entries(visibleActions).map(([name, entry]) => {
374
+ const tools = Object.entries(advertisedActions).map(([name, entry]) => {
266
375
  const hasLink = typeof entry.link === "function";
267
376
  const mcpAppResource = resolveMcpAppResource(config, name, entry, requestMeta);
268
377
  const rawToolMeta = entry.tool._meta &&
@@ -274,6 +383,7 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
274
383
  ...rawToolMeta,
275
384
  ...(mcpAppResource
276
385
  ? {
386
+ ...openAiToolDescriptorMeta(mcpAppResource),
277
387
  [MCP_APP_RESOURCE_URI_META_KEY]: mcpAppResource.uri,
278
388
  ui: {
279
389
  ...(rawToolMeta.ui &&
@@ -290,6 +400,8 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
290
400
  const baseDescription = entry.tool.description ?? name;
291
401
  const annotations = {
292
402
  readOnlyHint: entry.readOnly === true,
403
+ destructiveHint: entry.publicAgent?.isConsequential === true,
404
+ openWorldHint: false,
293
405
  };
294
406
  if (hasLink)
295
407
  annotations["agent-native/producesOpenLink"] = true;
@@ -306,7 +418,8 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
306
418
  annotations,
307
419
  };
308
420
  });
309
- if (config.askAgent &&
421
+ if (!compactMcpAppCatalog &&
422
+ config.askAgent &&
310
423
  hasMcpOAuthScope(effectiveIdentity?.oauthScopes, "mcp:write")) {
311
424
  tools.push({
312
425
  name: "ask-agent",
@@ -323,7 +436,11 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
323
436
  },
324
437
  required: ["message"],
325
438
  },
326
- annotations: { readOnlyHint: false },
439
+ annotations: {
440
+ readOnlyHint: false,
441
+ destructiveHint: false,
442
+ openWorldHint: false,
443
+ },
327
444
  });
328
445
  }
329
446
  return { tools };
@@ -382,14 +499,30 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
382
499
  const resultForClient = isMcpActionResult(result)
383
500
  ? result.text
384
501
  : result;
385
- const text = typeof resultForClient === "string"
386
- ? resultForClient
387
- : JSON.stringify(resultForClient);
388
- const content = [{ type: "text", text }];
502
+ const mcpAppResource = resolveMcpAppResource(config, name, entry, requestMeta);
389
503
  const { block, _meta } = buildLinkArtifacts(entry, args ?? {}, isMcpActionResult(result) ? result.raw : result, requestMeta);
504
+ const responseMeta = {
505
+ ...(_meta ?? {}),
506
+ ...(mcpAppResource ? openAiToolResultMeta(mcpAppResource) : {}),
507
+ };
508
+ const structuredContent = mcpAppResource
509
+ ? mcpAppStructuredContent(isMcpActionResult(result) ? result.raw : result, responseMeta)
510
+ : undefined;
511
+ const text = mcpAppResource
512
+ ? conciseMcpAppToolText(name, resultForClient, structuredContent)
513
+ : typeof resultForClient === "string"
514
+ ? resultForClient
515
+ : JSON.stringify(resultForClient);
516
+ const content = [{ type: "text", text }];
390
517
  if (block)
391
518
  content.push(block);
392
- return { content, ...(_meta ? { _meta } : {}) };
519
+ return {
520
+ content,
521
+ ...(structuredContent ? { structuredContent } : {}),
522
+ ...(Object.keys(responseMeta).length > 0
523
+ ? { _meta: responseMeta }
524
+ : {}),
525
+ };
393
526
  }
394
527
  catch (err) {
395
528
  return {
@@ -415,12 +548,23 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
415
548
  }));
416
549
  });
417
550
  server.setRequestHandler(ListResourceTemplatesRequestSchema, async () => {
418
- return { resourceTemplates: [] };
551
+ return {
552
+ resourceTemplates: mcpAppResources.map((resource) => ({
553
+ uriTemplate: resource.uri,
554
+ name: resource.name,
555
+ ...(resource.title ? { title: resource.title } : {}),
556
+ ...(resource.description
557
+ ? { description: resource.description }
558
+ : {}),
559
+ mimeType: resource.mimeType,
560
+ ...(resource._meta ? { _meta: resource._meta } : {}),
561
+ })),
562
+ };
419
563
  });
420
564
  server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
421
565
  return withCallerContext(async () => {
422
566
  const uri = request.params?.uri;
423
- const found = Object.entries(visibleActions)
567
+ const found = Object.entries(advertisedActions)
424
568
  .map(([name, entry]) => ({
425
569
  actionName: name,
426
570
  resource: resolveMcpAppResource(config, name, entry, requestMeta),
@@ -1 +1 @@
1
- {"version":3,"file":"build-server.js","sourceRoot":"","sources":["../../src/mcp/build-server.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shared MCP server builder.\n *\n * Extracted from `server.ts` so the stateless Streamable-HTTP mount\n * (`mountMCP`) and the stdio transport (`runMCPStdio --standalone`) build the\n * *same* MCP server from the *same* `ActionEntry` registry. Both surfaces:\n *\n * - expose every action as an MCP tool (+ the `ask-agent` meta-tool),\n * - append the framework deep-link block / `_meta` to every tool result,\n * - wrap `run()` / `askAgent()` in `runWithRequestContext` so per-user /\n * per-org scoping (accessFilter, resolveCredential, MCP visibility) is\n * honoured.\n *\n * `server.ts` re-exports `createMCPServerForRequest` and the auth helpers so\n * any (future) external importer of `@agent-native/core/mcp` keeps resolving.\n *\n * Node-only at the SDK level, but this module itself has no Node-only imports\n * — it can be bundled into the serverless function alongside `mountMCP`.\n */\n\nimport type { ActionEntry } from \"../agent/production-agent.js\";\nimport { isMcpActionResult } from \"../mcp-client/app-result.js\";\nimport {\n MCP_APP_EXTENSION_ID,\n MCP_APP_MIME_TYPE,\n MCP_APP_RESOURCE_URI_META_KEY,\n type ActionMcpAppResourceConfig,\n} from \"../action.js\";\nimport { MCP_APP_REQUEST_ORIGIN_CSP_SOURCE } from \"./embed-app.js\";\nimport { runWithRequestContext } from \"../server/request-context.js\";\nimport { toAbsoluteOpenUrl, toDesktopOpenUrl } from \"../server/deep-link.js\";\nimport {\n isAgentNativeOpenDeepLink,\n withCollapsedAgentSidebarParam,\n} from \"../shared/agent-sidebar-url.js\";\nimport { getBuiltinCrossAppTools } from \"./builtin-tools.js\";\nimport { MCP_CONNECT_SCOPE } from \"./connect-store.js\";\nimport {\n MCP_OAUTH_SCOPES,\n hasMcpOAuthScope,\n verifyMcpOAuthAccessToken,\n} from \"./oauth-token.js\";\n\nexport interface MCPConfig {\n /** App name shown in MCP server info */\n name: string;\n /**\n * Canonical app id (directory under `apps/`, e.g. `mail`) this MCP server\n * is mounted for. Optional & back-compat: when omitted the builtin\n * cross-app tools fall back to lowercasing `name`. Used by `open_app` /\n * `ask_app` / `create_workspace_app` to tell \"this app\" from a cross-app\n * target so they resolve the *target* app's origin rather than echoing the\n * current request origin.\n */\n appId?: string;\n /** App description */\n description: string;\n /** Version string (default \"1.0.0\") */\n version?: string;\n /** Action registry — same as agent chat and A2A */\n actions: Record<string, ActionEntry>;\n /**\n * Full (\"production\") action surface served to an **authenticated real\n * caller** — a connect-minted token, an `agent-native mcp install` stdio\n * proxy (owner-email header / `AGENT_NATIVE_OWNER_EMAIL`), or a deployed /\n * `AGENT_MODE=production` app. In local dev `actions` is intentionally the\n * sparse, dev-toggled surface (builtins + read-only public-agent actions)\n * so the local agent chat and unauthenticated dev probes don't see every\n * mutating tool; but per the external-agents contract a real caller that\n * connected with a token MUST get the full surface even in dev. When unset\n * (production, where `actions` already IS the full set) the swap is a\n * no-op. See `external-agents` skill, \"Dev vs production tool surface\".\n */\n productionActions?: Record<string, ActionEntry>;\n /** Handler for the ask-agent meta-tool — runs the full agent loop */\n askAgent?: (message: string) => Promise<string>;\n /**\n * Disable the generic cross-app builtin tools (`list_apps`, `open_app`,\n * `ask_app`, `create_workspace_app`, `list_templates`). They are merged in\n * by default so external agents get a stable verb set; a template action of\n * the same name always wins (template precedence). Set to `false` only for\n * a constrained / locked-down mount.\n */\n builtinCrossAppTools?: boolean;\n}\n\n/**\n * Identity extracted from a verified MCP bearer token / JWT. Used to wrap\n * `entry.run()` and `config.askAgent()` calls in `runWithRequestContext`\n * so downstream tools (db-query, accessFilter, resolveCredential) honour\n * per-user / per-org scoping. Without this wrap the MCP endpoint would\n * silently bypass tenant isolation. See finding #6 in\n * /tmp/security-audit/12-mcp-a2a-agent.md.\n */\nexport interface MCPCallerIdentity {\n userEmail: string | undefined;\n orgDomain: string | undefined;\n /** Present only for standard remote MCP OAuth access tokens. */\n oauthScopes?: string[];\n}\n\n/** Per-request context used to turn an action's relative deep link into the\n * absolute web URL (and desktop `agentnative://` URL) the external agent\n * surfaces. Derived from the inbound request headers in `mountMCP`, or from\n * the resolved local app origin in the stdio standalone path. */\nexport interface MCPRequestMeta {\n /** Origin of the running app, e.g. `http://localhost:8100`. */\n origin?: string;\n /** Optional client preference for which URL the *markdown* link uses. */\n target?: \"browser\" | \"desktop\" | \"terminal\";\n /**\n * The caller authenticated with a real credential (verified A2A/connect\n * JWT, matching ACCESS_TOKEN, or a forwarded owner-email header from\n * `agent-native mcp install`) — not the unauthenticated local dev-open\n * path. When true, `createMCPServerForRequest` serves\n * `config.productionActions` (the full surface) instead of the sparse dev\n * `config.actions`. Set by `mountMCP` from `verifyAuth`.\n */\n fullSurface?: boolean;\n}\n\ntype McpOAuthScope = (typeof MCP_OAUTH_SCOPES)[number];\n\nfunction isActionVisibleForOAuthScope(\n entry: ActionEntry,\n scopes: string[] | undefined,\n): boolean {\n if (!scopes) return true;\n const required: McpOAuthScope =\n entry.readOnly === true ? \"mcp:read\" : \"mcp:write\";\n return hasMcpOAuthScope(scopes, required);\n}\n\ninterface ResolvedMcpAppResource {\n uri: string;\n name: string;\n title?: string;\n description?: string;\n html: ActionMcpAppResourceConfig[\"html\"];\n mimeType: typeof MCP_APP_MIME_TYPE;\n _meta?: Record<string, unknown>;\n}\n\n/**\n * Build the deep-link content block + structured `_meta` for a tool result.\n * Best-effort: any throw / nullish link is swallowed so a bad `link` builder\n * never fails the tool call.\n */\nexport function buildLinkArtifacts(\n entry: ActionEntry,\n args: Record<string, any>,\n result: any,\n meta: MCPRequestMeta | undefined,\n): {\n block?: { type: \"text\"; text: string };\n _meta?: Record<string, unknown>;\n} {\n if (typeof entry.link !== \"function\") return {};\n try {\n const lk = entry.link({ args: args ?? {}, result });\n if (!lk?.url) return {};\n const linkUrl = isAgentNativeOpenDeepLink(lk.url)\n ? withCollapsedAgentSidebarParam(lk.url)\n : lk.url;\n const webUrl = toAbsoluteOpenUrl(linkUrl, meta?.origin);\n const desktopUrl = toDesktopOpenUrl(linkUrl);\n const markdownUrl = meta?.target === \"desktop\" ? desktopUrl : webUrl;\n return {\n block: { type: \"text\", text: `\\n\\n[${lk.label} →](${markdownUrl})` },\n _meta: {\n \"agent-native/openLink\": {\n label: lk.label,\n view: lk.view,\n webUrl,\n desktopUrl,\n },\n },\n };\n } catch {\n return {};\n }\n}\n\n/**\n * Merge the generic cross-app builtin tools into the config's action\n * registry. **Template actions take precedence**: if a template defines an\n * action with the same name as a builtin (e.g. its own `list_apps`), the\n * template entry wins and the builtin is dropped. This mirrors the\n * template-over-workspace-core precedence in `autoDiscoverActions`.\n *\n * The builtins are pure-ish navigators / scaffolders; they call back into the\n * same `config.actions` / `config.askAgent` so there is no second agent loop.\n */\nfunction mergeBuiltinTools(\n config: MCPConfig,\n baseActions: Record<string, ActionEntry>,\n requestMeta?: MCPRequestMeta,\n): Record<string, ActionEntry> {\n if (config.builtinCrossAppTools === false) return baseActions;\n const builtins = getBuiltinCrossAppTools(config, requestMeta);\n const merged: Record<string, ActionEntry> = { ...builtins };\n // Template / app actions overwrite same-named builtins.\n for (const [name, entry] of Object.entries(baseActions)) {\n merged[name] = entry;\n }\n return merged;\n}\n\nfunction safeUiSegment(value: string | undefined, fallback: string): string {\n const normalized = (value || fallback)\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9._-]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n return normalized || fallback;\n}\n\nfunction defaultMcpAppUri(config: MCPConfig, actionName: string): string {\n const app = safeUiSegment(config.appId ?? config.name, \"agent-native\");\n const action = safeUiSegment(actionName, \"tool\");\n return `ui://${app}/${action}`;\n}\n\nfunction expandRequestOriginSources(\n sources: string[] | undefined,\n requestMeta?: MCPRequestMeta,\n): string[] | undefined {\n if (!sources) return undefined;\n const origin = requestMeta?.origin;\n return sources.flatMap((source) =>\n source === MCP_APP_REQUEST_ORIGIN_CSP_SOURCE && origin\n ? [origin]\n : [source],\n );\n}\n\nfunction mcpAppUiMeta(\n resource: ActionMcpAppResourceConfig,\n requestMeta?: MCPRequestMeta,\n): Record<string, unknown> | undefined {\n const base =\n resource._meta && typeof resource._meta === \"object\"\n ? { ...resource._meta }\n : {};\n const existingUi =\n base.ui && typeof base.ui === \"object\" && !Array.isArray(base.ui)\n ? (base.ui as Record<string, unknown>)\n : {};\n const ui: Record<string, unknown> = { ...existingUi };\n if (resource.csp) {\n ui.csp = {\n ...resource.csp,\n connectDomains: expandRequestOriginSources(\n resource.csp.connectDomains,\n requestMeta,\n ),\n resourceDomains: expandRequestOriginSources(\n resource.csp.resourceDomains,\n requestMeta,\n ),\n frameDomains: expandRequestOriginSources(\n resource.csp.frameDomains,\n requestMeta,\n ),\n baseUriDomains: expandRequestOriginSources(\n resource.csp.baseUriDomains,\n requestMeta,\n ),\n };\n }\n if (resource.permissions) ui.permissions = resource.permissions;\n if (resource.domain) ui.domain = resource.domain;\n if (typeof resource.prefersBorder === \"boolean\") {\n ui.prefersBorder = resource.prefersBorder;\n }\n if (Object.keys(ui).length > 0) base.ui = ui;\n return Object.keys(base).length > 0 ? base : undefined;\n}\n\nfunction resolveMcpAppResource(\n config: MCPConfig,\n actionName: string,\n entry: ActionEntry,\n requestMeta?: MCPRequestMeta,\n): ResolvedMcpAppResource | null {\n const resource = entry.mcpApp?.resource;\n if (!resource) return null;\n const uri = resource.uri?.trim() || defaultMcpAppUri(config, actionName);\n if (!uri.startsWith(\"ui://\")) return null;\n const resourceMeta = mcpAppUiMeta(resource, requestMeta);\n return {\n uri,\n name: resource.name?.trim() || actionName,\n ...(resource.title ? { title: resource.title } : {}),\n ...((resource.description ?? entry.tool.description)\n ? { description: resource.description ?? entry.tool.description }\n : {}),\n html: resource.html,\n mimeType: resource.mimeType ?? MCP_APP_MIME_TYPE,\n ...(resourceMeta ? { _meta: resourceMeta } : {}),\n };\n}\n\nfunction getMcpAppResources(\n config: MCPConfig,\n actions: Record<string, ActionEntry>,\n requestMeta?: MCPRequestMeta,\n): ResolvedMcpAppResource[] {\n return Object.entries(actions).flatMap(([name, entry]) => {\n const resource = resolveMcpAppResource(config, name, entry, requestMeta);\n return resource ? [resource] : [];\n });\n}\n\nfunction renderMcpAppHtml(\n resource: ResolvedMcpAppResource,\n actionName: string,\n config: MCPConfig,\n requestMeta?: MCPRequestMeta,\n): string {\n if (typeof resource.html === \"function\") {\n return resource.html({\n actionName,\n appId: config.appId,\n requestOrigin: requestMeta?.origin,\n });\n }\n return resource.html;\n}\n\n// ---------------------------------------------------------------------------\n// MCP Server creation — converts ActionEntry registry to MCP tools\n// ---------------------------------------------------------------------------\n\n/**\n * Build a fully-wired MCP `Server` for a single request / session.\n *\n * Shared by the stateless Streamable-HTTP mount (`mountMCP`) and the stdio\n * standalone transport. The HTTP mount passes the per-request origin via\n * `requestMeta`; the stdio standalone path passes the resolved local app\n * origin so deep links still become absolute URLs.\n */\nexport async function createMCPServerForRequest(\n config: MCPConfig,\n identity: MCPCallerIdentity | undefined,\n requestMeta?: MCPRequestMeta,\n) {\n const { Server } = await import(\"@modelcontextprotocol/sdk/server/index.js\");\n const {\n ListToolsRequestSchema,\n CallToolRequestSchema,\n ListResourcesRequestSchema,\n ReadResourceRequestSchema,\n ListResourceTemplatesRequestSchema,\n } = await import(\"@modelcontextprotocol/sdk/types.js\");\n\n // Resolve the effective caller identity. JWT / header-derived identity\n // (passed by `mountMCP` via `verifyAuth`) wins. When the caller passed no\n // identity — the stdio **standalone** path — fall back to the\n // `AGENT_NATIVE_OWNER_EMAIL` env the `agent-native mcp install` flow writes\n // into the `agent-native mcp serve` process env, so standalone tool runs are\n // tenant-scoped to the configured owner instead of running unscoped. Stays\n // undefined for true dev-open (no token, no secret, no owner) — behavior\n // there is unchanged.\n const ownerFromEnv = process.env.AGENT_NATIVE_OWNER_EMAIL?.trim();\n const effectiveIdentity: MCPCallerIdentity | undefined =\n identity ??\n (ownerFromEnv\n ? { userEmail: ownerFromEnv, orgDomain: undefined }\n : undefined);\n\n // The action set the request handlers operate on = base actions + generic\n // cross-app builtins (template wins on name collision). An authenticated\n // real caller (connect-minted token / `mcp install` owner / production —\n // `requestMeta.fullSurface`, or the stdio standalone path identified by\n // `AGENT_NATIVE_OWNER_EMAIL`) gets the full `productionActions` surface\n // even in local dev; the unauthenticated dev-open path keeps the sparse\n // `config.actions`. See `external-agents` skill, \"Dev vs production tool\n // surface\".\n const useFullSurface = requestMeta?.fullSurface === true || !!ownerFromEnv;\n const baseActions =\n useFullSurface && config.productionActions\n ? config.productionActions\n : config.actions;\n const actions = mergeBuiltinTools(config, baseActions, requestMeta);\n const visibleActions = Object.fromEntries(\n Object.entries(actions).filter(([, entry]) =>\n isActionVisibleForOAuthScope(entry, effectiveIdentity?.oauthScopes),\n ),\n );\n const mcpAppResources = hasMcpOAuthScope(\n effectiveIdentity?.oauthScopes,\n \"mcp:apps\",\n )\n ? getMcpAppResources(config, visibleActions, requestMeta)\n : [];\n const supportsMcpApps = mcpAppResources.length > 0;\n const server = new Server(\n { name: config.name, version: config.version ?? \"1.0.0\" },\n {\n capabilities: {\n tools: {},\n ...(supportsMcpApps\n ? {\n resources: {},\n extensions: {\n [MCP_APP_EXTENSION_ID]: {\n mimeTypes: [MCP_APP_MIME_TYPE],\n },\n },\n }\n : {}),\n },\n },\n );\n\n // Resolve orgId once per request (DB lookup) so subsequent wraps are\n // synchronous. The caller identity may be undefined for true dev-open —\n // in that case we run with no userEmail/orgId, which makes downstream\n // tools that require per-user scope return empty results rather than\n // cross-tenant data (the safe default).\n const orgIdPromise = resolveOrgIdFromDomain(effectiveIdentity?.orgDomain);\n\n /**\n * Wrap a callback in\n * `runWithRequestContext({ userEmail, orgId, requestOrigin }, fn)`.\n * Both the tools/list and tools/call handlers go through this so\n * downstream `accessFilter`, `resolveCredential`, and per-user MCP\n * visibility checks see the verified caller's identity. `requestOrigin`\n * is the live server origin derived from the inbound request (same value\n * used to absolutize deep links) so actions that build fetchable URLs\n * (e.g. design `export-coding-handoff`'s signed raw-code URL) resolve the\n * correct local-workspace origin instead of a prod/localhost fallback.\n */\n async function withCallerContext<T>(fn: () => Promise<T>): Promise<T> {\n const orgId = await orgIdPromise;\n return runWithRequestContext(\n {\n userEmail: effectiveIdentity?.userEmail,\n orgId,\n ...(requestMeta?.origin ? { requestOrigin: requestMeta.origin } : {}),\n },\n fn,\n ) as Promise<T>;\n }\n\n // tools/list — return all actions + ask-agent meta-tool. Wrapped in the\n // request context so per-user MCP visibility (mcp-client/visibility.ts)\n // applies to the listing too.\n server.setRequestHandler(ListToolsRequestSchema, async () => {\n return withCallerContext(async () => {\n const tools = Object.entries(visibleActions).map(([name, entry]) => {\n const hasLink = typeof entry.link === \"function\";\n const mcpAppResource = resolveMcpAppResource(\n config,\n name,\n entry,\n requestMeta,\n );\n const rawToolMeta =\n (entry.tool as any)._meta &&\n typeof (entry.tool as any)._meta === \"object\" &&\n !Array.isArray((entry.tool as any)._meta)\n ? { ...((entry.tool as any)._meta as Record<string, unknown>) }\n : {};\n const toolMeta = {\n ...rawToolMeta,\n ...(mcpAppResource\n ? {\n [MCP_APP_RESOURCE_URI_META_KEY]: mcpAppResource.uri,\n ui: {\n ...(((rawToolMeta.ui as any) &&\n typeof rawToolMeta.ui === \"object\" &&\n !Array.isArray(rawToolMeta.ui)\n ? rawToolMeta.ui\n : {}) as Record<string, unknown>),\n resourceUri: mcpAppResource.uri,\n visibility: entry.mcpApp?.visibility ?? [\"model\", \"app\"],\n },\n }\n : {}),\n };\n const baseDescription = entry.tool.description ?? name;\n const annotations: Record<string, unknown> = {\n readOnlyHint: entry.readOnly === true,\n };\n if (hasLink) annotations[\"agent-native/producesOpenLink\"] = true;\n return {\n name,\n description: hasLink\n ? `${baseDescription} After calling, surface the returned \"Open in … →\" link to the user.`\n : baseDescription,\n inputSchema: entry.tool.parameters ?? {\n type: \"object\" as const,\n properties: {},\n },\n ...(Object.keys(toolMeta).length > 0 ? { _meta: toolMeta } : {}),\n annotations,\n };\n });\n\n if (\n config.askAgent &&\n hasMcpOAuthScope(effectiveIdentity?.oauthScopes, \"mcp:write\")\n ) {\n tools.push({\n name: \"ask-agent\",\n description:\n \"Send a natural-language message to the app's AI agent and get a response. \" +\n \"Use this for complex, multi-step tasks that require the agent's reasoning \" +\n \"and full context about the app.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n message: {\n type: \"string\",\n description: \"The message to send to the agent\",\n },\n },\n required: [\"message\"],\n },\n annotations: { readOnlyHint: false },\n });\n }\n\n return { tools };\n });\n });\n\n // tools/call — dispatch to action registry or ask-agent. Wrapped in the\n // request context so the action's `run(args)` and `askAgent()` execute\n // with the verified caller's identity, not the platform default.\n server.setRequestHandler(CallToolRequestSchema, async (request: any) => {\n return withCallerContext(async () => {\n const { name, arguments: args } = request.params;\n\n if (name === \"ask-agent\" && config.askAgent) {\n if (!hasMcpOAuthScope(effectiveIdentity?.oauthScopes, \"mcp:write\")) {\n return {\n content: [\n {\n type: \"text\",\n text: \"Forbidden: OAuth scope does not allow ask-agent\",\n },\n ],\n isError: true,\n };\n }\n const message = args?.message ?? \"\";\n try {\n const result = await config.askAgent(message);\n return { content: [{ type: \"text\", text: result }] };\n } catch (err: any) {\n return {\n content: [{ type: \"text\", text: `Error: ${err.message}` }],\n isError: true,\n };\n }\n }\n\n const entry = actions[name];\n if (!entry) {\n return {\n content: [{ type: \"text\", text: `Unknown tool: ${name}` }],\n isError: true,\n };\n }\n if (\n !isActionVisibleForOAuthScope(entry, effectiveIdentity?.oauthScopes)\n ) {\n return {\n content: [\n {\n type: \"text\",\n text: `Forbidden: OAuth scope does not allow tool ${name}`,\n },\n ],\n isError: true,\n };\n }\n\n try {\n const result = await entry.run((args as Record<string, string>) ?? {});\n const resultForClient = isMcpActionResult(result)\n ? result.text\n : result;\n const text =\n typeof resultForClient === \"string\"\n ? resultForClient\n : JSON.stringify(resultForClient);\n const content: any[] = [{ type: \"text\", text }];\n const { block, _meta } = buildLinkArtifacts(\n entry,\n (args as Record<string, any>) ?? {},\n isMcpActionResult(result) ? result.raw : result,\n requestMeta,\n );\n if (block) content.push(block);\n return { content, ...(_meta ? { _meta } : {}) };\n } catch (err: any) {\n return {\n content: [{ type: \"text\", text: `Error: ${err.message}` }],\n isError: true,\n };\n }\n });\n });\n\n if (supportsMcpApps) {\n server.setRequestHandler(ListResourcesRequestSchema, async () => {\n return withCallerContext(async () => ({\n resources: mcpAppResources.map((resource) => ({\n uri: resource.uri,\n name: resource.name,\n ...(resource.title ? { title: resource.title } : {}),\n ...(resource.description\n ? { description: resource.description }\n : {}),\n mimeType: resource.mimeType,\n ...(resource._meta ? { _meta: resource._meta } : {}),\n })),\n }));\n });\n\n server.setRequestHandler(ListResourceTemplatesRequestSchema, async () => {\n return { resourceTemplates: [] };\n });\n\n server.setRequestHandler(\n ReadResourceRequestSchema,\n async (request: any) => {\n return withCallerContext(async () => {\n const uri = request.params?.uri;\n const found = Object.entries(visibleActions)\n .map(([name, entry]) => ({\n actionName: name,\n resource: resolveMcpAppResource(config, name, entry, requestMeta),\n }))\n .find((candidate) => candidate.resource?.uri === uri);\n if (!found?.resource) {\n throw new Error(`MCP App resource not found: ${uri}`);\n }\n return {\n contents: [\n {\n uri: found.resource.uri,\n mimeType: found.resource.mimeType,\n text: renderMcpAppHtml(\n found.resource,\n found.actionName,\n config,\n requestMeta,\n ),\n ...(found.resource._meta\n ? { _meta: found.resource._meta }\n : {}),\n },\n ],\n };\n });\n },\n );\n }\n\n return server;\n}\n\n// ---------------------------------------------------------------------------\n// Auth — reuses the same pattern as A2A (Bearer token or JWT). Shared so the\n// HTTP mount and any stdio-side auth-aware helper resolve identity identically.\n// ---------------------------------------------------------------------------\n\nexport function getAccessTokens(): string[] {\n const single = process.env.ACCESS_TOKEN;\n const multi = process.env.ACCESS_TOKENS;\n const tokens: string[] = [];\n if (single) tokens.push(single);\n if (multi) {\n tokens.push(\n ...multi\n .split(\",\")\n .map((t) => t.trim())\n .filter(Boolean),\n );\n }\n return tokens;\n}\n\n/**\n * Resolve the caller identity for a static-token (or dev-open) auth path.\n *\n * Static `ACCESS_TOKEN` / `ACCESS_TOKENS` auth carries no per-caller claims,\n * so without this the MCP endpoint would run every tool with\n * `userEmail === undefined` and per-user / per-org scoped actions\n * (`accessFilter`, `resolveAccess`, `resolveCredential`) would return\n * empty / wrong data. The `agent-native mcp install` flow writes\n * `AGENT_NATIVE_OWNER_EMAIL` into the client config env and the stdio proxy\n * forwards it as the `X-Agent-Native-Owner-Email` request header (see\n * `mcp/stdio.ts#authHeaders`). We trust that owner hint *only* on the\n * static-token path — JWT auth already carries a cryptographically verified\n * `sub`, so the header is ignored there and never widens JWT scope.\n *\n * Precedence is server-trusted-first: the server process's\n * `AGENT_NATIVE_OWNER_EMAIL` env (set out-of-band by the operator / deploy)\n * ALWAYS wins, and a client-supplied `X-Agent-Native-Owner-Email` header is\n * honored *only as a fallback when that env is unset*. A static `ACCESS_TOKEN`\n * is a shared bearer secret; letting a request header override a\n * server-configured owner would let anyone holding a leaked token act as any\n * user. The header path remains for the single-tenant local-dev install flow\n * where the app server process has no owner env and the token *is* the\n * workspace secret; multi-tenant deployments must use A2A JWT (verified `sub`),\n * not a static token, for per-user scope.\n *\n * Returns `undefined` when no owner email is available (true dev-open: no\n * token, no secret, no owner) so behavior there stays unchanged.\n */\nfunction deriveStaticTokenIdentity(\n ownerEmailHeader: string | undefined,\n): MCPCallerIdentity | undefined {\n const owner =\n process.env.AGENT_NATIVE_OWNER_EMAIL?.trim() ||\n (typeof ownerEmailHeader === \"string\" && ownerEmailHeader.trim()) ||\n \"\";\n if (!owner) return undefined;\n return { userEmail: owner, orgDomain: undefined };\n}\n\n/**\n * Verify the inbound auth header. Returns:\n * - { authed: true, identity } when verified — `identity` is derived from\n * the JWT (`sub` / `org_domain`) for JWT auth, or from the\n * `AGENT_NATIVE_OWNER_EMAIL` env / `X-Agent-Native-Owner-Email` header\n * for static-token auth (the `agent-native mcp install` flow). `identity`\n * is undefined only for true dev-open with no owner hint.\n * - { authed: false } on rejection.\n *\n * When A2A_SECRET is set we extract the JWT's `sub` (caller email) and\n * `org_domain` claims so the MCP endpoint can wrap tool runs in\n * `runWithRequestContext({ userEmail, orgId })`. Without that wrap, the\n * MCP endpoint loses tenant identity and downstream `accessFilter` /\n * `resolveCredential` calls fall back to platform-wide defaults.\n *\n * `ownerEmailHeader` is the forwarded `X-Agent-Native-Owner-Email` value; it\n * is consulted ONLY on the static-token / dev-open path (never to influence\n * verified JWT identity), so the install flow runs tools as the configured\n * owner instead of an unscoped anonymous caller.\n */\nexport async function verifyAuth(\n authHeader: string | undefined,\n ownerEmailHeader?: string | undefined,\n options: { allowDevOpen?: boolean; resourceUrl?: string } = {},\n): Promise<{\n authed: boolean;\n identity?: MCPCallerIdentity;\n /**\n * The caller presented a real credential — a verified A2A/connect JWT, a\n * matching ACCESS_TOKEN, or (on the no-auth-configured path) a forwarded\n * owner-email header from `agent-native mcp install`. Drives the full vs\n * sparse MCP tool surface in local dev. The pure unauthenticated dev-open\n * path (no secret, no token, no owner header) is `false`.\n */\n fullSurface?: boolean;\n}> {\n // No auth configured → allow only when the route caller has already\n // established that this is a loopback/local dev request. Still honour an\n // owner hint there so the local install/connect flow stays tenant-scoped.\n const accessTokens = getAccessTokens();\n const hasA2ASecret = !!process.env.A2A_SECRET;\n const token = authHeader?.startsWith(\"Bearer \")\n ? authHeader.slice(7)\n : undefined;\n if (token) {\n const oauthIdentity = await verifyMcpOAuthAccessToken(\n token,\n options.resourceUrl,\n );\n if (oauthIdentity) {\n return {\n authed: true,\n identity: {\n userEmail: oauthIdentity.userEmail,\n orgDomain: oauthIdentity.orgDomain,\n oauthScopes: oauthIdentity.scopes,\n },\n fullSurface: true,\n };\n }\n }\n if (accessTokens.length === 0 && !hasA2ASecret) {\n if (options.allowDevOpen === false) {\n return { authed: false };\n }\n return {\n authed: true,\n identity: deriveStaticTokenIdentity(ownerEmailHeader),\n // `mcp install`'s stdio proxy forwards an owner-email header even when\n // the local app has no secret configured — that is a real, identified\n // caller and gets the full surface. A bare browser/curl dev probe with\n // no owner hint stays on the sparse dev surface.\n fullSurface: !!(ownerEmailHeader && ownerEmailHeader.trim()),\n };\n }\n\n if (!token) return { authed: false };\n\n // Try JWT via A2A_SECRET\n if (hasA2ASecret) {\n try {\n const jose = await import(\"jose\");\n const { payload } = await jose.jwtVerify(\n token,\n new TextEncoder().encode(process.env.A2A_SECRET!),\n );\n\n const tokenScope =\n typeof payload.scope === \"string\" ? payload.scope : undefined;\n if (tokenScope && tokenScope !== MCP_CONNECT_SCOPE) {\n return { authed: false };\n }\n\n // Connect-minted tokens (scope === \"mcp-connect\") carry a random `jti`\n // and are individually revocable. Only these tokens hit the revoke\n // store — ordinary A2A delegation JWTs skip the DB lookup entirely so\n // the hot path is unchanged. The revoke check FAILS OPEN on any\n // store/DB error: a transient Neon WS drop must never lock every\n // connected agent out. The signature was already cryptographically\n // verified above, so failing open here only widens the explicit-revoke\n // gate, never the trust boundary.\n if (tokenScope === MCP_CONNECT_SCOPE) {\n if (typeof payload.jti !== \"string\" || !payload.jti) {\n return { authed: false };\n }\n const jti = payload.jti;\n try {\n const { isJtiRevoked, touchTokenUsed } =\n await import(\"./connect-store.js\");\n if (await isJtiRevoked(jti)) {\n return { authed: false };\n }\n // Best-effort usage telemetry — never blocks / throws.\n void touchTokenUsed(jti);\n } catch {\n // Store import / lookup failed — fail open (see comment above).\n }\n }\n\n return {\n authed: true,\n identity: {\n userEmail: typeof payload.sub === \"string\" ? payload.sub : undefined,\n orgDomain:\n typeof payload.org_domain === \"string\"\n ? (payload.org_domain as string)\n : undefined,\n },\n // Verified JWT (connect-minted or A2A delegation) — a real caller.\n fullSurface: true,\n };\n } catch {\n // Not a valid JWT — fall through to token check\n }\n }\n\n // Try ACCESS_TOKEN / ACCESS_TOKENS exact match. Static tokens carry no\n // per-caller claims, so derive identity from the forwarded owner-email\n // hint (install flow) — otherwise tools would run unscoped.\n if (accessTokens.length > 0 && accessTokens.includes(token)) {\n return {\n authed: true,\n identity: deriveStaticTokenIdentity(ownerEmailHeader),\n // Matched a configured ACCESS_TOKEN — a real caller.\n fullSurface: true,\n };\n }\n\n return { authed: false };\n}\n\nexport async function resolveOrgIdFromDomain(\n orgDomain: string | undefined,\n): Promise<string | undefined> {\n if (!orgDomain) return undefined;\n try {\n const { resolveOrgByDomain } = await import(\"../org/context.js\");\n const org = await resolveOrgByDomain(orgDomain);\n return org?.orgId ?? undefined;\n } catch {\n return undefined;\n }\n}\n"]}
1
+ {"version":3,"file":"build-server.js","sourceRoot":"","sources":["../../src/mcp/build-server.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Shared MCP server builder.\n *\n * Extracted from `server.ts` so the stateless Streamable-HTTP mount\n * (`mountMCP`) and the stdio transport (`runMCPStdio --standalone`) build the\n * *same* MCP server from the *same* `ActionEntry` registry. Both surfaces:\n *\n * - expose every action as an MCP tool (+ the `ask-agent` meta-tool),\n * - append the framework deep-link block / `_meta` to every tool result,\n * - wrap `run()` / `askAgent()` in `runWithRequestContext` so per-user /\n * per-org scoping (accessFilter, resolveCredential, MCP visibility) is\n * honoured.\n *\n * `server.ts` re-exports `createMCPServerForRequest` and the auth helpers so\n * any (future) external importer of `@agent-native/core/mcp` keeps resolving.\n *\n * Node-only at the SDK level, but this module itself has no Node-only imports\n * — it can be bundled into the serverless function alongside `mountMCP`.\n */\n\nimport type { ActionEntry } from \"../agent/production-agent.js\";\nimport { isMcpActionResult } from \"../mcp-client/app-result.js\";\nimport {\n MCP_APP_EXTENSION_ID,\n MCP_APP_MIME_TYPE,\n MCP_APP_RESOURCE_URI_META_KEY,\n type ActionMcpAppResourceConfig,\n} from \"../action.js\";\nimport { MCP_APP_REQUEST_ORIGIN_CSP_SOURCE } from \"./embed-app.js\";\nimport { runWithRequestContext } from \"../server/request-context.js\";\nimport { toAbsoluteOpenUrl, toDesktopOpenUrl } from \"../server/deep-link.js\";\nimport {\n isAgentNativeOpenDeepLink,\n withCollapsedAgentSidebarParam,\n} from \"../shared/agent-sidebar-url.js\";\nimport { getBuiltinCrossAppTools } from \"./builtin-tools.js\";\nimport { MCP_CONNECT_SCOPE } from \"./connect-store.js\";\nimport {\n MCP_OAUTH_SCOPES,\n hasMcpOAuthScope,\n verifyMcpOAuthAccessToken,\n} from \"./oauth-token.js\";\n\nexport interface MCPConfig {\n /** App name shown in MCP server info */\n name: string;\n /**\n * Canonical app id (directory under `apps/`, e.g. `mail`) this MCP server\n * is mounted for. Optional & back-compat: when omitted the builtin\n * cross-app tools fall back to lowercasing `name`. Used by `open_app` /\n * `ask_app` / `create_workspace_app` to tell \"this app\" from a cross-app\n * target so they resolve the *target* app's origin rather than echoing the\n * current request origin.\n */\n appId?: string;\n /** App description */\n description: string;\n /** Version string (default \"1.0.0\") */\n version?: string;\n /** Action registry — same as agent chat and A2A */\n actions: Record<string, ActionEntry>;\n /**\n * Full (\"production\") action surface served to an **authenticated real\n * caller** — a connect-minted token, an `agent-native mcp install` stdio\n * proxy (owner-email header / `AGENT_NATIVE_OWNER_EMAIL`), or a deployed /\n * `AGENT_MODE=production` app. In local dev `actions` is intentionally the\n * sparse, dev-toggled surface (builtins + read-only public-agent actions)\n * so the local agent chat and unauthenticated dev probes don't see every\n * mutating tool; but per the external-agents contract a real caller that\n * connected with a token MUST get the full surface even in dev. When unset\n * (production, where `actions` already IS the full set) the swap is a\n * no-op. See `external-agents` skill, \"Dev vs production tool surface\".\n */\n productionActions?: Record<string, ActionEntry>;\n /** Handler for the ask-agent meta-tool — runs the full agent loop */\n askAgent?: (message: string) => Promise<string>;\n /**\n * Disable the generic cross-app builtin tools (`list_apps`, `open_app`,\n * `ask_app`, `create_workspace_app`, `list_templates`). They are merged in\n * by default so external agents get a stable verb set; a template action of\n * the same name always wins (template precedence). Set to `false` only for\n * a constrained / locked-down mount.\n */\n builtinCrossAppTools?: boolean;\n}\n\n/**\n * Identity extracted from a verified MCP bearer token / JWT. Used to wrap\n * `entry.run()` and `config.askAgent()` calls in `runWithRequestContext`\n * so downstream tools (db-query, accessFilter, resolveCredential) honour\n * per-user / per-org scoping. Without this wrap the MCP endpoint would\n * silently bypass tenant isolation. See finding #6 in\n * /tmp/security-audit/12-mcp-a2a-agent.md.\n */\nexport interface MCPCallerIdentity {\n userEmail: string | undefined;\n orgDomain: string | undefined;\n /** Present only for standard remote MCP OAuth access tokens. */\n oauthScopes?: string[];\n}\n\n/** Per-request context used to turn an action's relative deep link into the\n * absolute web URL (and desktop `agentnative://` URL) the external agent\n * surfaces. Derived from the inbound request headers in `mountMCP`, or from\n * the resolved local app origin in the stdio standalone path. */\nexport interface MCPRequestMeta {\n /** Origin of the running app, e.g. `http://localhost:8100`. */\n origin?: string;\n /** Optional client preference for which URL the *markdown* link uses. */\n target?: \"browser\" | \"desktop\" | \"terminal\";\n /**\n * The caller authenticated with a real credential (verified A2A/connect\n * JWT, matching ACCESS_TOKEN, or a forwarded owner-email header from\n * `agent-native mcp install`) — not the unauthenticated local dev-open\n * path. When true, `createMCPServerForRequest` serves\n * `config.productionActions` (the full surface) instead of the sparse dev\n * `config.actions`. Set by `mountMCP` from `verifyAuth`.\n */\n fullSurface?: boolean;\n}\n\ntype McpOAuthScope = (typeof MCP_OAUTH_SCOPES)[number];\n\nfunction isActionVisibleForOAuthScope(\n entry: ActionEntry,\n scopes: string[] | undefined,\n): boolean {\n if (!scopes) return true;\n const required: McpOAuthScope =\n entry.readOnly === true ? \"mcp:read\" : \"mcp:write\";\n return hasMcpOAuthScope(scopes, required);\n}\n\nconst COMPACT_MCP_APP_CATALOG_BUILTINS = new Set([\n \"list_apps\",\n \"open_app\",\n \"create_embed_session\",\n]);\n\nfunction isDispatchConfig(config: MCPConfig): boolean {\n const id = (config.appId ?? \"\").toLowerCase();\n const name = (config.name ?? \"\").toLowerCase();\n return id === \"dispatch\" || name.includes(\"dispatch\");\n}\n\nfunction isActionAdvertisedInCompactMcpAppCatalog(\n config: MCPConfig,\n name: string,\n entry: ActionEntry,\n): boolean {\n if (COMPACT_MCP_APP_CATALOG_BUILTINS.has(name)) return true;\n if (name === \"ask_app\" && isDispatchConfig(config)) return true;\n if (entry.mcpApp?.resource) return true;\n return entry.publicAgent?.expose === true;\n}\n\ninterface ResolvedMcpAppResource {\n uri: string;\n name: string;\n title?: string;\n description?: string;\n html: ActionMcpAppResourceConfig[\"html\"];\n mimeType: typeof MCP_APP_MIME_TYPE;\n _meta?: Record<string, unknown>;\n}\n\n/**\n * Build the deep-link content block + structured `_meta` for a tool result.\n * Best-effort: any throw / nullish link is swallowed so a bad `link` builder\n * never fails the tool call.\n */\nexport function buildLinkArtifacts(\n entry: ActionEntry,\n args: Record<string, any>,\n result: any,\n meta: MCPRequestMeta | undefined,\n): {\n block?: { type: \"text\"; text: string };\n _meta?: Record<string, unknown>;\n} {\n if (typeof entry.link !== \"function\") return {};\n try {\n const lk = entry.link({ args: args ?? {}, result });\n if (!lk?.url) return {};\n const linkUrl = isAgentNativeOpenDeepLink(lk.url)\n ? withCollapsedAgentSidebarParam(lk.url)\n : lk.url;\n const webUrl = toAbsoluteOpenUrl(linkUrl, meta?.origin);\n const desktopUrl = toDesktopOpenUrl(linkUrl);\n const markdownUrl = meta?.target === \"desktop\" ? desktopUrl : webUrl;\n return {\n block: { type: \"text\", text: `\\n\\n[${lk.label} →](${markdownUrl})` },\n _meta: {\n \"agent-native/openLink\": {\n label: lk.label,\n view: lk.view,\n webUrl,\n desktopUrl,\n },\n },\n };\n } catch {\n return {};\n }\n}\n\n/**\n * Merge the generic cross-app builtin tools into the config's action\n * registry. **Template actions take precedence**: if a template defines an\n * action with the same name as a builtin (e.g. its own `list_apps`), the\n * template entry wins and the builtin is dropped. This mirrors the\n * template-over-workspace-core precedence in `autoDiscoverActions`.\n *\n * The builtins are pure-ish navigators / scaffolders; they call back into the\n * same `config.actions` / `config.askAgent` so there is no second agent loop.\n */\nfunction mergeBuiltinTools(\n config: MCPConfig,\n baseActions: Record<string, ActionEntry>,\n requestMeta?: MCPRequestMeta,\n): Record<string, ActionEntry> {\n if (config.builtinCrossAppTools === false) return baseActions;\n const builtins = getBuiltinCrossAppTools(config, requestMeta);\n const merged: Record<string, ActionEntry> = { ...builtins };\n // Template / app actions overwrite same-named builtins.\n for (const [name, entry] of Object.entries(baseActions)) {\n merged[name] = entry;\n }\n return merged;\n}\n\nfunction safeUiSegment(value: string | undefined, fallback: string): string {\n const normalized = (value || fallback)\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9._-]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n return normalized || fallback;\n}\n\nfunction defaultMcpAppUri(config: MCPConfig, actionName: string): string {\n const app = safeUiSegment(config.appId ?? config.name, \"agent-native\");\n const action = safeUiSegment(actionName, \"tool\");\n return `ui://${app}/${action}`;\n}\n\nfunction expandRequestOriginSources(\n sources: string[] | undefined,\n requestMeta?: MCPRequestMeta,\n): string[] | undefined {\n if (!sources) return undefined;\n const origin = requestMeta?.origin;\n return sources.flatMap((source) =>\n source === MCP_APP_REQUEST_ORIGIN_CSP_SOURCE && origin\n ? [origin]\n : [source],\n );\n}\n\nfunction openAiWidgetCsp(\n resource: ActionMcpAppResourceConfig,\n requestMeta?: MCPRequestMeta,\n): Record<string, string[]> | undefined {\n if (!resource.csp) return undefined;\n const csp: Record<string, string[]> = {};\n const connectDomains = expandRequestOriginSources(\n resource.csp.connectDomains,\n requestMeta,\n );\n const resourceDomains = expandRequestOriginSources(\n resource.csp.resourceDomains,\n requestMeta,\n );\n const frameDomains = expandRequestOriginSources(\n resource.csp.frameDomains,\n requestMeta,\n );\n if (connectDomains?.length) csp.connect_domains = connectDomains;\n if (resourceDomains?.length) csp.resource_domains = resourceDomains;\n if (frameDomains?.length) csp.frame_domains = frameDomains;\n return Object.keys(csp).length > 0 ? csp : undefined;\n}\n\nfunction mcpAppUiMeta(\n resource: ActionMcpAppResourceConfig,\n requestMeta?: MCPRequestMeta,\n description?: string,\n): Record<string, unknown> | undefined {\n const base =\n resource._meta && typeof resource._meta === \"object\"\n ? { ...resource._meta }\n : {};\n const existingUi =\n base.ui && typeof base.ui === \"object\" && !Array.isArray(base.ui)\n ? (base.ui as Record<string, unknown>)\n : {};\n const ui: Record<string, unknown> = { ...existingUi };\n if (resource.csp) {\n ui.csp = {\n ...resource.csp,\n connectDomains: expandRequestOriginSources(\n resource.csp.connectDomains,\n requestMeta,\n ),\n resourceDomains: expandRequestOriginSources(\n resource.csp.resourceDomains,\n requestMeta,\n ),\n frameDomains: expandRequestOriginSources(\n resource.csp.frameDomains,\n requestMeta,\n ),\n baseUriDomains: expandRequestOriginSources(\n resource.csp.baseUriDomains,\n requestMeta,\n ),\n };\n }\n if (resource.permissions) ui.permissions = resource.permissions;\n if (resource.domain) ui.domain = resource.domain;\n if (typeof resource.prefersBorder === \"boolean\") {\n ui.prefersBorder = resource.prefersBorder;\n }\n if (Object.keys(ui).length > 0) base.ui = ui;\n if (description && base[\"openai/widgetDescription\"] == null) {\n base[\"openai/widgetDescription\"] = description;\n }\n if (\n typeof resource.prefersBorder === \"boolean\" &&\n base[\"openai/widgetPrefersBorder\"] == null\n ) {\n base[\"openai/widgetPrefersBorder\"] = resource.prefersBorder;\n }\n const openAiCsp = openAiWidgetCsp(resource, requestMeta);\n if (openAiCsp && base[\"openai/widgetCSP\"] == null) {\n base[\"openai/widgetCSP\"] = openAiCsp;\n }\n return Object.keys(base).length > 0 ? base : undefined;\n}\n\nfunction resolveMcpAppResource(\n config: MCPConfig,\n actionName: string,\n entry: ActionEntry,\n requestMeta?: MCPRequestMeta,\n): ResolvedMcpAppResource | null {\n const resource = entry.mcpApp?.resource;\n if (!resource) return null;\n const uri = resource.uri?.trim() || defaultMcpAppUri(config, actionName);\n if (!uri.startsWith(\"ui://\")) return null;\n const description = resource.description ?? entry.tool.description;\n const resourceMeta = mcpAppUiMeta(resource, requestMeta, description);\n return {\n uri,\n name: resource.name?.trim() || actionName,\n ...(resource.title ? { title: resource.title } : {}),\n ...(description ? { description } : {}),\n html: resource.html,\n mimeType: resource.mimeType ?? MCP_APP_MIME_TYPE,\n ...(resourceMeta ? { _meta: resourceMeta } : {}),\n };\n}\n\nfunction getMcpAppResources(\n config: MCPConfig,\n actions: Record<string, ActionEntry>,\n requestMeta?: MCPRequestMeta,\n): ResolvedMcpAppResource[] {\n return Object.entries(actions).flatMap(([name, entry]) => {\n const resource = resolveMcpAppResource(config, name, entry, requestMeta);\n return resource ? [resource] : [];\n });\n}\n\nfunction renderMcpAppHtml(\n resource: ResolvedMcpAppResource,\n actionName: string,\n config: MCPConfig,\n requestMeta?: MCPRequestMeta,\n): string {\n if (typeof resource.html === \"function\") {\n return resource.html({\n actionName,\n appId: config.appId,\n requestOrigin: requestMeta?.origin,\n });\n }\n return resource.html;\n}\n\nfunction openAiToolDescriptorMeta(\n resource: ResolvedMcpAppResource,\n): Record<string, unknown> {\n const label = resource.title ?? resource.name;\n return {\n \"openai/outputTemplate\": resource.uri,\n \"openai/toolInvocation/invoking\": `Opening ${label}`,\n \"openai/toolInvocation/invoked\": `${label} ready`,\n \"openai/widgetAccessible\": true,\n };\n}\n\nfunction openAiToolResultMeta(\n resource: ResolvedMcpAppResource,\n): Record<string, unknown> {\n const label = resource.title ?? resource.name;\n return {\n \"openai/outputTemplate\": resource.uri,\n \"openai/toolInvocation/invoking\": `Opening ${label}`,\n \"openai/toolInvocation/invoked\": `${label} ready`,\n \"openai/widgetAccessible\": true,\n };\n}\n\nfunction primitiveValue(value: unknown): value is string | number | boolean {\n return (\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\"\n );\n}\n\nfunction mcpAppStructuredContent(\n result: unknown,\n meta: Record<string, unknown> | undefined,\n): Record<string, unknown> {\n const out: Record<string, unknown> =\n result && typeof result === \"object\" && !Array.isArray(result)\n ? { ...(result as Record<string, unknown>) }\n : primitiveValue(result)\n ? { result }\n : {};\n const openLink = meta?.[\"agent-native/openLink\"];\n if (openLink && typeof openLink === \"object\" && !Array.isArray(openLink)) {\n out.openLink = openLink;\n const webUrl = (openLink as Record<string, unknown>).webUrl;\n if (typeof webUrl === \"string\" && !out.url) out.url = webUrl;\n }\n return Object.keys(out).length > 0 ? out : { status: \"ok\" };\n}\n\nfunction truncateToolText(value: string, max = 2000): string {\n if (value.length <= max) return value;\n return `${value.slice(0, max - 1)}…`;\n}\n\nfunction conciseMcpAppToolText(\n name: string,\n result: unknown,\n structuredContent: Record<string, unknown>,\n): string {\n if (typeof result === \"string\") return truncateToolText(result);\n const message = structuredContent.message;\n if (typeof message === \"string\" && message.trim()) {\n return truncateToolText(message.trim());\n }\n const title = structuredContent.title ?? structuredContent.name;\n if (typeof title === \"string\" && title.trim()) {\n return `${title.trim()} is ready.`;\n }\n const id = structuredContent.id;\n if (typeof id === \"string\" && id.trim()) {\n return `${name} completed for ${id.trim()}.`;\n }\n return `${name} completed.`;\n}\n\n// ---------------------------------------------------------------------------\n// MCP Server creation — converts ActionEntry registry to MCP tools\n// ---------------------------------------------------------------------------\n\n/**\n * Build a fully-wired MCP `Server` for a single request / session.\n *\n * Shared by the stateless Streamable-HTTP mount (`mountMCP`) and the stdio\n * standalone transport. The HTTP mount passes the per-request origin via\n * `requestMeta`; the stdio standalone path passes the resolved local app\n * origin so deep links still become absolute URLs.\n */\nexport async function createMCPServerForRequest(\n config: MCPConfig,\n identity: MCPCallerIdentity | undefined,\n requestMeta?: MCPRequestMeta,\n) {\n const { Server } = await import(\"@modelcontextprotocol/sdk/server/index.js\");\n const {\n ListToolsRequestSchema,\n CallToolRequestSchema,\n ListResourcesRequestSchema,\n ReadResourceRequestSchema,\n ListResourceTemplatesRequestSchema,\n } = await import(\"@modelcontextprotocol/sdk/types.js\");\n\n // Resolve the effective caller identity. JWT / header-derived identity\n // (passed by `mountMCP` via `verifyAuth`) wins. When the caller passed no\n // identity — the stdio **standalone** path — fall back to the\n // `AGENT_NATIVE_OWNER_EMAIL` env the `agent-native mcp install` flow writes\n // into the `agent-native mcp serve` process env, so standalone tool runs are\n // tenant-scoped to the configured owner instead of running unscoped. Stays\n // undefined for true dev-open (no token, no secret, no owner) — behavior\n // there is unchanged.\n const ownerFromEnv = process.env.AGENT_NATIVE_OWNER_EMAIL?.trim();\n const effectiveIdentity: MCPCallerIdentity | undefined =\n identity ??\n (ownerFromEnv\n ? { userEmail: ownerFromEnv, orgDomain: undefined }\n : undefined);\n\n // The action set the request handlers operate on = base actions + generic\n // cross-app builtins (template wins on name collision). An authenticated\n // real caller (connect-minted token / `mcp install` owner / production —\n // `requestMeta.fullSurface`, or the stdio standalone path identified by\n // `AGENT_NATIVE_OWNER_EMAIL`) gets the full `productionActions` surface\n // even in local dev; the unauthenticated dev-open path keeps the sparse\n // `config.actions`. See `external-agents` skill, \"Dev vs production tool\n // surface\".\n const useFullSurface = requestMeta?.fullSurface === true || !!ownerFromEnv;\n const baseActions =\n useFullSurface && config.productionActions\n ? config.productionActions\n : config.actions;\n const actions = mergeBuiltinTools(config, baseActions, requestMeta);\n const visibleActions = Object.fromEntries(\n Object.entries(actions).filter(([, entry]) =>\n isActionVisibleForOAuthScope(entry, effectiveIdentity?.oauthScopes),\n ),\n );\n const compactMcpAppCatalog =\n Array.isArray(effectiveIdentity?.oauthScopes) &&\n hasMcpOAuthScope(effectiveIdentity.oauthScopes, \"mcp:apps\");\n const advertisedActions = compactMcpAppCatalog\n ? Object.fromEntries(\n Object.entries(visibleActions).filter(([name, entry]) =>\n isActionAdvertisedInCompactMcpAppCatalog(config, name, entry),\n ),\n )\n : visibleActions;\n const mcpAppResources = compactMcpAppCatalog\n ? getMcpAppResources(config, advertisedActions, requestMeta)\n : [];\n const supportsMcpApps = mcpAppResources.length > 0;\n const server = new Server(\n { name: config.name, version: config.version ?? \"1.0.0\" },\n {\n capabilities: {\n tools: {},\n ...(supportsMcpApps\n ? {\n resources: {},\n extensions: {\n [MCP_APP_EXTENSION_ID]: {\n mimeTypes: [MCP_APP_MIME_TYPE],\n },\n },\n }\n : {}),\n },\n },\n );\n\n // Resolve orgId once per request (DB lookup) so subsequent wraps are\n // synchronous. The caller identity may be undefined for true dev-open —\n // in that case we run with no userEmail/orgId, which makes downstream\n // tools that require per-user scope return empty results rather than\n // cross-tenant data (the safe default).\n const orgIdPromise = resolveOrgIdFromDomain(effectiveIdentity?.orgDomain);\n\n /**\n * Wrap a callback in\n * `runWithRequestContext({ userEmail, orgId, requestOrigin }, fn)`.\n * Both the tools/list and tools/call handlers go through this so\n * downstream `accessFilter`, `resolveCredential`, and per-user MCP\n * visibility checks see the verified caller's identity. `requestOrigin`\n * is the live server origin derived from the inbound request (same value\n * used to absolutize deep links) so actions that build fetchable URLs\n * (e.g. design `export-coding-handoff`'s signed raw-code URL) resolve the\n * correct local-workspace origin instead of a prod/localhost fallback.\n */\n async function withCallerContext<T>(fn: () => Promise<T>): Promise<T> {\n const orgId = await orgIdPromise;\n return runWithRequestContext(\n {\n userEmail: effectiveIdentity?.userEmail,\n orgId,\n ...(requestMeta?.origin ? { requestOrigin: requestMeta.origin } : {}),\n },\n fn,\n ) as Promise<T>;\n }\n\n // tools/list — return all actions + ask-agent meta-tool. Wrapped in the\n // request context so per-user MCP visibility (mcp-client/visibility.ts)\n // applies to the listing too.\n server.setRequestHandler(ListToolsRequestSchema, async () => {\n return withCallerContext(async () => {\n const tools = Object.entries(advertisedActions).map(([name, entry]) => {\n const hasLink = typeof entry.link === \"function\";\n const mcpAppResource = resolveMcpAppResource(\n config,\n name,\n entry,\n requestMeta,\n );\n const rawToolMeta =\n (entry.tool as any)._meta &&\n typeof (entry.tool as any)._meta === \"object\" &&\n !Array.isArray((entry.tool as any)._meta)\n ? { ...((entry.tool as any)._meta as Record<string, unknown>) }\n : {};\n const toolMeta = {\n ...rawToolMeta,\n ...(mcpAppResource\n ? {\n ...openAiToolDescriptorMeta(mcpAppResource),\n [MCP_APP_RESOURCE_URI_META_KEY]: mcpAppResource.uri,\n ui: {\n ...(((rawToolMeta.ui as any) &&\n typeof rawToolMeta.ui === \"object\" &&\n !Array.isArray(rawToolMeta.ui)\n ? rawToolMeta.ui\n : {}) as Record<string, unknown>),\n resourceUri: mcpAppResource.uri,\n visibility: entry.mcpApp?.visibility ?? [\"model\", \"app\"],\n },\n }\n : {}),\n };\n const baseDescription = entry.tool.description ?? name;\n const annotations: Record<string, unknown> = {\n readOnlyHint: entry.readOnly === true,\n destructiveHint: entry.publicAgent?.isConsequential === true,\n openWorldHint: false,\n };\n if (hasLink) annotations[\"agent-native/producesOpenLink\"] = true;\n return {\n name,\n description: hasLink\n ? `${baseDescription} After calling, surface the returned \"Open in … →\" link to the user.`\n : baseDescription,\n inputSchema: entry.tool.parameters ?? {\n type: \"object\" as const,\n properties: {},\n },\n ...(Object.keys(toolMeta).length > 0 ? { _meta: toolMeta } : {}),\n annotations,\n };\n });\n\n if (\n !compactMcpAppCatalog &&\n config.askAgent &&\n hasMcpOAuthScope(effectiveIdentity?.oauthScopes, \"mcp:write\")\n ) {\n tools.push({\n name: \"ask-agent\",\n description:\n \"Send a natural-language message to the app's AI agent and get a response. \" +\n \"Use this for complex, multi-step tasks that require the agent's reasoning \" +\n \"and full context about the app.\",\n inputSchema: {\n type: \"object\" as const,\n properties: {\n message: {\n type: \"string\",\n description: \"The message to send to the agent\",\n },\n },\n required: [\"message\"],\n },\n annotations: {\n readOnlyHint: false,\n destructiveHint: false,\n openWorldHint: false,\n },\n });\n }\n\n return { tools };\n });\n });\n\n // tools/call — dispatch to action registry or ask-agent. Wrapped in the\n // request context so the action's `run(args)` and `askAgent()` execute\n // with the verified caller's identity, not the platform default.\n server.setRequestHandler(CallToolRequestSchema, async (request: any) => {\n return withCallerContext(async () => {\n const { name, arguments: args } = request.params;\n\n if (name === \"ask-agent\" && config.askAgent) {\n if (!hasMcpOAuthScope(effectiveIdentity?.oauthScopes, \"mcp:write\")) {\n return {\n content: [\n {\n type: \"text\",\n text: \"Forbidden: OAuth scope does not allow ask-agent\",\n },\n ],\n isError: true,\n };\n }\n const message = args?.message ?? \"\";\n try {\n const result = await config.askAgent(message);\n return { content: [{ type: \"text\", text: result }] };\n } catch (err: any) {\n return {\n content: [{ type: \"text\", text: `Error: ${err.message}` }],\n isError: true,\n };\n }\n }\n\n const entry = actions[name];\n if (!entry) {\n return {\n content: [{ type: \"text\", text: `Unknown tool: ${name}` }],\n isError: true,\n };\n }\n if (\n !isActionVisibleForOAuthScope(entry, effectiveIdentity?.oauthScopes)\n ) {\n return {\n content: [\n {\n type: \"text\",\n text: `Forbidden: OAuth scope does not allow tool ${name}`,\n },\n ],\n isError: true,\n };\n }\n\n try {\n const result = await entry.run((args as Record<string, string>) ?? {});\n const resultForClient = isMcpActionResult(result)\n ? result.text\n : result;\n const mcpAppResource = resolveMcpAppResource(\n config,\n name,\n entry,\n requestMeta,\n );\n const { block, _meta } = buildLinkArtifacts(\n entry,\n (args as Record<string, any>) ?? {},\n isMcpActionResult(result) ? result.raw : result,\n requestMeta,\n );\n const responseMeta: Record<string, unknown> = {\n ...(_meta ?? {}),\n ...(mcpAppResource ? openAiToolResultMeta(mcpAppResource) : {}),\n };\n const structuredContent = mcpAppResource\n ? mcpAppStructuredContent(\n isMcpActionResult(result) ? result.raw : result,\n responseMeta,\n )\n : undefined;\n const text = mcpAppResource\n ? conciseMcpAppToolText(name, resultForClient, structuredContent!)\n : typeof resultForClient === \"string\"\n ? resultForClient\n : JSON.stringify(resultForClient);\n const content: any[] = [{ type: \"text\", text }];\n if (block) content.push(block);\n return {\n content,\n ...(structuredContent ? { structuredContent } : {}),\n ...(Object.keys(responseMeta).length > 0\n ? { _meta: responseMeta }\n : {}),\n };\n } catch (err: any) {\n return {\n content: [{ type: \"text\", text: `Error: ${err.message}` }],\n isError: true,\n };\n }\n });\n });\n\n if (supportsMcpApps) {\n server.setRequestHandler(ListResourcesRequestSchema, async () => {\n return withCallerContext(async () => ({\n resources: mcpAppResources.map((resource) => ({\n uri: resource.uri,\n name: resource.name,\n ...(resource.title ? { title: resource.title } : {}),\n ...(resource.description\n ? { description: resource.description }\n : {}),\n mimeType: resource.mimeType,\n ...(resource._meta ? { _meta: resource._meta } : {}),\n })),\n }));\n });\n\n server.setRequestHandler(ListResourceTemplatesRequestSchema, async () => {\n return {\n resourceTemplates: mcpAppResources.map((resource) => ({\n uriTemplate: resource.uri,\n name: resource.name,\n ...(resource.title ? { title: resource.title } : {}),\n ...(resource.description\n ? { description: resource.description }\n : {}),\n mimeType: resource.mimeType,\n ...(resource._meta ? { _meta: resource._meta } : {}),\n })),\n };\n });\n\n server.setRequestHandler(\n ReadResourceRequestSchema,\n async (request: any) => {\n return withCallerContext(async () => {\n const uri = request.params?.uri;\n const found = Object.entries(advertisedActions)\n .map(([name, entry]) => ({\n actionName: name,\n resource: resolveMcpAppResource(config, name, entry, requestMeta),\n }))\n .find((candidate) => candidate.resource?.uri === uri);\n if (!found?.resource) {\n throw new Error(`MCP App resource not found: ${uri}`);\n }\n return {\n contents: [\n {\n uri: found.resource.uri,\n mimeType: found.resource.mimeType,\n text: renderMcpAppHtml(\n found.resource,\n found.actionName,\n config,\n requestMeta,\n ),\n ...(found.resource._meta\n ? { _meta: found.resource._meta }\n : {}),\n },\n ],\n };\n });\n },\n );\n }\n\n return server;\n}\n\n// ---------------------------------------------------------------------------\n// Auth — reuses the same pattern as A2A (Bearer token or JWT). Shared so the\n// HTTP mount and any stdio-side auth-aware helper resolve identity identically.\n// ---------------------------------------------------------------------------\n\nexport function getAccessTokens(): string[] {\n const single = process.env.ACCESS_TOKEN;\n const multi = process.env.ACCESS_TOKENS;\n const tokens: string[] = [];\n if (single) tokens.push(single);\n if (multi) {\n tokens.push(\n ...multi\n .split(\",\")\n .map((t) => t.trim())\n .filter(Boolean),\n );\n }\n return tokens;\n}\n\n/**\n * Resolve the caller identity for a static-token (or dev-open) auth path.\n *\n * Static `ACCESS_TOKEN` / `ACCESS_TOKENS` auth carries no per-caller claims,\n * so without this the MCP endpoint would run every tool with\n * `userEmail === undefined` and per-user / per-org scoped actions\n * (`accessFilter`, `resolveAccess`, `resolveCredential`) would return\n * empty / wrong data. The `agent-native mcp install` flow writes\n * `AGENT_NATIVE_OWNER_EMAIL` into the client config env and the stdio proxy\n * forwards it as the `X-Agent-Native-Owner-Email` request header (see\n * `mcp/stdio.ts#authHeaders`). We trust that owner hint *only* on the\n * static-token path — JWT auth already carries a cryptographically verified\n * `sub`, so the header is ignored there and never widens JWT scope.\n *\n * Precedence is server-trusted-first: the server process's\n * `AGENT_NATIVE_OWNER_EMAIL` env (set out-of-band by the operator / deploy)\n * ALWAYS wins, and a client-supplied `X-Agent-Native-Owner-Email` header is\n * honored *only as a fallback when that env is unset*. A static `ACCESS_TOKEN`\n * is a shared bearer secret; letting a request header override a\n * server-configured owner would let anyone holding a leaked token act as any\n * user. The header path remains for the single-tenant local-dev install flow\n * where the app server process has no owner env and the token *is* the\n * workspace secret; multi-tenant deployments must use A2A JWT (verified `sub`),\n * not a static token, for per-user scope.\n *\n * Returns `undefined` when no owner email is available (true dev-open: no\n * token, no secret, no owner) so behavior there stays unchanged.\n */\nfunction deriveStaticTokenIdentity(\n ownerEmailHeader: string | undefined,\n): MCPCallerIdentity | undefined {\n const owner =\n process.env.AGENT_NATIVE_OWNER_EMAIL?.trim() ||\n (typeof ownerEmailHeader === \"string\" && ownerEmailHeader.trim()) ||\n \"\";\n if (!owner) return undefined;\n return { userEmail: owner, orgDomain: undefined };\n}\n\n/**\n * Verify the inbound auth header. Returns:\n * - { authed: true, identity } when verified — `identity` is derived from\n * the JWT (`sub` / `org_domain`) for JWT auth, or from the\n * `AGENT_NATIVE_OWNER_EMAIL` env / `X-Agent-Native-Owner-Email` header\n * for static-token auth (the `agent-native mcp install` flow). `identity`\n * is undefined only for true dev-open with no owner hint.\n * - { authed: false } on rejection.\n *\n * When A2A_SECRET is set we extract the JWT's `sub` (caller email) and\n * `org_domain` claims so the MCP endpoint can wrap tool runs in\n * `runWithRequestContext({ userEmail, orgId })`. Without that wrap, the\n * MCP endpoint loses tenant identity and downstream `accessFilter` /\n * `resolveCredential` calls fall back to platform-wide defaults.\n *\n * `ownerEmailHeader` is the forwarded `X-Agent-Native-Owner-Email` value; it\n * is consulted ONLY on the static-token / dev-open path (never to influence\n * verified JWT identity), so the install flow runs tools as the configured\n * owner instead of an unscoped anonymous caller.\n */\nexport async function verifyAuth(\n authHeader: string | undefined,\n ownerEmailHeader?: string | undefined,\n options: { allowDevOpen?: boolean; resourceUrl?: string } = {},\n): Promise<{\n authed: boolean;\n identity?: MCPCallerIdentity;\n /**\n * The caller presented a real credential — a verified A2A/connect JWT, a\n * matching ACCESS_TOKEN, or (on the no-auth-configured path) a forwarded\n * owner-email header from `agent-native mcp install`. Drives the full vs\n * sparse MCP tool surface in local dev. The pure unauthenticated dev-open\n * path (no secret, no token, no owner header) is `false`.\n */\n fullSurface?: boolean;\n}> {\n // No auth configured → allow only when the route caller has already\n // established that this is a loopback/local dev request. Still honour an\n // owner hint there so the local install/connect flow stays tenant-scoped.\n const accessTokens = getAccessTokens();\n const hasA2ASecret = !!process.env.A2A_SECRET;\n const token = authHeader?.startsWith(\"Bearer \")\n ? authHeader.slice(7)\n : undefined;\n if (token) {\n const oauthIdentity = await verifyMcpOAuthAccessToken(\n token,\n options.resourceUrl,\n );\n if (oauthIdentity) {\n return {\n authed: true,\n identity: {\n userEmail: oauthIdentity.userEmail,\n orgDomain: oauthIdentity.orgDomain,\n oauthScopes: oauthIdentity.scopes,\n },\n fullSurface: true,\n };\n }\n }\n if (accessTokens.length === 0 && !hasA2ASecret) {\n if (options.allowDevOpen === false) {\n return { authed: false };\n }\n return {\n authed: true,\n identity: deriveStaticTokenIdentity(ownerEmailHeader),\n // `mcp install`'s stdio proxy forwards an owner-email header even when\n // the local app has no secret configured — that is a real, identified\n // caller and gets the full surface. A bare browser/curl dev probe with\n // no owner hint stays on the sparse dev surface.\n fullSurface: !!(ownerEmailHeader && ownerEmailHeader.trim()),\n };\n }\n\n if (!token) return { authed: false };\n\n // Try JWT via A2A_SECRET\n if (hasA2ASecret) {\n try {\n const jose = await import(\"jose\");\n const { payload } = await jose.jwtVerify(\n token,\n new TextEncoder().encode(process.env.A2A_SECRET!),\n );\n\n const tokenScope =\n typeof payload.scope === \"string\" ? payload.scope : undefined;\n if (tokenScope && tokenScope !== MCP_CONNECT_SCOPE) {\n return { authed: false };\n }\n\n // Connect-minted tokens (scope === \"mcp-connect\") carry a random `jti`\n // and are individually revocable. Only these tokens hit the revoke\n // store — ordinary A2A delegation JWTs skip the DB lookup entirely so\n // the hot path is unchanged. The revoke check FAILS OPEN on any\n // store/DB error: a transient Neon WS drop must never lock every\n // connected agent out. The signature was already cryptographically\n // verified above, so failing open here only widens the explicit-revoke\n // gate, never the trust boundary.\n if (tokenScope === MCP_CONNECT_SCOPE) {\n if (typeof payload.jti !== \"string\" || !payload.jti) {\n return { authed: false };\n }\n const jti = payload.jti;\n try {\n const { isJtiRevoked, touchTokenUsed } =\n await import(\"./connect-store.js\");\n if (await isJtiRevoked(jti)) {\n return { authed: false };\n }\n // Best-effort usage telemetry — never blocks / throws.\n void touchTokenUsed(jti);\n } catch {\n // Store import / lookup failed — fail open (see comment above).\n }\n }\n\n return {\n authed: true,\n identity: {\n userEmail: typeof payload.sub === \"string\" ? payload.sub : undefined,\n orgDomain:\n typeof payload.org_domain === \"string\"\n ? (payload.org_domain as string)\n : undefined,\n },\n // Verified JWT (connect-minted or A2A delegation) — a real caller.\n fullSurface: true,\n };\n } catch {\n // Not a valid JWT — fall through to token check\n }\n }\n\n // Try ACCESS_TOKEN / ACCESS_TOKENS exact match. Static tokens carry no\n // per-caller claims, so derive identity from the forwarded owner-email\n // hint (install flow) — otherwise tools would run unscoped.\n if (accessTokens.length > 0 && accessTokens.includes(token)) {\n return {\n authed: true,\n identity: deriveStaticTokenIdentity(ownerEmailHeader),\n // Matched a configured ACCESS_TOKEN — a real caller.\n fullSurface: true,\n };\n }\n\n return { authed: false };\n}\n\nexport async function resolveOrgIdFromDomain(\n orgDomain: string | undefined,\n): Promise<string | undefined> {\n if (!orgDomain) return undefined;\n try {\n const { resolveOrgByDomain } = await import(\"../org/context.js\");\n const org = await resolveOrgByDomain(orgDomain);\n return org?.orgId ?? undefined;\n } catch {\n return undefined;\n }\n}\n"]}
@@ -152,7 +152,7 @@ If your app is an [A2A](/docs/a2a-protocol) peer, other agent-native apps discov
152
152
 
153
153
  ## Exposing it over MCP {#mcp}
154
154
 
155
- With MCP enabled, your actions show up in the framework's MCP server at `/_agent-native/mcp`. Any MCP client Claude, ChatGPT custom MCP apps, Claude Desktop/Code, Cursor, Codex, etc. can connect and see them as tools. See [MCP Protocol](/docs/mcp-protocol).
155
+ With MCP enabled, your actions show up in the framework's MCP server at `/_agent-native/mcp`. Stdio/static-token developer clients see the full connected action surface. OAuth app hosts that request `mcp:apps` get a compact catalog containing app-facing builtins, actions with `mcpApp`, and actions explicitly marked `publicAgent.expose`, so ChatGPT/Claude discovery stays small. See [MCP Protocol](/docs/mcp-protocol).
156
156
 
157
157
  For UI-capable MCP hosts, actions can also attach an optional MCP Apps resource.
158
158
  Use the shared full-app embed helper when the action needs an inline experience.
@@ -188,7 +188,7 @@ export default defineAction({
188
188
  });
189
189
  ```
190
190
 
191
- This advertises the MCP Apps extension (`io.modelcontextprotocol/ui`), exposes the HTML via MCP resources, and includes both current and legacy UI resource metadata for compatible hosts. Keep `link` as the fallback for CLI and non-UI MCP clients; see [External Agents](/docs/external-agents#mcp-apps).
191
+ This advertises the MCP Apps extension (`io.modelcontextprotocol/ui`), exposes the HTML via MCP resources/templates, and includes standard MCP Apps plus ChatGPT Apps SDK widget metadata for compatible hosts. Keep `link` as the fallback for CLI and non-UI MCP clients; see [External Agents](/docs/external-agents#mcp-apps).
192
192
 
193
193
  The helper launches the action's `link` target through `/_agent-native/embed/start` with a short-lived browser session, so routes such as full dashboards, filtered inboxes, drafts, and extension pages can reuse the app's React components directly.
194
194
 
@@ -229,6 +229,8 @@ On top of the per-action tools the MCP server exposes a stable verb set, so an e
229
229
 
230
230
  `create_workspace_app` rejects any non-allow-listed template — the public template allow-list in `packages/shared-app-config/templates.ts` is authoritative and CI-guarded; an external agent cannot widen it. A same-named template action overrides a builtin (template-over-core precedence). Disable the whole set with `MCPConfig.builtinCrossAppTools: false`.
231
231
 
232
+ For OAuth callers that request `mcp:apps`, the server intentionally advertises a compact `tools/list` catalog so app hosts do not ingest every internal action schema. The model sees app-facing builtins (`list_apps`, `open_app`, app-only `create_embed_session`), actions with `mcpApp`, and actions explicitly marked `publicAgent.expose`. Stdio/static-token developer clients still get the full connected action surface. If a host should be able to call a new action from an MCP App conversation, mark it with `mcpApp` for UI-producing work or `publicAgent` for safe read/ingest work.
233
+
232
234
  ### Per-app tour {#tour}
233
235
 
234
236
  Every allow-listed template that produces or lists a navigable resource ships a `link` builder, and the ingest-heavy ones ship a GET + `publicAgent` action so a connected agent can pull live state:
@@ -306,7 +308,7 @@ export default defineAction({
306
308
  });
307
309
  ```
308
310
 
309
- The MCP server advertises extension `io.modelcontextprotocol/ui`, adds `_meta.ui.resourceUri` plus `_meta["ui/resourceUri"]` to `tools/list`, and exposes the HTML through `resources/list` + `resources/read` using MIME `text/html;profile=mcp-app`. The stdio proxy forwards those resource handlers from the live app, so desktop and CLI clients see the same resources as HTTP clients.
311
+ The MCP server advertises extension `io.modelcontextprotocol/ui`, adds `_meta.ui.resourceUri` plus `_meta["ui/resourceUri"]` to `tools/list`, and also emits ChatGPT Apps SDK compatibility metadata (`openai/outputTemplate`, widget CSP/description/accessibility). It exposes the HTML through `resources/list`, `resources/templates/list`, and `resources/read` using MIME `text/html;profile=mcp-app`. The stdio proxy forwards those resource handlers from the live app, so desktop and CLI clients see the same resources as HTTP clients.
310
312
 
311
313
  Keep the existing `link` builder even when adding `mcpApp`. CLI-only clients, older hosts, and any host that does not render MCP Apps will ignore the UI metadata and still need the `"Open in … →"` link. `embedApp()` uses that link as its launch target, calls the app-only `create_embed_session` helper, exchanges a one-time SQL ticket at `/_agent-native/embed/start`, and loads the target route in an iframe with a short-lived browser session plus a bearer fallback for same-origin fetches. `open_app({ app, path, embed: true })` is the generic escape hatch for routes such as full dashboards, filtered inboxes, calendar draft views, analyses, and extension pages, and should be used liberally when the full app is the clearest review/edit surface.
312
314
 
@@ -72,11 +72,13 @@ POST https://your-app.example.com/_agent-native/mcp
72
72
 
73
73
  The server supports the standard MCP handshake: `initialize` → `initialized` → `tools/list` → `tools/call`.
74
74
 
75
- If an action declares `mcpApp`, the server also advertises the official MCP Apps extension (`io.modelcontextprotocol/ui`) and supports `resources/list`, `resources/templates/list`, and `resources/read` for the app resource. Hosts that render MCP Apps can show the UI inline; hosts that do not can still call the tool and use the deep-link fallback. Product UIs should use `embedApp()` so the inline surface is the real React app route, or a focused route that renders a shared React component such as an Analytics chart, not a separate plain HTML implementation. The current official extension matrix includes Claude, Claude Desktop, VS Code GitHub Copilot, Goose, Postman, MCPJam, ChatGPT, and Cursor; host support varies by version and plan, so use the [External Agents MCP Apps notes](/docs/external-agents#mcp-apps-compatibility) for the user-facing guidance.
75
+ If an action declares `mcpApp`, the server also advertises the official MCP Apps extension (`io.modelcontextprotocol/ui`) and supports `resources/list`, `resources/templates/list`, and `resources/read` for the app resource. Hosts that render MCP Apps can show the UI inline; hosts that do not can still call the tool and use the deep-link fallback. Product UIs should use `embedApp()` so the inline surface is the real React app route, or a focused route that renders a shared React component such as an Analytics chart, not a separate plain HTML implementation. The server emits both standard MCP Apps metadata and ChatGPT Apps SDK compatibility metadata so app-capable hosts can find the same `ui://` resource. The current official extension matrix includes Claude, Claude Desktop, VS Code GitHub Copilot, Goose, Postman, MCPJam, ChatGPT, and Cursor; host support varies by version and plan, so use the [External Agents MCP Apps notes](/docs/external-agents#mcp-apps-compatibility) for the user-facing guidance.
76
76
 
77
77
  ## Tools {#tools}
78
78
 
79
- All actions registered in your app are exposed as MCP tools. The mapping is direct:
79
+ Stdio/static-token developer clients see all connected app actions as MCP tools. OAuth callers that request `mcp:apps` get a compact app-host catalog: app-facing builtins, actions with `mcpApp`, and actions explicitly marked `publicAgent.expose`. This keeps ChatGPT/Claude app-host discovery small while preserving the full developer surface for local agents.
80
+
81
+ The mapping is direct:
80
82
 
81
83
  | Action property | MCP tool property |
82
84
  | ------------------ | ----------------- |
@@ -84,7 +86,7 @@ All actions registered in your app are exposed as MCP tools. The mapping is dire
84
86
  | `tool.parameters` | `inputSchema` |
85
87
  | Action name | Tool name |
86
88
 
87
- When `mcpApp` is present, the tool entry also includes `_meta.ui.resourceUri` and `_meta["ui/resourceUri"]`, and the corresponding `ui://` resource is returned as `text/html;profile=mcp-app`.
89
+ When `mcpApp` is present, the tool entry also includes `_meta.ui.resourceUri`, `_meta["ui/resourceUri"]`, and `_meta["openai/outputTemplate"]`, and the corresponding `ui://` resource is returned as `text/html;profile=mcp-app`.
88
90
 
89
91
  ### The `ask-agent` tool {#ask-agent}
90
92
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.22.10",
3
+ "version": "0.22.11",
4
4
  "type": "module",
5
5
  "description": "Framework for agent-native application development — where AI agents and UI share state via files",
6
6
  "license": "MIT",