# Rhei MCP Server

Local-first MCP server for Rhei Code Context and governed agent handoffs.

The default mode requires no remote credentials. It exposes Code Context as the shared agent-facing primitive so Codex CLI, other MCP clients, web Rhei, and local Rhei can all consume the same `AgentWorkBriefV1` handoff instead of passing raw graph output around.

The local path follows current MCP TypeScript SDK practice: high-level `McpServer.registerTool`, Zod input/output schemas, read-only tool annotations, `structuredContent` in tool results, and stderr-only server logging so stdout stays reserved for JSON-RPC.

## Current Center Of Gravity

The current code-intelligence center of gravity is the chain from goal to bounded context, workflow, proof, review, trail, and governed acceptance. See `../../docs/analysis/code-intelligence-center-of-gravity-2026-05-20.md`, especially `MCP And Code Intelligence Spine`, for the compact architecture note.

```text
rhei_code_goal / rhei_context_builder / rhei_code_context_for_goal
  -> ProgramPlanV1 when program-scale
  -> Auto-Sliced ContextPacketV1
  -> ContextReceiptV1 when exported for agent handoff
  -> AgentWorkBriefV1 + CodeContextAgentSurfaceV1
  -> CodeStrategyPlanV1 -> WorkflowPlanV1 -> CodeWorkHandoffV1
  -> RheiCodeSessionV1
  -> proposal / impact / proof / dry-run / diff / validation
  -> ReviewDiff / PR Review / story-scoped CodeTrail / run graph / AgentEditSession
  -> opt-in local Codex or Modal sandbox result import
  -> Writer Arbitration or Discard
```

The ProgramPlan-to-Auto-Sliced-ContextPacket bridge is now a named MCP transition. Program plans remain inventory/routing evidence, and `rhei_code_context_for_goal` exposes `autoSlicedContextPacketTransition` so agents can see the first-safe-workstream handoff, target auto-sliced packet id, missing-ref receipt, truncation receipt, failure receipt, and no-authority guardrails before implementation starts.

### Architecture Refactor Notes

- The local code-context surface is split into intent-named modules under `src/codeContextTools/` and re-exported by the small `src/codeContextTools.ts` barrel. Keep future seams named by responsibility (`codeGoal*`, `codeIo*`, `toolDefinitions`, `toolDispatcher*`) rather than numbered chunks.
- `@rhei/core` owns portable `codeSession` and `contextQuery` contracts. MCP adapts those contracts into local receipts/tool payloads; Convex remains the owner of persisted session state and write-authority checks.
- Runtime freshness is observable through the MCP runtime fingerprint and `reloadStatus`. After changing MCP source or beta package contents, restart/reconnect the MCP client and verify the new `pid`/`loadedAt` reports `status: current` before trusting tool schemas.
- Context Query handoff is read-only provenance. Web may pass the envelope into workroom `contextHints`, but `advisoryOnly`, `authorizesExecution: false`, and `mutatesWorkingSet: false` semantics must stay intact.

## Local Tools

Closed beta users should run the default `mcp:rhei` server. That public profile exposes the generic 20-tool surface: `goal`, `context_builder`, `workspace_context`, `manage_selection`, `read_file`, `file_search`, `get_file_tree`, `get_code_structure`, `graph`, `apply_edits`, `file_actions`, `git`, `validate`, `index`, `status`, `ledger`, `agent_run`, `agent_manage`, `oracle_send`, and `oracle_utils`.

The detailed `rhei_code_*` tools below are the legacy/full-profile and Rhei self-development reference surface. They are for dogfooding, compatibility, and debugging only; do not use them in tester install instructions. Default local edit availability stays beta/report-only: search, exact reads, proposals, `CodeImpactPredictionV1`, Proof Synapse, dry-run diffs, and validation evidence are advertised so agents can use Rhei before falling back. The full Code Session profile exposes one edit family, `rhei_code_edits`; by default it runs preview -> gated apply attempt -> durable afteredit verification. Missing apply gates return preview plus blockers without writing. Source apply remains tmp/local-beta gated by explicit env, receipts, root allowlists, and Writer Arbitration.

| Tool | Purpose |
| --- | --- |
| `rhei_code_goal` | Central mode-based goal surface backed by pure `@rhei/core/goalIntelligence` builders plus MCP receipts. `mode=context` wraps compact Code Context, `mode=verify` runs scoped search/read/absence proof with searched scopes/counts/confidence/caveats and Trail evidence, `mode=edit` runs Rhei Edit Transaction V1 over search/read/proposal/dry-run/diff/validation/AgentEditSession/Trail evidence, `mode=trail` summarizes session history, reads, proposal/dry-run ids, final/reverse diffs, validations, human decisions, replay refs, and CodeTrail export evidence, `mode=learn_from_outcome` turns accepted/rejected edits and human rewrites into replay evidence/memory candidates without memory writes, `mode=report` produces safe Markdown diff previews/receipts and optional explicit report writes, `mode=diagnose` attaches diagnostics/Growth Diagnostics/Connected Surface Coverage evidence, `mode=outcome_feedback` captures human rewrites/style/outcome feedback as memory candidates only, `mode=steer` decides whether a new instruction continues/branches/replaces, and the continuity modes emit resume packets, intelligence commit receipts, preference replay plans, diagnostic closure reports, and service-impact evidence. Report-only; no service writes, graph mutation, provider calls, transcript replay, memory promotion, or hidden apply authority. |
| `rhei_code_io` | Public ergonomic IO wrapper for `read`, `search`, and `edit`. `op=edit` accepts `changes` or multi-file `files`, consumes `workflowPlan` advisory context, defaults to preview, and routes through `rhei_code_edits` so Synapse, diff, receipts, and local-beta/test apply gates stay in one existing writer path. |
| `rhei_context_builder` / `context_builder` | Fast algorithmic context-builder handoff. The caller gives a goal plus optional `repoPath`, `scopePaths`, `tokenBudget`, `responseType`, `targetAgent`, and `exportResponse`; Rhei returns `ContextReceiptV1`, selected files/slices, symbol summaries, relevant diff status, token accounting, omitted candidates, per-file include reasons, `AgentWorkBriefV1`, a ready-to-send prompt, and optional export path/instruction. It reuses Rhei's deterministic local selector and never calls providers, starts Oracle/agents, mutates graph/canon state, or grants write authority. |
| `rhei_code_context_for_goal` | Scans a local repo for a user goal, builds bounded `CodeMarketSnapshotV1`, then returns `AgentWorkBriefV1`, compact `CodeContextAgentSurfaceV1`, selected refs, risks, optional report-only lanes, the named `autoSlicedContextPacketTransition` for ProgramPlan inventory -> Auto-Sliced ContextPacket -> AgentWorkBrief, local index status, and optional handoff markdown. |
| `rhei_service_intelligence_for_goal` | Builds a report-only `ServiceIntelligenceReportV1` from explicit `ServiceConnectionV1`/evidence inputs plus optional `context_for_goal` refs. It emits service/resource edges, absence proof, guardrails, and the next backend/UI/test/docs slice without live runtime-surface ingest, provider calls, graph writes, memory promotion, or canon mutation. |
| `rhei_code_context_build_work_brief` | Builds an `AgentWorkBriefV1`, compact `CodeContextAgentSurfaceV1`, and deterministic handoff markdown from selected Code Context. |
| `rhei_code_context_doctor` | Health-check tool for MCP config, repo path, local mode, advertised tools, sample context selection, schema exposure, and no-live invariants. Use when setup looks wrong, not on every task. |
| `rhei_code_context_runs` | Returns recent process-local context run metadata: request id, goal hash, timings, file counts, token estimates, selected refs, warnings, no-live result, and artifact path. It does not return source contents or raw goal text. |
| `rhei_code_context_agent_instructions` | Returns the guardrails and expected payload shape for local agents. |
| `rhei_code_prepare_work` | Builds the central report-only handoff envelope: `CodeStrategyPlanV1` + `WorkflowPlanV1` + `CodeWorkHandoffV1`. It never mutates Code Session and never grants apply authority. |
| `rhei_code_session_start` | Starts a process-local `RheiCodeSessionV1` facade from a goal plus `rhei_code_context_for_goal` or `CodeWorkHandoffV1` evidence. |
| `rhei_code_search` | Performs deterministic bounded search through one surface with RepoPrompt-style ergonomics: use an existing `sessionId` or pass `repoPath` plus `query`/`exactText` for a one-call search that auto-starts a read-only session. Includes local lexical/index/codemap ranking plus optional supplied semantic, Qdrant/session-vector, Convex-unified, graph advisory, service-connection, depth, budget, coverage, and next-read controls. |
| `rhei_code_read` | Reads files with RepoPrompt-style ergonomics: singular `read` string/object, `path`/`file`/`refId`/`ref`/`readSliceId`, batch `read`/`reads`/`paths`/`files`/`refs`/`refIds`, `lines`, `start_line`/`startLine` + `limit`, `end_line`/`endLine`, negative `start_line`, `lines: "-N"`, or pasted `path.ts:-N` tail reads, numeric strings for line/window/token fields, `contentFormat`/`content_format`/`format` controls, and path-only counted full-file reads. Returns baseline hash, token estimate, repeated-read telemetry, full-file reason/warnings, and no write authority. |
| `rhei_code_session_context` | Reports selected refs, slices, budget, token totals, repeated reads, quality metrics, no-live state, and proposal/dry-run/validation refs without source contents. |
| `rhei_code_plan_edits` | Creates `CodeWriteProposalV1` only and attaches an explicit `CodeImpactPredictionV1` report-only packet. |
| `rhei_code_proof_plan` | Creates a report-only Proof Synapse contract: required tests, docs, contracts, validation commands, missing evidence, traceability, and collaboration roles. |
| `rhei_code_edit_cycle` | Ergonomic loop wrapper for proposal -> `CodeImpactPredictionV1` -> Proof Synapse -> dry-run -> validation. It normalizes `editsByPath`, evaluates same-file edits sequentially, returns separate artifacts, and never calls apply. |
| `rhei_code_strategy_plan` | Builds a deterministic report-only `CodeStrategyPlanV1` from Code Context, ProgramPlan/MigrationPlan evidence, Code Session slices, explicit connected files, and optional oracle true/false feedback. |
| `rhei_code_workflow_plan` | Builds a deterministic report-only `WorkflowPlanV1` beside its strategy plan, including service connection gates, adjustable context-injection policy, session selection, and Oracle prompt packets only; no session lookup/mutation, live Oracle, source reads, provider calls, or writes. |
| `rhei_code_oracle` | Primary Oracle workflow surface. `mode` supports `session_start`, `session_context`, `manage_workspace`, `build_context_bundle`, `export_markdown`, `plan_packets`, `import_feedback`, `refine_workflow`, `summarize_feedback`, and `fork_session`; V1 never calls a live Oracle/provider and never mutates Code Session state. |
| `rhei_code_agent` | Report-only external-agent handoff/import/ranking surface. `mode` supports `handoff`, `import_result`, `summarize_result`, and `rank_results`; it packages work for agents, imports their reports, and ranks evidence without spawning agents, calling providers, writing files, mutating sessions, or granting apply authority. |
| `rhei_agent_explore` | Public ergonomic wrapper for short-lived explore handoffs over the same `rhei_code_agent` substrate. `action=start` accepts a full `CodeWorkHandoffV1` or a simple `requiredRefs`/`exactRefs`/`refs`/`files` + `message` request and auto-builds the report-only explore handoff/read-slice envelope; `poll`, `wait`, and `cancel` return deterministic local snapshots. It is process-local, report-only, no-spawn, no-provider, no-write, and no-authority. |
| `rhei_agent_run` | Public role-labelled wrapper for `explore`, `engineer`, `pair`, `review`, `validate`, and `design` agent work. `action=start` accepts a full `CodeWorkHandoffV1` or a simple `requiredRefs`/`exactRefs`/`refs`/`files` + `message` request and auto-builds the report-only handoff/read-slice envelope. It supports start/lifecycle, steering, result import, summary, ranking snapshots, an explicit local process plane (`executionMode=live`), and an explicit Modal AgentEditSession plane (`executionMode=sandbox`). Fake remains the default local adapter; Codex CLI and Modal sandbox are opt-in. Local Codex sessions start asynchronously with capped logs/cancel/cleanup receipts; Modal callbacks enter through explicit `action=import_result` no-authority result bundles. |
| `rhei_agent_manage` | Public catalog/session helper for listing roles/workflows, inspecting process-local agent sessions, exporting handoff snapshots, and cleaning local session state. It is not a provider-session controller. |
| `rhei_code_run` | Report-only process-local run graph switchboard. `mode` supports `start`, `context`, `add_oracle`, `add_agent_handoff`, `import_agent_result`, `switch_active`, `rank_results`, and `summarize`; it links Oracle sessions, Code Sessions, agent handoffs/results, review/proof/diff artifacts, and visible delegation leases without spawning agents or granting write authority. |
| `rhei_code_review` | Report-only team-aware review intelligence surface. `mode` supports `build_review_diff`, `build_pr_diff`, `rank_proposals`, `record_outcome`, `record_pr_outcomes`, `generate_memory_candidates`, and `summarize_review_room`; it groups session/PR diffs, ranks competing proposals, imports review outcomes, and emits assist-only memory candidates without write authority. |
| `rhei_code_dry_run_edits` | Checks baseline hashes and expected match counts, then returns an in-memory patch preview. `applyAvailable` is always false. |
| `rhei_code_session_diff` | Inspects the latest or selected proposal/dry-run as a git-like session diff with path summaries and optional reverse preview. It never writes, reverts, applies, or grants authority. |
| `rhei_code_validate` | Records validation evidence. Commands are skipped unless `execute: true`; validation never grants apply authority. |
| `rhei_code_session_act` | Local server helper that explicitly runs one task-level flow: context, session start, exact read, proposal, `CodeImpactPredictionV1`, dry-run, validation, and optional local-beta apply only when the separate apply gates are enabled. |
| `rhei_code_edits` | Full-profile edit family. The default action runs exact search/replace or create/rewrite preview, attempts apply only when env/receipt/root/Synapse gates allow it, then verifies durable filesystem readback before reporting `applied_verified`. Use `phase=preedit` for preview-only and `phase=afteredit` for rechecking a prior apply. |

