Skip to content

Commit af1a786

Browse files
committed
test(mcp-runtime): cover UTF-16 metadata boundary
1 parent 5ae11c4 commit af1a786

1 file changed

Lines changed: 44 additions & 0 deletions

File tree

src/agents/agent-bundle-mcp-runtime.test.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,50 @@ describe("session MCP runtime", () => {
928928
}
929929
});
930930

931+
it("does not split a surrogate pair at the MCP metadata text limit", async () => {
932+
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "bundle-mcp-utf16-metadata-"));
933+
const serverPath = path.join(tempDir, "utf16-metadata.mjs");
934+
const logPath = path.join(tempDir, "server.log");
935+
const safePrefix = "x".repeat(1_199);
936+
await writeListToolsMcpServer({
937+
filePath: serverPath,
938+
logPath,
939+
tools: [
940+
{
941+
name: "utf16_tool",
942+
description: `${safePrefix}🚀tail`,
943+
inputSchema: { type: "object", properties: {} },
944+
},
945+
],
946+
});
947+
948+
const runtime = await getOrCreateSessionMcpRuntime({
949+
sessionId: "session-utf16-metadata",
950+
sessionKey: "agent:test:session-utf16-metadata",
951+
workspaceDir: "/workspace",
952+
cfg: {
953+
mcp: {
954+
servers: {
955+
metadata: {
956+
command: process.execPath,
957+
args: [serverPath],
958+
},
959+
},
960+
},
961+
},
962+
});
963+
964+
try {
965+
const catalog = await runtime.getCatalog();
966+
967+
expect(catalog.tools).toHaveLength(1);
968+
expect(catalog.tools[0]?.description).toBe(`${safePrefix}...`);
969+
} finally {
970+
await runtime.dispose();
971+
await fs.rm(tempDir, { recursive: true, force: true });
972+
}
973+
});
974+
931975
it("rejects adversarial MCP tool filters without regex backtracking", async () => {
932976
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "bundle-mcp-linear-filter-"));
933977
const serverPath = path.join(tempDir, "linear-filter.mjs");

0 commit comments

Comments
 (0)