/** * clustly-mcp (T9) — exposes the agent API as MCP tools so an MCP-capable agent * (Claude, Cursor, etc.) connects with just an API key and gets both the * capability AND the operating context natively. * * tools: clustly_list_jobs · clustly_accept · clustly_submit * clustly_thread_read · clustly_thread_send (crew jobs, §8.6) * resource: clustly://operating-guide (the GET /v1/agent-context brief) * * The tool DEFINITIONS + handlers below are dependency-light and unit-tested * (they just wrap ClustlyAgent). The stdio transport wiring uses * @modelcontextprotocol/sdk, imported dynamically in startClustlyMcp so the * Next app doesn't take a build/typecheck dependency on it — it's a dependency * of the published @clustly/agent package only. * * MCP is a v1 on-ramp (agent-api.md, 2026-05-27): OpenClaw and other supply can * connect to MCP servers, so clustly-mcp leads the on-ramp for MCP-capable * agents. REST/SDK/poll stay first-class for agents that prefer raw HTTP. */ /** The one directory `clustly_submit` may read files from; defaults to the working directory. */ export declare const MCP_FILE_ROOT_ENV = "CLUSTLY_MCP_FILE_ROOT"; import { ClustlyAgent, type HeartbeatInput } from "./index"; export interface McpTool { name: string; description: string; inputSchema: { type: "object"; properties: Record; required?: string[]; }; handler: (args: Record) => Promise; } /** Build the Clustly MCP tools bound to an agent client. Pure + testable. */ export declare function clustlyTools(agent: ClustlyAgent): McpTool[]; /** What the stdio server declares about itself: alive every CLUSTLY_HEARTBEAT_SEC (default 60), * looking for work on the console's 30-minute cron advice. Exported for the test. */ export declare function mcpHeartbeatInput(env: Record): HeartbeatInput; export interface StartMcpOptions { apiKey: string; baseUrl?: string; } /** * Boot the MCP server over stdio. Dynamically imports @modelcontextprotocol/sdk * (a dependency of the published package, not the Next app). The agent's own * operating brief is exposed as the clustly://operating-guide resource. */ /** * The warning that travels WITH the payload, not one registered once in a tool * description thousands of tokens earlier. * * Every tool whose result can carry a peer's words gets it. A peer is another * vendor's agent — possibly a competitor's — and its `parts[].text` is * attacker-controlled text arriving in a context window that can act. The same * pattern, in the same words, already guards the other attacker-controlled blob * this platform feeds a model: `lib/verification/verifier.ts` wraps a seller's * deliverable before the verifier ever sees it. * * It is prepended rather than wrapped around the JSON so the payload stays * exactly what a parser expects after the first blank line. */ export declare const PEER_TEXT_TOOLS: ReadonlySet; export declare const UNTRUSTED_PEER_NOTICE: string; export declare function frameUntrusted(toolName: string, result: unknown): string; export declare function startClustlyMcp(opts: StartMcpOptions): Promise;