The default local MCP profile advertises the generic 20-tool public surface listed above. Legacy and granular debug surfaces, including `rhei_code_goal`, `rhei_code_agent`, `rhei_code_session_start/context`, `rhei_code_plan_edits`, `rhei_code_proof_plan`, `rhei_code_edit_cycle`, `rhei_code_dry_run_edits`, `rhei_code_validate`, `rhei_code_strategy_plan`, `rhei_code_workflow_plan`, `rhei_code_context_build_work_brief`, `rhei_code_context_runs`, and `rhei_code_edit_session_handoff`, remain available only with `RHEI_MCP_LOCAL_TOOL_PROFILE=full` or an explicit `RHEI_MCP_LOCAL_TOOL_ALLOWLIST`.

## Central Goal Modes

Use the generic `goal` tool in the public profile when the caller has an evolving task and needs one stable entry point for context, edit/verify/trail receipts, diagnostics, feedback, steering, continuity, and service-impact evidence. In the full/dogfooding profile, the same legacy envelope is named `rhei_code_goal`; `@rhei/core/goalIntelligence` owns the shared V1 contracts/builders used by MCP and product tests:

- `mode=context`: returns a compact `rhei_code_context_for_goal` payload for the current explicit goal.
- `mode=verify`: runs a one-roof Rhei Verify Transaction V1: context -> Code Session start -> scoped search/prove-absence -> exact reads -> absence proof -> coverage summary -> caveats -> `rhei_code_trail_export`. It supports `searches`, `search`, `query`, `exactText`, `literalText`, `absenceClaim`, `scopePaths`/`scopes`, `candidateRefs`, RepoPrompt-style `read`/`reads` path strings or objects, and top-level `path`/`file` plus `start_line`/`limit` single-read shortcuts. When only explicit reads are supplied, verify skips goal-driven search noise and returns status `read`. Every absence proof includes searched scopes, searched/matched/skipped file counts when available, truncation status, confidence, reason codes, and caveats.
- `mode=edit`: runs a one-roof Rhei Edit Transaction V1: context -> optional scoped search/read -> multi-edit proposal -> dry-run -> session diff/reverse diff -> validation -> `AgentEditSessionV1` diff/finish receipt -> `rhei_code_trail_export`. It supports `proposedChanges` and `editsByPath`, ordered same-file edits, expected match counts, baseline hashes, validation evidence, final/reverse diff refs, and no hidden apply.
- `mode=trail`: runs a one-roof Rhei Trail Transaction V1: context -> explicit edit/verify/session evidence normalization -> per-session selected refs/searches/reads/proposals/dry-runs/final diffs/reverse diffs/validations/human decisions/outcome and replay refs -> coverage/caveat summary -> `rhei_code_trail_export`. It supports `trail`, `session`, `sessions`, `sessionIds`, `proposalIds`, `dryRunIds`, `diffRefs`, `reverseDiffRefs`, `validationRefs`, `receiptRefs`, and explicit `writeTrail` only for sanitized JSON inside `repoPath`.
- `mode=learn_from_outcome`: turns accepted/rejected edits, human rewrites, style preferences, and validation outcomes into replay evidence plus memory candidates only. It emits accepted/rejected refs, human-rewrite hashes, expected replay signals, promotion-required/no-write receipts, and `noMemoryWrite: true`; promotion stays gated outside this tool.
- `mode=report`: builds safe Markdown report output with a diff preview and report receipt. It accepts `reportPath`, `reportMarkdown`, `receiptRefs`, and `writeReport`; writes happen only when `writeReport: true`, the path resolves inside `repoPath`, and the path is under `docs/` or `.rhei/reports/`.
- `mode=diagnose`: runs the same bounded context selection with diagnostics and selected-context Growth Diagnostics/Connected Surface Coverage enabled by default. Feed failed commands, validation logs, PR review comments, or child-agent results through `evidenceIntake` or `diagnosticEvidence`.
- `mode=outcome_feedback`: captures accepted/rejected outcomes, human rewrites, style preferences, and evidence refs as report-only preference signals. It emits `memoryCandidates` with `promotionRequired: true` and `writeAuthority: false`; it never writes memory.
- `mode=steer`: compares an active goal with an incoming goal. New instructions branch or replace by explicit decision; they do not silently append unless `allowAppend: true` is supplied or the goal similarity is high.
- `mode=resume`: emits a compact `GoalSessionV1` continuity packet from done/current/stale/open refs, Code Market snapshots, Code Trail refs, PR review refs, commits, validation receipts, and outcome feedback refs. It sets `noTranscriptReplay: true`; resume is receipts and ranked deltas, not hidden long-context accumulation.
- `mode=intelligence_commit`: emits a report-only intelligence receipt that links git commits to context runs, Code Market snapshots, Code Trail, PR review, validation, outcome feedback, and service evidence. Git stays the source-diff history; the intelligence receipt records why/evidence around it.
- `mode=preference_replay`: replays human rewrites/style preferences as ranking-bias trial evidence. It can prove `style_preference_reused` or `human_rewrite_pattern_matched` without writing memory.
- `mode=diagnostic_closure`: links diagnostics, fix refs, validation refs, and outcome evidence so a diagnostic loop can move to `closed_with_validation` or request more `evidenceIntake`.
- `mode=service_impact`: links `ServiceConnectionV1`/service refs to impacted code/docs/test refs for analysis only. Promotion goes through `rhei_service_intelligence_for_goal`; no connector sync or service graph mutation occurs here.

Service connections remain evidence only in this surface. Pass `serviceConnections` or `serviceConnectionIds` to link diagnostics, outcome feedback, continuity, closure, replay, or steering to service context, but use the governed service/memory paths for any real write or promotion.

Goal Intelligence persists refs and receipts, not transcripts or full packets: Workroom session ids, CodeTrail refs, PR/review refs, validation refs, service refs, commit refs, and outcome refs. V1 intentionally does not add a dedicated goal-session table or grant hidden resume authority.

## Recommended Agent Loop

Agents should treat the MCP surface as a small workflow, not a flat list of equal tools:

```text
rhei_code_goal mode=verify
  -> scoped search / prove_absence
  -> exact reads
  -> coverage + absence proof receipt
  -> Trail export
  -> rhei_code_goal mode=edit
  -> context/search/read
  -> multi-edit proposal + dry-run
  -> session diff + reverse preview
  -> validation evidence
  -> AgentEditSession diff/finish receipt
  -> Trail export
  -> rhei_code_goal mode=trail
  -> per-session history + receipts
  -> CodeTrail export summary
  -> rhei_code_goal mode=learn_from_outcome / mode=report
  -> replay evidence or Markdown report receipt
```

For granular full-profile debugging, the same path is still available as `rhei_code_prepare_work -> rhei_code_session_start -> rhei_code_search / rhei_code_read -> rhei_code_edit_cycle -> rhei_code_session_diff -> rhei_code_validate`. The public profile keeps that lower-level complexity behind `rhei_code_goal mode=edit`, `rhei_code_goal mode=trail`, `rhei_code_session_act`, and the AgentEditSession family.

