Orleans.Lattice.Api.Mcp.RepoContext
This page documents Orleans.Lattice.Api.Mcp.RepoContext, which is unreleased, in the documentation for Orleans.Lattice 9.9.0 (release line 9.9), built 2026-10-04. It is also published as markdown, with every table and list, at README.md, and llms.txt lists every page.Optional, opt-in repository-context add-on for the Orleans.Lattice.Api.Mcp server. It gives an AI agent a durable, conflict-free place to capture and maintain detailed context about a codebase - structural facts, notes, and short-lived working memory - served as Model Context Protocol tools over dedicated Lattice trees.
What is it?
The repository-context module plugs into the Orleans.Lattice.Api.Mcp binding's permission-aware discovery core and contributes a group of repocontext_* tools:
- Onboarding.
repocontext_bootstrapwalks a repository and lands a structural node plus a content digest for every file on a durable tree, so an agent starts from a populated, queryable baseline instead of empty memory. Re-runs are incremental, idempotent, and resumable, and because a pass runs in the background,repocontext_index_statusreports its progress until it completes. In the container's workspace mode this onboarding is driven per-repository byrepocontext_add_repoandrepocontext_remove_repo, withrepocontext_list_reposenumerating what is registered andrepocontext_reset_indexdropping a wedged code index without discarding the repository's memory, ready for a followingrepocontext_add_repoto rebuild it. - Working memory.
repocontext_remember,repocontext_update, andrepocontext_forgetcapture agent-authored notes and decisions under topics, with an optional per-entry time-to-live for memory that lapses on its own.repocontext_neighborswalks the typed knowledge-linking edges out of an entry - outbound only - and reports which linked targets have drifted or no longer exist. - Retrieval.
repocontext_recall,repocontext_scan, andrepocontext_list_topicsread the context back;repocontext_searchadds meaning-based retrieval when an embedding provider is bound, degrading fail-closed to a deterministic keyword scan when it is not. The keyword scan ranks over file content (via a per-file content projection), not just filenames and identifiers, so it stays useful even with no embedder bound. Every search hit carries a deterministicreasonslist explaining why it ranked. - Graph navigation.
repocontext_outlinereturns a file's declared-symbol skeleton without reading its body,repocontext_relatedresolves a file's structural neighbourhood (references, dependents, and covering tests) from a reverse cross-reference projection, andrepocontext_changedreports how the workspace has drifted from the index and the blast radius of those edits. The first two are bounded reads over stored records that never touch the workspace;repocontext_changedwalks the repository's indexed path space through the fail-closed workspace boundary, settling each unchanged file by a stat rather than a re-read. - Exclusive claims.
repocontext_claim,repocontext_renew_claim,repocontext_release_claim, andrepocontext_claim_statustake a leased, fenced claim over a single memory record, so several agents can drain one shared work queue without colliding. The lease bounds a crashed holder and the monotonic fencing token is enforced on every subsequent write, so a superseded holder is refused rather than trusted. See The agent-operated backlog. - Token economics.
repocontext_contextpacks a ranked, explained bundle of source for a task under a hard token ceiling in one call, with reuse economics so an agent never pays twice for context it already holds;repocontext_statsreports aggregate token savings over a bounded recent window. See Retrieval and token economics. - Health.
repocontext_healthproves the surface is registered and reachable for the authenticated caller, and reports whether retrieval can actually serve.availablecovers reachability only;retrievalReady/retrievalPhasecover whether searches are trustworthy. WithoutrepoIdthese read the same host-wide vector-plane readiness signal that the container's HTTP/health/readyfolds in. SupplyrepoIdfor the passive repository verdict: its blocker and component evidence are resolved for that repository, not inferred from another repository or from metrics.
Every record is stored as a CRDT value on a named Lattice tree, so concurrent updates converge without locks, and the whole store inherits Lattice's durability, TTL, and tombstone-compaction behaviour. Nothing here introduces a new storage or expiry mechanism - it composes the core.
Fail-closed and permission-scoped
The module adds no authorization path of its own. The permission-aware discovery core advertises its tools only to a caller holding one of the data-plane operations that makes the built-in data group usable, and the fail-closed gate enforces the verdict at both advertisement and invocation. The mutating tools (bootstrap, remember, update, forget, the claim trio claim, renew_claim, release_claim, and in workspace mode add_repo, remove_repo, and reset_index) are contributed only when the host opts writes in via AddRepoContextTools(enableWrites: true), and each is offered only to a caller whose grant includes a write-shaped data-plane operation; a reader-only caller never sees them. repocontext_claim_status is a read and is always contributed.
The write opt-in is not on its own enough for the two onboarding tools. repocontext_bootstrap and repocontext_add_repo both take the working tree to walk from the wire, so they are contributed only when a workspace root is passed as workspaceRoot, and at invocation they run only when the effective path guard is enforcing. Without one the guard admits every absolute path on the host, which would let any caller holding a write grant have the server index a directory it never should have read and then hand the contents back through repocontext_context and repocontext_search. Everything else the write opt-in contributes keys on a repository id rather than a path and is unaffected.
The rule is about paths, not writes, so the read-only repocontext_changed is bound by it too. It also takes the directory to walk from the wire, and it answers with the name of every file it walked, so under an inert guard it is an arbitrary-local-read primitive that needs no write grant at all to reach. It is therefore contributed only when a workspace root is configured, and refuses at invocation as well: a repository with no persisted onboarding request has no walk root to contain the caller's path against, and is refused rather than walked from the caller's own path. The other two graph verbs, repocontext_outline and repocontext_related, project stored records and never touch disk, so neither is affected.
Quick Start
Register the module as a companion to AddLatticeMcp:
using Orleans.Lattice.Api.Mcp.RepoContext;
using Microsoft.Extensions.DependencyInjection;
var services = new ServiceCollection();
services.AddLatticeMcp(o => o.RequireAuthorization = true);
// The workspace root bounds every path a caller can ask the server to index
// or walk. Omit it and the path-taking tools (onboarding, and the read-only
// repocontext_changed) are withheld; the capture, claim, and record-projecting
// retrieval tools still work.
services.AddRepoContextTools(enableWrites: true, workspaceRoot: "/workspace");
The host must also map the MCP endpoint (app.MapLatticeMcp()) and, for repocontext_search to run a semantic query, bind an IEmbeddingProvider (for example the package's own Onyx provider, registered by AddOnyxEmbeddingProvider, which targets the separate embedding companion container). Without one, search still answers by keyword.
For a ready-to-run, restart-durable local deployment - "codebase memory in a box" - see the container quickstart and the container sample.
As an installable app (opt-in)
RepoContext is the pilot installable app. Passing registerAsApp: true to AddRepoContextTools additionally registers it as the app repo-context; it defaults to false, in which case nothing changes - the repocontext_* tool group, its advertised tools and the lattice_capabilities report are exactly as before.
When the flag is on, the package registers its embedded manifest with the in-image app source (making the app installable, not installed), adds the app MCP surface, and contributes the group's always-on read-only tools to it, so an installed and enabled app advertises them as repo-context_{tool} alongside - never instead of - the group tools. Write and path-taking tools stay group-only, because they depend on the host's enableWrites, workspaceMode and workspace-root opt-ins, which a fixed manifest cannot follow. The host remains responsible for AddLatticeApps, and for an MCP authorizer that admits the namespaced names.
The manifest declares every RepoContext tree under an app-local name that adopts the existing physical tree (repo-context-structural, repo-context-memory, and so on), so no data moves. Adopted trees are never granted structurally: an operator installing the app must approve each of them as an exception scope in the install ceiling, and uninstalling the app never deletes them. While the repo-context app is installed it exclusively owns those trees: no other app install in the tenant can adopt them, and no alias can point another tree at them. Uninstalling releases them. The manifest marks the derived vector trees (membership, metadata, index and coverage) rebuildable and declares every other tree, including the vector payload tree, not rebuildable. The flag is descriptive metadata: the apps control API's describe (ILatticeAppsControl.DescribeAsync) reports it as AppTreeDescriptor.Rebuildable, and no backup or restore path in this version acts on it, so it does not select between restoring a tree and re-deriving it. It declares two roles, reader (Read, RangeRead) and curator (adding Write, Delete, RangeDelete), over every tree. A regression test asserts the manifest's trees and rebuildable flags agree with the package's tree constants, so renaming a tree without updating the manifest fails CI.
Reference
- Architecture - a map of the constituent parts, the ingest, retrieval, and convergence flows, and the store-of-record versus rebuildable-projection distinction the design rests on.
- Record model - the named trees, the key grammar, the record families, and the CRDT store-of-record model.
- Tools - the full
repocontext_*tool catalogue and each tool's contract. - Retrieval and token economics - explainable search, the graph-navigation tools, the budgeted context bundle, reuse economics, usage accounting, and the shared token counter.
- Memory and TTL - agent memory, topics, and per-repository time-to-live policy.
- Memory durability - what survives destroying a deployment's state, why memory and the index cannot be split across volumes, and the memory archive that makes
docker compose down -vsurvivable. - The agent-operated backlog - leased, fenced claims over memory records, and the backlog they make safe for concurrent agent workers.
- Semantic search - the embedding seam, the approximate index (the default) and the exact scan with its warm vector cache, keyword search over file content, and fail-closed degradation.
- Container quickstart - running the module as a single durable local container.
- Local deployment runbook - operating a long-lived tuned local deployment: the build-and-tag ladder, the pin and rollback procedure, every setting the tracked compose files resolve to and the measurement behind it, the host-cores-versus-cgroup pool-sizing class, and recovering the deployment from nothing.
- Acceptance measures - the tracked register of the acceptance measures a reliability run scores, each pinned to the instrument arm it reads and to a ceiling derived from the constants in source, so a measure cannot be dropped between runs without the deletion appearing in a diff.
Related package docs:
- MCP Server - the host binding, credential bridge, and authorization gate this module composes.
- File WAL storage - the cloud-free durable WAL backend the local container uses.
- Multi-cluster replication - the opt-in
Orleans.Lattice.Api.Mcp.RepoContext.Replicationcompanion that enrols the replicated repository-context trees under their required merge modes.