MCP Interface

For a concise local setup path, see MCP Quickstart.

MCP is Zaxy's primary integration surface. The server exposes memory operations as typed tools so LangGraph, Claude Desktop, custom agents, or any MCP-capable client can use the same memory system without linking directly against Python application code.

Model Call Rhythm

memory_checkout is the front door to Zaxy memory; everything else is plumbing or power use. Use Zaxy tools in this order:

  1. At session start, call memory_bootstrap.
  2. Before substantial work, call memory_checkout.
  3. For multi-agent missions, use Coordinate tools to record worker-local findings and promote only accepted state.
  4. After using retrieved context, call memory_feedback.
  5. When checkout returns synthesis answer candidates and one materially shapes the answer, call memory_synthesis_artifact.
  6. When an individual synthesis ledger row is used or excluded, call memory_synthesis_evidence.

Tool Profiles

The server lists tools through a profile selected by MCP_TOOL_PROFILE or zaxy serve --profile core|full. The core profile is the default since 2.1.0; restore the previous every-tool listing with MCP_TOOL_PROFILE=full or zaxy serve --profile full. The core profile lists only the front-door verb set — memory_checkout, memory_append, memory_query, context_assemble, memory_feedback, memory_invalidate, memory_capabilities, and the experimental memory_feeling_of_knowing — so models facing a long tool registry select the right entry point more reliably. Both profiles list memory_checkout first: the front door leads the listing order. Profiles change listing, not capability: any tool remains callable by name under either profile, and memory_capabilities returns a profile block with the active profile name and, under core, the available-but-unlisted tool names so a core-profile agent can discover and request the full surface.

memory_append(event_type, actor, payload, thread?) appends a typed event to the Eventloom log for the selected session, extracts graph entities and edges, upserts the selected graph projection, records metrics, and emits a Pathlight span when tracing is enabled. Payload size is bounded and session IDs are validated before they affect filesystem paths.

memory_query(query, temporal_filter?, limit?) returns ranked context chunks. The query router validates the string and limit, optionally embeds the query, runs exact/keyword/vector/traversal search, fuses scores, and returns compact context suitable for an agent prompt. Temporal filters let a client ask what was valid at a specific time. Remote SSE requests are constrained to the session from the configured session header. Results include Eventloom citations when available so clients can display or replay the source event. Results also include score_explanation metadata for ranking diagnostics.

memory_verbatim(query, session_id?, limit?) returns exact source chunks from the Eventloom log without requiring a graph service. It is the source-recall lane for questions that need raw transcript turns, document chunks, identifiers, quoted phrases, or file/source citations. Results include the raw content, BM25 score, eventloom://... citation, source kind, and source metadata such as document path/line range or transcript source/turn index.

memory_feedback(entity_name, entity_type, feedback, ...) records whether a retrieved graph entity was useful. Positive feedback values, used and helpful, append a memory.reinforced event with optional importance, query, source, score, citation, and reason fields. Negative feedback, irrelevant, appends an audit-only memory.feedback event and does not delete or decay existing memory. Fabric-level feedback for assembled packet_memory context also preserves source packet projection metadata. The tool uses the same session scoping rules as append and query. Pass purpose and outcome when a memory item changes a purpose-specific action, such as accepted Coordinate state supporting a handoff; reinforced memory projection preserves compact purpose profile, evidence-policy, expected-action, authority, and mission metadata for future checkout and audit.

memory_synthesis_artifact(checkout, candidate?, outcome?, ...) persists the answer candidates from a Memory Checkout response as a deterministic memory.synthesis.artifact.created event. If a selected candidate is provided, outcome must also be provided; Zaxy records the normalized outcome as memory.synthesis.used, memory.synthesis.rejected, memory.synthesis.corrected, or memory.evidence.excluded. The checkout payload owns the session scope, so this tool intentionally has no separate session_id override. Candidate feedback must match one of diagnostics.synthesis.answer_candidates; Zaxy canonicalizes the persisted candidate from checkout diagnostics before appending the outcome event. Artifacts and candidate outcomes project into graph memory as synthesis artifact, answer-candidate, ledger-row, and source-group relationships.

memory_synthesis_evidence(checkout, row, outcome, candidate?, reason?, actor?) records synthesis evidence row feedback for one diagnostics.synthesis.ledger_rows item. used and helpful outcomes append memory.evidence.reinforced; excluded appends memory.evidence.excluded. The event preserves the row fact id, source group, citation, support source ids, optional selected answer candidate, checkout quality, slot plan, and reason. Use this when a composed answer depends on or explicitly rejects a ledger row instead of only recording the aggregate candidate outcome.

