MCP: the verbs as an agent's tools

For many agents MCP is the API, so the verb table is served as an MCP server: every verb is a tool, its tosijs-schema input is the tool's JSON Schema, and a call is callVerb — validated at the boundary, never throwing, an { ok: false } becoming a tool error rather than a crash. The protocol layer here is transport-free (a JSON-RPC message in, a response out) so it can sit on stdio, a WebSocket, or a test. virta-mcp (from this repo: bun run mcp) is the stdio server:

virta-mcp --host https://us-central1-<project>.cloudfunctions.net
virta-mcp --memory --seed 40             # a throwaway board, for trying it
virta-mcp --read-only                    # query, get, transcript, projects only
virta-mcp --allow query,get,comment      # exactly these verbs

On a host, the agent's identity is the token's label — machine × repo — and every write it makes carries that as by, with the host's own _by stamped beside it. Every call syncs the replica first, so reads see other writers' events and a write never decides against a stale view; when the host cannot be reached a read answers from the replica, prefixed (replica may be stale …), and a write is refused until a call finds the host back. Registering it with an MCP client is the usual shape (this repo's .mcp.json runs bun bin/mcp.ts instead, and finds the host from the stored token):

{ "mcpServers": { "virta": { "command": "virta-mcp",
    "args": ["--host", "https://us-central1-<project>.cloudfunctions.net", "--read-only"] } } }

Tools only, for now: the transcript verb already hands an agent the unfolded event stream, which is what the design says agents get. Resources (a task as virta://task/38) would be a reader's convenience on top; parked until an agent asks for it.