testJobsMakeAToolCall

tcmts.cli.mcp.testJobsMakeAToolCall · #6xp6livt · term

A tool's job asks an MCP server the call: what it hears of the tool's progress is its output, and what the tool answered (an error: exit 1) its end.

import { jobWhen, startJob } from "#codebase/tcmts/cli/mcp";
import assert from "node:assert/strict";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";

export const testJobsMakeAToolCall = async () => {
  const dir = fs.mkdtempSync(path.join(os.tmpdir(), "tcm jobs "));
  try {
    // a server that answers the call, saying what it was asked
    const server = `
      let buf = "";
      process.stdin.on("data", (d) => {
        buf += d;
        for (let nl = buf.indexOf("\\n"); nl >= 0; nl = buf.indexOf("\\n")) {
          const m = JSON.parse(buf.slice(0, nl));
          buf = buf.slice(nl + 1);
          const say = (x) => process.stdout.write(JSON.stringify({ jsonrpc: "2.0", ...x }) + "\\n");
          if (m.method === "initialize") say({ id: m.id, result: {} });
          if (m.method === "tools/call") {
            say({ method: "notifications/progress", params: { progressToken: m.params._meta.progressToken, message: "merging" } });
            say({ id: m.id, result: { content: [{ type: "text", text: m.params.name + " " + JSON.stringify(m.params.arguments) }], isError: true } });
          }
        }
      });`;
    const id = startJob(
      dir,
      { argv: [], tool: "tcm_merge" },
      {
        cmd: [process.execPath, "-e", server],
        cwd: dir,
        env: process.env,
        call: { name: "tcm_merge", arguments: { approved: true } },
      },
    );
    const job = await jobWhen(dir, id, (j) => !!j.done);
    assert.equal(job.out, "merging\n");
    assert.equal(job.tool, "tcm_merge");
    assert.deepEqual(job.done, { ...job.done, code: 1, text: 'tcm_merge {"approved":true}' });
  } finally {
    fs.rmSync(dir, { recursive: true, force: true });
  }
}

uses