In Coordinate missions, use coordination_record_synthesis_artifact instead of the generic memory tool when the answer candidate is part of a merge brief, approval packet, accepted checkout, or handoff. It writes the generic synthesis artifact and then appends a mission-scoped coordination.proof_packet.created event with accepted finding ids, review refs, promotion refs, worker source refs, optional handoff event refs, diagnostic pending ids, conflict ids, excluded row reasons, and non-authoritative row diagnostics. For decision_scope="handoff", provide handoff_id so the proof packet cites the exact coordination.handoff.created sequence and hash.

memory_skill(action, skill_id, ...) is a typed helper for procedural memory. It appends one of the deterministic skill lifecycle events skill.proposed, skill.validated, skill.revised, skill.deprecated, skill.contradicted, skill.applied, or skill.outcome_recorded, then projects the event through the same extractor and graph path as memory_append. Use it when an agent learns, validates, revises, applies, or records outcomes for a reusable procedure. The helper accepts version, name, summary, procedure, applicability, citations, task, success_score, feedback, evidence, reason, failure_modes, rollback, contradiction_reason, and supersedes_version as relevant to the action. Skill updates are never implicit checkout side effects.

Alpha Causal And Consolidation Tools

Zaxy 2.0 alpha.1 exposes a narrow causal and consolidation MCP surface. Alpha.2 extends consolidation with deterministic proposal generation from Eventloom history while keeping the same non-authoritative review boundary:

memory_causal_successors(entity_name, relation_type?, depth?, session_id?) reads graph-backed causal effects that start at entity_name. When relation_type is provided, it must use the causal taxonomy value such as caused, enabled, blocked, prevented, regressed, fixed, or explained; the server maps that to the corresponding causal_... graph relation label. Results include endpoint references, relation labels, confidence, method, citation, review status, authority status, evidence, and path length when available.

memory_causal_predecessors(entity_name, relation_type?, depth?, session_id?) uses the same contract in the incoming causal direction, returning cited causes that lead to entity_name.

memory_consolidation_candidate(candidate_type, title, summary, source_events, confidence, method, purpose?, session_id?, actor?) appends a cited consolidation.candidate.created event and immediately projects it. The candidate type must be episode, claim, or procedure; source_events must cite Eventloom events with sequence and hash; and the returned event reference is the durable audit handle for the candidate.

memory_consolidation_propose_from_log(session_id?, actor?, purpose?, limit?, max_events?, window_size?) replays Eventloom history for the selected session, selects deterministic event segments, and appends generated episode, claim, or procedure candidates through the same consolidation.candidate.created contract. It is a proposal tool, not an authority tool. It must not mark generated summaries as current facts, bypass review, or promote accepted-looking content into authoritative memory. Its output should be presented as cited review material with Eventloom source-event sequence and hash coverage.

memory_consolidation_review(candidate_id, status, rationale, session_id?, actor?) appends a consolidation.candidate.reviewed event. Review status is a lifecycle disposition, not an authority promotion. Valid review statuses are accepted, rejected, deferred, and conflicted. An accepted review means the candidate received that disposition; it does not make the generated episode, claim, or procedure authoritative without a separate promotion event.

memory_consolidation_status(session_id?) reports proposal and review counts for the selected session, including pending, accepted, rejected, conflicted, stale, superseded, and valid_to-closed candidates when those states are projected. Use this for review queues and diagnostics, not as evidence of external validation.

memory_consolidation(operation, ...) is an additive umbrella over the four tools above with operation set to candidate, propose_from_log, status, or review. Remaining arguments pass through unchanged to the corresponding single-purpose handler, and each operation validates its own required arguments. The single-purpose tool names remain available and unchanged; the umbrella is listed in the full profile only.

Procedure mining feeds the same review pipeline from the command line. zaxy memory mine-procedures reads captured tool.call.completed and command.completed lifecycle events, mines successful multi-step tool sequences that recur across at least --min-support (default 2) distinct sessions, and appends each as a review-pending procedure consolidation.candidate.created candidate with citations to its source traces. Mined candidates surface through the existing consolidation status and review tools and never become authoritative skills without review.

