// A stand-in for an LLM agent loop (atlibs-asyncai's, once it has a module): it speaks MCP to code mode // over the com.fedfork.exec.mcp.message hook (initialize, tools/list, tools/call) and runs the program its // input scripts, where a model would write one. Compiled by code mode's own compiler (examples/agent.mjs). const MCP = "com.fedfork.exec.mcp.message"; function rpc(id: i32, method: string, params: Json): Json { const msg = Json.object().set("jsonrpc", Json.string("2.0")).set("method", Json.string(method)).set("params", params); return id ? msg.set("id", Json.number(id)) : msg; } export function main(run: Run): void { if (run.start) { const client = Json.object().set("name", Json.string("stub-agent")).set("version", Json.string("0.1.0")); run.call("initialize", MCP, rpc(1, "initialize", Json.object().set("protocolVersion", Json.string("2025-11-25")).set("capabilities", Json.object()).set("clientInfo", client))); return; } if (!run.ok) { run.finish(Json.object().set("error", Json.string(run.id + ": " + run.error))); return; } const reply = run.output; if (run.id == "initialize") { print("server: " + reply.get("result").get("serverInfo").get("name").str + " " + reply.get("result").get("protocolVersion").str); run.call("initialized", MCP, rpc(0, "notifications/initialized", Json.object())); run.call("list", MCP, rpc(2, "tools/list", Json.object())); } else if (run.id == "list") { const tool = reply.get("result").get("tools").at(0).get("name"); print("tool: " + tool.str); const args = Json.object().set("code", run.input.get("code")).set("input", run.input.get("input")); run.call("call", MCP, rpc(3, "tools/call", Json.object().set("name", tool).set("arguments", args))); } else if (run.id == "call") { run.finish(reply); } }