MCP stdio server wrapping every AtpClient backend.
Started by Claude Code (or any other MCP host) as a child process; reads newline-delimited JSON-RPC 2.0 from stdin and writes responses to stdout.
Tools
Generic, multi-backend (use the unified AtpClient.Backend contract):
list_backends— enumerate configured backends and their labels;verify_backend— probe a backend's configuration / reachability;query_backend— submit a TPTP problem to any backend and get a normalized SZS result.
Backend-specific, kept because they expose surface the unified contract does not (system enumeration, multi-system fan-out, hand-written theories, source diagnostics):
list_provers—AtpClient.SystemOnTptp.list_provers/0;run_prover—AtpClient.SystemOnTptp.query_system/3;compare_provers—AtpClient.SystemOnTptp.query_selected_systems/3;prove_isabelle—AtpClient.Isabelle.query/3for hand-written theories (the unifiedquery_backendwithbackend: "isabelle"submits a TPTP problem instead);lint_problem—AtpClient.Lint.analyze/2.
Cancellation and progress
Long-running tool calls (run_prover, compare_provers,
query_backend, prove_isabelle) run inside their own Task in
AtpMcp.Runtime. The MCP host can:
- Send
notifications/cancelledcarrying the in-flight request id to abort a call. The Task is killed, and eachAtpClientbackend tears down its upstream work in response (seeAtpMcp.Runtime's moduledoc for per-backend details). SOTPTP is the only backend that cannot truly cancel server-side — its:time_limit_secis the only bound on remote work. - Set
_meta.progressTokenontools/callto receive periodicnotifications/progressframes while the call is in flight (heartbeat every five seconds by default; configurable via:atp_mcp, :heartbeat_ms).
Forward note: MCP experimental Tasks primitive
The 2025-11-25 MCP revision incubates a Tasks primitive for
long-running invocations (call-now / fetch-later, with a task handle for
status polling and deferred result retrieval). That maps almost exactly
onto ATP workflows. When the primitive stabilises, the long-running
tools here should grow a task-returning variant and a StarExec-style
submit/await pair becomes a natural addition.
Protocol
Speaks MCP revision 2025-11-25. The initialize handshake, ping,
tools/list, and tools/call are implemented; notifications are
accepted and silently acknowledged.
Summary
Functions
Decide what to do with one decoded JSON-RPC message. Pure: returns a
tag that handle_rpc/1 (synchronous) and AtpMcp.Runtime
(asynchronous) interpret in their own way.
Run a tool by name. Catches exceptions and returns an Error: … string
in their place, matching the tool-result error convention.
Parse one JSON-RPC line and return the encoded response, or nil for
notifications and blank lines. Provided for tests that drive the
protocol synchronously without spinning up AtpMcp.Runtime.
Functions
@spec classify(map()) :: {:reply, map()} | {:tool_call, term(), String.t() | nil, map(), term() | nil} | {:cancel, term()} | :noop
Decide what to do with one decoded JSON-RPC message. Pure: returns a
tag that handle_rpc/1 (synchronous) and AtpMcp.Runtime
(asynchronous) interpret in their own way.
Run a tool by name. Catches exceptions and returns an Error: … string
in their place, matching the tool-result error convention.
Parse one JSON-RPC line and return the encoded response, or nil for
notifications and blank lines. Provided for tests that drive the
protocol synchronously without spinning up AtpMcp.Runtime.