repotector

repotector

Enables AI agents to handshake with a repository, providing them with a map, standing decisions, and prior visit briefings so they can continue work without re-deriving the context. It also guards against regressions with a grandfathered baseline and maintains a visitor ledger and journal.

Category
Visit Server

README

Repotector ⬡

The repo that remembers.

Every AI agent that visits your repo starts from zero: it re-derives the map, re-discovers the conventions, re-breaks the thing the last agent just fixed. Repotector gives the repo itself a memory. An arriving agent knocks at the front door, handshakes, and is handed the map, the standing decisions, and the last visitor's briefing; on the way out it signs the register. The next agent continues in two minutes instead of wandering for an hour — and a refactor doesn't quietly break what already works.

Portable and self-contained: pure Node ESM, two dependencies (@modelcontextprotocol/sdk, zod). Works on any repo — JS/TS deeply, other stacks in honest orientation-lite.

Install into any repo

cd /path/to/your/repo
npx repotector init

init scans the repo (never fails you on day one — see grandfathered baseline below), wires the MCP server into .mcp.json, and writes the doorway blocks so every arriving agent knows to handshake. It writes only inside .repotector/ and inside REPOTECTOR:BEGIN/END markers — your prose and config are never overwritten. See SECURITY.md for the exact posture.

Under .repotector/:

File What it is
intent.json The contract: standards, required paths, bounded contexts, canon rules.
atlas.json The map: exports/imports/purpose/kind per file, routes, components, stack, and a deterministic fingerprint.
dna.json Reverse-engineered entities + API contracts + intent.
baseline.json The grandfathered floor — the debt that existed on day one.
proof.json Gate verdict, regressions vs grandfathered debt.
register.jsonl The visitor ledger: who entered, when, what they touched, who's inside.
dna.inferred.json Reverse-DNA clauses for foreign repos (skipped when a .psx/ mirror exists).

Plus, at the repo root, a regenerated JOURNAL.md — the diario di bordo, newest-first, that handshake serves the tail of so the next agent continues prior work instead of re-deriving it.

The front door (handshake-first)

The MCP server refuses deep tools until an agent calls handshake — and the initialize response already tells the agent to. In return the agent gets oriented in one call, and its exit is recorded for the next one.

  • handshake({ who, model?, purpose? }) — orientation, ground rules, live gate verdict, map freshness, passport. Read-only and fast (no tree walk).
  • city_map() — intent, stack, built-vs-missing, brain pointers. On a non-JS repo it says orientation-lite instead of faking an empty map.
  • find_existing({ intent }) — REUSE: does it already exist? Don't rebuild.
  • blast_radius({ changedFiles? }) — PROTECT: transitive dependents + impacted routes/components. Omit changedFiles to use the git diff.
  • canon_check({ changedFiles? }) — INTEGRATE: the repo's canon rules.
  • atlas_query({ query }) — keyword search across the map.
  • quality_gates() — line-budget / structure / secret-hygiene, reported as regressions vs grandfathered debt.
  • register() — who's inside now and the full crossing log.
  • journal({ limit? }) — the repo's recent story: what prior agents did and left unfinished. whats_next() — the sensible next work, derived from DNA gaps + open threads + TODOs, every suggestion citing its evidence.
  • dna_query({ clause?, topic? }) — what the repo specified (authored from a .psx/ mirror, or inferred, never merged). dna_coverage() — per clause: implemented / partial / missing. dna_diff({ changedFiles? }) — which clauses a change touches.
  • depart({ summary? }) — sign out; the git delta of your visit is recorded even if you forget the summary. Your summary becomes the next agent's briefing.

Grandfathered baseline — never red on day one

A guardian that fails your repo the moment you install it gets uninstalled the moment you install it. So init snapshots the debt that already exists (oversize files, tracked secrets, missing paths). Gates then fail only on regressions against that floor — a new offender, an offender that grew, a new leak. Pre-existing debt is reported loudly, never blocking. repotector baseline re-snapshots after you pay it down.

