ka2a documentation

Read-only MCP diagnostics

This guide describes ka2a at revision a34b8bc9d319502002f104d28f90d18c325a5d26. Source: docs/mcp.md. Source links require repository access. The App examples on the product page use reviewed revision a7c8ac4a85f5.

Contents

ka2a mcp lets an agent client inspect one endpoint's recorded state. Model Context Protocol (MCP) carries the tool calls. MCP Apps adds an interactive view inside a compatible client. Clients without App support receive text and JSON results.

The server reads an existing state directory. It works while ka2a run owns the endpoint and after the node stops. It needs no broker credentials and never contacts Kafka. The tools cannot send or change work.

Connect a client

  1. Build or locate the ka2a binary. For a source build with the App, run these commands from the repository root:

    make web
    make build

    This creates bin/ka2a. make web needs Node 22.12 or later and npm. The binary needs no Node at runtime. Without generated assets, all six tools work but advertise no App.

  2. Choose an existing endpoint state directory. The MCP process must run as a user who can read it. To create a demo endpoint first, follow Try it. The server refuses a missing, unsafe or incompatible store before the MCP session starts.

  3. Add the server to your MCP client. Replace both paths with absolute paths on the host that will run the process:

    {
      "mcpServers": {
        "ka2a": {
          "command": "/absolute/path/to/ka2a",
          "args": ["mcp", "--state-dir", "/absolute/path/to/endpoint-state"]
        }
      }
    }

    The configuration location depends on the client. It launches the command as a subprocess and exchanges MCP messages through standard input and output (stdio). You can use KA2A_STATE_DIR instead of --state-dir.

  4. Call node_status with {}. In an App-capable client, use the section navigation to inspect operations and other records. Otherwise, call the tools below directly.

There is no custom web listener or login page. Metrics and health probes keep their existing guarded endpoints. See the configuration reference for all startup flags.

Tools

ToolArgumentsResult
node_status{}A ka2a.snapshot/1 with endpoint identity, quarantine, storage and counts. Its record lists are empty.
list_operationsOptional limit (default 50, maximum 200), nonnegative cursor (default 0) and exchange states.A ka2a.snapshot/1 with sent operations, newest first. operations.next_cursor is 0 at the end.
get_operationRequired positive integer seq from an operation row.A ka2a.operation/1 with send, exchange, response and task observations.
inspect_endpointRequired section, with optional page and state filters described below.A snapshot page for outbox, dispatch, rejections, incidents or partitions.
get_recovery_rehearsal{}The sanitized simulation report selected at server startup.
get_implementation_replay{}The model/implementation observation artifact selected at server startup.

For example, call list_operations with:

{"limit": 10, "cursor": 0}

Then call get_operation with a seq from the result:

{"seq": 42}

A pseudonym such as op~... is display data, not a lookup key. Pseudonyms stay consistent within one server session and change when the server restarts. The tools have no option to reveal raw message identifiers.

Read the source before interpreting a result

Endpoint and operation results identify the store observation with source.statement and captured_at. Recovery reports use simulated_at and their notice. Replay artifacts identify sources, revision and scope, without a capture timestamp.

  • An owner lock means a process held the lock at capture time. It is not a health check.
  • Without an owner, the data is historical: the last state committed to the store.
  • Broker connectivity stays unknown unless you enable the separate live-status read below.
  • A broker acknowledgement does not establish remote recording. A protocol response does not establish that the application task completed.
  • Each page is a new snapshot. Concurrent writes can change counts between calls.
  • Free bytes inside SQLite are unused database pages, not free disk capacity.

The tools omit bodies, typed response results, task snapshots and key material. Stored text remains untrusted data. Tool metadata declares read-only, idempotent and closed-world hints. These describe the implementation and do not grant client permissions.

Endpoint status App

All six tools use one self-contained App. Its navigation, refresh, state filters and next/previous controls call fixed read-only tools through the host. Capture time, source limits and unknown observations stay visible.

The host must advertise the io.modelcontextprotocol/ui extension and support the text/html;profile=mcp-app MIME type. The server then adds a UI resource reference to the tool metadata. Its only App resource is ui://ka2a/node-status.html, at most 2 MiB. Text and JSON results remain available to every client.

The App makes no external API or resource requests. Its content security policy forbids external connections, assets, frames and forms. Stored text remains inert. Cancelled or superseded requests cannot replace a newer view.

Release binaries contain the App. Go-only source builds and make verify need no Node. The App build guide covers browser tests and screenshot regeneration. Those tests use a local host built with the official SDK. They do not qualify every third-party MCP client.

The App replaces the former serve-ui and run --ui-listen interface. There is no separate web UI, login token or cookie session.

Operation journeys and endpoint inspection

Select a row from list_operations, or call get_operation, to inspect one journey. Local admission, broker acknowledgement and the protocol response keep separate timestamps and meanings. The App labels remote recording “Not directly observed” because the local store has no separate remote receipt. The SDK and CLI can infer remote recording from a correlated response.