The trust contract is intentionally conservative. Causal edges and consolidation candidates are proposed, cited, non-authoritative memory surfaces in alpha. They should be used as diagnostics and operator review material, not as hidden facts. Memory Checkout keeps this boundary visible by reporting causal context and consolidation candidates in diagnostics and prompt guidance separate from deterministic current facts. Checkout diagnostics include candidate counts by type and review/staleness state so clients can distinguish pending, accepted, rejected, conflicted, stale, superseded, and closed candidates. Clients should preserve that separation in their own prompts and UI, especially when a candidate is pending, stale, conflicted, rejected, or superseded, when a causal edge is inferred, or when citations do not cover the claim.

Beta.1 reasoning-loop primitives follow the same boundary. Primitive calls are observable Eventloom records, not hidden chain-of-thought state: a call records the primitive name, deterministic phase (planning, execution, review, or reflection), status, result count, and cited evidence count. Belief updates are appended only as belief.update.proposed events with authority_status=non_authoritative and review_status=pending. A belief proposal can be inspected, replayed, and reviewed, but it does not update current facts unless a separate authority path promotes supported state. Memory Checkout reports these surfaces under diagnostics.reasoning_primitives and diagnostics.belief_update_proposals so clients can show trace evidence without granting authority.

Beta.2 adds metacognitive and procedural planning tools on the same boundary. memory_record_known_unknown(question, reason, source_events, claim_key, ...) records an open, cited, non-authoritative uncertainty item. memory_known_unknowns, memory_confidence_trajectory, and memory_reverification_needs replay the Eventloom log to surface open unknowns, append-only confidence assessments, unresolved conflict clusters, and explicit re-verification requests. Confidence trajectory events do not overwrite truth, and re-verification requests remain open until a separate workflow records a resolution. memory_plan_from_procedures(goal, ...) builds a non-authoritative planning packet from applicable procedural memory; rejected, conflicted, deprecated, contradicted, stale, superseded, closed, or uncited procedures are diagnostic or excluded instead of being returned as operational instructions.

memory_confidence(operation, ...) is an additive umbrella over the confidence and metacognition tools with operation set to claim (memory_claim_confidence), trajectory (memory_confidence_trajectory), reverification (memory_reverification_needs), known_unknowns (memory_known_unknowns), or record_known_unknown (memory_record_known_unknown). Remaining arguments pass through unchanged, each operation validates its own required arguments, and the single-purpose tool names remain available. The umbrella is listed in the full profile only.

memory_replay(session_id, from_seq?) rebuilds session history from the Eventloom log. This is useful for handoffs, audits, and debugging. In remote SSE mode, the authenticated session scope is enforced so a client cannot replay a different session. For long sessions, the CLI replay tool can inspect bounded Eventloom ranges with zaxy replay .eventloom/work.jsonl --from-seq N --to-seq M.

memory_invalidate(entity_name, entity_type, invalid_at) closes the validity window for a graph fact without deleting history. This lets agents correct memory while preserving provenance.

memory_capabilities(session_id?, current_task?) returns the model-facing memory contract for the active session. It tells the model what Zaxy is, which tools are available, when to refresh context, which capture paths appear healthy, and which call should normally happen next. Models should call this at session start or whenever tool awareness is unclear, then call memory_checkout for the current task. The contract explicitly treats memory as an ambient loop: session-start awareness is not enough, so models should refresh memory before major work, after compaction/resume, and before roadmap or architecture decisions.

memory_feeling_of_knowing(query, session_id?, cues?) is an experimental metamemory pre-check: it predicts whether memory_checkout would likely return something for a query, in roughly a millisecond, from in-memory session state only — no embedding call and no graph query. The response is the non-authoritative verdict likely, possible, or unlikely plus the raw score and the signal breakdown behind it (query term count, entity-name bloom hits, cue hits, salience mass). What it does not claim: a verdict is never a memory answer, never evidence, and never authority — it is a cheap prediction about a checkout you have not run yet, built from the session's active entity names alone. Optional cues string fields (mission, workspace, tool, phase) are probed alongside the query terms. Each call appends a non-authoritative metacognition.fok.predicted marker (query hash, verdict, raw score) so the internal calibration lane can score predictions against actual checkout outcomes; until that lane reports, treat verdicts as hints and call memory_checkout whenever the answer matters.

memory_bootstrap(session_id?, current_task?) is the shorter startup packet for clients that want one model-facing handoff. It embeds the capabilities manifest, the first recommended checkout call, deterministic capture status, and a trust policy for cited current facts, unsupported context, and feedback recording. Both memory_bootstrap and memory_checkout record lightweight activity markers so hooks and dashboards can tell whether Zaxy is still visible in a long session.

