agentmux 0.7.0

Multi-agent coordination runtime with inter-agent messaging across CLI, MCP, tmux, and ACP.
Documentation
# MCP Surface

This module implements the MCP stdio server for `agentmux`.

## Responsibilities

- Advertise and handle MCP tools:
  - `list` (requires `command="principals"`; `args.namespace` selects the
    scope: omitted/home bundle, a bundle name, `GLOBAL`, or `*` for fan-out)
  - `help`
  - `look`
  - `grant` (requires `command="list"` or `command="resolve"`)
  - `updown` (requires `command="up"` or `command="down"`)
  - `new` (requires `command="peer"`)
  - `change` (requires `command="psk"`)
  - `raww`
  - `send`
- Preserve canonical relay `list` and `look` success payloads without adapter
  reshaping:
  - `list`: relay `ListedBundle` (including the `hosted` flag and per-session
    `ready` flag) passes through unchanged; synthesized down-bundle payloads for
    the unreachable home bundle report `hosted: false` and `ready: false` for
    every configured session.
  - `look` tmux: `snapshot_format="lines"` + `snapshot_lines`
  - `look` ACP: `snapshot_format="acp_entries_v1"` + `snapshot_entries`
    (+ freshness fields), plus `entries_total` (full replay-buffer size) and
    `returned_entries_count` (entries in this window) so callers can detect
    truncation and bound backward walks.
  - `look` windowing parameters (both forwarded to the relay):
    - `lines` (optional): window size. tmux pane lines (default 120) or ACP
      replay entries (default 50 — ACP entries are far larger than tmux lines,
      so the smaller default keeps responses under the MCP payload limit).
    - `offset` (optional): entries to skip from the newest end before the
      tail-N window, for walking backward through older ACP context. ACP
      targets only; a non-zero `offset` against a tmux target is rejected with
      `validation_offset_unsupported`.
  - `send` and `look` both surface sender-attribution fields when the relay
    populates them:
    - `authenticated_identity` (optional): the relay-verified `principal_id`
      of the caller, present only for store-backed credential connections and
      omitted for socket-trust sessions.
    - `on_behalf_of` (optional): the delegated principal the caller is acting
      for. Reserved — always omitted for now; surfaced in the schema so callers
      can consume it without a breaking change once delegation activates.
    Both follow the relay's `skip_serializing_if` semantics: omitted entirely
    (not `null`) when absent.
- Validate MCP request payloads.
- Forward valid requests to relay over the bundle Unix socket.
- Preserve relay error taxonomy/details when relay returns structured errors.
- Emit MCP inscriptions for request, success, and error events.

## Data Flow

1. MCP client calls `list`, `look`, `grant`, `updown`, `raww`, or `send`.
2. MCP client can call `help` to discover tool/command schemas.
3. `src/mcp/mod.rs` validates parameter shape and transport-compatible options.
4. Request is forwarded as relay contract:
   - `list` (`command="principals"`) -> `RelayStreamSession` (`RelayRequest::List`)
   - `look` -> `RelayStreamSession` (`RelayRequest::Look`)
   - `grant` (`command="list"`) -> `RelayStreamSession`
     (`RelayRequest::PermissionList`)
   - `grant` (`command="resolve"`) -> `RelayStreamSession`
     (`RelayRequest::PermissionResolve`)
   - `updown` (`command="up"`) -> `RelayStreamSession` (`RelayRequest::Up`)
   - `updown` (`command="down"`) -> `RelayStreamSession` (`RelayRequest::Down`)
   - `new` (`command="peer"`) -> `RelayStreamSession` (`RelayRequest::NewPeer`)
   - `change` (`command="psk"`) -> `RelayStreamSession`
     (`RelayRequest::ChangePsk`)
   - `raww` -> `RelayStreamSession` (`RelayRequest::Raww`)
   - `send` -> `RelayStreamSession` (`RelayRequest::Send`)
5. For `all=true`, MCP performs adapter fanout across bundle relays in
   deterministic lexicographic order.
6. Relay response is mapped back to MCP JSON payload.

## Bundle Updown