Read/search ergonomics intentionally mirror the RepoPrompt `file_search` -> `read_file` loop: `rhei_code_search` can run in an existing `sessionId` or as a one-call `repoPath` + `query`/`exactText` search that auto-starts a read-only session and returns its `sessionId` for follow-up reads. Path-only reads return a counted full-file slice with token/warning receipts, `start_line` + `limit` reads a window, `line`/`lineNumber` reads one line, `lineNumber` + `count` reads a short window, bare `limit` or `count` reads the first N lines, bare `end_line`/`to` reads from line 1 through that line, negative `start_line` or `lines: "-40"` reads from the tail, pasted tail refs like `path.ts:-40` or `file:path.ts#L-40` read the last N lines, pasted refs like `path.ts:12-20`, diagnostic refs like `path.ts:12:4-20:1`, or hash refs like `path.ts#L12C4-L20C1` resolve to path plus lines, and `file`/`ref` are accepted aliases for `path`/`refId`. Numeric strings such as `start_line: "3"`, `limit: "20"`, `maxTokens: "2000"`, and `contextRefLimit: "4"` are accepted anywhere the read/goal surface accepts those numeric controls. `rhei_code_read` can read inside an existing `sessionId` or perform a one-call read with `repoPath` plus singular `read`, `path`/`file`/`ref`, auto-starting a read-only session and returning its `sessionId` for follow-up reads. It also accepts batch `read` arrays, `reads` (strings or read objects), `paths`/`files`/`refs`/`refIds` arrays, direct Code Context or handoff ref lists via `exactRefs`/`selectedRefs`/`requiredRefs`, and whole `contextForGoal`/`workBrief`/`agentSurface`/`handoff` packets that are normalized into bounded connected reads with `contextRefLimit`/`maxContextRefs`, returning per-file receipts plus combined content for a connected multi-file context grab; every read returns a compact `readPlan` and `selectionPreview` with path/range/token/hash metadata so agents can inspect the chosen set before consuming source. Pass `previewOnly: true`, `preview: true`, `planOnly: true`, `includeContent: false`, `returnContent: false`, `omitContent: true`, or `content: false` to resolve that same connected read plan while omitting source content from the response after the file is read for hashes/token estimates. Pass `selectionOnly: true`, `metadataOnly: true`, `readPlanOnly: true`, or `resolveOnly: true` when planning should be source-free: the response resolves paths and line labels for connected multi-file reads without opening source files, so token/hash estimates are intentionally absent. Read objects can use `lineRanges` or aliases `range`/`lineRange`/`line_range`/`ranges`/`line_ranges` with string labels, `start`/`end`, `from`/`to`, `start_line`, `limit`, `count`, and negative tail starts just like top-level reads. Batch reads fail fast by default, or return successful reads plus structured read errors when `continueOnError: true` / `continue_on_error: true` / `allowPartial: true` / `allow_partial: true` is set. By default read content is RepoPrompt-style copyable text without `N:` prefixes; pass `includeLineNumbers: true`, `contentFormat: "numbered"`, or `contentFormat: "annotated"` when line-number receipts should be embedded in the content, and `includeCodemap: true` to attach a compact symbol map for the returned slice. `rhei_code_goal` shares the same top-level `read`/`reads`, `paths`/`files`/`refs`/`refIds`, `exactRefs`/`selectedRefs`/`requiredRefs`, context packet, `path`/`file`/`ref`, pasted line/tail refs, line-window/range aliases, preview/content-omission/selection-only aliases, `continueOnError`/`allowPartial`, and `contentFormat`/`content_format`/`format` shortcuts, so simple verify reads do not require wrapping the request in `read`; compatible multi-file goal aliases execute through one connected `rhei_code_read` batch with a combined `readPlan`/`selectionPreview`, while mixed packet/global read modes fall back to separate reads to preserve semantics. Explicit read paths and typed refs such as `code_file:file:<path>` are forced into Code Context exact refs before broader scan limits can omit them. Use explicit `maxTokens` for large files.

Use `rhei_code_oracle` when the workflow needs Oracle packets, external/user feedback import, workflow refinement, or feedback summaries. Use `mode` rather than new one-off tool names:

- `session_start`
- `session_context`
- `manage_workspace`
- `build_context_bundle`
- `export_markdown`
- `plan_packets`
- `import_feedback`
- `refine_workflow`
- `summarize_feedback`
- `fork_session`

Use `rhei_code_context_doctor` only as a health check for MCP config, repo paths, tool exposure, schema mismatch, sample context selection, or no-live invariants. It is not part of the normal per-task loop.

Lower-level tools such as `rhei_code_context_for_goal`, `rhei_code_strategy_plan`, `rhei_code_workflow_plan`, `rhei_code_plan_edits`, `rhei_code_dry_run_edits`, and `rhei_code_proof_plan` remain useful for debugging, evals, and custom orchestration, but the default agent UX should start with the central handoff/edit-cycle loop above.

The manual edit loop is still report-only and should be used before fallback when available:

```text
rhei_code_plan_edits
  -> CodeImpactPredictionV1 / Synapse evidence
  -> rhei_code_proof_plan
  -> rhei_code_dry_run_edits
  -> rhei_code_validate
```

Only after `rhei_code_context_doctor` reports the edit loop is not advertised should an agent fall back to external editors for source changes. Even then, fallback does not imply apply authority inside Rhei.

For precise edits, search first with `rhei_code_search` using `matchMode: "literal"` or `exactText` to prove the exact snippet and duplicate count. Literal search accepts multi-line `exactText` and anchors `matchedLines`/`nextReadPlan` to the first matched line. Then pass `selectedLines` on each pattern edit; labels may be numeric (`1-8`) or editor-style (`L1-L8`), and dry-runs plus gated apply preflight scope replacements to those line ranges so one-file multi-edits and multi-file edits can avoid over-broad replacements when the same literal appears elsewhere in the file. Dry-run and session-diff previews use ordered unified hunks for normal-sized files, so duplicate-line replacements and same-line-set reorders are shown as real `-`/`+` evidence instead of being hidden by counted-line summaries.

`rhei_code_workflow_plan` centralizes source/context injection through `ContextInjectionPolicyV1`. Callers can pass `autoInjection: false` to keep refs path-only/deferred, `autoInjection: true` plus `autoInjectionLimit` to set the source-text budget, or a full `contextInjectionPolicy` with `mode`, `sourceTextTokenLimit`, `maxAutoInjectRefs`, `contextSlicerReviewThreshold`, `forcePaths`, `pathOnlyRefs`, and `deferRefs`. The resolved policy is returned in `workflowPlan.sessionSelect.contextInjection` so UI and agents can show and adjust the same knobs. `pathOnlyRefs` may name future/new files as metadata-only context refs; they do not authorize reads or writes.

Use `rhei_code_context_for_goal` when an agent only has a repo path and goal:

```json
{
  "repoPath": "/Users/mibook/saga/rhei",
  "goal": "Improve local Rhei MCP context selector and AgentWorkBrief handoff for Codex CLI",
  "workflowPresetId": "deep_plan",
  "maxFilesToScan": 1200,
  "maxExactFiles": 8,
  "maxEvidenceFiles": 6,
  "maxSymbols": 10,
  "includeMarkdown": true,
  "includeProgramPlan": true,
  "includeSurfaceCoverage": true,
  "includeGrowthDiagnostics": true,
  "plannerHandoffGraphAdvisory": {
    "schemaVersion": 1,
    "kind": "planner_handoff_graph_advisory",
    "source": "mcp_input",
    "basis": "explicit_metadata",
    "recommendedGraphMode": "soft_graph_depth3",
    "selectedGraphMode": "connected_work_shallow",
    "memgraphAllowed": false,
    "depth5Allowed": false,
    "reportOnly": true,
    "advisoryOnly": true,
    "noAuthority": true
  },
  "useLocalIndex": true,
  "writeLocalIndex": true,
  "reportOnlyEvidence": [
    {
      "kind": "connected_surface_coverage",
      "title": "Connected Surface Coverage",
      "summary": "Optional report-only readiness evidence from Rhei local/web."
    },
    {
      "kind": "growth_diagnostics",
      "title": "Growth Diagnostics",
      "summary": "Optional reuse/drift diagnostic evidence; no execution authority."
    },
    {
      "kind": "program_plan",
      "title": "ProgramPlanV1",
      "summary": "Optional program-scale control-plane evidence above bounded Code Context."
    }
  ]
}
```

`rhei_code_context_for_goal` accepts `evidenceIntake` as the preferred CodeEvidencePacketV1 lane, with `refinementEvidence` as a compatibility alias and `diagnosticEvidence` as a convenience lane for command/compiler output. Each lane accepts either structured evidence packets or raw strings, so agents can paste a compiler line, CI excerpt, validation note, or review summary without hand-wrapping it first. Use these after a failed command such as `bunx convex deploy` or `bun test`, or feed compact connected evidence from `rhei_code_validate`, `rhei_code_review`, `rhei_code_agent`, or `rhei_code_run`. The selector extracts repo-relative refs, grouped diagnostics, error codes, focused first-fix slices, and readiness metadata, then promotes matching files into exact context behind explicit `exactRefs`. Large logs are budgeted before parsing, repeated diagnostics are deduped by path/line/column/code, and compact MCP responses expose truncation/dedup counts while omitting raw command output. For diagnostic-only goals, product/UI summaries are suppressed in favor of diagnostic primary refs and first-fix slices. The compact response also includes `contextBudget`, which distinguishes `sourceExactRefs` governed by `maxExactFiles` from broader `agentSurface`/`workBrief` evidence refs such as tests, docs, symbols, and service evidence. For program-scale goals, the compact response includes `autoSlicedContextPacketTransition`, a report-only bridge receipt from `ProgramPlanV1`/path inventory to the required Auto-Sliced `ContextPacketV1` and then `AgentWorkBriefV1`; its `receipts.missingRefs`, `receipts.truncation`, and `receipts.failure` explain missing transition refs, bounded-scan omissions, and blocked handoffs without granting execution or apply authority. The returned `refinementIntelligence`, `editReadiness`, and transition are report-only/advisory.

```json
{
  "repoPath": "/Users/mibook/saga/rhei",
  "goal": "Fix Convex deploy TypeScript diagnostics",
  "evidenceIntake": [
    {
      "kind": "command_diagnostic",
      "command": "bunx convex deploy",
      "rawOutput": "convex/code_layer/teamBridge.ts:376:46 - error TS4111: Property 'projectionKind' comes from an index signature."
    }
  ]
}
```

### Fast Context Builder

Use `rhei_context_builder` when an agent needs the right working context and a readable handoff in one call, without starting Oracle, launching subagents, reading source text, or entering the edit loop. `context_builder` is the boring alias for MCP clients that prefer non-branded tool names.

```json
{
  "repoPath": "/Users/mibook/saga/rhei",
  "goal": "Plan the next MCP context-builder reliability slice",
  "scopePaths": ["packages/mcp-server/src", "convex-tests/codeLayer"],
  "tokenBudget": 12000,
  "contextWindowTokens": 60000,
  "packingMode": "budgeted_slices",
  "responseType": "plan",
  "targetAgent": "codex",
  "exportResponse": true,
  "evidenceMlTopFiles": [
    {
      "path": "packages/mcp-server/src/codeContextTools/mcpResultAndContextForGoalTool.ts",
      "score": 0.97,
      "modelId": "impact-ranker-v0"
    }
  ],
  "maxFilesToScan": 800,
  "maxExactFiles": 8,
  "maxEvidenceFiles": 6
}
```