Zaxy also records memory.reminder.suggested when lifecycle hooks detect a session boundary, resume, compaction, long session, long tool run, or roadmap/status question after stale memory activity. Treat that event as a runtime nudge: call memory_bootstrap if tool awareness is unclear, then call memory_checkout for the current task before answering.

memory_checkout(query, session_id?, ref?, replay_from_seq?, limit?, max_recent_events?, max_tokens?, purpose?) returns the high-level contract an agent should condition on before a turn. It wraps context assembly with a # Memory Checkout prompt, current facts that exclude superseded context, cited evidence, provenance parsed from eventloom://... citations, retention metadata, warnings, the active working set, and Checkout diagnostics. Diagnostics include source lane counts, total citation count, current-fact citation count, current fact count, excluded superseded context count, warning count, and a memory_feedback recommendation when cited context is returned. Optional max_tokens applies a deterministic prompt token budget: checkout sections are greedily packed, citation-bearing fields always survive, and diagnostics report budget_requested, budget_used, and an elided summary so the agent knows recall was truncated rather than empty. Checkout prompts render in stability tiers (consolidated, session-scoped, volatile) with a canonical consolidated prefix, and diagnostics report stable_prefix_chars so provider prompt-cache efficiency is measurable. The same budget is available on the CLI as zaxy memory checkout --max-tokens. purpose may be a preset such as coding, review, release, security, research, or coordinate, or an object with role, task, risk, time horizon, expected action, evidence policy, retention policy, and ontology lens fields. The normalized profile is returned in purpose, diagnostics, prompt guidance, and later synthesis feedback payloads so memory can be conditioned by the intended action instead of query text alone. Non-general purpose profiles condition retrieval before checkout projection by adding deterministic profile emphasis terms, purpose-specific recall floors, and a purpose-selected scoring profile; the applied policy is reported in diagnostics.purpose_retrieval_policy. Purpose suppress rules are then enforced before checkout projection, and any excluded rows are summarized in diagnostics.purpose_policy and retention.purpose_policy so clients can audit why retrieved material did not become current memory.

Skill Analytics

When applicable Skill Memory is retrieved, diagnostics also include a skills block and the prompt includes an Applicable Skills section with cited procedure steps. This lane is read-only: models may follow the guidance, but revisions require a new memory_skill or memory_append event. When retrieved skill versions and outcomes include enough history, diagnostics also include skill_analytics and procedural_memory, and the prompt includes skill and procedural diagnostics. Those sections report applicable, diagnostic, and excluded procedural memory; read-only promotion candidates; rollback candidates; contradiction counts; outcome counts; scores; citations; and exclusion reasons so the model can decide whether to apply, avoid, or explicitly revise a skill. This is the preferred tool when a model needs a bounded, auditable working state rather than a raw list of retrieval hits. The response also includes guidance with model-facing trust and ignore instructions, a recommended follow-up memory_checkout call, and concrete memory_feedback payload templates for cited facts that materially influence the next response. The quality block adds an answerability decision (answer_from_memory, refresh_recommended, or ask_user), a bounded confidence score, reasons, and any required next action. Checkout only returns answer_from_memory when current facts have current Eventloom citations and the checkout has no warnings; missing, superseded-only, uncited, or compacted checkout states ask the model to refresh memory or ask the user instead of answering from stale context. When reasoning-loop primitive observations or belief proposals are present, checkout guidance explicitly tells the model to treat primitive observations as replayable reasoning trace evidence rather than authority, and to treat belief updates as proposals until reviewed and promoted by a separate authority path. When metacognitive state is present, checkout reports diagnostics.metacognition and tells the model to use known unknowns, confidence trajectories, conflict clusters, and reverify requests as diagnostic uncertainty signals, not as accepted facts. When ref is supplied, checkout resolves a Git-style memory ref such as HEAD or refs/heads/main and filters replay/context to the target event identity. MCP clients discover this tool through the standard tools/list handshake, so an already-running client must reconnect before the new tool appears in the model-visible tool registry.

Example checkout response fragment:

The canonical docs/test fixture for this contract is docs/examples/memory-checkout-contract.json; keep examples aligned with that fixture when changing the tool response.

