@jini-ai/agentic 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/a2ui/agent-to-renderer.d.ts +579 -0
- package/dist/a2ui/agent-to-renderer.d.ts.map +1 -0
- package/dist/a2ui/agent-to-renderer.js +169 -0
- package/dist/a2ui/agent-to-renderer.js.map +1 -0
- package/dist/a2ui/catalog.d.ts +73 -0
- package/dist/a2ui/catalog.d.ts.map +1 -0
- package/dist/a2ui/catalog.js +304 -0
- package/dist/a2ui/catalog.js.map +1 -0
- package/dist/a2ui/common-types.d.ts +401 -0
- package/dist/a2ui/common-types.d.ts.map +1 -0
- package/dist/a2ui/common-types.js +130 -0
- package/dist/a2ui/common-types.js.map +1 -0
- package/dist/a2ui/index.d.ts +16 -0
- package/dist/a2ui/index.d.ts.map +1 -0
- package/dist/a2ui/index.js +16 -0
- package/dist/a2ui/index.js.map +1 -0
- package/dist/a2ui/interpreter.d.ts +48 -0
- package/dist/a2ui/interpreter.d.ts.map +1 -0
- package/dist/a2ui/interpreter.js +287 -0
- package/dist/a2ui/interpreter.js.map +1 -0
- package/dist/a2ui/json-pointer.d.ts +48 -0
- package/dist/a2ui/json-pointer.d.ts.map +1 -0
- package/dist/a2ui/json-pointer.js +149 -0
- package/dist/a2ui/json-pointer.js.map +1 -0
- package/dist/a2ui/renderer-to-agent.d.ts +318 -0
- package/dist/a2ui/renderer-to-agent.d.ts.map +1 -0
- package/dist/a2ui/renderer-to-agent.js +98 -0
- package/dist/a2ui/renderer-to-agent.js.map +1 -0
- package/dist/a2ui/resolve.d.ts +28 -0
- package/dist/a2ui/resolve.d.ts.map +1 -0
- package/dist/a2ui/resolve.js +118 -0
- package/dist/a2ui/resolve.js.map +1 -0
- package/dist/a2ui/tree.d.ts +41 -0
- package/dist/a2ui/tree.d.ts.map +1 -0
- package/dist/a2ui/tree.js +35 -0
- package/dist/a2ui/tree.js.map +1 -0
- package/dist/dom/model-context.d.ts +15 -0
- package/dist/dom/model-context.d.ts.map +1 -1
- package/dist/dom/model-context.js +8 -0
- package/dist/dom/model-context.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/mcp-ui-apps.d.ts +81 -10
- package/dist/mcp-ui-apps.d.ts.map +1 -1
- package/dist/mcp-ui-apps.js +84 -11
- package/dist/mcp-ui-apps.js.map +1 -1
- package/dist/webmcp.d.ts +126 -5
- package/dist/webmcp.d.ts.map +1 -1
- package/dist/webmcp.js +110 -4
- package/dist/webmcp.js.map +1 -1
- package/package.json +16 -5
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param components The full component map (id -> instance).
|
|
3
|
+
* @param rootId The id to start walking from (typically `'root'`, but not assumed — a surface
|
|
4
|
+
* with no `root` component yet is the caller's concern, not this function's; see
|
|
5
|
+
* `interpreter.ts`'s `getRoot()`).
|
|
6
|
+
* @param getChildIds Given a present component, returns its child ids in render order (`[]` for
|
|
7
|
+
* a leaf, or a template-shaped `ChildList` this port doesn't expand — see module doc).
|
|
8
|
+
* @returns A depth-first, pre-order flattening. A `missing` node is a leaf in the output (its own
|
|
9
|
+
* children are never visited — there is nothing to look up). A `cycle` node is also a leaf: the
|
|
10
|
+
* id is emitted once more so a renderer can show *where* the cycle closes, but its children are
|
|
11
|
+
* not walked again (that walk already happened higher up the same path).
|
|
12
|
+
*/
|
|
13
|
+
export function flattenRenderTree(components, rootId, getChildIds) {
|
|
14
|
+
const output = [];
|
|
15
|
+
function visit(id, depth, ancestors) {
|
|
16
|
+
if (ancestors.has(id)) {
|
|
17
|
+
output.push({ id, depth, status: 'cycle' });
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const component = components.get(id);
|
|
21
|
+
if (!component) {
|
|
22
|
+
output.push({ id, depth, status: 'missing' });
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
output.push({ id, depth, status: 'ok' });
|
|
26
|
+
const nextAncestors = new Set(ancestors);
|
|
27
|
+
nextAncestors.add(id);
|
|
28
|
+
for (const childId of getChildIds(component)) {
|
|
29
|
+
visit(childId, depth + 1, nextAncestors);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
visit(rootId, 0, new Set());
|
|
33
|
+
return output;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=tree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tree.js","sourceRoot":"","sources":["../../src/a2ui/tree.ts"],"names":[],"mappings":"AA8BA;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,iBAAiB,CAC/B,UAAkC,EAClC,MAAc,EACd,WAAgD;IAEhD,MAAM,MAAM,GAAiB,EAAE,CAAC;IAEhC,SAAS,KAAK,CAAC,EAAU,EAAE,KAAa,EAAE,SAA8B;QACtE,IAAI,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YACtB,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;YAC5C,OAAO;QACT,CAAC;QACD,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACrC,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;YAC9C,OAAO;QACT,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;QACzC,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACtB,KAAK,MAAM,OAAO,IAAI,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7C,KAAK,CAAC,OAAO,EAAE,KAAK,GAAG,CAAC,EAAE,aAAa,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC;IAC5B,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -19,12 +19,27 @@
|
|
|
19
19
|
* that "that detection is deliberately NOT here: it touches browser globals, and this package
|
|
20
20
|
* holds none," which is exactly the DOM-free guarantee `src/dom/` exists to carve an exception
|
|
21
21
|
* for. See `dom/index.ts`'s re-export of this module.
|
|
22
|
+
*
|
|
23
|
+
* `AgentModelContextToolRegistration` gained `title`/`annotations` 2026-07-28, matching the same
|
|
24
|
+
* `ModelContextTool` dict fields `../webmcp.ts`'s `WebMcpToolRegistration` closed the same day —
|
|
25
|
+
* this file models the identical spec dictionary independently (no shared import; see the module
|
|
26
|
+
* doc above for why the DOM/DOM-free split keeps them separate files), so the two had drifted out
|
|
27
|
+
* of sync on the exact same gap. Found while wiring `examples/reference-web`'s WebMCP stress-test
|
|
28
|
+
* fixture: a raw (non-`toWebMcpTool`) registration carrying a `title` failed TypeScript's
|
|
29
|
+
* excess-property check against the un-widened type here.
|
|
22
30
|
*/
|
|
23
31
|
export interface AgentModelContextToolRegistration {
|
|
24
32
|
readonly name: string;
|
|
33
|
+
/** `ModelContextTool.title` — optional human-readable label, distinct from `name` and `description`. */
|
|
34
|
+
readonly title?: string;
|
|
25
35
|
readonly description: string;
|
|
26
36
|
readonly inputSchema: unknown;
|
|
27
37
|
readonly execute: (args: Record<string, unknown>) => Promise<unknown>;
|
|
38
|
+
/** `ModelContextTool.annotations` — `{ readOnlyHint?, untrustedContentHint? }` behavior hints. */
|
|
39
|
+
readonly annotations?: {
|
|
40
|
+
readonly readOnlyHint?: boolean;
|
|
41
|
+
readonly untrustedContentHint?: boolean;
|
|
42
|
+
};
|
|
28
43
|
}
|
|
29
44
|
/**
|
|
30
45
|
* Options `registerTool` accepts. Matches the draft's
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-context.d.ts","sourceRoot":"","sources":["../../src/dom/model-context.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"model-context.d.ts","sourceRoot":"","sources":["../../src/dom/model-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,MAAM,WAAW,iCAAiC;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,wGAAwG;IACxG,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACtE,kGAAkG;IAClG,QAAQ,CAAC,WAAW,CAAC,EAAE;QAAE,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CACrG;AAED;;;;GAIG;AACH,MAAM,WAAW,oCAAoC;IACnD,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AAED,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,YAAY,CAAC,IAAI,EAAE,iCAAiC,EAAE,OAAO,CAAC,EAAE,oCAAoC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrH;;;;OAIG;IACH,cAAc,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrC;AAMD,oGAAoG;AACpG,wBAAgB,oBAAoB,IAAI,qBAAqB,GAAG,SAAS,CAMxE"}
|
|
@@ -19,6 +19,14 @@
|
|
|
19
19
|
* that "that detection is deliberately NOT here: it touches browser globals, and this package
|
|
20
20
|
* holds none," which is exactly the DOM-free guarantee `src/dom/` exists to carve an exception
|
|
21
21
|
* for. See `dom/index.ts`'s re-export of this module.
|
|
22
|
+
*
|
|
23
|
+
* `AgentModelContextToolRegistration` gained `title`/`annotations` 2026-07-28, matching the same
|
|
24
|
+
* `ModelContextTool` dict fields `../webmcp.ts`'s `WebMcpToolRegistration` closed the same day —
|
|
25
|
+
* this file models the identical spec dictionary independently (no shared import; see the module
|
|
26
|
+
* doc above for why the DOM/DOM-free split keeps them separate files), so the two had drifted out
|
|
27
|
+
* of sync on the exact same gap. Found while wiring `examples/reference-web`'s WebMCP stress-test
|
|
28
|
+
* fixture: a raw (non-`toWebMcpTool`) registration carrying a `title` failed TypeScript's
|
|
29
|
+
* excess-property check against the un-widened type here.
|
|
22
30
|
*/
|
|
23
31
|
function isModelContext(value) {
|
|
24
32
|
return typeof value === 'object' && value !== null && typeof value.registerTool === 'function';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-context.js","sourceRoot":"","sources":["../../src/dom/model-context.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"model-context.js","sourceRoot":"","sources":["../../src/dom/model-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAsCH,SAAS,cAAc,CAAC,KAAc;IACpC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,OAAQ,KAA+B,CAAC,YAAY,KAAK,UAAU,CAAC;AAC5H,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,oBAAoB;IAClC,MAAM,GAAG,GAAI,UAAwD,CAAC,QAAQ,CAAC;IAC/E,IAAI,cAAc,CAAC,GAAG,EAAE,YAAY,CAAC;QAAE,OAAO,GAAG,CAAC,YAAY,CAAC;IAC/D,MAAM,GAAG,GAAI,UAAyD,CAAC,SAAS,CAAC;IACjF,IAAI,cAAc,CAAC,GAAG,EAAE,YAAY,CAAC;QAAE,OAAO,GAAG,CAAC,YAAY,CAAC;IAC/D,OAAO,SAAS,CAAC;AACnB,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -33,7 +33,7 @@ export { findFieldFillRefusal, findFieldReadRefusal, describeFieldRefusal, descr
|
|
|
33
33
|
* being neutral. None of them opens a connection or touches a browser global; a framework
|
|
34
34
|
* binding owns transport and host access.
|
|
35
35
|
*/
|
|
36
|
-
export { toWebMcpTool, toWebMcpTools, WebMcpConfirmationRequiredError, type WebMcpToolRegistration, type WebMcpUserInteraction, type RequestUserInteraction, type ToWebMcpToolOptions, } from './webmcp.js';
|
|
36
|
+
export { toWebMcpTool, toWebMcpTools, isValidWebMcpToolName, WebMcpConfirmationRequiredError, InvalidWebMcpToolNameError, type WebMcpToolRegistration, type WebMcpToolAnnotations, type WebMcpRegisterToolOptions, type WebMcpUserInteraction, type RequestUserInteraction, type ToWebMcpToolOptions, } from './webmcp.js';
|
|
37
37
|
/**
|
|
38
38
|
* Genuine AG-UI: the {@link CapabilityDef} → AG-UI *frontend tool* projection. Real conformance —
|
|
39
39
|
* it emits the protocol's own `parameters` field name (not `inputSchema`) and its canonical
|
|
@@ -61,5 +61,5 @@ export { toAgUiTool, toAgUiTools, createAgUiToolResult, AG_UI_TOOL_CALL_EVENTS,
|
|
|
61
61
|
* `@jini-ai/protocol`, so it is deliberately not bundled with this directory move.
|
|
62
62
|
*/
|
|
63
63
|
export { createAguiEncoder, type AguiEncodeContext, type AguiEncoder, type AGUIAgentMessageEvent, type AGUIEvent, type AGUIEventBase, type AGUIEventKind, type AGUIRunLifecycleEvent, type AGUIStateUpdateEvent, type AGUISurfaceRequestedEvent, type AGUISurfaceRespondedEvent, type AGUIToolCallEvent, } from './gen-ui/index.js';
|
|
64
|
-
export { MCP_UI_VIEW_METHODS, MCP_UI_HOST_NOTIFICATIONS, MCP_UI_SANDBOX_NOTE, JINI_PAGE_ACTION_METHOD, JSON_RPC_ERROR_CODES, isJsonRpcMessage, isJsonRpcRequest, createJsonRpcRequest, createJsonRpcNotification, createJsonRpcResult, createJsonRpcError, createPageActionRequest, type JsonRpcMessage, type JsonRpcRequest, type JsonRpcNotification, type JsonRpcResponse, type JsonRpcError, } from './mcp-ui-apps.js';
|
|
64
|
+
export { MCP_UI_VIEW_METHODS, MCP_UI_HOST_NOTIFICATIONS, MCP_UI_VIEW_NOTIFICATIONS, MCP_UI_HOST_REQUESTS, MCP_UI_SANDBOX_NOTE, JINI_PAGE_ACTION_METHOD, JSON_RPC_ERROR_CODES, isJsonRpcMessage, isJsonRpcRequest, createJsonRpcRequest, createJsonRpcNotification, createJsonRpcResult, createJsonRpcError, createPageActionRequest, type JsonRpcMessage, type JsonRpcRequest, type JsonRpcNotification, type JsonRpcResponse, type JsonRpcError, } from './mcp-ui-apps.js';
|
|
65
65
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,qBAAqB,EACrB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,KAAK,iBAAiB,GACvB,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEvE,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,qBAAqB,EACrB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,oBAAoB,GAC1B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,GACvB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE1F,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,mBAAmB,EACnB,sBAAsB,EACtB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,eAAe,GACrB,MAAM,aAAa,CAAC;AAErB;;;;;;;;GAQG;AACH,OAAO,EACL,YAAY,EACZ,aAAa,EACb,+BAA+B,EAC/B,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,GACzB,MAAM,aAAa,CAAC;AAErB;;;;;GAKG;AACH,OAAO,EACL,UAAU,EACV,WAAW,EACX,oBAAoB,EACpB,sBAAsB,EACtB,KAAK,QAAQ,EACb,KAAK,qBAAqB,GAC3B,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EACL,iBAAiB,EACjB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,qBAAqB,EAC1B,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAC9B,KAAK,yBAAyB,EAC9B,KAAK,iBAAiB,GACvB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,mBAAmB,EACnB,uBAAuB,EACvB,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,yBAAyB,EACzB,mBAAmB,EACnB,kBAAkB,EAClB,uBAAuB,EACvB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,YAAY,GAClB,MAAM,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,qBAAqB,EACrB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,KAAK,iBAAiB,GACvB,MAAM,iBAAiB,CAAC;AAEzB,YAAY,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEvE,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,qBAAqB,EACrB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,oBAAoB,GAC1B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,KAAK,gBAAgB,EACrB,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,GACvB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE1F,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,mBAAmB,EACnB,sBAAsB,EACtB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,eAAe,GACrB,MAAM,aAAa,CAAC;AAErB;;;;;;;;GAQG;AACH,OAAO,EACL,YAAY,EACZ,aAAa,EACb,qBAAqB,EACrB,+BAA+B,EAC/B,0BAA0B,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,yBAAyB,EAC9B,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,GACzB,MAAM,aAAa,CAAC;AAErB;;;;;GAKG;AACH,OAAO,EACL,UAAU,EACV,WAAW,EACX,oBAAoB,EACpB,sBAAsB,EACtB,KAAK,QAAQ,EACb,KAAK,qBAAqB,GAC3B,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EACL,iBAAiB,EACjB,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,qBAAqB,EAC1B,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAC9B,KAAK,yBAAyB,EAC9B,KAAK,iBAAiB,GACvB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,yBAAyB,EACzB,oBAAoB,EACpB,mBAAmB,EACnB,uBAAuB,EACvB,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,yBAAyB,EACzB,mBAAmB,EACnB,kBAAkB,EAClB,uBAAuB,EACvB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,KAAK,eAAe,EACpB,KAAK,YAAY,GAClB,MAAM,kBAAkB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -32,7 +32,7 @@ export { findFieldFillRefusal, findFieldReadRefusal, describeFieldRefusal, descr
|
|
|
32
32
|
* being neutral. None of them opens a connection or touches a browser global; a framework
|
|
33
33
|
* binding owns transport and host access.
|
|
34
34
|
*/
|
|
35
|
-
export { toWebMcpTool, toWebMcpTools, WebMcpConfirmationRequiredError, } from './webmcp.js';
|
|
35
|
+
export { toWebMcpTool, toWebMcpTools, isValidWebMcpToolName, WebMcpConfirmationRequiredError, InvalidWebMcpToolNameError, } from './webmcp.js';
|
|
36
36
|
/**
|
|
37
37
|
* Genuine AG-UI: the {@link CapabilityDef} → AG-UI *frontend tool* projection. Real conformance —
|
|
38
38
|
* it emits the protocol's own `parameters` field name (not `inputSchema`) and its canonical
|
|
@@ -60,5 +60,5 @@ export { toAgUiTool, toAgUiTools, createAgUiToolResult, AG_UI_TOOL_CALL_EVENTS,
|
|
|
60
60
|
* `@jini-ai/protocol`, so it is deliberately not bundled with this directory move.
|
|
61
61
|
*/
|
|
62
62
|
export { createAguiEncoder, } from './gen-ui/index.js';
|
|
63
|
-
export { MCP_UI_VIEW_METHODS, MCP_UI_HOST_NOTIFICATIONS, MCP_UI_SANDBOX_NOTE, JINI_PAGE_ACTION_METHOD, JSON_RPC_ERROR_CODES, isJsonRpcMessage, isJsonRpcRequest, createJsonRpcRequest, createJsonRpcNotification, createJsonRpcResult, createJsonRpcError, createPageActionRequest, } from './mcp-ui-apps.js';
|
|
63
|
+
export { MCP_UI_VIEW_METHODS, MCP_UI_HOST_NOTIFICATIONS, MCP_UI_VIEW_NOTIFICATIONS, MCP_UI_HOST_REQUESTS, MCP_UI_SANDBOX_NOTE, JINI_PAGE_ACTION_METHOD, JSON_RPC_ERROR_CODES, isJsonRpcMessage, isJsonRpcRequest, createJsonRpcRequest, createJsonRpcNotification, createJsonRpcResult, createJsonRpcError, createPageActionRequest, } from './mcp-ui-apps.js';
|
|
64
64
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,qBAAqB,GAKtB,MAAM,iBAAiB,CAAC;AAIzB,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,qBAAqB,GAKtB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,GAKtB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,WAAW,EAAkD,MAAM,aAAa,CAAC;AAE1F,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,mBAAmB,EACnB,sBAAsB,GAKvB,MAAM,aAAa,CAAC;AAErB;;;;;;;;GAQG;AACH,OAAO,EACL,YAAY,EACZ,aAAa,EACb,+BAA+B,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EACL,cAAc,EACd,wBAAwB,EACxB,qBAAqB,GAKtB,MAAM,iBAAiB,CAAC;AAIzB,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,gBAAgB,EAChB,qBAAqB,GAKtB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,OAAO,EACL,uBAAuB,EACvB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,GAKtB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,WAAW,EAAkD,MAAM,aAAa,CAAC;AAE1F,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,wBAAwB,EACxB,mBAAmB,EACnB,sBAAsB,GAKvB,MAAM,aAAa,CAAC;AAErB;;;;;;;;GAQG;AACH,OAAO,EACL,YAAY,EACZ,aAAa,EACb,qBAAqB,EACrB,+BAA+B,EAC/B,0BAA0B,GAO3B,MAAM,aAAa,CAAC;AAErB;;;;;GAKG;AACH,OAAO,EACL,UAAU,EACV,WAAW,EACX,oBAAoB,EACpB,sBAAsB,GAGvB,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EACL,iBAAiB,GAYlB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,yBAAyB,EACzB,oBAAoB,EACpB,mBAAmB,EACnB,uBAAuB,EACvB,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,yBAAyB,EACzB,mBAAmB,EACnB,kBAAkB,EAClB,uBAAuB,GAMxB,MAAM,kBAAkB,CAAC"}
|
package/dist/mcp-ui-apps.d.ts
CHANGED
|
@@ -10,12 +10,34 @@
|
|
|
10
10
|
* MUST NOT send any request or notification to a View before receiving `initialized` — which is
|
|
11
11
|
* the fix for the "posted before the iframe was listening" race.
|
|
12
12
|
*
|
|
13
|
-
*
|
|
13
|
+
* Re-verified 2026-07-28 against the primary source (`github.com/modelcontextprotocol/ext-apps`,
|
|
14
|
+
* both `specification/2026-01-26/apps.mdx` [Stable] and `specification/draft/apps.mdx`) after an
|
|
15
|
+
* audit found the bucket below had the wrong direction for two lifecycle messages and mis-typed a
|
|
16
|
+
* third as fire-and-forget when the spec defines it as a request needing a response:
|
|
14
17
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
18
|
+
* - `ui/notifications/initialized` and `ui/notifications/size-changed` are **View→Host** (the
|
|
19
|
+
* sequence diagram is unambiguous: `UI ->> H: ui/notifications/initialized`, and the "Host
|
|
20
|
+
* Behavior" prose for size reads "hosts MUST **listen for** ... notifications **from the
|
|
21
|
+
* View**"). They were previously bucketed under `MCP_UI_HOST_NOTIFICATIONS`, i.e. backwards —
|
|
22
|
+
* now under {@link MCP_UI_VIEW_NOTIFICATIONS}.
|
|
23
|
+
* - `ui/resource-teardown` (Host→View) carries an `id` and has success/error response shapes in
|
|
24
|
+
* the spec's own wire examples, and the prose is explicit: "Host SHOULD wait for a response
|
|
25
|
+
* before tearing down the resource (to prevent data loss)." That is a request, not a
|
|
26
|
+
* notification — moved to {@link MCP_UI_HOST_REQUESTS}.
|
|
27
|
+
*
|
|
28
|
+
* The draft spec (not yet Stable, but already fixing the above and adding surface this module
|
|
29
|
+
* now also models) adds: `ui/notifications/request-teardown` (View→Host, the View asking to be
|
|
30
|
+
* torn down), `ui/download-file` and `sampling/createMessage` (View→Host requests), and the
|
|
31
|
+
* Host→App direction of `tools/call`/`tools/list` for Apps that register their own tools (the
|
|
32
|
+
* "App-Provided Tools" section, declared via `appCapabilities.tools` in `ui/initialize`).
|
|
33
|
+
*
|
|
34
|
+
* Two deliberate divergences from the spec, both load-bearing:
|
|
35
|
+
*
|
|
36
|
+
* 1. **Direction.** MCP Apps is primarily View→Host: the embedded UI calls tools. Host→View is a
|
|
37
|
+
* *fixed* lifecycle set with no generic "host asks the View to do something" (the App-tools
|
|
38
|
+
* addition above is the one exception, and it is opt-in and capability-gated). Jini's page
|
|
39
|
+
* verbs therefore ride as an explicitly-namespaced extension ({@link JINI_PAGE_ACTION_METHOD})
|
|
40
|
+
* — ours, not the spec's, and named so no one mistakes it.
|
|
19
41
|
* 2. **Sandbox.** The spec mandates `sandbox="allow-scripts allow-same-origin"`, which is safe
|
|
20
42
|
* *there* because the View is served from a separate origin behind a sandbox proxy. A host
|
|
21
43
|
* serving preview content from its own origin must NOT copy that line: `allow-same-origin`
|
|
@@ -25,9 +47,10 @@
|
|
|
25
47
|
* No transport here — this package touches no browser globals. These are pure builders and
|
|
26
48
|
* parsers; the binding that owns the iframe does the posting.
|
|
27
49
|
*/
|
|
28
|
-
/**
|
|
50
|
+
/** Requests the View may send the Host. From the 2026-01-26 [Stable] spec plus the draft's additions (marked below). */
|
|
29
51
|
export declare const MCP_UI_VIEW_METHODS: {
|
|
30
52
|
readonly initialize: "ui/initialize";
|
|
53
|
+
/** View→Host: call a server tool via the Host's proxy (distinct from {@link MCP_UI_HOST_REQUESTS.callAppTool}, the reverse direction). */
|
|
31
54
|
readonly callTool: "tools/call";
|
|
32
55
|
readonly readResource: "resources/read";
|
|
33
56
|
readonly log: "notifications/message";
|
|
@@ -35,21 +58,58 @@ export declare const MCP_UI_VIEW_METHODS: {
|
|
|
35
58
|
readonly sendMessage: "ui/message";
|
|
36
59
|
readonly requestDisplayMode: "ui/request-display-mode";
|
|
37
60
|
readonly updateModelContext: "ui/update-model-context";
|
|
61
|
+
/** Draft addition. Host-mediated file download from a sandboxed iframe that cannot use `allow-downloads`. */
|
|
62
|
+
readonly downloadFile: "ui/download-file";
|
|
63
|
+
/** Draft addition. Request an LLM completion from the Host; gated behind `hostCapabilities.sampling`. */
|
|
64
|
+
readonly createMessage: "sampling/createMessage";
|
|
38
65
|
readonly ping: "ping";
|
|
39
66
|
};
|
|
40
67
|
/**
|
|
41
|
-
* Notifications the Host may send the View
|
|
42
|
-
*
|
|
68
|
+
* Notifications the Host may send the View — fire-and-forget, no response expected or allowed.
|
|
69
|
+
* `initialized`/`size-changed` are NOT here: both are sent BY the View (see
|
|
70
|
+
* {@link MCP_UI_VIEW_NOTIFICATIONS}), and `teardown` is NOT here either: it is a request the Host
|
|
71
|
+
* sends TO the View expecting a response (see {@link MCP_UI_HOST_REQUESTS}).
|
|
43
72
|
*/
|
|
44
73
|
export declare const MCP_UI_HOST_NOTIFICATIONS: {
|
|
45
|
-
readonly initialized: "ui/notifications/initialized";
|
|
46
74
|
readonly toolInputPartial: "ui/notifications/tool-input-partial";
|
|
47
75
|
readonly toolInput: "ui/notifications/tool-input";
|
|
48
76
|
readonly toolResult: "ui/notifications/tool-result";
|
|
49
77
|
readonly toolCancelled: "ui/notifications/tool-cancelled";
|
|
50
|
-
readonly sizeChanged: "ui/notifications/size-changed";
|
|
51
78
|
readonly hostContextChanged: "ui/notifications/host-context-changed";
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Notifications the View may send the Host — fire-and-forget, no response expected or allowed.
|
|
82
|
+
* The spec's own "Notifications (Host → View)" heading in the 2026-01-26 text is misleading for
|
|
83
|
+
* two of these (see the module doc's audit note); the draft spec corrects this by giving these
|
|
84
|
+
* two, plus its own new addition, an explicit "Notifications (View → Host)" heading.
|
|
85
|
+
*/
|
|
86
|
+
export declare const MCP_UI_VIEW_NOTIFICATIONS: {
|
|
87
|
+
/** The View→Host handshake completion notification. Host MUST NOT send anything to the View before this arrives. */
|
|
88
|
+
readonly initialized: "ui/notifications/initialized";
|
|
89
|
+
/** The View SHOULD send this "when rendered content body size changes." */
|
|
90
|
+
readonly sizeChanged: "ui/notifications/size-changed";
|
|
91
|
+
/** Draft addition. The View asking to be torn down (e.g. a "Done" button); the Host MAY defer or ignore it, but if it accepts, it still owes the View {@link MCP_UI_HOST_REQUESTS.teardown}. */
|
|
92
|
+
readonly requestTeardown: "ui/notifications/request-teardown";
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Requests the Host may send the View, needing a response. Distinct from
|
|
96
|
+
* {@link MCP_UI_HOST_NOTIFICATIONS} because a caller building a JSON-RPC envelope for one of
|
|
97
|
+
* these must attach an `id` and correlate the reply — using {@link createJsonRpcNotification}
|
|
98
|
+
* here would silently produce a message the View has no `id` to answer, and a Host that then
|
|
99
|
+
* "waits for a response" (the spec's own words) would wait forever.
|
|
100
|
+
*/
|
|
101
|
+
export declare const MCP_UI_HOST_REQUESTS: {
|
|
102
|
+
/**
|
|
103
|
+
* Host MUST send this before tearing down the UI resource, for any reason. Per spec: "Host
|
|
104
|
+
* SHOULD wait for a response before tearing down the resource (to prevent data loss)." — this
|
|
105
|
+
* is the message the bug report flagged: bucketing it as a fire-and-forget notification means a
|
|
106
|
+
* Host never learns whether the View acknowledged before disappearing.
|
|
107
|
+
*/
|
|
52
108
|
readonly teardown: "ui/resource-teardown";
|
|
109
|
+
/** Draft addition ("App-Provided Tools"). Host→App: execute a tool the App registered via `appCapabilities.tools`. */
|
|
110
|
+
readonly callAppTool: "tools/call";
|
|
111
|
+
/** Draft addition. Host→App: list the App's registered tools. */
|
|
112
|
+
readonly listAppTools: "tools/list";
|
|
53
113
|
};
|
|
54
114
|
/**
|
|
55
115
|
* Jini's page-action extension. **Not part of MCP Apps** — the namespace is explicit so it can
|
|
@@ -100,6 +160,17 @@ export declare const JSON_RPC_ERROR_CODES: {
|
|
|
100
160
|
* Messages arriving over `postMessage` are attacker-influenced input — any page able to reach the
|
|
101
161
|
* frame can post anything. Validate before dispatch; never trust the shape.
|
|
102
162
|
*
|
|
163
|
+
* Found by live adversarial testing against a real sandboxed iframe (2026-07-28), NOT by static
|
|
164
|
+
* review: a request whose `method` is a valid string but whose `id` is present and malformed
|
|
165
|
+
* (e.g. an object, `{ jsonrpc: '2.0', id: { nested: true }, method: 'tools/call' }`) used to pass
|
|
166
|
+
* this check — the `typeof value['method'] === 'string'` branch returned `true` unconditionally,
|
|
167
|
+
* without ever looking at `id`'s type. A Host trusting that then had to build a JSON-RPC response
|
|
168
|
+
* carrying a non-spec `id` back at the View, which the View's own correlation map (keyed by
|
|
169
|
+
* string ids) could never match — not a crash, but a real protocol violation this function exists
|
|
170
|
+
* specifically to catch. Now: if `id` is present at all, its type is checked before anything else,
|
|
171
|
+
* for every message shape (request, notification, or response) — a notification legitimately has
|
|
172
|
+
* no `id`, but a message that HAS one must have a valid one.
|
|
173
|
+
*
|
|
103
174
|
* @param value - The raw `event.data`.
|
|
104
175
|
* @returns True when the value is a well-formed JSON-RPC message.
|
|
105
176
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-ui-apps.d.ts","sourceRoot":"","sources":["../src/mcp-ui-apps.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"mcp-ui-apps.d.ts","sourceRoot":"","sources":["../src/mcp-ui-apps.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp-ui-apps.js
CHANGED
|
@@ -10,12 +10,34 @@
|
|
|
10
10
|
* MUST NOT send any request or notification to a View before receiving `initialized` — which is
|
|
11
11
|
* the fix for the "posted before the iframe was listening" race.
|
|
12
12
|
*
|
|
13
|
-
*
|
|
13
|
+
* Re-verified 2026-07-28 against the primary source (`github.com/modelcontextprotocol/ext-apps`,
|
|
14
|
+
* both `specification/2026-01-26/apps.mdx` [Stable] and `specification/draft/apps.mdx`) after an
|
|
15
|
+
* audit found the bucket below had the wrong direction for two lifecycle messages and mis-typed a
|
|
16
|
+
* third as fire-and-forget when the spec defines it as a request needing a response:
|
|
14
17
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
18
|
+
* - `ui/notifications/initialized` and `ui/notifications/size-changed` are **View→Host** (the
|
|
19
|
+
* sequence diagram is unambiguous: `UI ->> H: ui/notifications/initialized`, and the "Host
|
|
20
|
+
* Behavior" prose for size reads "hosts MUST **listen for** ... notifications **from the
|
|
21
|
+
* View**"). They were previously bucketed under `MCP_UI_HOST_NOTIFICATIONS`, i.e. backwards —
|
|
22
|
+
* now under {@link MCP_UI_VIEW_NOTIFICATIONS}.
|
|
23
|
+
* - `ui/resource-teardown` (Host→View) carries an `id` and has success/error response shapes in
|
|
24
|
+
* the spec's own wire examples, and the prose is explicit: "Host SHOULD wait for a response
|
|
25
|
+
* before tearing down the resource (to prevent data loss)." That is a request, not a
|
|
26
|
+
* notification — moved to {@link MCP_UI_HOST_REQUESTS}.
|
|
27
|
+
*
|
|
28
|
+
* The draft spec (not yet Stable, but already fixing the above and adding surface this module
|
|
29
|
+
* now also models) adds: `ui/notifications/request-teardown` (View→Host, the View asking to be
|
|
30
|
+
* torn down), `ui/download-file` and `sampling/createMessage` (View→Host requests), and the
|
|
31
|
+
* Host→App direction of `tools/call`/`tools/list` for Apps that register their own tools (the
|
|
32
|
+
* "App-Provided Tools" section, declared via `appCapabilities.tools` in `ui/initialize`).
|
|
33
|
+
*
|
|
34
|
+
* Two deliberate divergences from the spec, both load-bearing:
|
|
35
|
+
*
|
|
36
|
+
* 1. **Direction.** MCP Apps is primarily View→Host: the embedded UI calls tools. Host→View is a
|
|
37
|
+
* *fixed* lifecycle set with no generic "host asks the View to do something" (the App-tools
|
|
38
|
+
* addition above is the one exception, and it is opt-in and capability-gated). Jini's page
|
|
39
|
+
* verbs therefore ride as an explicitly-namespaced extension ({@link JINI_PAGE_ACTION_METHOD})
|
|
40
|
+
* — ours, not the spec's, and named so no one mistakes it.
|
|
19
41
|
* 2. **Sandbox.** The spec mandates `sandbox="allow-scripts allow-same-origin"`, which is safe
|
|
20
42
|
* *there* because the View is served from a separate origin behind a sandbox proxy. A host
|
|
21
43
|
* serving preview content from its own origin must NOT copy that line: `allow-same-origin`
|
|
@@ -25,9 +47,10 @@
|
|
|
25
47
|
* No transport here — this package touches no browser globals. These are pure builders and
|
|
26
48
|
* parsers; the binding that owns the iframe does the posting.
|
|
27
49
|
*/
|
|
28
|
-
/**
|
|
50
|
+
/** Requests the View may send the Host. From the 2026-01-26 [Stable] spec plus the draft's additions (marked below). */
|
|
29
51
|
export const MCP_UI_VIEW_METHODS = {
|
|
30
52
|
initialize: 'ui/initialize',
|
|
53
|
+
/** View→Host: call a server tool via the Host's proxy (distinct from {@link MCP_UI_HOST_REQUESTS.callAppTool}, the reverse direction). */
|
|
31
54
|
callTool: 'tools/call',
|
|
32
55
|
readResource: 'resources/read',
|
|
33
56
|
log: 'notifications/message',
|
|
@@ -35,21 +58,58 @@ export const MCP_UI_VIEW_METHODS = {
|
|
|
35
58
|
sendMessage: 'ui/message',
|
|
36
59
|
requestDisplayMode: 'ui/request-display-mode',
|
|
37
60
|
updateModelContext: 'ui/update-model-context',
|
|
61
|
+
/** Draft addition. Host-mediated file download from a sandboxed iframe that cannot use `allow-downloads`. */
|
|
62
|
+
downloadFile: 'ui/download-file',
|
|
63
|
+
/** Draft addition. Request an LLM completion from the Host; gated behind `hostCapabilities.sampling`. */
|
|
64
|
+
createMessage: 'sampling/createMessage',
|
|
38
65
|
ping: 'ping',
|
|
39
66
|
};
|
|
40
67
|
/**
|
|
41
|
-
* Notifications the Host may send the View
|
|
42
|
-
*
|
|
68
|
+
* Notifications the Host may send the View — fire-and-forget, no response expected or allowed.
|
|
69
|
+
* `initialized`/`size-changed` are NOT here: both are sent BY the View (see
|
|
70
|
+
* {@link MCP_UI_VIEW_NOTIFICATIONS}), and `teardown` is NOT here either: it is a request the Host
|
|
71
|
+
* sends TO the View expecting a response (see {@link MCP_UI_HOST_REQUESTS}).
|
|
43
72
|
*/
|
|
44
73
|
export const MCP_UI_HOST_NOTIFICATIONS = {
|
|
45
|
-
initialized: 'ui/notifications/initialized',
|
|
46
74
|
toolInputPartial: 'ui/notifications/tool-input-partial',
|
|
47
75
|
toolInput: 'ui/notifications/tool-input',
|
|
48
76
|
toolResult: 'ui/notifications/tool-result',
|
|
49
77
|
toolCancelled: 'ui/notifications/tool-cancelled',
|
|
50
|
-
sizeChanged: 'ui/notifications/size-changed',
|
|
51
78
|
hostContextChanged: 'ui/notifications/host-context-changed',
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Notifications the View may send the Host — fire-and-forget, no response expected or allowed.
|
|
82
|
+
* The spec's own "Notifications (Host → View)" heading in the 2026-01-26 text is misleading for
|
|
83
|
+
* two of these (see the module doc's audit note); the draft spec corrects this by giving these
|
|
84
|
+
* two, plus its own new addition, an explicit "Notifications (View → Host)" heading.
|
|
85
|
+
*/
|
|
86
|
+
export const MCP_UI_VIEW_NOTIFICATIONS = {
|
|
87
|
+
/** The View→Host handshake completion notification. Host MUST NOT send anything to the View before this arrives. */
|
|
88
|
+
initialized: 'ui/notifications/initialized',
|
|
89
|
+
/** The View SHOULD send this "when rendered content body size changes." */
|
|
90
|
+
sizeChanged: 'ui/notifications/size-changed',
|
|
91
|
+
/** Draft addition. The View asking to be torn down (e.g. a "Done" button); the Host MAY defer or ignore it, but if it accepts, it still owes the View {@link MCP_UI_HOST_REQUESTS.teardown}. */
|
|
92
|
+
requestTeardown: 'ui/notifications/request-teardown',
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Requests the Host may send the View, needing a response. Distinct from
|
|
96
|
+
* {@link MCP_UI_HOST_NOTIFICATIONS} because a caller building a JSON-RPC envelope for one of
|
|
97
|
+
* these must attach an `id` and correlate the reply — using {@link createJsonRpcNotification}
|
|
98
|
+
* here would silently produce a message the View has no `id` to answer, and a Host that then
|
|
99
|
+
* "waits for a response" (the spec's own words) would wait forever.
|
|
100
|
+
*/
|
|
101
|
+
export const MCP_UI_HOST_REQUESTS = {
|
|
102
|
+
/**
|
|
103
|
+
* Host MUST send this before tearing down the UI resource, for any reason. Per spec: "Host
|
|
104
|
+
* SHOULD wait for a response before tearing down the resource (to prevent data loss)." — this
|
|
105
|
+
* is the message the bug report flagged: bucketing it as a fire-and-forget notification means a
|
|
106
|
+
* Host never learns whether the View acknowledged before disappearing.
|
|
107
|
+
*/
|
|
52
108
|
teardown: 'ui/resource-teardown',
|
|
109
|
+
/** Draft addition ("App-Provided Tools"). Host→App: execute a tool the App registered via `appCapabilities.tools`. */
|
|
110
|
+
callAppTool: 'tools/call',
|
|
111
|
+
/** Draft addition. Host→App: list the App's registered tools. */
|
|
112
|
+
listAppTools: 'tools/list',
|
|
53
113
|
};
|
|
54
114
|
/**
|
|
55
115
|
* Jini's page-action extension. **Not part of MCP Apps** — the namespace is explicit so it can
|
|
@@ -82,13 +142,26 @@ function isRecord(value) {
|
|
|
82
142
|
* Messages arriving over `postMessage` are attacker-influenced input — any page able to reach the
|
|
83
143
|
* frame can post anything. Validate before dispatch; never trust the shape.
|
|
84
144
|
*
|
|
145
|
+
* Found by live adversarial testing against a real sandboxed iframe (2026-07-28), NOT by static
|
|
146
|
+
* review: a request whose `method` is a valid string but whose `id` is present and malformed
|
|
147
|
+
* (e.g. an object, `{ jsonrpc: '2.0', id: { nested: true }, method: 'tools/call' }`) used to pass
|
|
148
|
+
* this check — the `typeof value['method'] === 'string'` branch returned `true` unconditionally,
|
|
149
|
+
* without ever looking at `id`'s type. A Host trusting that then had to build a JSON-RPC response
|
|
150
|
+
* carrying a non-spec `id` back at the View, which the View's own correlation map (keyed by
|
|
151
|
+
* string ids) could never match — not a crash, but a real protocol violation this function exists
|
|
152
|
+
* specifically to catch. Now: if `id` is present at all, its type is checked before anything else,
|
|
153
|
+
* for every message shape (request, notification, or response) — a notification legitimately has
|
|
154
|
+
* no `id`, but a message that HAS one must have a valid one.
|
|
155
|
+
*
|
|
85
156
|
* @param value - The raw `event.data`.
|
|
86
157
|
* @returns True when the value is a well-formed JSON-RPC message.
|
|
87
158
|
*/
|
|
88
159
|
export function isJsonRpcMessage(value) {
|
|
89
160
|
if (!isRecord(value) || value['jsonrpc'] !== '2.0')
|
|
90
161
|
return false;
|
|
91
|
-
|
|
162
|
+
if ('id' in value && typeof value['id'] !== 'number' && typeof value['id'] !== 'string')
|
|
163
|
+
return false;
|
|
164
|
+
const hasId = 'id' in value;
|
|
92
165
|
if (typeof value['method'] === 'string')
|
|
93
166
|
return true;
|
|
94
167
|
return hasId && ('result' in value || 'error' in value);
|
package/dist/mcp-ui-apps.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-ui-apps.js","sourceRoot":"","sources":["../src/mcp-ui-apps.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"mcp-ui-apps.js","sourceRoot":"","sources":["../src/mcp-ui-apps.ts"],"names":[],"mappings":"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"}
|