The response centers on `contextReceipt`:

- `selectedContext`: exact refs, selected files, planned read slices, related tests/docs/service evidence, and the next `rhei_code_io` read request.
- `codeMaps`: symbol summaries from the selected refs.
- `relevantDiffs`: read-only git status for selected refs plus a follow-up diff request.
- `tokenBudget`: requested budget, observed source-selection token estimate, and `within_budget`/`over_budget` status. In V1 this is reported, while `maxExactFiles` and `maxEvidenceFiles` remain the hard selector bounds.
- `contextPacking`: target-window fit guidance for 60k/120k/200k models, top-five source estimate, full selected-source estimate, recommended read mode, and Evidence ML top-file alignment.
- `budgetedContextBundle`: optional `BudgetedContextBundleV1` with packed source when `packingMode` is `top_five_full`, `budgeted_slices`, or `full_selected_when_fits`, or when `includeBudgetedContext` is true.
- `omittedCandidates`: bounded-scan omissions and non-selected candidate counts.
- `inclusionReasons`: per-file reason cards, scores, symbols, and token estimates.
- `sessionAttachment`: `contextReceiptId` and starter args a code session can carry forward.
- `benchmarkSignals`: elapsed-time target status, file-recall proxy, estimated tool-call reduction, and prompt readability counts.
- `readyToSendPrompt`: the agent-facing prompt/brief for the selected `responseType`.
- `export`: when `exportResponse` is true, a markdown handoff under `prompt-exports/` beside the repo root, with `ContextReceiptV1`, `AgentWorkBriefV1`, and the ready prompt.

`evidenceMlTopFiles` and `evidenceTopFiles` are advisory ranker lanes for the evidence ML model. These paths are seeded before normal goal-ranked exact refs, then reported back through `contextPacking.evidenceMlAlignment`. They do not grant authority; they only improve right-file recall.

Source text is opt-in. Leave `packingMode` unset for metadata-only RepoPrompt-style handoff planning. Use `packingMode: "budgeted_slices"` when the receiving agent needs a markdown export with selected source snippets. Use `top_five_full` for small top-ranked files, and `full_selected_when_fits` when source should only be included if all selected refs fit the requested model window.

`rhei_context_builder` is a packaging layer over Rhei's existing deterministic local context selector. It is report-only/advisory, does not read full source contents by default, does not call providers or live graph services, does not start Oracle/agents, and does not grant write authority.

`rhei_code_context_for_goal` can also perform an explicit connected read when the standalone read tool is not exposed in a client profile. Pass `read`, `reads`, `paths`, `files`, `refs`, or `refIds` to attach a compact `contextRead` receipt backed by `rhei_code_read`. Use `rhei_code_goal mode=read` or direct read aliases on `rhei_code_goal` when you only want the file slice and receipt; that route skips the goal context scan and omits `contextForGoal`. Use `mode=context` when you want planning context plus a mirrored `contextRead` inside `contextForGoal.contextRead`. Set `includeContent: false`, `previewOnly: true`, or `selectionOnly: true` for a source-free read plan; set `readFromContext: true` to derive the read set from the selected context refs. Plain context calls do not read source content beyond normal bounded selection unless one of these read inputs is present.

```json
{
  "repoPath": "/Users/mibook/saga/rhei",
  "goal": "Plan and read the MCP source refs in one call",
  "paths": [
    "packages/mcp-server/src/codeContextTools.ts",
    "packages/mcp-server/README.md"
  ],
  "includeContent": false,
  "contentFormat": "plain"
}
```

For a slim central read:

```json
{
  "repoPath": "/Users/mibook/saga/rhei",
  "mode": "read",
  "path": "packages/mcp-server/src/codeContextTools.ts",
  "start_line": 1343,
  "limit": 40,
  "includeContent": false
}
```

The response keeps the structured receipt in `read.receipt` and `contextRead`, including read ids, session/run ids, content/baseline hashes, token estimates, selection previews, lightweight symbol hints, and authority flags. It also includes a compact `contextRead.presentation` for humans:

```text
contextRead OK
files: 2
content: omitted
tokens: ~72.5k source / 0 emitted
paths:
- packages/mcp-server/src/codeContextTools.ts
- packages/mcp-server/README.md
syntax: lightweight_symbol_scan
symbols:
- buildRheiCodeGoalPayload
- codeGoalMode
authority: report-only
```

When line windows are requested, the presentation adds readable ranges:

```text
reads:
- packages/mcp-server/README.md:216-231
- packages/mcp-server/src/codeContextTools.ts:1738-1775
```

The higher-level goal transactions expose the same compact human lane without replacing their structured receipts. `verify.presentation`, `edit.presentation`, `trail.presentation`, and `report.presentation` summarize status, key counts, receipt count, authority, and a short `markdown` array while the underlying search/read/diff/Trail/report objects remain available for agents:

```text
verify absence_proven
searches: 2
reads: 1
coverage: 2 searched / 1 matched / high
absenceProof: 1
receipts: 5
authority: report-only
```

```text
edit dry_run_passed
dryRun: pass
validation: skipped
changedFiles: 1
apply: disabled
authority: report-only
```

Context responses also include a compact `workflowPlan` by default. It is a report-only bridge for the next agent step: `sessionSelect.exactRefs` names the bounded refs, `sessionSelect.readSlices` gives stable path and line-window hints, and `followups.read.args`, `followups.search.plans[].args`, and `followups.edit.args` are ready-to-run inputs for `rhei_code_read`, `rhei_code_search`, and preview-safe `rhei_code_io op=edit`. These follow-ups never execute during context selection, and their guardrails keep source reads, searches, and edits explicit. Pass `includeWorkflowPlan: false` only when the response must omit this planning lane.

By default it does not write snapshots. Set `writeSnapshot: true` only when you explicitly want a local artifact at `.rhei/code-context/latest-code-market-snapshot.json` or `snapshotOutputPath`.

The local selector can reuse `.rhei/code-context/local-index.json`. `useLocalIndex` defaults to true; `writeLocalIndex: true` creates or refreshes the cache with path, size, mtime, and hash metadata so repeated local context calls can skip the full repo listing. Use `refreshLocalIndex: true` after large file moves or package reshapes.

Every `rhei_code_context_for_goal` response now includes a metadata-only observability block:

```json
{
  "relatedFiles": {
    "exactFiles": ["packages/mcp-server/src/codeContextTools.ts"],
    "relatedTests": ["convex-tests/codeLayer/localCodeContextForGoal.test.ts"],
    "docsEvidence": ["packages/mcp-server/README.md"],
    "serviceConnectionEvidenceRefs": [],
    "all": []
  },
  "observability": {
    "requestId": "rhei-context:...",
    "goalHash": "deterministic-hash",
    "durationMs": 42,
    "phaseDurationsMs": {
      "collectCandidates": 12,
      "initialSelection": 4,
      "finalSelection": 3,
      "toolPayload": 42
    },
    "fileCounts": {
      "scanned": 1200,
      "listed": 3642,
      "considered": 143,
      "exact": 8,
      "relatedTests": 6,
      "docs": 1
    },
    "tokens": {
      "total": 18000,
      "files": 16000,
      "byFile": [
        {
          "path": "packages/mcp-server/src/codeContextTools.ts",
          "roles": ["exact"],
          "tokens": 2400,
          "bytes": 9600,
          "lineCount": 220
        }
      ],
      "estimateVersion": "char-div-4-v1"
    },
    "evidenceKinds": ["session_validation"],
    "evidenceCount": 1,
    "primaryRefs": ["packages/mcp-server/src/codeContextTools.ts"],
    "errorCodes": ["TS2305"],
    "readinessStatus": "edit_ready_from_evidence",
    "warnings": [],
    "noLive": { "pass": true }
  }
}
```

Token counts are deterministic estimates for context sizing and debugging. They are not billing telemetry and should not be used as provider accounting.

## `rhei_code_agent` V1 external-agent handoff

`rhei_code_agent` is the Rhei-native report-only surface for coordinating external local agents from one parent task without granting write, provider, network, graph, session-mutation, or apply authority. It is distinct from the lower-level Code Session edit tools and is not an executor: it packages agent handoffs, imports agent results, and ranks/summarizes evidence so a human or a later gated workflow can decide what to do next.

The public agent family is additive over that same substrate:

- `rhei_agent_explore`: `action=start | poll | wait | cancel`, always maps to `explore_agent`.
- `rhei_agent_run`: `action=start | poll | wait | cancel | get_log | steer | respond | import_result | summarize | rank`, with role labels `explore`, `engineer`, `pair`, `review`, `validate`, and `design`. `executionMode=live` starts the local process plane; `executionMode=sandbox` starts the Modal AgentEditSession plane only when Modal runner env is configured.
- `rhei_agent_manage`: `action=list_agents | list_sessions | get_log | extract_handoff | handoff | create_session | resume_session | stop_session | cleanup_sessions | list_workflows`.

These public tools are the preferred agent-facing entry points and their MCP schemas require `action`, not legacy `mode`. `rhei_code_agent` remains a lower-level compatibility substrate for typed V1 handoffs/imports/ranking and is hidden from the default public MCP profile; use the full profile only for contract tests, migration work, or granular debugging.

Public agent boundary: execution planes are explicit. The local process plane is process-local and report-only; the fake adapter remains default, and the Codex CLI adapter is opt-in. The sandbox plane is Modal-backed AgentEditSession handoff only; it reuses allowed paths, denied paths, validation command, callback HMAC, baseline checks, and no-canonical-apply authority. Explicit sandbox callback imports use `rhei_agent_run action=import_result` with the Modal callback envelope; successful imports update the process-local sandbox session, result bundle, summary/ranking surfaces, and public logs without applying source changes. Requests for unsupported live or sandbox actions must return structured boundary receipts rather than silently degrading into another execution plane.

V1 role vocabulary is deliberately small:

- `explore_agent`: finds required refs, likely risks, missing evidence, and next-read guidance.
- `engineer_agent`: proposes an edit plan and patch preview only; no source writes or provider calls.
- `review_agent`: critiques the proposal, proof gaps, risk coverage, and compliance.
- `validation_agent`: checks commands, evidence receipts, test/docs coverage, and validation gaps.
- `design_agent`: critiques architecture, product, UX, and workflow shape; produces design notes, risks, alternatives, and decision guidance. It is advisory/report-only by default.

There is no core `pair_agent` handoff role in V1. The public `pair` label is a UX/agent-routing convenience on `rhei_agent_run`; it maps to `engineer_agent` and emits `rhei_agent_run:pair_maps_to_engineer_agent_v1` so clients can display the compatibility boundary.

The expected multi-agent eval shape is one parent task with three child handoffs:

