Girder
MCP serverDev toolsLocal semantic code graph: source, definitions, callers, callees, impact, and semantic change review
Unavailable. This server has no hosted endpoint yet, so ahel can't serve it.
Connect ahel once, and every AI you use reads what you have installed.
From the project's README
As published by dhishwasher/girder in README.md.
Girder gives coding agents exactly the code they need, instead of whole files. It parses your repository into a living semantic graph — functions, definitions, call edges — and answers questions against that graph: exact function source, callers and callees, impact analysis, minimal test selection, and verified graph-addressed edits. It is one static Rust binary that any agent can drive over MCP, plus an optional native IDE.
curl -fsSL https://raw.githubusercontent.com/dhishwasher/Girder/main/install.sh | sh
Languages: Rust, Python, TypeScript/TSX, and Go. Rust and Python are the most mature; TypeScript and Go are measured and gated, with their limits written down (TypeScript, Go).
Tiers: the free tier is permanent and needs no account — get_source,
find_definition, search_code, ask_codebase, and review_changes on a
single repository. The orient and impacted_tests tools need a
paid license. Keys are verified offline; the binary never phones
home.
On the committed 15-task orient measurement, one bundled call per task
returned 48,814 output bytes versus 101,302, using 15 calls versus 78
for the equivalent command chain, with 37/37 gated checks passing after
the disclosed fixes. See the post-fix observation
and limitations. These are output bytes,
not tokens, and the baseline is Girder's separate commands.
Install
A prebuilt binary, no Rust toolchain needed:
curl -fsSL https://raw.githubusercontent.com/dhishwasher/Girder/main/install.sh | sh
girder --version
Or from source:
cargo install --path crates/aether-app
girder --help
This builds the default headless profile and installs the girder binary to
~/.cargo/bin (make sure it's on your PATH). No GPU, display, network, or API
key is required — the default AI provider is an offline MockProvider. The GUI
and live AI providers are opt-in Cargo features not included in a plain
install; see The GUI and Local-first AI below.
Windows installer
Each Windows release also includes Girder-<version>-setup.exe. It installs
for the current user under %LOCALAPPDATA%\Programs\Girder, adds Girder to the
user PATH, creates a Start Menu shortcut, and does not request administrator
access. Open a new terminal after installation so it sees the updated PATH.
The installer includes the desktop GUI, and its Start Menu shortcut opens it.
The archives and npm installation continue to provide the headless CLI.
The installer is not code-signed yet, so Windows SmartScreen will warn on first run. After downloading the installer from the GitHub release, double-click it, choose More info on the “Windows protected your PC” dialog, verify that the app is Girder and the publisher is shown as unknown, then choose Run anyway. If those details do not match, cancel instead.
Search accuracy
Exact-symbol lookup is Girder's strongest search path. Natural-language intent search is experimental: it reached 41.9% top-1 and 77.4% top-5 accuracy on the committed 31-item corpus, below the precommitted 75% and 90% thresholds. See the observation and policy.
Use it from an AI coding agent
girder mcp serves the read-only graph commands over the
Model Context Protocol, so an agent can ask
about your codebase instead of reading files into its context window.
Preview the changes, then configure detected agents:
npx -y girder-mcp setup --dry-run
npx -y girder-mcp setup
setup detects Claude Code (~/.claude or an existing in-home project
.mcp.json), Codex (~/.codex or an in-home CODEX_HOME), and Cursor
(~/.cursor). It merges the girder MCP entry into each detected agent's
documented config and registers an advisory PreToolUse hook for Claude Code and
Cursor. Codex receives the MCP entry but no read hook: its documented shell
reads do not expose a structured Read payload. A generic MCP client has no
universal config path and is reported as not detected. Setup never writes
outside your home directory. Existing girder entries remain untouched unless
you pass --force; girder setup --uninstall removes only setup-owned changes.
The hook writes a one-line suggestion to stderr only when a saved graph is
already present and never blocks a read. Some clients show successful-hook
stderr only in debug logs, so it is advisory logging rather than guaranteed
model-visible guidance.
For clients setup cannot detect, add this entry to their documented MCP config manually:
{
"mcpServers": {
"girder": {
"command": "npx",
"args": ["-y", "girder-mcp", "."]
}
}
}
With a binary already installed, "command": "girder", "args": ["mcp", "."]
skips npm entirely.
Girder 0.2.6 and later can opt into a cached graph generation with
girder mcp . --watch or npx -y girder-mcp . --watch. The server keeps
one validated graph generation in memory and incrementally reparses changed
files. The committed watcher measurement matched fresh cold analysis after all
45 mutations while reusing 98.70% of file extractions; the claim is limited to
preserving cold-analysis resolution while reusing parsing. See the
watcher result and limitations.
Seven tools, all read-only:
| Tool | What it answers | Tier |
|---|---|---|
get_source | The source of specific functions, without the file around them. | Free |
find_definition | Where an exact identifier is declared. Not a substring search. | Free |
search_code | Which functions match a description, when you don't know the name. | Free |
ask_codebase | Callers, callees, and blast radius, by graph traversal. | Free |
impacted_tests | Only the tests that can reach what changed. | Paid |
review_changes | What changed in the working tree, as semantics rather than text. | Free |
orient | Source, callers, callees, tests, and impact for one node, in one call. | Paid |
What that saves, and what it doesn't
orient bundles what get_source + ask_codebase (callers, callees, and
impact) + impacted_tests otherwise answer across 5-6 separate calls into
one. On a 15-task corpus spanning ten pinned repositories, that one call used
fewer aggregate bytes than the chain it replaces (48,814 vs 101,302,
a 0.48 ratio) while cutting 78 round trips to 15 — one per task — and, after
two disclosed defects were fixed, 37 of 37 gated checks pass. The first
run found impacted_tests --quiet silently dropping non-Rust/Python test
names (orient's own test-coverage section did not share the bug, which is
how it was found); that filter is now removed. Its natural-language intent
input still inherits search_code's accuracy — all three intent tasks in
this corpus resolved to the wrong node, unchanged and out of scope for this
fix — but orient's confidence heuristic, which originally caught none of
the three, now flags all three "confidence": "low" with candidate scores
attached, at the cost of also flagging some correct resolutions when a
runner-up is close. See docs/orient-tool.md and
the committed policy /
original observation /
post-fix observation.
Two additional precommitted measurements, both counting bytes of command output rather than tokens (no tokenizer was run):
get_sourceagainst a naive whole-file-read baseline: 97.85% fewer bytes across ten functions sampled by source-size decile, cheaper on all ten (docs/context-vs-read-cost.md).find_definitionagainst a plain-grep baseline: 97.98% fewer bytes across ten identifiers (docs/names-cost.md).
Both are single-repository measurements. The direction is structural — files
are much larger than the functions in them, and grep returns every mention
where find_definition returns only declarations — but the exact percentages
are not portable.
These comparisons do not measure a competent agent choosing grep searches and bounded file reads adaptively. No agentic-grep cost claim is established here.
The subsequent agentic-grep campaign with a local 1.5B model stopped incomplete and produced no pairs with two correct answers. It establishes no comparative cost advantage or frontier-model behavior.
impacted_tests is advisory. It over-selects unrelated tests, and it
misses tests reached only through dynamic dispatch (measured: recall 0.000 on a
polymorphic-dispatch case, docs/core-representative-mutations.md).
A full test run remains the authority before calling a change safe.
Selecting extra tests costs CPU time; missing a relevant test can conceal a regression.
The project root is fixed when the server starts, so no tool call can reach
another directory. GIRDER_MCP_TIMEOUT_SECONDS (default 120) bounds each
call; raise it for a very large repository.
Everything below assumes girder is on your PATH. Building from a source
checkout without installing works the same way with cargo run -p aether-app --
in place of girder.
Quickstart
# Full end-to-end demo — no GPU, display, or API key required:
girder
# Run the test suite (graph, builder, AI router, agent swarm, debugger):
cargo test --workspace
# Optional: compile live providers and run the real debugpy adapter test:
cargo check -p aether-ai --features live-providers
python3 -m pip install debugpy
cargo test -p aether-dap --test debugpy -- --ignored
Analyze a repository
Use the CLI to build and query a repository's semantic graph:
# Build the semantic graph from a project and save it as <dir>/project.aether:
girder analyze sample-project
# Inspect a saved graph and a node's impact set:
girder inspect sample-project/project.aether crate::lib::add
# Concept search: rank functions by relevance to a natural-language query:
girder search sample-project "sum numbers in a list"
# Graph-semantic rename — follows Calls edges (not text search) and rewrites
# only the real callers, then saves the updated graph:
girder refactor sample-project rename crate::lib::add plus
# Preview what the swarm would build — graph-aware Planner only, no code written:
girder swarm-plan sample-project "add user authentication"
# Dispatch the agent swarm on a project with a natural-language intent:
girder forge sample-project "add a subtract function"
# Author a single graph-addressed plan step via a wired-in model (the
# offline MockProvider by default) and execute it through the same
# verified plan executor as `plan run` below, repairing from check
# failures automatically. Never point this — or `plan run --authored` —
# at sample-project/: it is a pinned measurement fixture, not a demo
# target, and both refuse it outright (see "Demo target" below):
girder do demo-project "add an exclamation mark to the farewell"
# Emit graph context, a real Plan Format v2 authoring schema, and a plan
# skeleton as one JSON object — for pasting into any external chat model
# that isn't wired in as a provider. See "External authoring" below for
# the full loop from here to a verified, applied edit:
girder context demo-project --nodes crate::greeter::farewell "add an exclamation mark to the farewell" --json
# Validate/inspect/execute a plan file directly. `--authored` is for a plan
# an external model wrote by hand (see "External authoring" below); without
# it, `run` executes a plan exactly as authored (used internally by `do`):
girder plan validate my-plan.json
girder plan explain my-plan.json
girder plan run my-plan.json --dry
# Semantic code review vs HEAD (typed mutations, not text diffs):
girder review sample-project --since HEAD~1
# Minimal test selection: find every test reachable from changed functions:
girder test-impact sample-project --run
# Knowledge-graph query — answer a question by traversing the semantic graph:
girder query sample-project "what would break if I change add?"
girder query sample-project "what calls sum_list?"
girder query sample-project # interactive REPL (reads stdin)
# Start a graph-native collaboration history, give another replica its own actor,
# record that replica's current source graph, and deterministically merge it:
girder collab init sample-project alice alice.aetherc
girder collab fork alice.aetherc bob bob.aetherc --approve
girder collab sync sample-project bob.aetherc
girder collab merge alice.aetherc bob.aetherc merged.aethercb
girder collab materialize merged.aethercb merged.aether
# Membership changes are causal operations and require explicit approval:
girder collab member add alice.aetherc carol --approve
girder collab member remove alice.aetherc carol --approve
# Or exchange deltas in a mutually authenticated live loopback session.
# Secret contents are generated with private permissions and never printed.
# Group-secret-only operation remains available as a migration mode:
girder collab secret collaboration.secret
# Strict identity mode additionally pins each roster actor to an Ed25519 key.
# Generate each actor's private/shareable-public pair, compare the printed
# SHA-256 fingerprints out of band, and approve the exact peer fingerprint:
girder collab identity generate alice.aetherc \
alice.identity alice.identity.pub
girder collab identity generate bob.aetherc \
bob.identity bob.identity.pub
girder collab identity show bob.identity.pub
girder collab identity trust alice.trust \
bob.identity.pub --approve <bob-fingerprint>
girder collab identity trust bob.trust \
alice.identity.pub --approve <alice-fingerprint>
# Sign existing local-authored history now (strict host/join also does this
# in memory before exchange), then audit a fully attested bundle offline:
girder collab identity attest alice.aetherc alice.identity
girder collab identity attest bob.aetherc bob.identity
girder collab host alice.aetherc 127.0.0.1:7331 \
--identity-file alice.identity --trust-store alice.trust \
--secret-file collaboration.secret --discovery-dir .bitcode/peers \
--presence "reviewing parser changes"
girder collab discover bob.aetherc .bitcode/peers \
--secret-file collaboration.secret
girder collab join-peer bob.aetherc alice .bitcode/peers \
--identity-file bob.identity --trust-store bob.trust \
--secret-file collaboration.secret --presence "running transport tests"
# An explicit address remains available when local discovery is not in use:
girder collab join bob.aetherc 127.0.0.1:7331 \
--secret-file collaboration.secret \
--identity-file bob.identity --trust-store bob.trust
# Verify every retained non-bootstrap operation against the current local pins:
girder collab identity verify \
alice.aetherc alice.identity alice.trust
# To rotate your own key, first generate a new pair, then record a dual-signed
# causal transition while both private keys are available. Peers can then rotate
# their current pin before the next strict session:
girder collab identity generate alice.aetherc \
alice-new.identity alice-new.identity.pub
girder collab identity rotate-local alice.aetherc \
alice.identity alice-new.identity \
--from <old-alice-fingerprint> --approve <new-alice-fingerprint>
# Peer trust rotation/removal also requires the exact reviewed fingerprints:
girder collab identity rotate alice.trust \
bob-new.identity.pub --from <old-bob-fingerprint> --approve <new-bob-fingerprint>
girder collab identity remove alice.trust bob \
--approve <new-bob-fingerprint>
# Successful sessions persist both peers' causal acknowledgements. Once every
# active member has acknowledged superseded history, prune it conservatively:
girder collab compact alice.aetherc
# Rebuild remote whole-file projections, show semantic/file changes and
# conflicts, then explicitly validate and journal-commit the reviewed bytes:
girder collab review sample-project alice.aetherc
girder collab apply sample-project alice.aetherc --approve
# Real Python execution tracer — records every variable at every line/call/return:
girder debug script.py
girder debug script.py --what-if x=10 at 2
# DAP adapter dry-run: resolve graph breakpoints without launching an adapter:
girder dap script.py --dry-run
# Generate and review an extension recipe without changing the project:
girder extension sample-project generate "show call impact"
# Grant the exact recipe digest/capabilities, then manage its lifecycle:
girder extension sample-project generate "show call impact" --approve
girder extension sample-project list
girder extension sample-project disable dev.bitcode.generated.show-call-impact
girder extension sample-project remove dev.bitcode.generated.show-call-impact
# Install a hand-authored declarative recipe after the same explicit review:
girder extension sample-project install recipe.json --approve
# Browse the built-in reviewed marketplace and inspect a listing:
girder extension sample-project marketplace search impact
girder extension sample-project marketplace show org.bitcode.impact-navigator
# Regenerate a reviewed intent for this project, preview its capability delta,
# then explicitly approve the adapted recipe:
girder extension sample-project marketplace adapt org.bitcode.impact-navigator
girder extension sample-project marketplace adapt org.bitcode.impact-navigator --approve
# Portable catalogs use the same bounded parser and print a catalog fingerprint:
girder extension sample-project marketplace list \
--catalog marketplace/girder-extensions.json
# Full help:
girder --help
analyze/forge walk every .rs, .py, .ts, .tsx, .mts, .cts, and
.go file (skipping target, .git, …),
build the graph with directory-aware module paths, resolve free and
receiver-qualified method calls across files, and persist the .aether graph.
Supported languages are Rust, Python, TypeScript/TSX, and Go. The TypeScript and Go
graph surfaces are measured and gated, but remain less mature than Rust and
Python: TypeScript meets its precision and recall gates, while Go currently
records one false negative (micro-recall 0.954545 against a 1.0 gate). See the
honest support boundaries and results for
TypeScript and Go, with the
committed observations for
TypeScript and
Go.
Rust module-scope imports retain renamed symbol identity across bounded public
re-export chains, including crate-root and mod.rs facades, so collisions are
resolved by exact path while ambiguous or cyclic aliases stay unlinked.
Rust parameter annotations and direct type-qualified local constructors provide
bounded receiver types, including inside macro token trees. Function signatures
also supply parser-owned return types for local factory bindings through ?,
unwrap/expect, and result-preserving error adapters. Instance factories
returning Self resolve to their owning type, while single-argument generic
wrappers propagate an inner receiver only when their signatures prove the same
direct type parameter flows through. Recursive factory hints have a hard size
budget. Unknown receiver types remain unresolved rather than being linked to an
unrelated same-named method.
forge plans every candidate byte, checks conflict
baselines, validates the candidate in a copied workspace, runs Cargo build/tests
when a manifest is present plus configured validation commands, and only then
journal-commits the source projection and graph together.
collab exchanges semantic graph operations rather than text ranges. Each
human or agent replica has a validated actor id and causal version vector;
minimal idempotent deltas converge regardless of delivery order. Concurrent
deletes win, concurrent updates have a deterministic tie-break, and deleting
then recreating a node cannot resurrect edges from its old generation. RON
.aetherc bundles are reviewable; .aethercb bundles use compact bincode.
Init/sync reconciles source with the durable graph so graph-owned agent and
extension metadata participates instead of being discarded. Bundle saves use a
synced atomic replacement.
Membership is part of the causal operation history rather than a local address
book. An approved collab fork registers the invited actor in both the source
and forked bundles; if writing the fork fails, the source roster is rolled back.
collab member add|remove ... --approve records convergent add/remove
operations, concurrent removal wins, normal replica APIs reject new operations
after the local actor is removed, and membership changes invalidate stale
acknowledgements. A history has one genesis self-membership root: separately
initialized actors cannot self-invite through a relayed delta. Removal records
the highest counter observed for that actor; unseen later counters fail until
their context observes a causal re-add, so a removed offline actor cannot keep
extending a stale membership epoch. Version
1 and 2 bundles migrate conservatively by retaining the local actor, previously
acknowledged peers, and non-bootstrap actors already present in the causal
clock. Use fork to allocate a new actor replica; direct member add is for
re-authorizing an already allocated unique actor, since it does not create that
actor's bundle. Version 1-3 bundles load as explicit unsigned legacy history;
version 4 stores operation attestations without changing existing CRDT dots.
Live host/join uses fresh random challenges, mutual HMAC-SHA256 group authentication, direction- and sequence-bound message integrity, bounded frames checked before allocation, and socket timeouts. Secrets are read from non-symlink regular files owned by the current user with private permissions. Optional identity mode adds transcript-bound Ed25519 proofs and a local actor-to-key trust store: both endpoints must configure it, each public key must match the peer actor's exact pinned fingerprint, and either attempted downgrade to group-secret-only mode is refused. The signed transcript also authenticates fresh X25519 keys, deriving a session-integrity key that another group-secret holder cannot calculate from captured traffic. Private identity files receive the same ownership, symlink, and permission checks. New trust, rotation, and removal are explicit fingerprint-approved operations, and identity files are actor-bound to their collaboration bundle.
Strict identity sessions also give every retained non-bootstrap CRDT operation a
durable Ed25519 attestation. A delta importing a new operation, or a new
retroactive attestation for an already-known dot, triggers verification of that
actor's complete retained history before any bundle is replaced. The signature
binds the dot, causal context, and exact action, so action tampering, actor
forgery, unsigned relay, conflicting proofs, and replayed dot changes fail
atomically. Local legacy operations can be upgraded with identity attest;
identity verify audits a whole bundle against the local private identity and
peer trust store.
Shortened here. Read the whole README on GitHub.
Signals
- GitHub stars
- 12
- Last commit
- Sep 2026
Advanced
- Delivery
- girder MCP server → your ahel gateway (mcp.ahel.ai) → every connected AI client.
- Catalog kind
- mcp-server
- Gateway key
io-github-dhishwasher-girder- Source
- github.com/dhishwasher/girder