@emseepea/testing 0.13.1 → 0.14.1
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/README.md +39 -0
- package/dist/browser.d.ts +26 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +113 -0
- package/dist/browser.js.map +1 -0
- package/dist/mcp-app-host.d.ts +11 -0
- package/dist/mcp-app-host.d.ts.map +1 -1
- package/dist/mcp-app-host.js +77 -61
- package/dist/mcp-app-host.js.map +1 -1
- package/package.json +9 -2
package/README.md
CHANGED
|
@@ -250,6 +250,45 @@ responses, cancellation, and teardown. It does not prove behavior in ChatGPT,
|
|
|
250
250
|
Claude, or another exact host. Qualify each supported host separately through
|
|
251
251
|
its real public journey before making a host-specific production claim.
|
|
252
252
|
|
|
253
|
+
## Run a Compiled MCP App in a Browser
|
|
254
|
+
|
|
255
|
+
Use `createMcpAppDevelopmentHost` from `@emseepea/testing/browser` in a local
|
|
256
|
+
development page. The host creates an iframe, loads the compiled widget, and
|
|
257
|
+
uses the same protocol engine as `createMcpAppHostSimulator`.
|
|
258
|
+
|
|
259
|
+
```js
|
|
260
|
+
import { createMcpAppDevelopmentHost } from "@emseepea/testing/browser";
|
|
261
|
+
|
|
262
|
+
const host = createMcpAppDevelopmentHost({
|
|
263
|
+
container: document.querySelector("#preview"),
|
|
264
|
+
entryPoint: "../dist/order-result.js",
|
|
265
|
+
rootElementId: "order-result-root",
|
|
266
|
+
fixtures: {
|
|
267
|
+
ready: { orderId: "example-123", status: "ready" },
|
|
268
|
+
delayed: { orderId: "example-456", status: "delayed" },
|
|
269
|
+
},
|
|
270
|
+
hostContext: { theme: "light", platform: "web" },
|
|
271
|
+
});
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
The first fixture is the default. These URL parameters override it for a local
|
|
275
|
+
browser run:
|
|
276
|
+
|
|
277
|
+
- `fixture=delayed` selects a named fixture.
|
|
278
|
+
- `theme=dark` selects the initial light or dark host theme.
|
|
279
|
+
- `width=288` constrains the iframe from 200 to 2,000 pixels.
|
|
280
|
+
- `motion=reduce` makes the iframe match `prefers-reduced-motion`.
|
|
281
|
+
- `message=reject` rejects `ui/message`; the default succeeds.
|
|
282
|
+
|
|
283
|
+
Use `deliverFixture()`, `changeHostContext()`, and `setContainerWidth()` for
|
|
284
|
+
changes without reloading. `messageRequests()` exposes captured action text.
|
|
285
|
+
Call `destroy()` when the preview is no longer needed.
|
|
286
|
+
|
|
287
|
+
Keep fixtures, widget styles, screenshot policy, and assertions in the
|
|
288
|
+
application. This development host proves only the browser lifecycle that you
|
|
289
|
+
run. It does not establish compatibility with ChatGPT, Claude, or another
|
|
290
|
+
public host. Qualify each supported host through its real public journey.
|
|
291
|
+
|
|
253
292
|
## Diagnose Failures
|
|
254
293
|
|
|
255
294
|
The evidence file contains readable test prompts, assistant responses,
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { McpAppHostContext } from "@emseepea/server/ui";
|
|
2
|
+
import { type McpAppMessageRequest } from "./mcp-app-host.js";
|
|
3
|
+
export interface McpAppDevelopmentHostOptions {
|
|
4
|
+
readonly container: HTMLElement;
|
|
5
|
+
readonly entryPoint: string | URL;
|
|
6
|
+
readonly fixtures: Readonly<Record<string, unknown>>;
|
|
7
|
+
readonly rootElementId: string;
|
|
8
|
+
readonly hostContext?: McpAppHostContext;
|
|
9
|
+
readonly messageResponse?: "succeed" | "reject";
|
|
10
|
+
readonly reducedMotion?: boolean;
|
|
11
|
+
readonly searchParams?: URLSearchParams;
|
|
12
|
+
readonly title?: string;
|
|
13
|
+
readonly width?: number;
|
|
14
|
+
}
|
|
15
|
+
export interface McpAppDevelopmentHost {
|
|
16
|
+
readonly iframe: HTMLIFrameElement;
|
|
17
|
+
initialized(): boolean;
|
|
18
|
+
messageRequests(): readonly McpAppMessageRequest[];
|
|
19
|
+
deliverFixture(name: string): void;
|
|
20
|
+
changeHostContext(context: Partial<McpAppHostContext>): void;
|
|
21
|
+
setContainerWidth(width?: number): void;
|
|
22
|
+
destroy(): void;
|
|
23
|
+
}
|
|
24
|
+
/** Run a compiled MCP App in a small, framework-neutral browser host. */
|
|
25
|
+
export declare function createMcpAppDevelopmentHost(options: McpAppDevelopmentHostOptions): McpAppDevelopmentHost;
|
|
26
|
+
//# sourceMappingURL=browser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,mBAAmB,CAAC;AAE3B,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,GAAG,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACrD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,WAAW,CAAC,EAAE,iBAAiB,CAAC;IACzC,QAAQ,CAAC,eAAe,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAChD,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,YAAY,CAAC,EAAE,eAAe,CAAC;IACxC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,WAAW,IAAI,OAAO,CAAC;IACvB,eAAe,IAAI,SAAS,oBAAoB,EAAE,CAAC;IACnD,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,iBAAiB,CAAC,OAAO,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAAG,IAAI,CAAC;IAC7D,iBAAiB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,yEAAyE;AACzE,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,4BAA4B,GACpC,qBAAqB,CA2EvB"}
|
package/dist/browser.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { createMcpAppHostProtocol, } from "./mcp-app-host.js";
|
|
2
|
+
/** Run a compiled MCP App in a small, framework-neutral browser host. */
|
|
3
|
+
export function createMcpAppDevelopmentHost(options) {
|
|
4
|
+
if (!options.container || typeof options.container.append !== "function") {
|
|
5
|
+
throw new TypeError("container must be an HTML element");
|
|
6
|
+
}
|
|
7
|
+
if (!/^[A-Za-z][A-Za-z0-9_.:-]*$/.test(options.rootElementId)) {
|
|
8
|
+
throw new TypeError("rootElementId must be a valid non-empty HTML ID");
|
|
9
|
+
}
|
|
10
|
+
const fixtureNames = Object.keys(options.fixtures);
|
|
11
|
+
if (fixtureNames.length === 0)
|
|
12
|
+
throw new TypeError("fixtures must contain at least one fixture");
|
|
13
|
+
const params = options.searchParams ?? new URLSearchParams(location.search);
|
|
14
|
+
const fixtureName = params.get("fixture") ?? fixtureNames[0];
|
|
15
|
+
fixture(options.fixtures, fixtureName);
|
|
16
|
+
const requestedTheme = params.get("theme");
|
|
17
|
+
const theme = requestedTheme === "light" || requestedTheme === "dark"
|
|
18
|
+
? requestedTheme
|
|
19
|
+
: options.hostContext?.theme;
|
|
20
|
+
const messageResponse = params.get("message") === "reject" ? "reject" : options.messageResponse ?? "succeed";
|
|
21
|
+
const reducedMotion = params.get("motion") === "reduce" || options.reducedMotion === true;
|
|
22
|
+
const width = params.has("width") ? checkedWidth(params.get("width")) : checkedWidth(options.width);
|
|
23
|
+
const iframe = document.createElement("iframe");
|
|
24
|
+
iframe.title = options.title ?? "MCP App preview";
|
|
25
|
+
options.container.append(iframe);
|
|
26
|
+
setWidth(iframe, width);
|
|
27
|
+
const child = iframe.contentWindow;
|
|
28
|
+
const childDocument = iframe.contentDocument;
|
|
29
|
+
if (!child || !childDocument)
|
|
30
|
+
throw new Error("The development host could not create its preview frame.");
|
|
31
|
+
const protocol = createMcpAppHostProtocol({
|
|
32
|
+
hostContext: { ...options.hostContext, ...(theme ? { theme } : {}) },
|
|
33
|
+
}, (message) => child.postMessage(message, "*"));
|
|
34
|
+
const receive = (event) => {
|
|
35
|
+
if (event.source !== child)
|
|
36
|
+
return;
|
|
37
|
+
const wasInitialized = protocol.initialized();
|
|
38
|
+
const requestCount = protocol.messageRequests().length;
|
|
39
|
+
protocol.receive(event.data);
|
|
40
|
+
if (!wasInitialized && protocol.initialized()) {
|
|
41
|
+
protocol.deliverToolResult(fixture(options.fixtures, fixtureName));
|
|
42
|
+
}
|
|
43
|
+
for (const request of protocol.messageRequests().slice(requestCount)) {
|
|
44
|
+
if (messageResponse === "reject")
|
|
45
|
+
request.reject();
|
|
46
|
+
else
|
|
47
|
+
request.succeed();
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
window.addEventListener("message", receive);
|
|
51
|
+
childDocument.open();
|
|
52
|
+
childDocument.write("<!doctype html><html><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"></head><body></body></html>");
|
|
53
|
+
childDocument.close();
|
|
54
|
+
childDocument.title = options.title ?? "MCP App preview";
|
|
55
|
+
childDocument.documentElement.lang = document.documentElement.lang || "en";
|
|
56
|
+
if (reducedMotion)
|
|
57
|
+
installReducedMotion(child);
|
|
58
|
+
const root = childDocument.createElement("div");
|
|
59
|
+
root.id = options.rootElementId;
|
|
60
|
+
childDocument.body.append(root);
|
|
61
|
+
const script = childDocument.createElement("script");
|
|
62
|
+
script.src = new URL(options.entryPoint, location.href).href;
|
|
63
|
+
childDocument.body.append(script);
|
|
64
|
+
return {
|
|
65
|
+
iframe,
|
|
66
|
+
initialized: protocol.initialized,
|
|
67
|
+
messageRequests: protocol.messageRequests,
|
|
68
|
+
deliverFixture: (name) => protocol.deliverToolResult(fixture(options.fixtures, name)),
|
|
69
|
+
changeHostContext: protocol.changeHostContext,
|
|
70
|
+
setContainerWidth: (nextWidth) => setWidth(iframe, checkedWidth(nextWidth)),
|
|
71
|
+
destroy: () => {
|
|
72
|
+
window.removeEventListener("message", receive);
|
|
73
|
+
iframe.remove();
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function fixture(fixtures, name) {
|
|
78
|
+
if (!Object.prototype.hasOwnProperty.call(fixtures, name)) {
|
|
79
|
+
throw new TypeError(`Unknown fixture: ${name}`);
|
|
80
|
+
}
|
|
81
|
+
return fixtures[name];
|
|
82
|
+
}
|
|
83
|
+
function checkedWidth(value) {
|
|
84
|
+
if (value === null || value === undefined)
|
|
85
|
+
return undefined;
|
|
86
|
+
const width = typeof value === "string" && /^\d+$/.test(value) ? Number(value) : value;
|
|
87
|
+
if (!Number.isSafeInteger(width) || Number(width) < 200 || Number(width) > 2_000) {
|
|
88
|
+
throw new TypeError("width must be an integer from 200 to 2000");
|
|
89
|
+
}
|
|
90
|
+
return Number(width);
|
|
91
|
+
}
|
|
92
|
+
function setWidth(iframe, width) {
|
|
93
|
+
iframe.style.width = width === undefined ? "" : `${width}px`;
|
|
94
|
+
}
|
|
95
|
+
function installReducedMotion(target) {
|
|
96
|
+
const nativeMatchMedia = target.matchMedia.bind(target);
|
|
97
|
+
Object.defineProperty(target, "matchMedia", {
|
|
98
|
+
configurable: true,
|
|
99
|
+
value: (query) => /prefers-reduced-motion\s*:\s*reduce/.test(query)
|
|
100
|
+
? {
|
|
101
|
+
matches: true,
|
|
102
|
+
media: query,
|
|
103
|
+
onchange: null,
|
|
104
|
+
addListener() { },
|
|
105
|
+
removeListener() { },
|
|
106
|
+
addEventListener() { },
|
|
107
|
+
removeEventListener() { },
|
|
108
|
+
dispatchEvent: () => true,
|
|
109
|
+
}
|
|
110
|
+
: nativeMatchMedia(query),
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=browser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"browser.js","sourceRoot":"","sources":["../src/browser.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp-app-host.d.ts
CHANGED
|
@@ -22,6 +22,17 @@ export interface McpAppHostSimulator {
|
|
|
22
22
|
/** Deliver an arbitrary message from a different source for trust-boundary tests. */
|
|
23
23
|
dispatchUntrusted(message: unknown): void;
|
|
24
24
|
}
|
|
25
|
+
export interface McpAppHostProtocol {
|
|
26
|
+
initialized(): boolean;
|
|
27
|
+
messageRequests(): readonly McpAppMessageRequest[];
|
|
28
|
+
deliverToolResult(structuredContent: unknown): void;
|
|
29
|
+
changeHostContext(context: Partial<McpAppHostContext>): void;
|
|
30
|
+
cancel(reason?: string): void;
|
|
31
|
+
teardown(reason?: string): Promise<void>;
|
|
32
|
+
receive(message: unknown): void;
|
|
33
|
+
}
|
|
25
34
|
/** Deterministic, framework-neutral simulation of the MCP Apps browser host lifecycle. */
|
|
26
35
|
export declare function createMcpAppHostSimulator(options?: McpAppHostSimulatorOptions): McpAppHostSimulator;
|
|
36
|
+
/** @internal Shared protocol engine for deterministic and browser hosts. */
|
|
37
|
+
export declare function createMcpAppHostProtocol(options: McpAppHostSimulatorOptions, send: (message: unknown) => void): McpAppHostProtocol;
|
|
27
38
|
//# sourceMappingURL=mcp-app-host.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-app-host.d.ts","sourceRoot":"","sources":["../src/mcp-app-host.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,WAAW,CAAC,EAAE,iBAAiB,CAAC;CAC1C;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,IAAI,IAAI,CAAC;IAChB,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,mBAAmB;IAClC,mFAAmF;IACnF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,WAAW,IAAI,OAAO,CAAC;IACvB,eAAe,IAAI,SAAS,oBAAoB,EAAE,CAAC;IACnD,iBAAiB,CAAC,iBAAiB,EAAE,OAAO,GAAG,IAAI,CAAC;IACpD,iBAAiB,CAAC,OAAO,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAAG,IAAI,CAAC;IAC7D,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACjC,qFAAqF;IACrF,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;CAC3C;AAOD,0FAA0F;AAC1F,wBAAgB,yBAAyB,CACvC,OAAO,GAAE,0BAA+B,GACvC,mBAAmB,
|
|
1
|
+
{"version":3,"file":"mcp-app-host.d.ts","sourceRoot":"","sources":["../src/mcp-app-host.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,WAAW,CAAC,EAAE,iBAAiB,CAAC;CAC1C;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,IAAI,IAAI,CAAC;IAChB,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,mBAAmB;IAClC,mFAAmF;IACnF,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,WAAW,IAAI,OAAO,CAAC;IACvB,eAAe,IAAI,SAAS,oBAAoB,EAAE,CAAC;IACnD,iBAAiB,CAAC,iBAAiB,EAAE,OAAO,GAAG,IAAI,CAAC;IACpD,iBAAiB,CAAC,OAAO,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAAG,IAAI,CAAC;IAC7D,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,+EAA+E;IAC/E,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACjC,qFAAqF;IACrF,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;CAC3C;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,IAAI,OAAO,CAAC;IACvB,eAAe,IAAI,SAAS,oBAAoB,EAAE,CAAC;IACnD,iBAAiB,CAAC,iBAAiB,EAAE,OAAO,GAAG,IAAI,CAAC;IACpD,iBAAiB,CAAC,OAAO,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAAG,IAAI,CAAC;IAC7D,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;CACjC;AAOD,0FAA0F;AAC1F,wBAAgB,yBAAyB,CACvC,OAAO,GAAE,0BAA+B,GACvC,mBAAmB,CAoCrB;AAED,4EAA4E;AAC5E,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,0BAA0B,EACnC,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAC/B,kBAAkB,CA4FpB"}
|
package/dist/mcp-app-host.js
CHANGED
|
@@ -1,63 +1,9 @@
|
|
|
1
1
|
/** Deterministic, framework-neutral simulation of the MCP Apps browser host lifecycle. */
|
|
2
2
|
export function createMcpAppHostSimulator(options = {}) {
|
|
3
3
|
const events = new EventTarget();
|
|
4
|
-
const requests = [];
|
|
5
|
-
const responses = new Map();
|
|
6
|
-
let initialized = false;
|
|
7
|
-
let sequence = 0;
|
|
8
4
|
const parent = {
|
|
9
5
|
postMessage(message) {
|
|
10
|
-
|
|
11
|
-
return;
|
|
12
|
-
if ((typeof message.id === "string" || typeof message.id === "number") &&
|
|
13
|
-
(record(message.result) || record(message.error))) {
|
|
14
|
-
responses.set(message.id, {
|
|
15
|
-
...(message.result !== undefined ? { result: message.result } : {}),
|
|
16
|
-
...(message.error !== undefined ? { error: message.error } : {}),
|
|
17
|
-
});
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
if (message.method === "ui/initialize" &&
|
|
21
|
-
(typeof message.id === "string" || typeof message.id === "number")) {
|
|
22
|
-
dispatch({
|
|
23
|
-
jsonrpc: "2.0",
|
|
24
|
-
id: message.id,
|
|
25
|
-
result: {
|
|
26
|
-
protocolVersion: "2026-01-26",
|
|
27
|
-
hostInfo: { name: "emseepea-test-host", version: "0.0.0" },
|
|
28
|
-
hostCapabilities: {},
|
|
29
|
-
hostContext: options.hostContext ?? {},
|
|
30
|
-
},
|
|
31
|
-
}, parent);
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
if (message.method === "ui/notifications/initialized") {
|
|
35
|
-
initialized = true;
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
if (message.method !== "ui/message" ||
|
|
39
|
-
(typeof message.id !== "string" && typeof message.id !== "number") ||
|
|
40
|
-
!record(message.params) || message.params.role !== "user" ||
|
|
41
|
-
!Array.isArray(message.params.content) || message.params.content.length !== 1 ||
|
|
42
|
-
!record(message.params.content[0]) || message.params.content[0].type !== "text" ||
|
|
43
|
-
typeof message.params.content[0].text !== "string")
|
|
44
|
-
return;
|
|
45
|
-
const id = message.id;
|
|
46
|
-
let settled = false;
|
|
47
|
-
const answer = (response) => {
|
|
48
|
-
if (settled)
|
|
49
|
-
throw new Error("The ui/message request has already been answered.");
|
|
50
|
-
settled = true;
|
|
51
|
-
dispatch({ jsonrpc: "2.0", id, ...response }, parent);
|
|
52
|
-
};
|
|
53
|
-
requests.push(Object.freeze({
|
|
54
|
-
id,
|
|
55
|
-
text: message.params.content[0].text,
|
|
56
|
-
succeed: () => answer({ result: {} }),
|
|
57
|
-
reject: (reason = "The test host rejected the message.") => answer({
|
|
58
|
-
error: { code: -32_000, message: reason },
|
|
59
|
-
}),
|
|
60
|
-
}));
|
|
6
|
+
protocol.receive(message);
|
|
61
7
|
},
|
|
62
8
|
};
|
|
63
9
|
const untrusted = {};
|
|
@@ -74,21 +20,92 @@ export function createMcpAppHostSimulator(options = {}) {
|
|
|
74
20
|
});
|
|
75
21
|
events.dispatchEvent(event);
|
|
76
22
|
}
|
|
23
|
+
const protocol = createMcpAppHostProtocol(options, (message) => dispatch(message));
|
|
77
24
|
return {
|
|
78
25
|
channel,
|
|
26
|
+
initialized: protocol.initialized,
|
|
27
|
+
messageRequests: protocol.messageRequests,
|
|
28
|
+
deliverToolResult: protocol.deliverToolResult,
|
|
29
|
+
changeHostContext: protocol.changeHostContext,
|
|
30
|
+
cancel: protocol.cancel,
|
|
31
|
+
teardown: protocol.teardown,
|
|
32
|
+
dispatch: (message) => dispatch(message),
|
|
33
|
+
dispatchUntrusted: (message) => dispatch(message, untrusted),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/** @internal Shared protocol engine for deterministic and browser hosts. */
|
|
37
|
+
export function createMcpAppHostProtocol(options, send) {
|
|
38
|
+
const requests = [];
|
|
39
|
+
const responses = new Map();
|
|
40
|
+
let initialized = false;
|
|
41
|
+
let sequence = 0;
|
|
42
|
+
const receive = (message) => {
|
|
43
|
+
if (!record(message) || message.jsonrpc !== "2.0")
|
|
44
|
+
return;
|
|
45
|
+
if ((typeof message.id === "string" || typeof message.id === "number") &&
|
|
46
|
+
(record(message.result) || record(message.error))) {
|
|
47
|
+
responses.set(message.id, {
|
|
48
|
+
...(message.result !== undefined ? { result: message.result } : {}),
|
|
49
|
+
...(message.error !== undefined ? { error: message.error } : {}),
|
|
50
|
+
});
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (message.method === "ui/initialize" &&
|
|
54
|
+
(typeof message.id === "string" || typeof message.id === "number")) {
|
|
55
|
+
send({
|
|
56
|
+
jsonrpc: "2.0",
|
|
57
|
+
id: message.id,
|
|
58
|
+
result: {
|
|
59
|
+
protocolVersion: "2026-01-26",
|
|
60
|
+
hostInfo: { name: "emseepea-test-host", version: "0.0.0" },
|
|
61
|
+
hostCapabilities: {},
|
|
62
|
+
hostContext: options.hostContext ?? {},
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (message.method === "ui/notifications/initialized") {
|
|
68
|
+
initialized = true;
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (message.method !== "ui/message" ||
|
|
72
|
+
(typeof message.id !== "string" && typeof message.id !== "number") ||
|
|
73
|
+
!record(message.params) || message.params.role !== "user" ||
|
|
74
|
+
!Array.isArray(message.params.content) || message.params.content.length !== 1 ||
|
|
75
|
+
!record(message.params.content[0]) || message.params.content[0].type !== "text" ||
|
|
76
|
+
typeof message.params.content[0].text !== "string")
|
|
77
|
+
return;
|
|
78
|
+
const id = message.id;
|
|
79
|
+
let settled = false;
|
|
80
|
+
const answer = (response) => {
|
|
81
|
+
if (settled)
|
|
82
|
+
throw new Error("The ui/message request has already been answered.");
|
|
83
|
+
settled = true;
|
|
84
|
+
send({ jsonrpc: "2.0", id, ...response });
|
|
85
|
+
};
|
|
86
|
+
requests.push(Object.freeze({
|
|
87
|
+
id,
|
|
88
|
+
text: message.params.content[0].text,
|
|
89
|
+
succeed: () => answer({ result: {} }),
|
|
90
|
+
reject: (reason = "The test host rejected the message.") => answer({
|
|
91
|
+
error: { code: -32_000, message: reason },
|
|
92
|
+
}),
|
|
93
|
+
}));
|
|
94
|
+
};
|
|
95
|
+
return {
|
|
79
96
|
initialized: () => initialized,
|
|
80
97
|
messageRequests: () => Object.freeze([...requests]),
|
|
81
|
-
deliverToolResult: (structuredContent) =>
|
|
98
|
+
deliverToolResult: (structuredContent) => send({
|
|
82
99
|
jsonrpc: "2.0",
|
|
83
100
|
method: "ui/notifications/tool-result",
|
|
84
101
|
params: { structuredContent },
|
|
85
102
|
}),
|
|
86
|
-
changeHostContext: (context) =>
|
|
103
|
+
changeHostContext: (context) => send({
|
|
87
104
|
jsonrpc: "2.0",
|
|
88
105
|
method: "ui/notifications/host-context-changed",
|
|
89
106
|
params: context,
|
|
90
107
|
}),
|
|
91
|
-
cancel: (reason) =>
|
|
108
|
+
cancel: (reason) => send({
|
|
92
109
|
jsonrpc: "2.0",
|
|
93
110
|
method: "ui/notifications/tool-cancelled",
|
|
94
111
|
...(reason === undefined ? {} : { params: { reason } }),
|
|
@@ -96,7 +113,7 @@ export function createMcpAppHostSimulator(options = {}) {
|
|
|
96
113
|
teardown: async (reason) => {
|
|
97
114
|
const id = `emseepea-host-teardown-${++sequence}`;
|
|
98
115
|
responses.delete(id);
|
|
99
|
-
|
|
116
|
+
send({
|
|
100
117
|
jsonrpc: "2.0",
|
|
101
118
|
id,
|
|
102
119
|
method: "ui/resource-teardown",
|
|
@@ -109,8 +126,7 @@ export function createMcpAppHostSimulator(options = {}) {
|
|
|
109
126
|
if (response.error !== undefined)
|
|
110
127
|
throw new Error("The app rejected resource teardown.");
|
|
111
128
|
},
|
|
112
|
-
|
|
113
|
-
dispatchUntrusted: (message) => dispatch(message, untrusted),
|
|
129
|
+
receive,
|
|
114
130
|
};
|
|
115
131
|
}
|
|
116
132
|
function record(value) {
|
package/dist/mcp-app-host.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-app-host.js","sourceRoot":"","sources":["../src/mcp-app-host.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"mcp-app-host.js","sourceRoot":"","sources":["../src/mcp-app-host.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@emseepea/testing",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.1",
|
|
4
4
|
"description": "MCP integration and semantic testing helpers",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -20,6 +20,10 @@
|
|
|
20
20
|
"types": "./dist/index.d.ts",
|
|
21
21
|
"import": "./dist/index.js"
|
|
22
22
|
},
|
|
23
|
+
"./browser": {
|
|
24
|
+
"types": "./dist/browser.d.ts",
|
|
25
|
+
"import": "./dist/browser.js"
|
|
26
|
+
},
|
|
23
27
|
"./semantic": {
|
|
24
28
|
"types": "./semantic/test.d.mts",
|
|
25
29
|
"import": "./semantic/test.mjs"
|
|
@@ -41,9 +45,12 @@
|
|
|
41
45
|
"test:built": "node --test test/*.test.mjs"
|
|
42
46
|
},
|
|
43
47
|
"dependencies": {
|
|
44
|
-
"@emseepea/server": "0.
|
|
48
|
+
"@emseepea/server": "0.14.0",
|
|
45
49
|
"@modelcontextprotocol/client": "2.0.0"
|
|
46
50
|
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"playwright": "1.62.1"
|
|
53
|
+
},
|
|
47
54
|
"engines": {
|
|
48
55
|
"node": ">=22"
|
|
49
56
|
}
|