```text
parent rhei_code_agent task
  -> explore_agent child handoff: required refs + risks
  -> engineer_agent child handoff: proposal + in-memory patch preview
  -> review_agent child handoff: critique + proof gaps
  -> import child results
  -> rank/summarize by required-ref recall, proposal quality, patch preview correctness,
     risk/proof coverage, token use/repeated reads when available, and no-write/no-provider compliance
```

Imported child results must remain evidence. Token counts are context-sizing estimates, repeated-read counts are workflow-quality signals, and patch previews are review artifacts. They do not authorize the apply leg of `rhei_code_edits`, provider calls, live Oracle calls, Memgraph execution, route persistence, or Truth Gate promotion.

Focused coverage lives in `convex-tests/codeLayer/rheiCodeAgentHandoff.contract.test.ts`, `convex-tests/codeLayer/codeAgent.test.ts`, and `convex-tests/codeLayer/codeAgentTools.test.ts`. Those tests document the public API, exercise the core `packages/core/src/codeAgent/*` builders, assert the registered `rhei_code_agent` plus `rhei_agent_*` family contracts, cover handoff creation, result import, summary/ranking, required-ref recall, proposal/proof/risk/validation/efficiency signals, and preserve the no-live/no-provider/no-authority guardrails.

## `rhei_code_run` V1 run graph switchboard

`rhei_code_run` is the process-local parent control-plane for coordinating multiple report-only code workflow artifacts. It is not an executor: it never spawns agents, calls providers, persists to Convex, writes files, promotes canon, or grants apply authority. It records the visible graph that a parent session can inspect before deciding what to do next.

Supported modes:

- `start`: create a parent `RheiCodeRunGraphV1` with a root node.
- `add_oracle`: attach an existing Oracle session/reference node.
- `add_agent_handoff`: attach one or more existing agent handoff references as visible child nodes.
- `import_agent_result`: import external agent result reports as evidence nodes.
- `rank_results`: rank imported result nodes by required-ref coverage and readiness signals.
- `switch_active`: move the active-node pointer for context switching.
- `context`: return the current active node, visible node ids, delegation leases, and parent control-plane metadata.
- `summarize`: return node counts, active lease counts, refs, warnings, and next action.

Delegated autonomy is modeled as data only. Agent/run nodes can carry a `delegationPolicy` with `allowedRoles`, `maxDepth`, `maxChildren`, token/time budgets, `writeAllowed: false`, `parentCanCancel: true`, and `parentCanSupersede: true`. When a node can delegate, the graph records a `DelegationLeaseV1` with child node ids, status, budget, expiry, `revocable: true`, `reportOnly: true`, `noAuthority: true`, and `noWriteAuthority: true`. Exhausted role/depth/child-count constraints pause the branch and emit warnings; they do not execute cancellation or hidden work.

Focused coverage lives in `convex-tests/codeLayer/codeRunTools.test.ts`. The contract test covers one parent run, one Oracle node, two handoff nodes, two imported results, ranking/next action, active-node context switching, visible delegation leases, and paused/warning behavior for bounded child-spawn constraints.

## Code Session V1

The default V1 session loop is local, read-only, and dry-run only:

```text
rhei_code_context_for_goal
-> rhei_code_prepare_work
-> rhei_code_session_start
-> rhei_code_read exact slices
-> rhei_code_edit_cycle
-> rhei_code_session_diff for review / reverse preview / Trail evidence
-> review separate proposal / impactPrediction / proofPlan / dryRun / validation artifacts
-> optional rhei_code_io op=edit for two-call workflowPlan -> multi-file preview
-> optional rhei_code_edits default transaction for low-ceremony preview/apply/verify
```

`rhei_code_edit_cycle` is a clean-loop convenience, not a new authority layer. The granular tools remain available and distinct for proposal, proof, dry-run, validation, and review; low-ceremony edit work goes through `rhei_code_edits` with no phase required for the normal case. Use `phase=preedit` only when an agent wants preview without the apply attempt, and `phase=afteredit` only to re-verify a prior apply. Use `editsByPath` when many edits target one file; grouped changes are flattened in order, pattern `editKind` can be inferred from `search` + `replace`, and dry-run/apply preflight evaluates same-file edits sequentially before any gated write path exists.

`rhei_code_session_diff` is the review-facing view of session changes. It can summarize a selected proposal or dry-run, return a compact patch preview, and return a reverse patch preview for agent analysis. The reverse preview is evidence only: `revertAvailable` is false, `sourceWrites` is false, and any future revert/apply path must go through Writer Arbitration. This makes session diffs suitable for Trail projection, PR-session analysis, review-comment learning, and proposal ranking without turning review evidence into write authority.

`rhei_code_search` is the single Code Session search surface. Keep basic use as `query` plus optional `facets`; turn on richer behavior with `purpose`, `profile`, `engines`, `depth`, and `budget`. Profiles are `fast_local`, `smart_local`, `semantic_readonly`, `graph_advisory`, `full_readonly_ranked`, plus recall-gradient aliases `action`, `integration`, `audit`, and `prove_absence`. The default profile is `graph_advisory`: local lexical/index/codemap ranking with connected shallow refs and soft graph depth3 advisory evidence. Local MCP never executes Convex, Qdrant, Memgraph, embedding providers, network calls, or writes from search. Semantic/Qdrant/Convex engines consume supplied evidence arrays only, graph refs stay labeled advisory evidence, `memgraph: true` only records a no-live warning, and graph depth above 3 requires `depth5EvalOnly: true` so depth5 cannot become the default path by accident. Search returns per-ref `rankingEvidence`, no-live flags, evidence refs, warnings, and a `nextReadPlan` bounded by the requested token/ref budget.

For recall-sensitive questions, use audit purposes: `integration_audit`, `caller_audit`, `surface_audit`, or `prove_absence`, with `coverage: true` and optional `scopePaths`. Audit/prove-absence searches scan the live local filesystem outside the current selected refs unless explicit candidate refs constrain the scope, then return `coverageReceipt` with searched/matched file counts, searched scopes, truncation, matched refs, recommended exact refs, and absence claims. If the scan is truncated or files are skipped, absence confidence is low and warnings include `coverage:absence_not_proven`.

MCP tool responses are compact by default for agent use: `rhei_code_context_for_goal` omits full snapshots, raw `observability.tokens.byFile`, prompt text, and duplicated long ref arrays; it keeps counts plus omitted totals so agents can see when to expand. `rhei_code_search` caps returned refs but preserves counts, omitted totals, and absence confidence in `coverageReceipt`.

Code Session payloads expose `liveEvidence` and `taskDisplay` so agents can see whether Memgraph/Qdrant/Convex evidence was requested or supplied upstream. These fields are status and routing metadata only. Default mode is `no_live`, graph advisory is `soft_graph_depth3`, Code Session itself does not execute live backends, and local MCP session display does not write Convex task state. Cloud task display requires a cloud/workroom session id from the Convex session layer.

`CodeImpactPredictionV1` may consume planner graph refs, service connection ids, receipts, and explicit Synapse impact evidence as labeled advisory evidence. It exposes supplied Synapse evidence as a sanitized `synapseEvidence` packet with `execution.attempted`, `execution.memgraphExecuted`, `execution.providerCalls`, and `execution.writes` forced to `false`. It does not execute Memgraph, call providers, promote graph/service hints to truth, write files, or authorize apply. Writer Arbitration is separate and remains disabled for production V1.


`ProofSynapseV1` is the companion evidence map. Impact Synapse predicts what may be affected; Proof Synapse states what must be proven before the proposal can move forward: focused tests, docs, contracts, validation commands, missing evidence, traceability expectations, collaboration roles, and a dry-run/human-review verdict. It is report-only, advisory-only, no-authority, and cannot approve or apply edits.

`rhei_code_session_act` is the local one-call task helper for agents. It keeps the phase objects separate in the response: context selection and Planner Graph Advisory explain why refs were selected, `CodeImpactPredictionV1` predicts impact, `ProofSynapseV1` maps required evidence, dry-run checks the patch, and Writer Arbitration decides whether optional apply can run. Without `applyMode: "local_beta"`, it never writes.

## MCP Surface Benchmark Snapshot

Rhei's public MCP surface is optimized for agent workflow cost, not raw tool count. The release benchmark compares shared capabilities across Rhei, codedb, codegraph, and RepoPrompt by the bytes an agent actually receives: MCP `structuredContent` plus text content, converted to an approximate token count with `bytes / 4`. Rhei keeps richer receipts available through normal/debug modes, while narrow output modes make the common read/search/graph lanes as small as their equivalent comparator tasks.

Current narrow modes:

| Mode | Public path | Use |
| --- | --- | --- |
| `outputMode=content` | `read_file` | Return only path, line range, and source content for a read slice. |
| `outputMode=locator` | `file_search mode=symbol` | Return compact symbol rows with `path`, `symbol`, `kind`, `stableKey`, line, and score. |
| `outputMode=edges` | `graph op=callers/callees/neighbors/impact` | Return compact relationship rows without the full receipt envelope. |

Latest local cross-tool run, generated 2026-06-08:

| Comparator | Comparable lanes | Rhei tokens | Comparator tokens | Savings | Interpretation |
| --- | ---: | ---: | ---: | ---: | --- |
| codedb MCP | read + symbol + callers | ~584 | ~1,395 | ~811 saved, 58% less | Clean same-MCP win across the shared lanes. |
| RepoPrompt MCP-bound | read + symbol | ~516 | ~784 | ~268 saved, 34% less | RepoPrompt is measured through `bind_context`; it has no callers/callees primitive. |
| codegraph CLI | symbol + callers | ~222 | ~874 | ~653 saved, 75% less | Directional only: codegraph MCP timed out locally; CLI callers alone is smaller than Rhei by ~32 tokens. |
| Successful same/bound MCP rows | codedb MCP + RepoPrompt bound | ~1,100 | ~2,179 | ~1,079 saved, 50% less | Best release-safe aggregate claim from the current benchmark. |

Per-lane detail:

| Lane | Rhei | Comparator | Savings |
| --- | ---: | ---: | ---: |
| Read slice vs codedb MCP | ~363 tok | ~860 tok | ~498 tok, 58% |
| Read slice vs RepoPrompt bound | ~363 tok | ~392 tok | ~29 tok, 7% |
| Symbol locate vs codedb MCP | ~153 tok | ~295 tok | ~142 tok, 48% |
| Symbol locate vs RepoPrompt bound | ~153 tok | ~392 tok | ~239 tok, 61% |
| Callers graph vs codedb MCP | ~69 tok | ~240 tok | ~171 tok, 71% |
| Callers graph vs codegraph CLI | ~69 tok | ~37 tok | Rhei costs ~32 more tokens, but is faster and MCP-native. |

The clean release claim is:

```text
On successful same/bound MCP comparator rows, Rhei's narrow public modes reduce
agent-facing payload by about 50% overall. Against codedb MCP across read,
symbol lookup, and callers, Rhei uses about 58% fewer tokens.
```