v1.2 "Gatekeeper" — from advisor to checkpoint

  • Commit guardrepotector hooks installs a pre-commit that runs the gates; gates exits non-zero on regressions, so hooks and CI actually block. Grandfathered baseline means it never blocks day-one debt — only new damage.
  • Protected pathsintent.protect.paths globs (CI workflows, LICENSE…) that agents must not touch: change-based, never grandfathered, overridden only by editing the intent (an explicit, diffable act).
  • Claimsclaim({ paths }) declares your work zone; overlapping claims from live sessions answer granted:false with who/why. Advisory by design (blocking would be theater on a filesystem we don't control); claims die with the session.
  • Decision recordsdepart({ decisions: [{ chose, over, because }] }) writes the why to the register and projects DECISIONS.md; the handshake serves standing decisions and decisions_query answers "was this deliberate?" — so agent 2 doesn't undo agent 1's choice.
  • repotector doctor — one command, semaphore answer to "how protected is this repo, really?", with a fix for every red.

v1.5 "Mission" — the single verifiable chain

The whole visit becomes one auditable contract:

handshake → declare_mission → (auto)claim → work
        → off-claim / forbidden reconciliation
        → evidence pack (machine-verified vs agent-declared)
        → depart → the next agent inherits it all
  • declare_mission({ goal, acceptance, claimPaths?, forbiddenPaths?, risk? }) — bind the visit to a contract: your zone is auto-claimed (conflicts surfaced), and you get a one-shot briefing (gates, merge status, standing decisions, protected paths).
  • Evidence pack at depart — the register records what the MACHINE verified (gates verdict, trial-merge clean/conflicted, files touched, off-claim, forbidden violations) strictly apart from what the AGENT declared (per-criterion self-report); unreported criteria are listed, never assumed. "Done" becomes something the register can check, not a courtesy.
  • Other agents see missions in progress at handshake — what you're doing, not just where.

v1.3 "Merge Guard" — commit without colliding

  • merge_check — a zero-damage TRIAL merge (git merge-tree) of HEAD against the integration base, run BEFORE you commit: reports clean/conflicted with the exact files, each attributed to who holds that zone (live claims — and, in PSX Workbench repos, the Merge Machine's leases via the .psx mirror). CLI: repotector merge-check [target] (exit 1 on conflicts, so hooks/CI can gate on it). Zero network: it trial-merges against your LOCAL refs and says so — fetch first for the freshest truth.

Resilient register — agents die without signing out

Sessions that enter and never leave (the agent was killed, the pipe closed) are auto-departed on the next handshake, with the git delta of what they touched. The ledger never fills with immortal open sessions, and a depart carries real work even when nobody called it.

CLI

npx repotector init          # scan, wire .mcp.json, write the doors — day-one green
npx repotector refresh       # re-derive the map + re-stamp the doorway blocks
npx repotector handshake     # orientation + live gate + passport (logged visit)
npx repotector city-map      # built-vs-missing + brain pointers
npx repotector dna-coverage  # per specified clause: implemented / missing
npx repotector whats-next    # the sensible next work, with evidence
npx repotector journal       # the diario di bordo (regenerates JOURNAL.md)
npx repotector gates         # regressions vs grandfathered debt
npx repotector baseline      # re-snapshot the grandfathered floor
npx repotector register      # the visitor ledger
npx repotector lock <pass>   # optional passphrase gate on the deep map
npx repotector mcp           # start the stdio MCP server

Docker

The image on GHCR wraps the CLI and the MCP server; the guarded repo is mounted, never baked in:

docker run --rm -v "$PWD:/repo" ghcr.io/dir-ai/repotector init
docker run --rm -v "$PWD:/repo" ghcr.io/dir-ai/repotector gates
docker run -i --rm -v "$PWD:/repo" ghcr.io/dir-ai/repotector mcp   # stdio MCP

Multi-arch (amd64/arm64), built and smoke-tested by CI on every release tag (see Dockerfile).

GitHub Action

Guard a repo in CI with one step — grandfathered semantics apply, so the job fails only on regressions, never on day-one debt:

- uses: dir-ai/repotector@main
  with:
    command: gates     # default; any CLI command works
    version: latest    # pin an exact npm version for reproducible CI

Honesty

Repotector guards repos, so it holds itself to its own standard. The lock is a compliance signal, not filesystem access control; the register is append-integrity, not tamper-proof; a static badge is self-reported. It spawns only git, makes no network calls, and pins exact versions in .mcp.json. The full threat model is in SECURITY.md — no security theater.

Determinism

The Atlas fingerprint is a SHA-256 over sorted source contents (16 hex chars), no timestamps — the same tree always fingerprints the same. Large files (>1MB, generated/minified) are marked, never read into the fingerprint. builtAtHead stamps the git sha so freshness can be checked without a walk.

License

MIT © PSX System. The core an agent needs in a repo is free forever; the compounding brain (Genome cloud, authored DNA) is the premium layer.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured