VoidBot/scripts/smoke-repo-face-shared-documents-mcp.mjs
2026-07-15 20:23:41 +01:00

75 lines
3 KiB
JavaScript

#!/usr/bin/env node
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import { existsSync } from "node:fs";
import { mkdtemp, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join, resolve } from "node:path";
const workspaceRoot = resolve(process.cwd());
const serverPath = resolve(workspaceRoot, "apps", "worker", "dist", "mcp-server.js");
const storageRoot = await mkdtemp(join(tmpdir(), "voidbot-shared-documents-mcp-"));
if (!existsSync(serverPath)) {
throw new Error(`MCP server entrypoint is missing at ${serverPath}. Run the build first.`);
}
const expectedTools = ["read_shared_document", "create_shared_document", "update_shared_document"];
const transport = new StdioClientTransport({
command: process.execPath,
args: [serverPath],
cwd: workspaceRoot,
env: {
...process.env,
STORAGE_ROOT: storageRoot,
REPO_DISCORD_IDENTITIES_PATH: resolve(workspaceRoot, ".voidbot", "private", "repo-discord-identities.json"),
VOIDBOT_REPO_FACE_IDENTITY: "nibu",
VOIDBOT_MCP_TOOL_ALLOWLIST: expectedTools.join(","),
},
stderr: "pipe",
});
const client = new Client({ name: "voidbot-shared-documents-smoke", version: "0.0.0" });
try {
await client.connect(transport);
const tools = await client.listTools();
const names = tools.tools.map((tool) => tool.name).sort();
if (JSON.stringify(names) !== JSON.stringify([...expectedTools].sort())) {
throw new Error(`Unexpected shared-document tool surface: ${names.join(", ")}`);
}
const created = await client.callTool({
name: "create_shared_document",
arguments: { documentId: "shared-scratch", title: "Shared scratch", body: "First mark" },
});
assertOk(created, "create_shared_document");
if (created.structuredContent?.document?.createdBy !== "nibu") {
throw new Error("MCP server did not stamp the active Face identity on create.");
}
const read = await client.callTool({ name: "read_shared_document", arguments: { documentId: "shared-scratch" } });
assertOk(read, "read_shared_document");
if (read.structuredContent?.document?.version !== 1) {
throw new Error("MCP read did not return the created revision.");
}
const updated = await client.callTool({
name: "update_shared_document",
arguments: { documentId: "shared-scratch", body: "Second mark", expectedVersion: 1 },
});
assertOk(updated, "update_shared_document");
if (updated.structuredContent?.document?.version !== 2) {
throw new Error("MCP update did not advance the revision.");
}
process.stdout.write(`${JSON.stringify({ ok: true, tools: names, document: updated.structuredContent?.document })}\n`);
} finally {
await client.close();
await rm(storageRoot, { recursive: true, force: true });
}
function assertOk(result, tool) {
if (result.isError) {
const text = (result.content ?? []).map((entry) => entry.type === "text" ? entry.text : "").join("\n");
throw new Error(`${tool} failed: ${text}`);
}
}