Benchmark artifacts live under `convex-tests/evals/reports/mcp-compare/`:

- `cross-tool-scoreboard.md`: Rhei vs codedb/codegraph/RepoPrompt shared-lane scoreboard.
- `cross-tool.jsonl`: machine-readable cross-tool measurements.
- `rhei-surface-overview.md`: Rhei public-surface payload and latency overview.
- `rhei-surface.jsonl`: machine-readable Rhei surface measurements.

Run the current benchmarks from the repo root workspace:

```bash
cd /Users/mibook/Code/saga/rhei
RP_CLI_WINDOW=1 CODEDB_BIN=codedb CODEGRAPH_BIN=codegraph \
  bun --env-file=.env convex-tests/evals/tools/mcpCrossToolBench.ts

RHEI_SURFACE_INCLUDE_CROSS_TOOL=0 MCP_SURFACE_REPO=/Users/mibook/Code/saga/rhei \
  bun --env-file=.env convex-tests/evals/tools/rheiSurfaceOverview.ts
```

For a harder release benchmark, use macro task profiles instead of only per-call micro lanes:

| Profile | Measures |
| --- | --- |
| `symbol_to_impact` | Locate a symbol, read its definition, find callers/callees, and summarize blast radius. |
| `change_readiness` | Locate target code, read implementation and tests, graph impact, and recommend validation. |
| `reuse_or_dead_code` | Search a symbol family, inspect graph neighbors, return reuse/dead-code candidates, and read top evidence. |
| `root_mismatch_recovery` | Intentionally use a wrapper repo root and measure whether the tool explains the artifact/root mismatch and fix. |

Those macro profiles should score total transcript tokens, turns, latency, answer correctness, and recovery quality. They are a better product benchmark than micro payload alone because they measure whether Rhei saves tokens across the whole agent workflow.

Latest repeated external JS act benchmark evidence, generated 2026-05-18 from three real Codex CLI runs on the local `escape-string-regexp` fixture, shows the one-call Rhei dry-run loop using a mean 62,229 tokens versus RepoPrompt's mean 233,585 tokens. That is 171,356 fewer tokens per run, a 73.4% reduction, or 26.6% of RepoPrompt token usage. The same token budget therefore buys about 3.75x more bounded edit-session work. The stability signal is as important as the mean: RepoPrompt ranged from 93k to 367k tokens across repeats, while Rhei stayed tightly around 62k-63k with required-ref recall, patch preview correctness, and expected-match correctness all at 1.0. The batch report remains a local fixture benchmark, not a universal production claim; it used read-only sandboxing, approval policy `never`, and no source writes.

## Migration Synapse V1

Migration Synapse is a ProgramPlan specialization, not a separate execution product. For migration or rewrite goals, `ProgramPlanV1` remains the entry point and can attach `MigrationPlanV1` with `includeMigrationPlan: true` or by automatic migration classification. The migration plan is report-only and contains the migration rulebook, inventory shards, first safe shard, proof strategy, risks, and guardrails.

The intended flow is:

```text
ProgramPlanV1
-> MigrationPlanV1
-> first safe migration shard
-> auto-sliced ContextPacketV1
-> RheiCodeSessionV1
-> CodeImpactPredictionV1
-> ProofSynapseV1
-> dry-run / validation
-> Writer Arbitration for future apply only
```

The apply leg of `rhei_code_edits` is registered as part of the edit family, but source writes remain disabled unless `RHEI_CODE_SESSION_ENABLE_APPLY_EDITS=1` is set in local beta or disposable benchmark sessions. The tmp test bypass uses `applyMode: "test_bypass"` with `confirmTestOnly: true`, `confirmNoProduction: true`, and a `testBypassReceipt`; the repo path must be under `os.tmpdir()` or `RHEI_CODE_SESSION_APPLY_ROOT_ALLOWLIST`.

For low-ceremony local development, `phase: "apply"` with `applyMode: "local"`, `confirmLocalCodebase: true`, `confirmNoProduction: true`, and `executeValidation: true` reruns executable validation when the preview only recorded evidence-only/skipped validation. Apply still reports `productionAuthority: false`, requires the repo path to match the root allowlist, and performs durable readback before afteredit verification.

For Rhei self-development local beta only, launch the MCP server with `bun run mcp:rhei:local-beta`, then use `applyMode: "local_beta"` with `confirmLocalBeta: true`, `confirmNoProduction: true`, `localBetaReceipt`, `approvalRef`, and `leaseId`. Do not give this command to closed-beta testers; tester setup should use the default `bun run mcp:rhei` public profile. Local beta still requires a prior `CodeImpactPredictionV1` with sanitized predictive Synapse evidence (`reportOnly`, `advisoryOnly`, `noAuthority`, and no live execution flags), a passing dry-run, baseline hash match, expected match counts, receipts, Trail projection metadata, explicit root allowlist, and protected-path checks. It returns `writer_arbitration_local_beta`, `productionAuthority: false`, and blocks secret-like, generated, vendor, VCS, and build-output paths.

`rhei_code_session_start` accepts `contextForGoal` plus the agent-friendly aliases `context`, `contextPacket`, and `contextForGoalPayload`. If no context object is supplied, it uses the most recent process-local `rhei_code_context_for_goal` metadata for the same MCP server process, or a matching `contextRequestId` when supplied. Absolute paths under `repoPath` are normalized back to repo-relative refs before reads/searches are counted.

`rhei_code_session_start` accepts explicit `blockedRefs`/`excludedRefs`/`forbiddenRefs` for session policy. Automatic selection and search skip those refs, and exact read/proposal attempts against them fail read-only with a blocked-by-policy error. This is a selection safety constraint only; it is not Writer Arbitration and does not authorize writes.

## Code Strategy Plan V1

`rhei_code_strategy_plan` is a local, deterministic strategy-prompt surface for the planning handoff between Code Context/ProgramPlan evidence and a later Code Session. It returns `CodeStrategyPlanV1` with connected file groups, generated strategy prompts, oracle boolean feedback metadata, and token estimates by path, group, prompt, and feedback. It never includes source text in the plan.

Use it after `rhei_code_context_for_goal`, after a `ProgramPlanV1`/`MigrationPlanV1`, or after `rhei_code_session_context` when an agent needs a more explicit strategy prompt before reading or proposing edits:

```json
{
  "goal": "Plan the next safe implementation slice for CodeStrategyPlan docs",
  "strategyKind": "auto",
  "promptSpecificity": "balanced",
  "contextForGoal": { "...": "rhei_code_context_for_goal payload" },
  "codeSessionContext": { "...": "optional rhei_code_session_context payload" },
  "oracleFeedback": [
    {
      "feedbackId": "feedback:make-validation-more-specific",
      "questionKind": "specific_enough",
      "answer": false,
      "targetPromptId": "prompt:code-strategy:implementation_slice:example:validation"
    }
  ]
}
```

Feedback is report-only metadata. `specific_enough: false` or `too_abstract: true` shifts the target prompt one step more specific; `abstract_enough: false` or `too_specific: true` shifts it one step more abstract. Conflicting feedback is summed and clamped deterministically. It does not approve work, bypass scope, or grant authority.

If only `sessionId` is supplied, the tool builds Code Session context from the process-local session and may increment Code Session tool-call telemetry. That mutation is observability-only; it does not read source, write files, call providers, execute commands, or authorize apply.

`CodeStrategyPlanV1` guardrails are fixed to `reportOnly`, `advisoryOnly`, `noAuthority`, `noProviderCalls`, `noNetworkCalls`, `noFilesystemSourceScan`, and `workingSetGrantsAuthority: false`. Token estimates use the same `char-div-4-v1` convention as Code Context/Code Session and are context-sizing estimates, not billing telemetry.

## Workflow Plan V1

`rhei_code_workflow_plan` is a local, deterministic planning surface for the handoff after Code Strategy Plan and before any Code Session/Proof Synapse write flow. It returns the `strategyPlan` and `workflowPlan` side by side with `advisoryOnly: true`, `noAuthority: true`, and a no-live snapshot.

Public `workflowKind` values are `orchestrate`, `deep_plan`, `investigate`, `review`, `optimize`, `refactor`, and `export_context`. `workflowKind` chooses the user-facing workflow intent and read-slice priorities. `workflowPreset` chooses planning/token shape (`compact_plan`, `balanced_plan`, or `deep_plan`). Support metadata uses `supportStatus`: active means implemented in V1; planned vocabulary must remain metadata-only and must not add executable workflow kinds.

Workflow specializations are internal routing metadata only: `drift_repair`, `migration_slice`, `service_boundary`, `proof_hardening`, `security_review`, `performance_tuning`, and `context_compression`. They may steer prompt packets, service gates, risk emphasis, or read-slice priority inside the planner, but they are not public workflow kinds, public tools, or user-facing workflow names.

Legacy compatibility aliases may still be accepted as inputs: `review_proposal` maps to `review`, `optimize_context` maps to `optimize` and may use `context_compression`, `refactor_slice` maps to `refactor`, `migration_slice` maps to `refactor` plus the `migration_slice` specialization, and `drift_repair` maps by intent plus the `drift_repair` specialization. New docs and examples should use the public workflow vocabulary above.

Service boundaries are represented as compact control-plane refs only. `serviceConnectionIds` identify connected contracts, while `serviceConnectionGates` explain whether those IDs and service evidence refs are satisfied, need contract context, need a compact ID, or need external evidence. Gates are blocking-before-write, report-only, advisory-only, and no-authority. They may include IDs, evidence refs, context group IDs, and required read-slice IDs; they must not include service contract body text.

`sessionSelect` tells an agent what to read next without reading it itself: `exactRefs`, `readSlices`, `avoidRefs`, stop conditions, and a deterministic `char-div-4-v1` read-token budget. Required service evidence slices are selected before optional slices. Overflow and explicitly avoided non-required refs stay in `avoidRefs`.

Oracle integration is prompt-packet-only. `OraclePromptPacketV1` carries `workflowKind`, `workflowPreset`, service connection IDs, source strategy identifiers/hashes, context group IDs, selected read-slice IDs, boolean questions, prompt text, and execution flags all set to false. Every active workflow emits a `context_sufficiency` question; service gates add `connected_contract`. `rhei_code_workflow_plan` does not call a live Oracle/provider, fetch source text, mutate Code Session state, execute commands, or write files.

`rhei_code_oracle` is the primary Oracle workflow loop for those packets. V1 is still no-live and report-only. Use `mode: "session_start"` / `mode: "session_context"` / `mode: "fork_session"` to manage the process-local Oracle session artifact, `mode: "manage_workspace"` to add/set/remove/get/clear a process-local Oracle workspace selection, `mode: "build_context_bundle"` to materialize bounded `sessionSelect` source slices for Oracle review, `mode: "export_markdown"` to render a shareable markdown packet from a context bundle, `mode: "plan_packets"` to surface/refine prompt packets, `mode: "import_feedback"` to pass external/user Oracle answers, `mode: "refine_workflow"` to recompile the workflow/handoff from imported feedback, and `mode: "summarize_feedback"` to compact the feedback result for review or learning evidence.