{
  "current_facts": [
    {
      "content": "Memory Checkout is the model-facing context contract.",
      "citation": "eventloom://zaxy-default/events/1882#abc123def456",
      "source_lane": "graph",
      "entity_name": "memory checkout",
      "entity_type": "decision"
    }
  ],
  "diagnostics": {
    "source_lanes": {"graph": 1},
    "citation_count": 1,
    "current_citation_count": 1,
    "current_fact_count": 1,
    "superseded_contexts_excluded": 0,
    "warning_count": 0,
    "feedback_recommended": true,
    "feedback_tool": "memory_feedback",
    "consolidation_candidates": {
      "candidate_count": 1,
      "candidate_types": ["episode"],
      "pending_count": 1,
      "accepted_count": 0,
      "rejected_count": 0,
      "conflicted_count": 0,
      "stale_count": 0,
      "superseded_count": 0,
      "valid_to_count": 0,
      "authority_status": "non_authoritative"
    },
    "reasoning_primitives": {
      "context_count": 2,
      "phase_counts": {"planning": 1, "review": 1},
      "primitive_counts": {"explain_outcome": 1, "get_claim_confidence": 1},
      "authority_status": "non_authoritative"
    },
    "belief_update_proposals": {
      "proposal_count": 1,
      "pending_count": 1,
      "authority_status": "non_authoritative"
    },
    "skills": {
      "count": 1,
      "items": [
        {
          "skill_id": "python-test-first",
          "version": "1",
          "status": "validated",
          "procedure": ["Write failing test", "Run pytest"],
          "citation": "eventloom://zaxy-default/events/1883#def456abc123"
        }
      ]
    }
  },
  "quality": {
    "answerability": "answer_from_memory",
    "confidence": 0.75,
    "reasons": ["Retrieved current facts with Eventloom citations."],
    "required_action": null
  },
  "guidance": {
    "feedback": {
      "tool": "memory_feedback",
      "payloads": [
        {
          "entity_name": "memory checkout",
          "entity_type": "decision",
          "feedback": "used",
          "actor": "assistant",
          "citation": "eventloom://zaxy-default/events/1882#abc123def456"
        }
      ]
    }
  }
}

Model consumption rule: answer from memory only when quality.answerability is answer_from_memory. If it is refresh_recommended, call the quality.required_action tool before relying on the checkout. If it is ask_user, ask for missing context instead of inventing continuity. When cited facts materially influence the response, call memory_feedback with one of the listed payloads so Zaxy can reinforce useful context.

For composed questions, checkout diagnostics also include a slot_plan contract that names required retrieval slots such as source, numeric, and temporal, plus optional exact and semantic slots. When evidence is incomplete, quality.required_action includes missing_slots and suggested_queries so the model can retry checkout before answering. Numeric and aggregation synthesis bundles are projected into diagnostics.synthesis.answer_candidates, including rank, candidate type, answer value, confidence, supporting source IDs, and excluded source IDs. Generated synthesis bundles also expose diagnostics.synthesis.ledger_rows with fact IDs, source groups, citations, values, labels, and include/exclude reasons. After using one of those candidates in a response, record the checkout and candidate outcome through memory_synthesis_artifact; this keeps composed answers auditable without mutating source memory. When a specific ledger row materially supports or is excluded from that answer, record the row-level outcome through memory_synthesis_evidence so future checkout can reinforce or diagnose the exact cited fact.

In Coordinate missions, synthesis bundles are the proof format for merge briefs, approval packets, accepted checkout, and handoff answers. Each ledger row must preserve whether it came from accepted parent state, pending worker-local findings, rejected findings, stale evidence, or conflict diagnostics. Accepted checkout synthesis must default to parent-accepted state; pending worker-local rows may appear only in diagnostics and must be labeled non-authoritative.

Degraded checkout response fragment:

{
  "current_facts": [
    {
      "content": "Memory Checkout is current.",
      "citation": null,
      "source_lane": "graph"
    }
  ],
  "diagnostics": {
    "citation_count": 0,
    "current_citation_count": 0,
    "current_fact_count": 1,
    "warning_count": 1
  },
  "quality": {
    "answerability": "refresh_recommended",
    "confidence": 0.29,
    "reasons": [
      "Retrieved current facts, but they lack Eventloom citations.",
      "Checkout contains warnings that reduce confidence."
    ],
    "required_action": {
      "tool": "memory_checkout",
      "query": "current decisions, blockers, and next actions for: Memory Checkout is current.",
      "reason": "Refresh memory before major follow-up work, after compaction/resume, or when task scope changes."
    }
  }
}