The view shows publication attempts, reasons and the observed task state. Its arrows describe protocol stages. They do not reconstruct an event history or fill gaps in evidence.

inspect_endpoint accepts these arguments:

ArgumentValues
sectionoutbox, dispatch, rejections, incidents or partitions.
limitOptional integer from 1 to 200.
cursorOptional page cursor. Partitions have no cursor.
statesOptional array for outbox and dispatch. Default filters show unresolved publication and started or held dispatch.

Each row can reveal all retained fields in the observation result. Configuration, counts and outbox totals come from the same read. list_operations also accepts an exchange states filter.

Optional live status

For the running node's broker, credential and catalog observations, start the node with run --control. Add --live-status to the MCP command:

ka2a mcp --state-dir /absolute/state --live-status

MCP reads GET /status on the endpoint's private local socket. It does not contact a broker. A missing socket leaves connectivity unknown. This process observation is separate from the store transaction. --budget-bytes selects the observed storage budget, and the App labels its source.

Inspect a retained snapshot

To read a previously exported snapshot instead of a current store:

ka2a mcp --snapshot /absolute/snapshot.json

The file must contain pseudonymized identifiers. It keeps its original capture time and contains only the recorded pages. The server never reads a current store for this source. Operation lookup searches only the recorded operations page.

Retained files show source.retained_file: true. Their page limits stay visible. Custom limits, filters and further cursors are refused. The App disables those controls.

Retained recovery rehearsals

A recovery rehearsal is a saved simulation report. The simulator runs real store transitions on a private copy. The MCP tool reads the report without running or applying recovery.

Run the simulator, save its JSON output, then select that file when starting the MCP server. Replace the paths and dispatch number with your own values:

ka2a recovery simulate --state-dir /absolute/state \
  --release-dispatch 3 --reason operator_checked --output json > /absolute/rehearsal.json
ka2a mcp --state-dir /absolute/state --recovery-report /absolute/rehearsal.json

Call get_recovery_rehearsal with {}. The App shows before/after states, refused actions and invariant checks: the store rules that the simulation checked. The operator supplies the report, and the viewer does not independently verify it. An apply receipt is not a rehearsal.

The reader accepts at most 256 KiB, 100 actions, 200 changed records and 32 invariants. It refuses malformed or duplicate JSON fields and unsupported states. The view omits source paths, source identifiers and free-text details. Operation targets use session pseudonyms. Keep the original local report for exact refusal details. Its SHA-256 digest appears in the App.

Model and implementation replay

A replay compares expected model states with recorded implementation observations. The development harness exports observations from the real checkpoint coordinator and SQLite store. Run this command from the source checkout, then select the artifact at MCP startup:

KA2A_REPLAY_EXPORT=/absolute/replay.json \
  go test ./internal/modelbridge -run '^TestExportModelImplementationReplay$' -count=1
ka2a mcp --state-dir /absolute/state --replay-report /absolute/replay.json

Call get_implementation_replay with {}. One cursor moves through both sets of values. The App highlights the first mismatch. The display includes selected observation points and labels test broker and handler counters. The harness also checks the complete replay mapping. A negative-control test confirms that a broken coordinator produces a mismatch.

The model-implementation-replay/1 artifact records:

  • model, trace and mapping paths with SHA-256 digests.
  • the implementation revision, or unknown, and whether the working tree was modified.
  • exact integers as #bigint strings.
  • the trace scope and exclusions.

The reader accepts at most 256 KiB, 200 steps and 64 comparisons per step. The normalized MCP replay result is at most 512 KiB, including its text fallback. The reader refuses inconsistent comparison flags and first-divergence claims.

Agreement covers the recorded trace and mapping. It does not prove general implementation correctness or liveness. The production binary never runs Quint or the replay harness.

Boundaries and request limits

The tools never take ownership, migrate, admit, retry, release, abandon, import, export or purge work. Tool arguments cannot supply paths. Startup flags select retained files.

LimitValue
Request frameAt most 64 KiB.
Unanswered calls in the SDK sessionAt most 16.
Tool deadlineFive seconds.
Tool resultAt most 1 MiB, including structured content and the JSON text fallback. The JSON-RPC envelope is outside this bound.
Drain after end of inputUp to five seconds for accepted calls.

An excessive result asks the client to narrow the page. Unknown arguments and out-of-range values fail. Storage and lookup failures retain their observation error codes, such as state_missing, unsafe_storage, not_found or expired.

Standard output carries only protocol messages, including with --output json. Diagnostics go to standard error. A stop signal ends the command even if the client stopped reading output.

Read-only SQLite inspection can create an empty write-ahead log (WAL) and its shared-memory index beside a closed store. It does not change durable records or the epoch.

All ka2a documents