- The `updown` tool administers bundle runtime state for the associated
  bundle:
  - `command="up"` requests `RelayRequest::Up` (host the bundle).
  - `command="down"` requests `RelayRequest::Down` (unhost the bundle).
- Requests ride the MCP server's long-lived `RelayStreamSession`; the relay
  authorizes the caller-session principal carried by the Hello-established
  connection against the `updown` policy control (deny by default).
- The MCP tool only addresses the MCP server's associated bundle; cross-bundle
  administration requires a separate relay connection and is out of scope.
- Relay returns `RelayResponse::BundleTransition` on success; the MCP response
  forwards `schema_version`, `action`, `bundles`, `changed_bundle_count`,
  `skipped_bundle_count`, `failed_bundle_count`, and `changed_any` unchanged.
- Relay `authorization_forbidden` (capability `updown`) surfaces as a typed
  MCP tool error with the relay error code and details preserved.

## Permission Granting

- The `grant` tool exposes the relay ACP permission queue:
  - `command="list"` polls the bundle-scoped pending-request set; the response
    payload mirrors the `permission.requested` event fields exactly.
  - `command="resolve"` submits a decision (`outcome="selected"` requires
    `option_id`; `outcome="cancelled"` rejects `option_id`).
- MCP rejects decider-identity fields (`decided_by`, `ui_session_id`,
  `operator_session_id`) before relay submission; the deciding identity is
  association-derived and relay-stamped.
- Both subcommands are gated solely on the sender session's `grant` policy
  capability. The MCP server forwards the decision over its relay stream, and
  the relay authorizes it against the bundle policy preset. Sessions whose
  policy does not enable `grant` receive the relay submitter-gate rejection.

## Credential Administration

- The `new` tool (`command="peer"`) registers a principal and mints its PSK:
  the relay generates the PSK, stores only its SHA-256 hash, and returns the raw
  value once (or, with `args.output_path`, writes it to that absolute path and
  omits it from the response). `args.scope` is recorded on the principal
  (set for `@RELAY`/`@EXTERNAL`).
- The `change` tool (`command="psk"`) rotates an existing principal's PSK and
  returns the new value; Slice 1 is a store update only (no revocation dispatch).
- Both are relay-wide operations: they ride the MCP server's relay stream, and
  the relay authorizes the connection's principal against its policy preset
  relay-wide, requiring an `all:all` `new.peer` / `change.psk` grant. A
  bundle-relative `all:home` grant is insufficient. The MCP server's own
  identity must therefore carry an operator policy for these tools to succeed.

## Key Types

- `McpConfiguration`
  - startup configuration for runtime roots, bundle paths, and sender session
    identity.
- `McpServer`
  - tool router + handlers.
- `SendParams`
  - MCP `send` request schema, including optional transport-scoped timeout
    overrides (`quiescence_timeout_ms`, `acp_turn_timeout_ms`).

## Module Layout

- `mod.rs`
  - Module declarations and public re-exports.
- `server.rs`
  - MCP server state, tool handlers, and relay/list plumbing.
- `params.rs`
  - MCP tool parameter and meta-tool argument schemas plus shared command
    constants.
- `validation.rs`
  - request-shape validation, meta-tool argument parsing, and relay I/O error
    classification helpers.
- `help.rs`
  - help catalog responses and generated JSON schemas.
- `errors.rs`
  - relay/configuration/runtime error mapping and MCP error payload helpers.

## Validation and Error Policy

- MCP rejects invalid request shapes before relay submission (for example empty
  targets or conflicting timeout fields).
- MCP rejects unknown top-level tool fields and unknown meta-tool `args` fields
  with `validation_invalid_params`; error details include the rejected field
  paths (for example `args.bundle_name_typo`).
- Help schemas set `additionalProperties=false` for documented request shapes.
- MCP does not perform shadow authorization checks.
- Relay `authorization_forbidden` and other relay codes are passed through as
  MCP errors with relay details.

## Event Handling Note

- Relay may return stream events alongside direct responses.
- Current MCP behavior logs these events via inscriptions and ignores them at
  tool-response level.