context_assemble(query, session_id?, replay_from_seq?, limit?, max_recent_events?, max_tokens?) returns a prompt-ready bundle containing bounded recent replay plus ranked retrieval. Optional max_tokens applies the same greedy token-budget packing as memory_checkout, reporting budget_requested, budget_used, and the elided summary in the response's budget payload. The assembled retrieval set includes a reserved verbatim Eventloom source-recall lane by default, and each context item includes metadata with an assembly_lane value such as graph or verbatim. The response also includes assembly_policy and context_counts fields so clients can inspect the active policy and the number of graph, verbatim, and replay items returned. The prompt begins with an # Active Memory Working Set section, and the JSON response includes working_set items for bounded goals, decisions, tasks, artifacts, blockers, and source anchors. context_after_turn(role, content, ...) first appends a transcript.turn event, then assembles context for the next model call. subagent_cleanup(parent_session_id, subagent_session_id, summary, ...) records subagent.cleaned in the subagent session and returns a handoff bundle with summary and integrity status. These lifecycle tools are session-scoped under remote SSE auth just like query and append.

Coordination tools package the parent mission plus worker session workflow: coordination_start, coordination_worker_create, coordination_assign, coordination_report_finding, coordination_merge_brief, coordination_checkout, coordination_performance_ledger, coordination_approval_packet, coordination_apply_approval, coordination_review_finding, coordination_promote, and coordination_handoff. coordination_record_synthesis_artifact binds a mission-scoped Memory Checkout synthesis artifact to a Coordinate proof packet for briefs, approvals, accepted checkout, and handoffs. Handoff-scoped proof packets require handoff_id and return handoff_event_ref with the cited Eventloom sequence and hash. They preserve accepted finding ids, non-authoritative diagnostic rows, conflict ids, and handoff refs as graph-projected coordinator memory, so future checkout can retrieve both the accepted support and the excluded worker-local rows. Selected answer-candidate feedback must also match the checkout candidates, so the proof packet, artifact, and outcome event cannot disagree about support ids. Coordinate keeps worker-local findings isolated until a coordinator review promotes accepted state into the parent mission history. The first merge brief, accepted checkout, inspection handoff records, and performance ledger are replay-backed and do not require graph availability. coordination_checkout returns promoted parent state by default and includes the coordinate purpose profile: accepted parent state is authoritative, worker-local pending rows are suppressed unless diagnostics are requested, and proof packets/handoff refs are retained as coordinator memory. Set include_diagnostics to include pending findings and conflicts as non-authoritative diagnostics. coordination_performance_ledger returns per-worker outcome metrics such as accepted, rejected, duplicate, missing-evidence, and test-backed finding rates. coordination_handoff appends a replayable parent mission event with summary, next steps, and risks; later handoff-scoped proof packets are linked back during mission inspection through their cited handoff_event_ref. coordination_proof_trace resolves a proof by artifact_id, handoff_id, or proof_seq and returns the replayed proof event, synthesis artifact event, handoff event, accepted finding refs, review/promotion refs, answer candidates, ledger rows, and non-authoritative diagnostics. The approval tools export pending/conflicted findings for remote review and apply returned decisions as ordinary review events, with promotion only when a decision explicitly sets promote.

MCP dispatch also performs automatic lifecycle capture by default. After each tool call, Zaxy appends a tool.call.completed event to the resolved session with the tool name, status, argument keys, and a bounded result summary. Raw argument values are not persisted in the lifecycle payload. Capture is best-effort: failures while recording metadata do not fail the original MCP tool call. Set MCP_LIFECYCLE_CAPTURE_ENABLED=false to disable this automatic capture. Server shutdown also records a best-effort session.ended event for the default session when lifecycle capture is enabled, and subagent cleanup records subagent.completed alongside the existing subagent.cleaned event.

Run stdio locally:

zaxy serve

At session start, clients or agents should bootstrap model awareness:

zaxy memory bootstrap --session-id zaxy-default
zaxy memory checkout "current task, project direction, and recent decisions" --session-id zaxy-default

memory_bootstrap returns the compact session-start handoff: the active capability manifest, recommended first checkout call, capture status, and trust policy. During a long session, repeat checkout before important work and after compaction or resume. Capture meaningful completions with context_after_turn or typed memory_append, and reinforce cited context that was actually used with memory_feedback.

Generate first-run MCP client config:

zaxy ide-config claude-desktop --eventloom-path .eventloom
zaxy ide-config claude-code --install --workspace .
zaxy ide-config cursor --eventloom-path .eventloom
zaxy ide-config cursor --install --workspace .
zaxy ide-config vscode --eventloom-path .eventloom
zaxy ide-config vscode --install --workspace .
zaxy ide-config codex --install --domain zaxy
zaxy ide-config codex --install --codex-config-scope project --codex-trusted-project --workspace .
zaxy ide-config hermes --install
zaxy ide-config claude-desktop --eventloom-path .eventloom --domain zaxy

