From 4e73c2b918c131df2ecba0bd4aa1b8e528bbe521 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Thu, 3 Sep 2026 01:05:46 +0000 Subject: [PATCH 1/2] test(mcp): reserve relay host origin Hold the test host listener open so ephemeral proxy allocation cannot reuse its origin and trip the production isolation guard. --- .../tests/mcp-app-sandbox.test.ts | 33 ++++++++++++------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/packages/agent-bundle/tests/mcp-app-sandbox.test.ts b/packages/agent-bundle/tests/mcp-app-sandbox.test.ts index 82f1c5abe..dbe837768 100644 --- a/packages/agent-bundle/tests/mcp-app-sandbox.test.ts +++ b/packages/agent-bundle/tests/mcp-app-sandbox.test.ts @@ -296,18 +296,26 @@ it('provides a valid built App resource without imposing the runtime message-siz }); it('uses an opaque child relay shell with real MCP Apps JSON-RPC notification methods', async () => { - const proxy = await createMcpAppSandboxProxy({ - hostOrigin: 'http://127.0.0.1:43123', - maxMessageBytes: 1_024, - port: 0, - }); - const frame = createMcpAppSandboxFrame({ - consent, - declaration, - hostOrigin: 'http://127.0.0.1:43123', - proxy, - }); + const host = createServer(); + host.listen({ host: '127.0.0.1', port: 0 }); + await once(host, 'listening'); + const address = host.address(); + if (address === null || typeof address === 'string') throw new Error('The MCP App sandbox test host did not receive a TCP address.'); + const hostOrigin = `http://127.0.0.1:${address.port}`; + let proxy: Awaited> | undefined; + try { + proxy = await createMcpAppSandboxProxy({ + hostOrigin, + maxMessageBytes: 1_024, + port: 0, + }); + const frame = createMcpAppSandboxFrame({ + consent, + declaration, + hostOrigin, + proxy, + }); const shell = await fetch(proxy.url).then((response) => response.text()); expect(shell).toContain('sandbox="allow-scripts"'); expect(shell).toContain("event.origin !== 'null'"); @@ -318,7 +326,8 @@ it('uses an opaque child relay shell with real MCP Apps JSON-RPC notification me expect(shell).not.toContain('byteLength(message) > maxMessageBytes'); expect(new URL(frame.src).hash).toContain('maxMessageBytes'); } finally { - await proxy.close(); + await proxy?.close(); + await new Promise((resolve, reject) => host.close((error) => error === undefined ? resolve() : reject(error))); } }); From 43309abfa9857d7835c96d4462b0a64537237450 Mon Sep 17 00:00:00 2001 From: ScriptedAlchemy Date: Thu, 3 Sep 2026 01:19:58 +0000 Subject: [PATCH 2/2] test(claude): align path token fixture Keep coverage on documented env substitutions without using the unsupported MCP cwd field tightened by the Claude lifecycle contract. --- packages/agent-bundle/tests/path-token-resolver.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/agent-bundle/tests/path-token-resolver.test.ts b/packages/agent-bundle/tests/path-token-resolver.test.ts index 4603e318e..f38df9617 100644 --- a/packages/agent-bundle/tests/path-token-resolver.test.ts +++ b/packages/agent-bundle/tests/path-token-resolver.test.ts @@ -246,8 +246,8 @@ it('resolves Claude path tokens outside command when launching a generated artif fixture: { args: [`${pathTokens.workspaceRoot}/tool`], command: `${pathTokens.pluginRoot}/bin/unchanged`, - cwd: pathTokens.pluginData, env: { + DATA: pathTokens.pluginData, ROOT: pathTokens.pluginRoot, WORKSPACE: pathTokens.workspaceRoot, }, @@ -295,8 +295,8 @@ it('resolves Claude path tokens outside command when launching a generated artif expect(stdio[0]).toMatchObject({ args: [`${fixture.roots.workspaceRoot}/tool`], command: '${CLAUDE_PLUGIN_ROOT}/bin/unchanged', - cwd: expect.any(String), env: { + DATA: expect.any(String), ROOT: expect.any(String), WORKSPACE: fixture.roots.workspaceRoot, },