`mode: "manage_workspace"` is the Rhei-native equivalent of curating an Oracle workspace selection. Pass `workspaceAction: "add" | "set" | "remove" | "clear" | "get"`, use `connectedFiles` or `workspaceFiles` for files and line slices, and use `pathOnlyRefs` / `workspacePathOnlyRefs` for future or new files. This only mutates the process-local Oracle session artifact; it does not read, write, spawn agents, or call providers.

`mode: "build_context_bundle"` returns an exportable `OracleContextBundleV1` in the MCP payload and process-local Oracle session. It is not a durable file write. Source text can only come from compiled `sessionSelect.readSlices` / `exactRefs` plus explicit `manage_workspace` selected read slices. Direct `pathOnlyRefs`, `exportedPathOnlyRefs`, and workspace path-only refs are metadata-only and are useful for new-file refs in external-agent handoffs. Supplying `forcePaths` to this mode is ignored with a warning because `forcePaths` belongs in workflow planning, not bundle materialization.

`mode: "export_markdown"` returns `markdownExport.markdown` plus token accounting, read receipts, external Oracle model metadata, and return instructions for `mode: "import_feedback"`. It defaults to `externalOracleModel: "gpt-5.5"` and `externalOracleReasoningEffort: "low"` when those fields are omitted. `exportPath` is recorded as a suggested path only; V1 does not write files, call providers, open network connections, or run a live Oracle session.

Pass external/user Oracle feedback plus an existing strategy, workflow, handoff, or context payload; the tool recompiles typed artifacts, retargets feedback when generated IDs change, returns token deltas and applied feedback summaries, and keeps `reportOnly`, `advisoryOnly`, `noAuthority`, `noProviderCalls`, and `noSessionMutation` fixed to true.

When `sessionId` is supplied without `codeSessionContext`, `rhei_code_workflow_plan` deliberately ignores it and returns `workflow_tool:session_id_ignored_to_avoid_session_mutation`. To include session evidence, callers must pass an already-built `codeSessionContext` payload explicitly.

```json
{
  "goal": "Plan a bounded refactor workflow",
  "contextForGoal": { "...": "rhei_code_context_for_goal payload" },
  "workflowKind": "refactor",
  "workflowPreset": "compact_plan",
  "serviceConnectionIds": ["service:billing-contract"],
  "serviceConnectionRefs": [
    {
      "serviceConnectionId": "service:billing-contract",
      "evidenceRef": "docs/contracts/billing.md",
      "reason": "external API boundary"
    }
  ],
  "avoidRefs": ["docs/broad-background.md"],
  "sessionSelectTokenBudget": 2000
}
```

`plannerHandoffGraphAdvisory` is optional metadata on `rhei_code_context_for_goal` and `rhei_code_context_build_work_brief`. Graph routing advisory explains context selection. It does not authorize graph mutation, provider synthesis, Memgraph execution, code writes, or Truth Gate promotion. The server normalizes unsafe input back to `reportOnly: true`, `advisoryOnly: true`, `noAuthority: true`, `memgraphAllowed: false`, `depth5Allowed: false`, and `synapsePredictionInputAllowed: false`. It is not fed into Synapse prediction unless `rhei_code_plan_edits` is explicitly called in a session flow; it never triggers provider calls, route persistence, UI surfacing, production writes, or graph default changes. Depth5 remains non-default and production default mode remains `convex_local`.

Use `rhei_code_context_runs` to inspect recent local calls:

```json
{
  "repoPath": "/Users/mibook/saga/rhei",
  "limit": 5
}
```

The run log is in-memory for the MCP server process and resets on restart. It stores metadata only: no file contents, no raw goal text, no provider calls, and no production writes.

`includeProgramPlan` defaults to auto: program-scale goals get a report-only `ProgramPlanV1`; bounded coding tasks stay on Code Context unless you pass `includeProgramPlan: true`.

`reportOnlyEvidence` is optional. It is how local/web Rhei can attach Connected Surface Coverage or Growth Diagnostics summaries to the same Code Context snapshot without giving those diagnostics execution authority. `includeSurfaceCoverage` and `includeGrowthDiagnostics` generate deterministic report-only cards from the selected context only; they do not run live planners, providers, Convex writes, Memgraph, route persistence, or capability runs.

Use `rhei_code_context_build_work_brief` when web/local Rhei already supplied Code Context. It accepts either:

- `snapshot`: a `CodeMarketSnapshotV1` JSON object.
- `snapshotPath`: a local path to a `CodeMarketSnapshotV1` JSON file.
- neither: uses the committed source-backed fixture for smoke testing only.

Selection fields:

```json
{
  "snapshotPath": ".rhei/code-context/latest-code-market-snapshot.json",
  "tileIds": ["tile-id-or-stable-key"],
  "clusterIds": ["cluster-id-or-stable-key"],
  "selectedRefIds": ["packages/core/src/codeMarket/workBrief.ts"],
  "selectedRefStableKeys": ["file:repo_rhei_fixture:packages/core/src/codeMarket/workBrief.ts"],
  "userGoal": "Plan the next safe implementation slice.",
  "workflowPresetId": "deep_plan",
  "plannerHandoffGraphAdvisory": {
    "source": "mcp_input",
    "basis": "explicit_metadata",
    "recommendedGraphMode": "soft_graph_depth3",
    "selectedGraphMode": "connected_work_shallow",
    "reportOnly": true,
    "advisoryOnly": true,
    "noAuthority": true
  }
}
```

The output keeps the governed handoff boundary:

- Code Context is bounded evidence, not authority.
- `contextPlan.exactRefs` is the initial scope.
- Canon changes, memory promotion, and execution still require explicit gates.
- No Memgraph, soft-edge projection, provider lane, capability run, route persistence, or UI surfacing is enabled by this server.

## Run From Source

From `rhei/`:

```bash
bun install
bun run --silent mcp:rhei
```

For direct package development:

```bash
bun run --cwd packages/mcp-server --silent dev:stdio
```

### CLI install and init

The package is published as `@rhei-team/rhei` and exposes `rhei`, `rhei-mcp`, `mcp-server`, and `saga-mcp` binaries. Because the package's unscoped name is `rhei`, plain scoped execution selects the `rhei` bin directly — no `--package` needed:

```bash
npx -y @rhei-team/rhei install --target auto --yes --index
```

Explicit-bin forms also work:

```bash
npx -y --package @rhei-team/rhei rhei install --target auto --yes --index
bunx --package @rhei-team/rhei rhei install --target auto --yes --index
pnpm dlx --silent --package @rhei-team/rhei rhei install --target auto --yes --index
```

`rhei-mcp` with no subcommand keeps the historical stdio MCP behavior; `rhei mcp` or `rhei serve` starts the MCP server explicitly.

Use the installer to register Rhei with local MCP clients:

```bash
rhei install --target auto
rhei doctor
rhei print-config --target codex
rhei uninstall --target codex
```

Supported install targets are `claude`, `codex`, `gemini`, `cursor`, `windsurf`, `devin`, and `opencode`; `auto`, `all`, and comma-separated target lists are accepted. `rhei init --path /path/to/repo --install` registers clients, builds the local index, warms SQL reports, and prints a repository overview.

Safe repeat-test loop without touching real MCP client configs:

```bash
tmp_home=$(mktemp -d)

HOME="$tmp_home" \
RHEI_PROGRESS=plain \
RHEI_MCP_INSTALL_COMMAND=bun \
RHEI_MCP_INSTALL_ARGS='--cwd /Users/mibook/Code/saga/rhei/packages/mcp-server tsx src/index.ts' \
bun --cwd /Users/mibook/Code/saga/rhei/packages/mcp-server tsx src/index.ts install \
  --target all \
  --yes \
  --index \
  --path /Users/mibook/Code/saga/rhei

HOME="$tmp_home" \
bun --cwd /Users/mibook/Code/saga/rhei/packages/mcp-server tsx src/index.ts uninstall \
  --target all \
  --yes

rm -rf "$tmp_home"
```

### Runtime freshness and restart verification

MCP responses include a `runtime.reloadStatus` fingerprint. Source-mode fingerprints hash the MCP server TypeScript files that affect Code Context, Code Session, and facade behavior; dist/beta-mode fingerprints hash the built JavaScript files under `dist/`. If a file changes while a client is connected, compact responses include `reloadStatus.status: "restart_required"` plus a `restartAction` and `restartWorkflow`.

Source development loop from `rhei/`:

```bash
bun run mcp:rhei:check # optional typecheck/build gate
# restart the running MCP launcher / Codex MCP session
# verify with rhei_code_io op=status or rhei_code_context_doctor until reloadStatus.status is current
```

Beta tarball loop from `rhei/`:

```bash
bun run mcp:rhei:pack-beta
# reinstall dist/rhei-mcp-beta/artifacts/rhei-mcp-server-<version>.tgz
# reconnect the MCP client and verify reloadStatus.status is current
```

If `pid` and `loadedAt` do not change after restart, the restart did not reach the connected MCP process.

For local Streamable HTTP beta testing:

```bash
RHEI_MCP_HTTP_AUTH_DISABLED=true \
RHEI_MCP_HTTP_PORT=8788 \
bun run --silent mcp:rhei:http
```

The HTTP endpoint serves `/mcp` and an unauthenticated `/healthz`. `RHEI_MCP_HTTP_AUTH_DISABLED=true` is accepted only for loopback hosts by default. Use bearer auth outside private local testing:

```bash
RHEI_MCP_TRANSPORT=http \
RHEI_MCP_HTTP_HOST=0.0.0.0 \
RHEI_MCP_HTTP_PORT=8788 \
RHEI_MCP_HTTP_BEARER_TOKEN=<token> \
RHEI_MCP_INDEXING_ENABLED=false \
bun run --cwd packages/mcp-server --silent dev:http
```

To deliberately run auth-disabled HTTP on a non-loopback private test network, set `RHEI_MCP_HTTP_ALLOW_INSECURE_NON_LOOPBACK=true`. Do not use that setting for hosted or enterprise endpoints.

Remote HTTP mode adds these beta tools:

- `rhei_auth_status`: reports transport/auth posture.
- `rhei_connect_github`: returns the configured GitHub App install URL.
- `rhei_link_local_repo`: explains that local repo proof requires local stdio MCP.
- `rhei_index_status`: reports the disabled-by-default indexing contract.
- `rhei_sync_status`: reports local/cloud sync defaults and consent posture.
- `rhei_cloud_workspace_status`: reports whether cloud workspace indexing is explicitly enabled.