By default, ide-config prints copyable config. The --install flag is limited to verified targets: project-local .mcp.json for Claude Code, .cursor/mcp.json for Cursor, .vscode/mcp.json for VS Code, explicit Codex TOML scopes, and Hermes Agent's global config.yaml. Install mode merges the zaxy server entry into the documented root object, preserves unrelated servers, and refuses to replace an existing zaxy entry unless --force is passed.

Codex is CLI-assisted by default: zaxy ide-config codex --install prints the official codex mcp add zaxy -- zaxy serve command. Codex config is kept workspace-neutral because user-level Codex MCP servers can be reused across repositories: it does not write graph-backend variables such as NEO4J_URI, PROJECTION_BACKEND, or repo identity values such as EVENTLOOM_PATH, EVENTLOOM_THREAD, or ZAXY_DOMAIN. A bare zaxy serve resolves .eventloom, the projection backend, and the domain-prefixed default session from the process workspace at startup. Direct TOML writes are opt-in through --codex-config-scope project|user. Project-scoped writes target .codex/config.toml and require --codex-trusted-project because Codex only loads project config from trusted projects. User-scoped writes target CODEX_HOME/config.toml or ~/.codex/config.toml.

zaxy ide-config codex without --install also prints the Codex CLI command, because Codex does not use the JSON config shapes consumed by Claude, Cursor, or VS Code.

Hermes Agent uses a global YAML config, normally ~/.hermes/config.yaml or HERMES_HOME/config.yaml, with MCP servers under mcp_servers. Zaxy keeps the Hermes server workspace-neutral for the same reason as Codex: the global config may be reused across repositories. zaxy ide-config hermes prints the YAML fragment. zaxy ide-config hermes --install merges it into the Hermes config, or --hermes-config /path/to/config.yaml can target an explicit file. The generated entry exposes the model-facing memory tools without writing graph-backend variables or repo-specific EVENTLOOM_PATH, EVENTLOOM_THREAD, or ZAXY_DOMAIN; zaxy serve derives those from the current workspace at startup.

Embedded runtime ownership: when PROJECTION_BACKEND=embedded, one workspace zaxy serve process owns the repo-local LadybugDB graph in read-write mode. Additional stdio zaxy serve processes, including worker/subagent MCP launches, proxy to that owner through .eventloom/runtime/zaxy-embedded-owner.sock instead of opening LadybugDB themselves. This preserves full graph-backed checkout without starting in degraded mode.

zaxy init and zaxy doctor clean stale embedded owner records when no live owner lock is held. If the owner lock is held but no healthy proxy socket exists, doctor reports embedded_mcp_runtime with an action to fully exit stale Codex/Zaxy processes before retrying. Verify the local process set with:

ps -ef | awk '/[z]axy serve/ {print}'

Install the zaxy CLI before generating MCP config:

pipx install zaxy-memory
# or: pip install zaxy-memory

MCP clients cannot launch a server command that does not exist yet. Generated stdio config uses the resolved executable path by default, preferring the installed zaxy console script and falling back to the current process path. This is more reliable for GUI clients than assuming they inherit your shell PATH.

Generate observer hook adapters:

zaxy hooks claude-code --eventloom-path .eventloom --domain zaxy
zaxy hooks codex --eventloom-path .eventloom --domain zaxy

For Codex, the default local preset also writes .codex/zaxy-capture.json. Starting Codex through the printed zaxy activate codex ... --launch command ensures that managed watcher is running; explicit supervisors can still call zaxy capture start --workspace .. The watcher reads Codex's local session JSONL and appends normalized Eventloom observations. It does not proxy provider traffic or require an OpenAI API key. For supervised checks, add --watch-iterations <n> to run a bounded number of capture passes to the underlying zaxy codex-capture --watch command. Add --graph to zaxy capture start when the selected projection backend should receive newly captured observations during the same pass.

Hook adapters do not proxy tool execution. Agents and tools continue to execute normally while hooks append lightweight Eventloom observations through zaxy hook-event. The sink is intentionally graph-independent so session stop and pre-compaction hooks can record provenance even when the selected graph projection is unavailable. Custom clients can implement the same contract by emitting normalized triggers such as session-start, stop, precompact, checkpoint, command, and file-edit. Command and file-edit triggers become first-class command.completed and file.edit.applied events, which lets automatic capture feed retrieval and working-set projection without storing raw file content.

This deterministic capture path is the default Zaxy onboarding posture. Packet capture is optional and should be enabled only when raw provider request/response audit is worth the provider quota and transport-compatibility cost.

