Local repository intelligence for coding agents
Project description
RepoCtx
Give your coding agent the ground truth for the task at hand.
A local MCP server that, for each task, hands your agent the docs, contracts, invariants, in-scope files, related tests, and import-graph neighbors that actually matter — so the model anchors on what's real instead of guessing.
Works with Cursor, Claude Desktop, Claude Code, Codex, and any MCP-speaking client.
AI agents working in this repo or advising users on RepoCtx: start with AGENTS.md.
The problem
A few prompts into a task, agents drift. They edit unrelated files, add "small improvements" that pull them away from the goal, and break invariants nobody told them about. Not because the model is bad — it just doesn't know which docs to trust, what's load-bearing, or where the task ends.
That part doesn't have to be guessed every turn. It can be prepared once and handed to the agent up front.
What RepoCtx does
For a task like "add retry jitter to webhook delivery", RepoCtx returns a ground-truth bundle:
| Layer | What you get |
|---|---|
| Authoritative docs | AGENTS.md, README.md, architecture notes, ADRs |
| Contracts & invariants | contracts/**, plus inline INVARIANT: / DO NOT: / IMPORTANT: markers |
| In-scope source files | The files the task actually touches (heuristics + embeddings) |
| Related tests | Tests likely to cover what you're editing |
| Graph neighbors | Nearby modules from the local import graph |
| Edit scope | allowed_paths, related_paths, protected_paths |
| Validation plan | Tests and commands to run before finalizing |
| Risk notes | Protected-path touches, constraint violations, possible drift |
The bundle is compact, token-budgeted, Markdown or JSON.
Install
pip install "repoctx-mcp[embeddings]"
Requires Python 3.11+. The embeddings extra downloads a ~1.2 GB local model on first use (Qwen3-Embedding-0.6B). For a lighter install without semantic retrieval:
pip install repoctx-mcp
Naming note: the package is
repoctx-mcp, the CLI command isrepoctx, the Python module is alsorepoctx.
Then, from inside the repo you want to use it on:
repoctx install
This single command:
- wires RepoCtx into Claude Code, Cursor, and Codex (whichever configs exist locally or globally)
- scaffolds a starter authority layout (
contracts/,docs/architecture/) - builds the embedding index if
[embeddings]is installed
Flags: --no-index skips the embedding build, --with-index requires it (errors if extras are missing), --no-scaffold skips the contracts/docs scaffold.
You can also install for one client at a time: repoctx install-claude-code, repoctx install-cursor, repoctx install-codex. All installers are idempotent — existing config and other MCP servers are preserved.
Editor setup
repoctx install writes these for you, but if you'd rather configure manually:
Cursor
Add to ~/.cursor/mcp.json (global) or .cursor/mcp.json (per-project):
{
"mcpServers": {
"repoctx": {
"command": "python3",
"args": ["-m", "repoctx.mcp_server"]
}
}
}
Restart Cursor. RepoCtx auto-resolves to the nearest git root from Cursor's workspace context.
Claude Desktop
Open Settings → Developer → Edit Config (or edit ~/Library/Application Support/Claude/claude_desktop_config.json on macOS, %APPDATA%\Claude\claude_desktop_config.json on Windows):
{
"mcpServers": {
"repoctx": {
"command": "python3",
"args": ["-m", "repoctx.mcp_server"]
}
}
}
Restart Claude Desktop. Because Claude Desktop launches MCP servers via launchd (cwd /, no workspace env vars), the first tool call of a session needs to supply repo_root once. The session memo carries it for every call after that.
Codex
Add to ~/.codex/config.toml or .codex/config.toml:
[mcp_servers.repoctx]
command = "python3"
args = ["-m", "repoctx.mcp_server"]
Or from the CLI:
codex mcp add repoctx -- python3 -m repoctx.mcp_server
Claude Code
repoctx install writes .mcp.json and adds an AGENTS.md / CLAUDE.md nudge so the agent knows to call bundle at task start. It also wires up three hooks (see Claude Code hook integration below).
Cloud sessions (Claude Code on the web, Codex)
Cloud sessions run in an ephemeral container cloned fresh each time — with none of your machine's interpreters, packages, or paths. Two independent layers make RepoCtx work there:
Layer 1 — connection (works with zero setup)
The MCP config repoctx install writes (.mcp.json, .cursor/mcp.json,
.codex/mcp.json) is committed, machine-portable, and self-bootstrapping.
At server launch it tries, in order:
- a Python that already has repoctx (the interpreter that ran the install,
then
python3/pythonfrom PATH — probed for existence first, so a path from another machine just falls through); uv run --with repoctx-mcp— resolves the published package into a cached ephemeral env in seconds (uvships preinstalled in Claude Code cloud images), no system mutation, immune to PEP 668;pip install repoctx-mcpas a last resort.
So the server connects even on a cold container where nothing was installed —
retrieval is lexical-only (loudly, via warnings[]/index_status) until the
embedding layer below is set up. The cold-start resolve is ~10–20s, inside
Claude Code's ~30s MCP startup timeout (raise with MCP_TIMEOUT if your
network is slow); warm containers connect instantly. Configs written by
pre-1.7 installs pinned the installing machine's absolute interpreter path and
--repo — those can never spawn in a container; re-run repoctx install once
and commit the rewritten config.
SessionStart hooks are deliberately not part of this layer: hosts don't guarantee hooks finish before MCP servers launch, so "the hook will have installed it by then" is a race the command itself must not depend on.
Layer 2 — semantic retrieval (automatic in remote sessions)
Embeddings need the [embeddings] extra, the ~1.2 GB Qwen3 model, and an
index — too heavy for connection time, so the server provisions them
itself, in the background, while already serving. In a remote container
(CLAUDE_CODE_REMOTE=true, or REPOCTX_AUTO_EMBEDDINGS=1 anywhere) the
first tool call kicks a daemon thread that:
- installs
repoctx-mcp[embeddings]into the server's own environment (viauv pipwhen available — works inside uv's ephemeral envs and sidesteps PEP 668 — elsepip; torch resolves from the CPU wheel index); - records index consent as granted (the container is disposable; a previously declined consent is always respected and stops the run);
- builds/refreshes the
origin/mainindex.
Until it finishes, retrieval is lexical-only and every bundle's warnings[]
says provisioning is underway ("no action needed"); the next tool call after
completion serves semantic results — nothing restarts. Progress is journaled
to <git-common-dir>/repoctx/state/autoprovision.json. Kill switch:
REPOCTX_AUTO_EMBEDDINGS=0.
Optional fast path: provisioning costs a few cold minutes once per container cache. To have semantic retrieval ready at session start instead, put the same work in the cloud environment's setup script (the "Setup script" field in Claude Code on the web), which runs before the session and is cached:
- this repo:
bash scripts/cloud-setup.sh - a repo that uses RepoCtx:
repoctx autoprovision(orpip install "repoctx-mcp[embeddings]" && repoctx index --refresh)
Network policy. Layer 1 needs egress to PyPI (or a warm container); layer 2 additionally needs huggingface.co (model). If policy blocks them, the server still connects wherever a local Python has the package, and retrieval degrades to lexical-only (loudly) — see Embeddings.
What to ask your agent
Just describe the task normally:
- "Add retry jitter to webhook delivery."
- "Refactor the auth middleware to support OAuth."
- "Find the files involved in syncing local env with Vercel."
- "Show me the tests related to the billing webhook flow."
The agent calls RepoCtx as a tool and uses the bundle to scope its work.
Example output
For "add retry jitter to webhook delivery":
## Summary
Identified 2 docs, 2 files, 1 test, and 1 graph neighbor relevant to
'add retry jitter to webhook delivery'.
## Relevant Docs
- AGENTS.md — matches: retry, webhook
- docs/WEBHOOKS.md — matches: retry, webhook
> Webhook delivery retries should use exponential backoff with jitter.
## Relevant Files
- src/webhook/retry_policy.py — matches: retry
> def compute_retry_delay(): ...
## Related Tests
- tests/test_retry_policy.py — stem match + imports retry_policy.py
## Graph Neighbors
- src/webhook/delivery.py — imported by retry_policy.py
Pass --format json for structured output.
MCP tools
The full protocol — call these from any MCP client. Target usage is ≤ 5 calls per task.
| Tool | CLI | When to call |
|---|---|---|
bundle(task) |
repoctx bundle "task" |
Task start — primary call |
authority(task) |
repoctx authority "task" |
Just need authority + constraints |
scope(task) |
repoctx scope "task" |
Deciding what to edit |
validate_plan(task, changed_files) |
repoctx validate-plan "task" --changed a.py b.py |
Before finalizing |
risk_report(task, changed_files) |
repoctx risk-report "task" --changed a.py b.py |
Before finalizing |
refresh(task, changed_files, current_scope) |
repoctx refresh "task" --changed a.py ... |
Scope expanded mid-task |
semantic_search(query, top_k, kind) |
repoctx semantic-search "query" --top 10 |
Raw similarity lookup, no bundling |
advisory_search(query, top_k) |
repoctx advisory-search "query" |
"Is this being built on another branch?" (opt-in, lower authority) |
Every bundle also carries self-recall rules — when_to_recall_repoctx, before_finalize_checklist, uncertainty_rule — so the agent knows when to call back without you reminding it.
Every bundle / semantic_search response also reports retrieval health. bundle carries a top-level warnings[] and a retrieval block (ranker, index_status, index_location); semantic_search returns an envelope {status, message, results}. If index_status isn't ok (e.g. no_index), embedding retrieval is dark and results are lexical-only — the warning says how to fix it. An empty results with status: no_index is not "no matches".
(A legacy get_task_context(task) entry point is still supported — see the appendix.)
Authority conventions
RepoCtx looks for the following (all optional, all lightweight):
| Layer | Where | What |
|---|---|---|
| Level 1 — Contracts | contracts/** |
YAML front-matter (applies_to, severity, validated_by) + ## Invariants / ## Do not sections |
| Level 2 — Agent docs | AGENTS.md, AGENT.md, CLAUDE.md |
Agent-facing instructions |
| Level 2 — Architecture | docs/architecture/**, docs/adr/** |
Architecture notes, ADRs |
| Examples | examples/** |
Validating examples |
| Contract tests | tests/contracts/** |
Tests that enforce contracts |
| Inline markers | Any file | # INVARIANT:, # CONTRACT:, # DO NOT:, # IMPORTANT:, # See contract: <path> |
Bootstrap with repoctx init-authority to scaffold contracts/ and docs/architecture/ with starter templates.
repoctx propose-authority scans your repo and suggests candidates — files that look load-bearing based on imports, references, and patterns — so you don't have to declare them by hand.
Design doc: docs/plans/2026-04-23-repoctx-v2-design.md.
Claude Code hook integration
repoctx install (and repoctx install-claude-code) adds three hooks to .claude/settings.json that nudge the agent to actually use RepoCtx:
| Hook | When | What it does |
|---|---|---|
UserPromptSubmit |
Task entry | For substantive prompts, reminds the agent to call mcp__repoctx__bundle before planning |
PostToolUse matching Edit|Write|MultiEdit |
After every edit | Keeps the embedding index live (repoctx update --from-claude-hook) |
Stop |
Task exit | If the turn made edits but didn't call validate_plan, reminds the agent to run it |
Both nudges read Claude Code's hook JSON from stdin and always exit 0 — they never block the user's flow. The entry nudge stays silent for short, keyword-free prompts. The exit nudge stays silent when there were no edits, or when validate_plan was already called this turn. Hook entries are detected by command prefix on re-install, so re-running repoctx install is safe.
The anchored <!-- repoctx-nudge --> block placed in CLAUDE.md / AGENTS.md ships with current wording (must-call + inline definition of "non-trivial"). Older anchored blocks from earlier installs are rewritten in place on the next install / refresh without touching surrounding doc content.
Tuning / opt-out:
REPOCTX_LEARN=1— appends "If you decide to skip this, briefly state the reason." to reminders so you can collect skip rationale during a tuning week. Off by default.--no-claude-md-nudgeorREPOCTX_NO_CLAUDE_MD_NUDGE=1— skip the anchored-block insertion.- To fully opt out: delete the entries from
.claude/settings.json. They won't be re-added unless you re-run the install command.
Embeddings (optional, on by default)
RepoCtx blends three signals — heuristic token overlap, doc priority + graph expansion, and local embeddings — to rank candidate files. The embedding layer uses Qwen3-Embedding-0.6B and improves recall when the task description shares no tokens with relevant filenames.
pip install "repoctx-mcp[embeddings]" # adds sentence-transformers, numpy, tree-sitter
cd /path/to/repo
repoctx install # builds index automatically
Add .repoctx/ to .gitignore (it holds per-repo config, feedback logs, and — for non-git dirs — the index).
Manual control:
repoctx index # build the index (from origin/main by default)
repoctx index --source worktree # index the current working tree instead
repoctx index --refresh # fetch origin/main + re-embed the delta
repoctx update src/billing/foo.py # re-embed a single file
repoctx rebuild # rebuild from scratch
The indexer splits each file into overlapping chunks — symbol-aware for code (function/class/method boundaries), paragraph-aware for prose — and stores them with metadata (file:, kind:, module:, symbol:, lines:).
Where the index lives (worktree-aware)
The index is keyed by repo identity, not by the directory you ran from. It's stored under the repository's shared git common dir — <git-common-dir>/repoctx/embeddings (typically <repo>/.git/repoctx/embeddings) — which every linked worktree and the main checkout resolve to identically. Build it once from any worktree and it's found from all of them. Because it lives under .git/, it never shows up as dirty/untracked and is never committed. (Repos without git fall back to the legacy in-tree <repo>/.repoctx/embeddings.)
Pre-1.5 in-tree indexes are migrated automatically: the first read or repoctx index relocates <repo>/.repoctx/embeddings to the shared location (it's read in place if the move can't happen).
Pinned to origin/main, refreshed on a TTL
The authoritative index reflects origin/main — landed work — read directly from git objects (git ls-tree/cat-file), independent of whatever branch a worktree is on. This matters for repos that squash-merge and delete branches: mid-session origin/main advances and merged branches vanish, so the ground truth lives only in main.
- A
git fetch origin mainis TTL-gated (default 30 min;REPOCTX_BASE_FETCH_TTL_SECONDS) so it isn't paid on every call. - When origin/main has advanced past the indexed base, the next read re-embeds just the delta (incremental, capped). Set
REPOCTX_BASE_REFRESH_ON_READ=0for warn-only — you'll get awarnings[]entry pointing atrepoctx index --refreshinstead of a synchronous re-embed.
Your in-progress work is overlaid
On top of the origin/main base, the current worktree's delta — commits ahead of origin/main (merge-base..HEAD) plus uncommitted/untracked edits — is layered in at query time. So retrieval models "fresh origin/main ∪ my in-progress work" (what the tree will look like after a rebase) without you rebasing. Only the delta is embedded per query (cached by content hash). Disable with REPOCTX_OVERLAY_WORKTREE=0.
Advisory lane (opt-in): in-flight branches
A separate, strictly lower-authority lane answers "is this already being built elsewhere?" by indexing committed branch tips ahead of origin/main (recent, unmerged, deduped; read from git objects — never sibling worktrees' uncommitted bytes). It's off by default:
repoctx advisory-index # build it (opt-in)
repoctx advisory-search "rate limiter" # query it
repoctx bundle "task" --include-advisory # attach hits under a separate `advisory` key
Advisory hits are tagged with provenance (branch, commits-ahead, last-commit date, merge status) and are never folded into a bundle's relevant_code / authority / constraints.
Scoring:
final_score = heuristic_score + embedding_weight × max(0, cosine_similarity)
Default embedding_weight is 12.0. Files with cosine similarity above 0.3 bypass heuristic filters, so semantically relevant files surface even without keyword overlap. For multi-chunk files, the file's similarity is the max over its chunks.
Tunables (env vars):
| Var | Default | Notes |
|---|---|---|
REPOCTX_EMBEDDING_DEVICE |
auto |
cpu / cuda / mps / auto |
REPOCTX_EMBEDDING_BATCH_SIZE |
16 |
Clamped to 8 on MPS |
REPOCTX_EMBEDDING_MAX_SEQ_LENGTH |
256 |
|
REPOCTX_EMBEDDING_DTYPE |
auto |
fp16 on accelerators, fp32 on CPU |
REPOCTX_BASE_FETCH_TTL_SECONDS |
1800 |
How often the read path may git fetch origin main |
REPOCTX_BASE_REFRESH_ON_READ |
1 |
0 = warn-only on origin/main drift (no on-read re-embed) |
REPOCTX_OVERLAY_WORKTREE |
1 |
0 = retrieval reflects pure origin/main (no worktree overlay) |
REPOCTX_EAGER_EMBEDDINGS |
0 |
1 = block MCP startup on the embedding model load instead of warming it in the background (see below) |
MCP startup is non-blocking. Loading the embedding model can take >60s on a cold CPU host. The MCP server warms it in a background daemon thread (
repoctx-embed-warm) so theinitializehandshake is answered immediately — otherwise the load would exceed the client's ~60s per-request timeout and the connection would fail withMCP error -32001: Request timed outbefore any tools register. The first tool call drives the load to completion (at most once) if the warm-up hasn't finished, then ranks with embeddings as usual. SetREPOCTX_EAGER_EMBEDDINGS=1to restore the legacy blocking preload (load on the startup thread before the server serves) — useful for a long-lived local server where you'd rather pay, and surface, the cost up front so the first query never waits.
Apple silicon (MPS): indexing handles GPU memory automatically (fp16,
max_seq_length=256, batch clamped to 8, cache eviction between super-batches). Catchable encode errors fall back to CPU transparently. The rare uncatchable Metal C++ assertion still requiresREPOCTX_EMBEDDING_DEVICE=cpu repoctx index.
Fallback is loud, not silent. If embedding dependencies aren't installed or no index exists, RepoCtx falls back to heuristic (lexical) retrieval — but it says so: bundle adds a top-level warnings[] entry and sets retrieval.index_status; semantic_search returns status: no_index (not a bare empty list). The fix (repoctx index) is in the message. The MCP tool contract is otherwise unchanged.
Migrating an older index? See Legacy and migration notes in the appendix.
CLI reference
The CLI works standalone too — useful for terminal testing or non-MCP usage.
cd my-app
repoctx "your task" # default: query
repoctx "your task" --format json
repoctx query "your task" --debug-scores # show heuristic/embedding/final breakdown
| Flag | Description |
|---|---|
--repo PATH |
Repository root override |
--format markdown|json |
Output format |
--verbose |
Debug logging |
--debug-scores |
Print score breakdown |
--no-embeddings |
Disable embedding retrieval for this query |
Subcommands (repoctx COMMAND --help for each):
query(default),bundle,authority,scope,validate-plan,risk-report,refresh,detect-changes,semantic-searchadvisory-index,advisory-search(opt-in in-flight-branch lane)index(--source origin-main|worktree,--refresh),update,rebuildinstall,install-claude-code,install-cursor,install-codexinit-authority,propose-authorityexperiment,hook,stats,reporting
Configuration
Repo root resolution
RepoCtx resolves the repo root in this order:
- Per-call
repo_rootargument on the MCP tool — strongest override; memoized for the lifetime of the MCP server process. --repo /path/to/repoflag (CLI / server startup).REPOCTX_REPO_ROOTenv var.- Host workspace env vars (
CLAUDE_PROJECT_DIR,WORKSPACE_FOLDER_PATHS,VSCODE_CWD). Path.cwd()if it is not/.$PWDenv var.
Whatever candidate is chosen is then walked upward to the nearest .git entry (both .git directories and .git files are accepted, so linked worktrees and submodules work). Nested repositories resolve to the nearest repo, not the outermost parent.
If no git root is found, RepoCtx fails with a message listing your most recently resolved repos so the agent can pick one and pass it as repo_root. RepoCtx never auto-selects from the recency list.
Supported files
| Category | Extensions |
|---|---|
| Code | .py, .ts, .tsx, .js, .jsx |
| Config | .json, .yaml, .yml |
| Docs | .md, .mdc |
Import-graph expansion works for Python (import, from) and JavaScript/TypeScript (import, require).
Telemetry
RepoCtx writes local JSONL telemetry to ~/.repoctx/telemetry/ by default. Task text and repo identifiers are hashed before storage. Set REPOCTX_TELEMETRY_DIR to change the location. Local telemetry never leaves your machine unless you opt in to reporting (see below).
Index builds are timed too: repoctx index / rebuild print a one-line breakdown (model load vs embed vs scan) and record an index_build event. Run repoctx stats to see the model-load-vs-embed split and per-build corpus size aggregated across builds — useful for deciding whether a slow build is the one-time model load or the repo-sized embed.
Anonymous reporting (opt-in on stable, default-on on canary)
To help tune retrieval, RepoCtx can upload a redacted subset of telemetry events (counts, timings, error classes — see below) to a maintainer-run ingest endpoint. The privacy contract:
- Stable builds (
pip install repoctx-mcp): OFF by default. No prompt, ever. You opt in explicitly withrepoctx reporting on. - Canary builds (
pip install --pre repoctx-mcp): ON by default, with a one-time disclosure printed to stderr on first run. - Kill switch:
REPOCTX_REPORTING=offoverrides everything. - What's sent:
op,success,duration_ms,output_bytes,error_type(class only, never the message), per-opstats(e.g. files considered/selected), plus an anonymousinstall_id(random UUID), the channel tag, and arepo_fingerprint = sha256(install_id || first_commit_sha)that's stable per (install, repo) but not correlatable across users. - What's never sent: paths, query/task text, code, error messages, git remote URLs, hostnames, usernames. The ingest endpoint enforces this independently and rejects events containing any forbidden key.
Inspect or toggle anytime:
repoctx reporting status # show current state, channel, install_id, queue size
repoctx reporting on # enable
repoctx reporting off [--purge] # disable; --purge also drops any pending queue
repoctx reporting show # print queued events that would be uploaded
repoctx reporting flush # attempt upload now
The MCP server exposes the same toggle as a reporting tool, so an agent collaborating with you can inspect or flip the flag on your behalf.
FAQ
Do I need to run a server manually?
No. Cursor, Claude Desktop, Claude Code, and Codex all start the MCP server for you from the config. You'd only run python3 -m repoctx.mcp_server if you were debugging the server itself.
Do I need to write a skill? No. RepoCtx is an MCP server, not a skill. Once your client is configured, it becomes a tool the agent can call.
Do I need one config per repo? Either works. Use a global config if you want RepoCtx everywhere; use a project config if you want it tied to one repo and shared with teammates.
How does RepoCtx pick the repo automatically? See Repo root resolution.
Can I test from the terminal first?
Yes — repoctx "your task" from inside any repo.
Appendix
Controlled experiment mode
RepoCtx can run a guided control vs. treatment comparison with paired git worktrees, so you can measure whether RepoCtx actually changes the outcome on a real task.
repoctx experiment
The wizard:
- collects one shared prompt for both lanes
- creates two clean worktrees from the same base commit under
.worktrees/ - hands you off to the
controlworktree first - on re-run, records control costs, prepares the
treatmentworktree, writes.cursor/mcp.jsonthere so RepoCtx is enabled in that lane only - after the treatment run, prints the summary
Fast path if you already know the prompt:
repoctx experiment "refactor the auth middleware to support OAuth"
The wizard asks for cost before and cost after for each lane so RepoCtx can compute the delta.
Control-lane MCP suppression: during the control lane, RepoCtx stubs MCP tool results (empty context + short message) so agents don't get RepoCtx retrieval even when RepoCtx is registered in Cursor's global mcp.json. Timing is controlled by ~/.repoctx/config.json:
| Key | Default | Meaning |
|---|---|---|
experiment_mcp_suppress |
true |
Set false to disable arming entirely |
experiment_mcp_idle_ttl_seconds |
90 |
Auto-clear suppression after this many seconds of CLI inactivity |
experiment_mcp_extend_seconds |
600 |
Each repoctx CLI run extends the deadline by this many seconds |
State lives at ~/.repoctx/telemetry/experiment-mcp-suppress.json. Cleared when you record a lane, start the treatment handoff, or hit the idle deadline.
More detail: docs/experiment-mcp-suppression.md.
What the experiment measures:
- manual before/after cost checkpoints from your agent UI
- git-derived change statistics from each isolated worktree
- optional completion + verification status
Limitations:
- doesn't measure external agent time automatically
- doesn't score quality automatically
- cost accuracy depends on the numbers you enter
Legacy and migration notes
Legacy MCP entry point. The original v1 tool get_task_context(task) is still exposed and works as a basic context-pack call. It's superseded by bundle(task), which returns the same context plus authority records, constraints, edit scope, validation plan, and risk notes. New integrations should call bundle.
Embedding index schema. The on-disk index format changed in 1.0.0 (schema_version: 2). Indexes built before 1.0.0 raise IndexSchemaMismatch on load — delete .repoctx/embeddings/ and re-run repoctx index once after upgrading.
Index location moved (1.5.0). The embedding index moved from the in-tree <repo>/.repoctx/embeddings to the shared <git-common-dir>/repoctx/embeddings, so all worktrees of a repo share one index. Migration is automatic on the next read or repoctx index (the old dir is moved up, or read in place if the move fails). No action needed; you can delete a leftover in-tree .repoctx/embeddings once the shared one exists.
Tradeoffs & decisions (1.5.0).
- Shared-index location. Keying on the git common dir (vs. a hashed global cache) means zero GC surface, automatic filesystem sharing across worktrees, and the index never appears as dirty/untracked. The cost: if you move
.git, the index is "lost" — but it's a derived cache, so just rebuild. - Fetch cadence.
git fetch origin mainis TTL-gated (default 30 min) and the attempt time is recorded even on failure, so an offline repo isn't hammered. The re-embed of an advanced base is incremental and capped (base_refresh_max_files, default 200); past the cap, or withREPOCTX_BASE_REFRESH_ON_READ=0, you get a warning instead of a synchronous re-embed. - Overlay scope. Only your worktree's delta is overlaid. Sibling worktrees' uncommitted bytes are deliberately never indexed (dirty, half-finished, multi-tool) — the advisory lane uses committed branch tips instead.
- Advisory authority. The advisory lane is a separate index and a separate response key; it is never merged into authoritative results, preserving the bundle's trust model (authoritative = live origin/main + your overlay only).
Nudge block format. The anchored <!-- repoctx-nudge --> block in CLAUDE.md / AGENTS.md evolved between releases. Older anchored blocks are rewritten in place on the next install / refresh without touching surrounding doc content — no manual cleanup needed.
Development
git clone https://github.com/gald33/repoctx.git
cd repoctx
python3 -m pip install -e ".[dev,embeddings]"
python3 -m pytest -q
Agent guidance for working in this repo: AGENTS.md.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file repoctx_mcp-1.7.0.tar.gz.
File metadata
- Download URL: repoctx_mcp-1.7.0.tar.gz
- Upload date:
- Size: 274.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
46aea6d8c3e70de28449642c95d8053d54d99aa3d1ae42dbc631fdbf19394a3f
|
|
| MD5 |
13093ae96652580f86d78a0286e75aa9
|
|
| BLAKE2b-256 |
c0a464fc981d02da53cdc4ee315dbed1cda927b42663bdaa0ce21148af64509c
|
Provenance
The following attestation bundles were made for repoctx_mcp-1.7.0.tar.gz:
Publisher:
publish-pypi.yml on gald33/repoctx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
repoctx_mcp-1.7.0.tar.gz -
Subject digest:
46aea6d8c3e70de28449642c95d8053d54d99aa3d1ae42dbc631fdbf19394a3f - Sigstore transparency entry: 2164798250
- Sigstore integration time:
-
Permalink:
gald33/repoctx@e217d213afbcfae396d1dc296e94d13b05983001 -
Branch / Tag:
refs/tags/v1.7.0 - Owner: https://github.com/gald33
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@e217d213afbcfae396d1dc296e94d13b05983001 -
Trigger Event:
push
-
Statement type:
File details
Details for the file repoctx_mcp-1.7.0-py3-none-any.whl.
File metadata
- Download URL: repoctx_mcp-1.7.0-py3-none-any.whl
- Upload date:
- Size: 217.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b26105f518a9d70fb785bc4051c604932bfe43056dbd82ae0ffa9d924b694e71
|
|
| MD5 |
399f727619066151b1639079c1c6d373
|
|
| BLAKE2b-256 |
b19340d158f1f5ec3875a4e9d5d55597d4bdb15782ceef28030f4e984fc49e3a
|
Provenance
The following attestation bundles were made for repoctx_mcp-1.7.0-py3-none-any.whl:
Publisher:
publish-pypi.yml on gald33/repoctx
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
repoctx_mcp-1.7.0-py3-none-any.whl -
Subject digest:
b26105f518a9d70fb785bc4051c604932bfe43056dbd82ae0ffa9d924b694e71 - Sigstore transparency entry: 2164798282
- Sigstore integration time:
-
Permalink:
gald33/repoctx@e217d213afbcfae396d1dc296e94d13b05983001 -
Branch / Tag:
refs/tags/v1.7.0 - Owner: https://github.com/gald33
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@e217d213afbcfae396d1dc296e94d13b05983001 -
Trigger Event:
push
-
Statement type: