@emseepea/testing 0.9.14 → 0.11.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 +72 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +32 -12
- package/dist/index.js.map +1 -1
- package/dist/mcp-app-host.d.ts +27 -0
- package/dist/mcp-app-host.d.ts.map +1 -0
- package/dist/mcp-app-host.js +119 -0
- package/dist/mcp-app-host.js.map +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -75,6 +75,22 @@ const running = await startEmseepea(t, await createApp({
|
|
|
75
75
|
const client = await running.connect();
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
+
The test context is optional. Use explicit cleanup with Vitest, Jest, another
|
|
79
|
+
runner, or a plain script:
|
|
80
|
+
|
|
81
|
+
```js
|
|
82
|
+
const running = await startEmseepea(await createApp());
|
|
83
|
+
try {
|
|
84
|
+
const client = await running.connect();
|
|
85
|
+
// assertions
|
|
86
|
+
} finally {
|
|
87
|
+
await running.close();
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Passing a test context with an `after` hook, as in the first example, registers
|
|
92
|
+
that same idempotent `close()` operation automatically.
|
|
93
|
+
|
|
78
94
|
Set `protocolVersion` on `startEmseepea` or `startMcpServer` to test one of the
|
|
79
95
|
server's documented protocol revisions. Omitting it keeps the `2026-07-28`
|
|
80
96
|
default; for example, `{ protocolVersion: "2025-11-25" }` exercises the legacy
|
|
@@ -93,6 +109,62 @@ For ordinary integration tests, `startMcpServer(...).output()` returns the
|
|
|
93
109
|
server's captured `stdout` and `stderr`. Use it to prove that logs do not expose
|
|
94
110
|
credentials or provider details.
|
|
95
111
|
|
|
112
|
+
## Simulate an MCP Apps Host
|
|
113
|
+
|
|
114
|
+
Use `createMcpAppHostSimulator` to test an app controller without creating a
|
|
115
|
+
fake parent window or JSON-RPC dispatcher. The simulator has no React, Svelte,
|
|
116
|
+
or test-runner dependency.
|
|
117
|
+
|
|
118
|
+
```js
|
|
119
|
+
import assert from "node:assert/strict";
|
|
120
|
+
import { createMcpAppController } from "@emseepea/server/ui";
|
|
121
|
+
import { createMcpAppHostSimulator } from "@emseepea/testing";
|
|
122
|
+
|
|
123
|
+
const host = createMcpAppHostSimulator({
|
|
124
|
+
hostContext: { theme: "light", displayMode: "inline" },
|
|
125
|
+
});
|
|
126
|
+
const controller = createMcpAppController({
|
|
127
|
+
name: "Order result",
|
|
128
|
+
version: "1.0.0",
|
|
129
|
+
parseResult: parseOrderResult,
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
controller.connect(host.channel);
|
|
133
|
+
host.deliverToolResult({ orderId: "example-123", status: "ready" });
|
|
134
|
+
host.changeHostContext({ theme: "dark" });
|
|
135
|
+
|
|
136
|
+
const sent = controller.sendMessage("Show the delivery details.");
|
|
137
|
+
host.messageRequests()[0].succeed();
|
|
138
|
+
await sent;
|
|
139
|
+
|
|
140
|
+
const rejected = controller.sendMessage("Change the delivery address.");
|
|
141
|
+
host.messageRequests()[1].reject("The action needs confirmation.");
|
|
142
|
+
await assert.rejects(rejected, /host rejected/i);
|
|
143
|
+
|
|
144
|
+
host.cancel("user cancelled");
|
|
145
|
+
await host.teardown("test complete");
|
|
146
|
+
|
|
147
|
+
function parseOrderResult(value) {
|
|
148
|
+
if (!value || typeof value !== "object" ||
|
|
149
|
+
typeof value.orderId !== "string" || value.status !== "ready") {
|
|
150
|
+
throw new TypeError("Invalid order result");
|
|
151
|
+
}
|
|
152
|
+
return { orderId: value.orderId, status: value.status };
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Initialization is automatic. `initialized()` shows whether the controller sent
|
|
157
|
+
`ui/notifications/initialized`. The app's `parseResult` function remains the
|
|
158
|
+
validation boundary for delivered structured content. Use `dispatch()` for a
|
|
159
|
+
malformed trusted-parent message and `dispatchUntrusted()` for a message from a
|
|
160
|
+
different source when testing that the controller ignores unsafe input.
|
|
161
|
+
|
|
162
|
+
This deterministic simulation proves the lifecycle behavior that the test
|
|
163
|
+
drives, including initialization, result validation, context changes, message
|
|
164
|
+
responses, cancellation, and teardown. It does not prove behavior in ChatGPT,
|
|
165
|
+
Claude, or another exact host. Qualify each supported host separately through
|
|
166
|
+
its real public journey before making a host-specific production claim.
|
|
167
|
+
|
|
96
168
|
## Diagnose Failures
|
|
97
169
|
|
|
98
170
|
The evidence file contains readable test prompts, assistant responses,
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Client } from "@modelcontextprotocol/client";
|
|
2
2
|
import { serveEmseepea, type AuthenticationOptions } from "@emseepea/server";
|
|
3
|
+
export { createMcpAppHostSimulator, type McpAppHostSimulator, type McpAppHostSimulatorOptions, type McpAppMessageRequest, } from "./mcp-app-host.js";
|
|
3
4
|
export type SupportedProtocolVersion = "2026-07-28" | "2025-11-25" | "2025-06-18" | "2025-03-26" | "2024-11-05" | "2024-10-07";
|
|
4
5
|
export interface TestCleanup {
|
|
5
6
|
after(cleanup: () => Promise<void>): void;
|
|
@@ -12,6 +13,7 @@ export interface StartMcpServerOptions {
|
|
|
12
13
|
token?: string;
|
|
13
14
|
}
|
|
14
15
|
export interface RunningMcpServer {
|
|
16
|
+
close(): Promise<void>;
|
|
15
17
|
connect(token?: string): Promise<Client>;
|
|
16
18
|
output(): Readonly<{
|
|
17
19
|
stdout: string;
|
|
@@ -21,6 +23,10 @@ export interface RunningMcpServer {
|
|
|
21
23
|
}
|
|
22
24
|
/** Test-only verifier. Never use it in a deployed server. */
|
|
23
25
|
export declare function insecureTestAuthentication(permissions: readonly string[], discovery?: "public" | "protected"): AuthenticationOptions;
|
|
24
|
-
|
|
26
|
+
type StartEmseepeaOptions = Pick<StartMcpServerOptions, "clientName" | "protocolVersion" | "token">;
|
|
27
|
+
type EmseepeaApp = Parameters<typeof serveEmseepea>[0];
|
|
28
|
+
export declare function startEmseepea(app: EmseepeaApp, options?: StartEmseepeaOptions): Promise<RunningMcpServer>;
|
|
29
|
+
export declare function startEmseepea(test: TestCleanup, app: EmseepeaApp, options?: StartEmseepeaOptions): Promise<RunningMcpServer>;
|
|
30
|
+
export declare function startMcpServer(serverUrl: URL, options?: StartMcpServerOptions): Promise<RunningMcpServer>;
|
|
25
31
|
export declare function startMcpServer(test: TestCleanup, serverUrl: URL, options?: StartMcpServerOptions): Promise<RunningMcpServer>;
|
|
26
32
|
//# 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":"AAGA,OAAO,EAAE,MAAM,EAAiC,MAAM,8BAA8B,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,KAAK,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAE7E,MAAM,MAAM,wBAAwB,GAChC,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,CAAC;AAEjB,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC3C;AAED,MAAM,WAAW,qBAAqB;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAChC,eAAe,CAAC,EAAE,wBAAwB,CAAC;IAC3C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,IAAI,QAAQ,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvD,GAAG,EAAE,GAAG,CAAC;CACV;AAED,6DAA6D;AAC7D,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,SAAS,MAAM,EAAE,EAC9B,SAAS,GAAE,QAAQ,GAAG,WAAyB,GAC9C,qBAAqB,CAyBvB;AAED,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAiC,MAAM,8BAA8B,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,KAAK,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAE7E,OAAO,EACL,yBAAyB,EACzB,KAAK,mBAAmB,EACxB,KAAK,0BAA0B,EAC/B,KAAK,oBAAoB,GAC1B,MAAM,mBAAmB,CAAC;AAE3B,MAAM,MAAM,wBAAwB,GAChC,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,GACZ,YAAY,CAAC;AAEjB,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAC3C;AAED,MAAM,WAAW,qBAAqB;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IAChC,eAAe,CAAC,EAAE,wBAAwB,CAAC;IAC3C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,OAAO,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,MAAM,IAAI,QAAQ,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvD,GAAG,EAAE,GAAG,CAAC;CACV;AAED,6DAA6D;AAC7D,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,SAAS,MAAM,EAAE,EAC9B,SAAS,GAAE,QAAQ,GAAG,WAAyB,GAC9C,qBAAqB,CAyBvB;AAED,KAAK,oBAAoB,GAAG,IAAI,CAAC,qBAAqB,EAAE,YAAY,GAAG,iBAAiB,GAAG,OAAO,CAAC,CAAC;AACpG,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;AAEvD,wBAAgB,aAAa,CAC3B,GAAG,EAAE,WAAW,EAChB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAC7B,wBAAgB,aAAa,CAC3B,IAAI,EAAE,WAAW,EACjB,GAAG,EAAE,WAAW,EAChB,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,gBAAgB,CAAC,CAAC;AA4B7B,wBAAgB,cAAc,CAC5B,SAAS,EAAE,GAAG,EACd,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAC7B,wBAAgB,cAAc,CAC5B,IAAI,EAAE,WAAW,EACjB,SAAS,EAAE,GAAG,EACd,OAAO,CAAC,EAAE,qBAAqB,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,6 +2,7 @@ import { spawn } from "node:child_process";
|
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
3
|
import { Client, StreamableHTTPClientTransport } from "@modelcontextprotocol/client";
|
|
4
4
|
import { serveEmseepea } from "@emseepea/server";
|
|
5
|
+
export { createMcpAppHostSimulator, } from "./mcp-app-host.js";
|
|
5
6
|
/** Test-only verifier. Never use it in a deployed server. */
|
|
6
7
|
export function insecureTestAuthentication(permissions, discovery = "protected") {
|
|
7
8
|
const resourceServerUrl = new URL("https://test.example/mcp");
|
|
@@ -29,20 +30,27 @@ export function insecureTestAuthentication(permissions, discovery = "protected")
|
|
|
29
30
|
},
|
|
30
31
|
};
|
|
31
32
|
}
|
|
32
|
-
export async function startEmseepea(
|
|
33
|
+
export async function startEmseepea(testOrApp, appOrOptions = {}, explicitOptions = {}) {
|
|
34
|
+
const usesTestHook = typeof appOrOptions.listen === "function";
|
|
35
|
+
const test = usesTestHook ? testOrApp : undefined;
|
|
36
|
+
const app = usesTestHook ? appOrOptions : testOrApp;
|
|
37
|
+
const options = usesTestHook ? explicitOptions : appOrOptions;
|
|
33
38
|
const running = await serveEmseepea(app, { port: 0 });
|
|
34
39
|
const clients = [];
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
await running.close();
|
|
38
|
-
});
|
|
40
|
+
const close = closeServer(clients, running.close);
|
|
41
|
+
test?.after(close);
|
|
39
42
|
return {
|
|
40
43
|
...running,
|
|
44
|
+
close,
|
|
41
45
|
output: () => Object.freeze({ stdout: "", stderr: "" }),
|
|
42
46
|
connect: (token = options.token) => connect(running.url, clients, options.clientName, token, options.protocolVersion),
|
|
43
47
|
};
|
|
44
48
|
}
|
|
45
|
-
export async function startMcpServer(
|
|
49
|
+
export async function startMcpServer(testOrServerUrl, serverUrlOrOptions = {}, explicitOptions = {}) {
|
|
50
|
+
const usesTestHook = !(testOrServerUrl instanceof URL);
|
|
51
|
+
const test = usesTestHook ? testOrServerUrl : undefined;
|
|
52
|
+
const serverUrl = usesTestHook ? serverUrlOrOptions : testOrServerUrl;
|
|
53
|
+
const options = usesTestHook ? explicitOptions : serverUrlOrOptions;
|
|
46
54
|
const child = spawn(process.execPath, [fileURLToPath(serverUrl)], {
|
|
47
55
|
env: {
|
|
48
56
|
...process.env,
|
|
@@ -84,11 +92,10 @@ export async function startMcpServer(test, serverUrl, options = {}) {
|
|
|
84
92
|
await stopProcess(child);
|
|
85
93
|
throw error;
|
|
86
94
|
});
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
await stopProcess(child);
|
|
90
|
-
});
|
|
95
|
+
const close = closeServer(clients, () => stopProcess(child));
|
|
96
|
+
test?.after(close);
|
|
91
97
|
return {
|
|
98
|
+
close,
|
|
92
99
|
url,
|
|
93
100
|
output: () => Object.freeze({ stdout: output, stderr: errors }),
|
|
94
101
|
connect: (token = options.token) => connect(url, clients, options.clientName, token, options.protocolVersion),
|
|
@@ -98,9 +105,22 @@ async function connect(url, clients, clientName = "emseepea-test", token, protoc
|
|
|
98
105
|
const client = new Client({ name: clientName, version: "0.0.0" }, protocolVersion === "2026-07-28"
|
|
99
106
|
? { versionNegotiation: { mode: { pin: protocolVersion } } }
|
|
100
107
|
: { supportedProtocolVersions: [protocolVersion], versionNegotiation: { mode: "legacy" } });
|
|
101
|
-
await client.connect(new StreamableHTTPClientTransport(url, token ? { authProvider: { token: async () => token } } : undefined));
|
|
102
108
|
clients.push(client);
|
|
103
|
-
|
|
109
|
+
try {
|
|
110
|
+
await client.connect(new StreamableHTTPClientTransport(url, token ? { authProvider: { token: async () => token } } : undefined));
|
|
111
|
+
return client;
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
await client.close().catch(() => undefined);
|
|
115
|
+
throw error;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function closeServer(clients, stop) {
|
|
119
|
+
let closing;
|
|
120
|
+
return () => closing ??= (async () => {
|
|
121
|
+
await Promise.allSettled(clients.map((client) => client.close()));
|
|
122
|
+
await stop();
|
|
123
|
+
})();
|
|
104
124
|
}
|
|
105
125
|
async function stopProcess(child) {
|
|
106
126
|
if (child.exitCode !== null)
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,MAAM,EAAE,6BAA6B,EAAE,MAAM,8BAA8B,CAAC;AACrF,OAAO,EAAE,aAAa,EAA8B,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { McpAppHostContext } from "@emseepea/server/ui";
|
|
2
|
+
export interface McpAppHostSimulatorOptions {
|
|
3
|
+
readonly hostContext?: McpAppHostContext;
|
|
4
|
+
}
|
|
5
|
+
export interface McpAppMessageRequest {
|
|
6
|
+
readonly id: string | number;
|
|
7
|
+
readonly text: string;
|
|
8
|
+
succeed(): void;
|
|
9
|
+
reject(message?: string): void;
|
|
10
|
+
}
|
|
11
|
+
export interface McpAppHostSimulator {
|
|
12
|
+
/** Pass this window-compatible channel to `createMcpAppController().connect()`. */
|
|
13
|
+
readonly channel: Window;
|
|
14
|
+
initialized(): boolean;
|
|
15
|
+
messageRequests(): readonly McpAppMessageRequest[];
|
|
16
|
+
deliverToolResult(structuredContent: unknown): void;
|
|
17
|
+
changeHostContext(context: Partial<McpAppHostContext>): void;
|
|
18
|
+
cancel(reason?: string): void;
|
|
19
|
+
teardown(reason?: string): Promise<void>;
|
|
20
|
+
/** Deliver an arbitrary message from the trusted parent for negative tests. */
|
|
21
|
+
dispatch(message: unknown): void;
|
|
22
|
+
/** Deliver an arbitrary message from a different source for trust-boundary tests. */
|
|
23
|
+
dispatchUntrusted(message: unknown): void;
|
|
24
|
+
}
|
|
25
|
+
/** Deterministic, framework-neutral simulation of the MCP Apps browser host lifecycle. */
|
|
26
|
+
export declare function createMcpAppHostSimulator(options?: McpAppHostSimulatorOptions): McpAppHostSimulator;
|
|
27
|
+
//# sourceMappingURL=mcp-app-host.d.ts.map
|
|
@@ -0,0 +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,CAgHrB"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/** Deterministic, framework-neutral simulation of the MCP Apps browser host lifecycle. */
|
|
2
|
+
export function createMcpAppHostSimulator(options = {}) {
|
|
3
|
+
const events = new EventTarget();
|
|
4
|
+
const requests = [];
|
|
5
|
+
const responses = new Map();
|
|
6
|
+
let initialized = false;
|
|
7
|
+
let sequence = 0;
|
|
8
|
+
const parent = {
|
|
9
|
+
postMessage(message) {
|
|
10
|
+
if (!record(message) || message.jsonrpc !== "2.0")
|
|
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
|
+
}));
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
const untrusted = {};
|
|
64
|
+
const channel = {
|
|
65
|
+
parent,
|
|
66
|
+
addEventListener: events.addEventListener.bind(events),
|
|
67
|
+
removeEventListener: events.removeEventListener.bind(events),
|
|
68
|
+
};
|
|
69
|
+
function dispatch(message, source = parent) {
|
|
70
|
+
const event = new Event("message");
|
|
71
|
+
Object.defineProperties(event, {
|
|
72
|
+
data: { value: message },
|
|
73
|
+
source: { value: source },
|
|
74
|
+
});
|
|
75
|
+
events.dispatchEvent(event);
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
channel,
|
|
79
|
+
initialized: () => initialized,
|
|
80
|
+
messageRequests: () => Object.freeze([...requests]),
|
|
81
|
+
deliverToolResult: (structuredContent) => dispatch({
|
|
82
|
+
jsonrpc: "2.0",
|
|
83
|
+
method: "ui/notifications/tool-result",
|
|
84
|
+
params: { structuredContent },
|
|
85
|
+
}),
|
|
86
|
+
changeHostContext: (context) => dispatch({
|
|
87
|
+
jsonrpc: "2.0",
|
|
88
|
+
method: "ui/notifications/host-context-changed",
|
|
89
|
+
params: context,
|
|
90
|
+
}),
|
|
91
|
+
cancel: (reason) => dispatch({
|
|
92
|
+
jsonrpc: "2.0",
|
|
93
|
+
method: "ui/notifications/tool-cancelled",
|
|
94
|
+
...(reason === undefined ? {} : { params: { reason } }),
|
|
95
|
+
}),
|
|
96
|
+
teardown: async (reason) => {
|
|
97
|
+
const id = `emseepea-host-teardown-${++sequence}`;
|
|
98
|
+
responses.delete(id);
|
|
99
|
+
dispatch({
|
|
100
|
+
jsonrpc: "2.0",
|
|
101
|
+
id,
|
|
102
|
+
method: "ui/resource-teardown",
|
|
103
|
+
params: reason === undefined ? {} : { reason },
|
|
104
|
+
});
|
|
105
|
+
const response = responses.get(id);
|
|
106
|
+
responses.delete(id);
|
|
107
|
+
if (!response)
|
|
108
|
+
throw new Error("The app did not answer resource teardown.");
|
|
109
|
+
if (response.error !== undefined)
|
|
110
|
+
throw new Error("The app rejected resource teardown.");
|
|
111
|
+
},
|
|
112
|
+
dispatch: (message) => dispatch(message),
|
|
113
|
+
dispatchUntrusted: (message) => dispatch(message, untrusted),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
function record(value) {
|
|
117
|
+
return typeof value === "object" && value !== null;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=mcp-app-host.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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.11.1",
|
|
4
4
|
"description": "MCP integration and semantic testing helpers",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"test:built": "node --test test/*.test.mjs"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"@emseepea/server": "0.11.
|
|
44
|
+
"@emseepea/server": "0.11.1",
|
|
45
45
|
"@modelcontextprotocol/client": "2.0.0"
|
|
46
46
|
},
|
|
47
47
|
"engines": {
|