Remote code-context tools require an explicit `repoPath` inside `RHEI_MCP_HTTP_REPO_ALLOWLIST`. Leaving that allowlist empty blocks server filesystem reads, which is the safer default for a public beta endpoint. For hosted beta, pair `RHEI_MCP_HTTP_BEARER_TOKENS` with fingerprint-only `RHEI_MCP_HTTP_BEARER_TOKEN_BINDINGS` so the active bearer token is limited to the intended project/repo before status or backend-backed tool calls run; `/status op=auth` reports only the active token fingerprint and binding posture. A hosted MCP endpoint cannot inspect a tester's private laptop checkout; use local stdio `rhei-mcp` when the agent needs local search/read/edit over that checkout.

HTTP product boundary:

- TS `rhei-mcp` streamable HTTP is the product/enterprise HTTP surface. It owns bearer transport auth, repo allowlists, project-scoped service-principal sync, Convex policy checks, cloud workspace consent, and GitHub App/PAT verification through the Rhei backend.
- Rust `rhei-code-intelligence mcp-http` is a local/headless structural SQL surface. Its bearer token is local transport auth only; it has no Rhei auth, GitHub auth, Convex sync, provider, embedding, vector, or cloud workspace authority.
- Local stdio remains the path for agents that need to interact with the developer machine's shell/files/repo checkout. HTTP is the path for controlled remote access where filesystem scope, auth, and policy need to be explicit.

Indexing is prepared but gated by explicit flags. With `RHEI_MCP_INDEXING_ENABLED=false`, remote callers can live-scan/read allowlisted repos but cannot pass `writeLocalIndex=true`. With the flag set to `true`, remote allowlisted calls may build the deterministic local index at `.rhei/code-context/local-index.json`. Cloud source indexing is separate and remains off unless `RHEI_MCP_CLOUD_WORKSPACE_ENABLED=true` and `RHEI_MCP_CLOUD_INDEXING_ENABLED=true` are both set for an explicitly consented project.

Local/cloud sync defaults are intentionally asymmetric: proof metadata and tool/patch receipts sync by default when backend credentials exist, while selected snippets, summaries, embeddings, raw diffs, and cloud workspace indexing are off by default. Local stdio calls can produce HMAC path/content signatures and Merkle roots for proof receipts without uploading raw source, local filesystem paths, raw refs/goals, or raw origin URLs; the full local daemon tool path queues metadata-only tool, PR review, patch, and validation receipts asynchronously when those backend credentials are present. Use `RHEI_MCP_SYNC_SERVICE_KEY` for project-scoped service-principal sync; legacy bearer/apikey sync remains a migration fallback and cannot grant cloud consent. See `../../docs/plans/local-cloud-sync-boundary-2026-05-22.md`.

For dogfooding async receipt sync, call `rhei_sync_status` after a few local tool calls. The response includes `receiptQueue.pendingCount`, enqueue/start/success/failure/retry counters, the last retry/failure reason, and `syncBackend.configured` plus `syncBackend.authMode`. A healthy local loop has `syncBackend.authMode: "service_principal"`, `pendingCount: 0` after the queue drains, and increasing `succeededCount` without persistent `lastFailureReason`.

Do not publish the beta Docker image publicly if the repository source should remain private. The hosted endpoint can be shared with testers through URL plus bearer token; registry/image access is operator-only.

## Public Package Boundary

The npm package is the local runner, MCP client installer, and onboarding/indexing CLI. Treat anything shipped in that package as inspectable by users.

Do ship:

- Local MCP transport and client registration code.
- Local deterministic repo scanning, preflight, smoke checks, and report-only receipts.
- Thin CLI launchers for `mcp-server`, `rhei`, `rhei-mcp`, and `saga-mcp`.

Do not ship in the public package:

- Eval corpora, benchmark repos, calibration reports, or training datasets.
- ML ranking models, model weights, prompts used for proprietary ranking, or service-connection enrichment logic that should remain product IP.
- Hosted backend credentials, API keys, customer data, generated secrets, or local `.env` files.

Premium intelligence should run behind authenticated Rhei APIs with project/user/org authorization and license checks. Offline enterprise intelligence should be distributed as a binary-only commercial package when needed, but that is only a friction boundary; any code or binary running on a customer machine must still be treated as reverse-engineerable.

The bundled package builder runs `tooling/audit-public-package.ts` before packing. That audit fails if the staged tarball contains denied paths such as evals, fixtures, corpora, model weights, source maps, or missing `npx` bin aliases.

The workspace `packages/mcp-server/package.json` is marked `private` to prevent accidental direct publication of the source-build package. Publish only the audited tarball produced under `dist/rhei-mcp-beta/artifacts/`.

## Private Local Beta Package

For a friend who should test local repo search without receiving the monorepo, ship the compiled beta tarball. From `rhei/`:

```bash
bun run mcp:rhei:pack-beta
```

The script writes a private package under:

```text
dist/rhei-mcp-beta/artifacts/rhei-mcp-server-<version>.tgz
```

The package contains a bundled JS MCP server plus bundled JS slices of the Rhei core modules required by the MCP runtime. It does not contain the whole monorepo, but it is still an inspectable local developer tool. Treat the tarball as private beta software, not a source-secrecy boundary.

Friend install smoke:

```bash
mkdir -p /tmp/rhei-mcp-smoke
cd /tmp/rhei-mcp-smoke
npm init -y
npm install /path/to/rhei-mcp-server-1.0.0-beta.0.tgz
./node_modules/.bin/rhei install --target auto --yes
./node_modules/.bin/rhei uninstall --target auto --yes
./node_modules/.bin/rhei-mcp
```

One-shot tarball smoke:

```bash
npx -y --package /path/to/rhei-mcp-server-1.0.0-beta.0.tgz rhei install --target auto --yes
bunx --package /path/to/rhei-mcp-server-1.0.0-beta.0.tgz rhei install --target auto --yes
pnpm dlx --silent --package /path/to/rhei-mcp-server-1.0.0-beta.0.tgz rhei install --target auto --yes
```

Public publish command, once the package boundary is approved:

```bash
npm publish dist/rhei-mcp-beta/artifacts/rhei-mcp-server-<version>.tgz --access public
```

Codex config for the tarball install:

```toml
[mcp_servers.Rhei]
command = "npx"
args = ["-y", "--package", "/path/to/rhei-mcp-server-1.0.0-beta.0.tgz", "rhei", "mcp"]
startup_timeout_sec = 60.0
tool_timeout_sec = 300.0
```

pnpm-backed MCP config for the tarball install:

```toml
[mcp_servers.Rhei]
command = "pnpm"
args = ["dlx", "--silent", "--package", "/path/to/rhei-mcp-server-1.0.0-beta.0.tgz", "rhei", "mcp"]
startup_timeout_sec = 60.0
tool_timeout_sec = 300.0
```

OpenCode config after local install:

```json
{
  "mcp": {
    "rhei": {
      "type": "local",
      "command": ["./node_modules/.bin/rhei-mcp"],
      "enabled": true
    }
  }
}
```

First local-index call from their agent:

```json
{
  "repoPath": "/Users/friend/project",
  "goal": "Map auth/session code and related tests",
  "workflowPresetId": "deep_plan",
  "useLocalIndex": true,
  "writeLocalIndex": true
}
```

This writes `.rhei/code-context/local-index.json` inside their repo. Recommend adding `.rhei/` to their `.gitignore`.

## Codex CLI

The installer can write the Codex MCP entry automatically:

```bash
rhei install --target codex
```

To configure Codex manually, add an MCP server entry like this to `~/.codex/config.toml` when you want Codex CLI to use local Rhei:

```toml
[mcp_servers.Rhei]
command = "bun"
args = ["run", "--silent", "--cwd", "/Users/mibook/saga/rhei", "mcp:rhei"]
startup_timeout_sec = 20.0
```

After restarting Codex CLI, call `status` to verify config, repo access, advertised tools, local mode, and no-live invariants. Full-profile dogfooding sessions may also use the legacy `rhei_code_context_doctor` helper.

If a Codex session was already running before an MCP tool/schema change, restart that Codex session so the client reloads the Rhei MCP tool list. A fresh `bun run --silent mcp:rhei` process will expose the current source immediately, but already-bound clients may keep the old tool schema until restart.

By default, the local server uses `RHEI_MCP_LOCAL_TOOL_PROFILE=public` and advertises the 20-tool generic agent-facing profile. Set `RHEI_MCP_LOCAL_TOOL_PROFILE=full` only for Rhei dogfooding or compatibility debugging, including legacy edit helpers. For measured single-flow sessions, `RHEI_MCP_LOCAL_TOOL_ALLOWLIST` overrides the profile; for example, `RHEI_MCP_LOCAL_TOOL_ALLOWLIST=context_builder,read_file` exposes only the context-builder/read path. `RHEI_MCP_LOCAL_TOOL_ALLOWLIST=*` or `all` exposes every registered tool, but does not make source apply official; the apply leg still requires `RHEI_CODE_SESSION_ENABLE_APPLY_EDITS=1` plus its local-beta/test receipts and root gates.

Codex workflow:

1. First call:

```json
{
  "repoPath": "/Users/mibook/saga/rhei",
  "goal": "Plan the next safe implementation slice.",
  "workflowPresetId": "deep_plan"
}
```

2. Read `agentSurface.prompt` first.
3. Treat `workBrief.contextPlan.exactRefs` as bounded context. Broaden only with an explicit reason.

Use `rhei_code_context_build_work_brief` only when local/web Rhei has already exported a snapshot, or with no args for the deterministic fixture smoke test.

## Implementation Notes

Local mode intentionally exposes the public read-only/report-only profile by default:

- `readOnlyHint: true`, `destructiveHint: false`, `idempotentHint: true`, and `openWorldHint: false` are set on local tools.
- `rhei_code_edits` uses write-capable MCP annotations because its default transaction can include apply when explicitly enabled for tmp/root-allowlisted benchmark fixtures; preview-only and afteredit-only behavior remain read-only.
- Each tool returns both text content and `structuredContent` so clients can display readable JSON while also consuming typed payloads.
- Input validation is done with Zod through the high-level SDK server. The legacy low-level server remains only for credentialed remote compatibility.
- All runtime logs use stderr. Never write diagnostic logs to stdout in stdio MCP servers.

## Remote Compatibility

Legacy remote Saga tools remain available only when API credentials are present:

```bash
RHEI_CONVEX_URL=https://convex.rhei.team RHEI_API_KEY=... bun run --silent mcp:rhei
```

Legacy env aliases such as `SUPABASE_URL`, `SAGA_API_KEY`, and `SAGA_PROJECT_ID` still work for compatibility, but new local agent integrations should use the Rhei Code Context tools above.

## Development Checks

```bash
bun run --filter @rhei/mcp-server typecheck
bun --env-file=.env vitest run convex-tests/codeLayer/localCodeContextForGoal.test.ts convex-tests/codeLayer/codeMarketLocalContextForGoal.test.ts convex-tests/codeLayer/codeContextAgentSurface.test.ts
```