These commands print copyable JSON fragments and do not include bearer tokens, passwords, or admin secrets. Keep remote SSE credentials in the client secret store or environment, not in committed config.

The verified write targets for future client-specific installers are tracked in mcp-install-targets.md. That matrix is the guardrail for deciding when zaxy init may write or merge config directly versus printing copyable instructions.

Generated project-local stdio configs include ZAXY_DOMAIN and a domain-prefixed EVENTLOOM_THREAD, such as zaxy-default. This prevents clients that omit session_id from accidentally sharing the global default session across different projects. Codex user-level config is the exception: it must keep Eventloom/session/domain state out of config and let zaxy serve derive those values from the active project. For remote SSE configs, the same default is sent through the session header.

For local stdio clients, the generated config is intentionally self-contained: it forces development-mode local settings and defaults to the embedded LadybugDB projection. Generated stdio configs set startup_timeout_sec to 90 so MCP clients do not kill startup while local indexes are opening or optional sidecars are warming. If you explicitly choose the optional Neo4j sidecar, Zaxy can reuse bolt://localhost:7687 or start a named Docker container, zaxy-neo4j, with the default local credentials. Leave NEO4J_AUTO_START=false when you manage Neo4j yourself; set NEO4J_AUTO_START=true only when you want Zaxy to start that local sidecar.

Run SSE daemon mode:

zaxy serve --transport sse --host 127.0.0.1 --port 8080

Production SSE requires either static bearer auth or OIDC. Static bearer auth uses MCP_REMOTE_AUTH_TOKEN or MCP_REMOTE_AUTH_TOKEN_FILE; clients send Authorization: Bearer <token> and a session header such as x-zaxy-session-id: agent-1. OIDC uses MCP_OIDC_ISSUER, MCP_OIDC_AUDIENCE, and MCP_OIDC_JWKS_URL; clients send an access token and Zaxy scopes the request from MCP_OIDC_SESSION_CLAIM. Production also requires MCP_ADMIN_TOKEN or MCP_ADMIN_TOKEN_FILE for replay and invalidation.

The MCP implementation lives in src/zaxy/mcp_server.py. Core orchestration lives in src/zaxy/core.py. Security helpers live in src/zaxy/security.py. See api.md for Python-level calls, configuration.md for environment variables, and security.md for remote transport hardening. The public overview is site/index.html, while README.md keeps the short command list.

MCP Tool Contract Snapshot

The v0.6 public-surface guardrail is docs/examples/mcp-tool-contract.json. That MCP tool contract snapshot records the tool count, tool names, descriptions, required fields, and full input schema for every public MCP tool exposed by src/zaxy/mcp_server.py.

Treat changes to that fixture as public contract changes. A schema change should be paired with docs, tests, and a changelog note explaining whether the affected tool is stable, beta, experimental, or internal. The snapshot is intentionally plain JSON so MCP clients and external adapter authors can inspect it without importing Python.

Representative Response Snapshots

The v0.6 response-shape guardrail is docs/examples/mcp-response-snapshots.json. It stores representative, normalized responses for memory_bootstrap, memory_checkout, memory_query, memory_verbatim, context_assemble, memory_feedback, and memory_synthesis_artifact, memory_synthesis_evidence, and coordination_checkout, covering startup, checkout, graph retrieval, verbatim source recall, prompt context assembly, feedback reinforcement, synthesis artifact writes, synthesis evidence row feedback, and accepted coordination state.

The snapshot deliberately preserves stable client fields rather than full prompt text. It covers startup sequence shape, recommended next tool, Eventloom status, checkout fact/citation diagnostics, quality status, purpose profile keys, feedback template keys, token-efficiency keys, required prompt sections, graph retrieval score explanation keys, verbatim source metadata keys, assembled context counts, feedback event identity, synthesis artifact event identity and normalized candidate outcome, and accepted coordination checkout counts. Update it only when the client-facing response contract intentionally changes.

Structured Error Payloads

MCP tool dispatch returns structured JSON error content instead of exposing raw Python exceptions to clients. The stable shape is:

{
  "error": {
    "code": "unknown_tool",
    "message": "Unknown tool: unknown_tool",
    "remediation": "Call list_tools and retry with one of the advertised tool names."
  }
}

The current error codes are:

Every error payload includes a human-readable message and remediation so MCP clients can surface actionable recovery text without parsing logs. Failed tool calls are still captured as lifecycle observations with the stable error summary, but secrets from arguments remain subject to the existing redaction path.