Install
$ agentstack add mcp-justinstimatze-defn ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
defn — code in high definition
[](https://github.com/justinstimatze/defn/actions/workflows/ci.yml) [](https://goreportcard.com/report/github.com/justinstimatze/defn) [](https://opensource.org/licenses/Apache-2.0) [](https://github.com/justinstimatze/defn/releases)
Your Go code lives in two places: files and a graph. Both are complete, lossless representations of the same code — kept in sync automatically. Files work with every tool in the Go ecosystem. The graph adds structure: every function, method, type, and constant is a node; every call, reference, and interface implementation is an edge.
Edit through defn or edit files directly. Either side auto-syncs to the other. Either can recover the other.
"What breaks if I change this function?" Tested on gin-gonic/gin (24K lines, 1,580 definitions):
> Without defn: grep → read 5 files → scroll → guess > 9 calls | 144K tokens | 45s | found 19 of 21 callers | no transitives | no test count
> With defn: code(op:"impact", name:"Render") > 2 calls | 51K tokens | 12s | 33 callers | 341 transitive | 238 tests — including interface dispatch
What makes this different
Files don't know about each other. grep finds text matches, not callers. Reading context.go doesn't tell you that responseWriter satisfies ResponseWriter, or that changing WriteHeader breaks 238 tests through interface dispatch. That information exists in the type system but dies when you close your editor.
defn makes it permanent. It parses your code with go/types (the same type checker gopls uses) and stores the result in Dolt — a SQL database with git semantics. The reference graph persists across sessions, includes interface satisfaction, and is queryable:
-- Who calls Render and has no tests?
SELECT d.name FROM definitions d
JOIN refs r ON r.from_def = d.id
WHERE r.to_def = (SELECT id FROM definitions WHERE name = 'Render' AND receiver = '*Context')
AND d.test = FALSE
AND NOT EXISTS (
SELECT 1 FROM refs r2
JOIN definitions t ON t.id = r2.from_def AND t.test = TRUE
WHERE r2.to_def = d.id
)
Setup
go install github.com/justinstimatze/defn/cmd/defn@latest
go install golang.org/x/tools/cmd/goimports@latest
cd your-go-project
defn init . --server # recommended: starts Dolt server for multi-agent
defn init . # or: embedded mode, no server needed
Then start Claude Code or Codex and ask:
"What's the blast radius of changing the Render function?"
"Which functions have no test coverage?"
"Find all functions that handle authentication"
To remove everything: defn clean
Requires Go 1.26+, CGO, and goimports. Binary is ~140MB due to embedded Dolt engine.
macOS: brew install icu4c then:
export CGO_CFLAGS="-I$(brew --prefix icu4c)/include"
export CGO_LDFLAGS="-L$(brew --prefix icu4c)/lib"
go install github.com/justinstimatze/defn/cmd/defn@latest
How it works
One MCP tool — code — with an op field. Your AI agent calls it naturally:
| What you ask | What defn does | |---|---| | "Show me Render" | code(op:"read", name:"Render") — full source, disambiguated by blast radius | | "What depends on this?" | code(op:"impact", name:"X") — callers, transitives, test coverage, interface dispatch | | "Change 3 lines in this function" | code(op:"edit", name:"X", old_fragment:"...", new_fragment:"...") — no need to provide the whole body | | "Rewrite this function" | code(op:"edit", name:"X", new_body:"...") — full replacement, auto-emits + builds | | "What's in this file?" | code(op:"overview", file:"server.go") — all definitions with caller/callee counts | | "Rename across the codebase" | code(op:"rename", old_name:"X", new_name:"Y") — updates definition + all callers | | "Run only affected tests" | code(op:"test", name:"X") — via reference graph, not go test ./... | | "Simulate a change" | code(op:"simulate", mutations:[...]) — throwaway branch, ripple report, discard |
All operations
| Op | What it does | Key params | |---|---|---| | read | Full source of a definition | name or file:line | | outline | Compact projection: signature + doc + caller/callee summary + top-level flow. Falls back to read for bodies under 300 bytes (v0.24.2). | name | | slice | Verbatim AST-role slice of a def: signature, doc, body, error-branch, return, loop (v0.24.2). Byte-exact against the source. | name, slice | | search | Find by name pattern (%) or body text | pattern | | impact | Blast radius, callers, test coverage | name | | explain | Signature + callers + callees + tests | name | | overview | All definitions in a file with relationships | file | | similar | Find definitions with similar signatures | name | | untested | Definitions without test coverage | — | | edit | Full body replace, OR fragment replace via old_fragment+new_fragment | name | | insert | Insert code after an anchor string | name, after, body | | create | Create (infers name/kind from body) | body, optional module | | delete | Remove + clean up references | name | | rename | Rename + update callers (AST-based, preserves comments) | old_name, new_name | | move | Move to another module | name, module | | test | Run only affected tests | name | | simulate | Throwaway branch, apply mutations, ripple report | mutations | | apply | Batch operations (transactional) | operations | | diff | Uncommitted changes | — | | history | Commit history for a definition | name | | find | Definition at a file:line | file, line | | sync | Re-ingest after file edits | — | | emit | Emit the tree to a directory (works while serve holds the DB) | out | | query | Read-only SQL | sql | | test-coverage | Test names covering a definition | name | | batch-impact | Combined blast radius for multiple definitions | names | | file-defs | Map file path to definitions | file | | traverse | BFS over the ref graph, direction + kind filtered | name, direction | | literals | Composite literal fields (type/field/value) | pattern, name, body | | pragmas | Comment pragmas (//go:generate, //winze:...) | pattern | | branch, checkout, merge, commit, status | git-style versioning on the DB | see Versioning | | conflicts, resolve, merge-abort | Definition-level merge conflict resolution | name, body or pick | | diff-defs | Structural diff between two refs | from, optional to |
Name-based ops accept file:line paths and Receiver.Method syntax (Context.Render, (*Router).Handle).
Versioning
Dolt gives git semantics on SQL data. Branch, merge, diff, commit — natively, on definitions.
defn branch feature && defn checkout feature
# make changes
defn commit "add auth middleware"
defn checkout main && defn merge feature
In server mode, multiple agents branch and merge concurrently on the same Dolt server. For filesystem isolation, defn worktree [] emits a new tree pinned to a branch (writes .defn-worktree.json so all CLI invocations in that dir stay on that branch).
Only one defn serve process can own an embedded .defn/ at a time — enforced via syscall.Flock on .defn/serve.pid. A concurrent CLI gets an actionable error pointing at defn worktree or DEFN_DSN, and defn status shows who's holding the lock along with any version skew between the running serve and the on-disk binary.
Scale
| Project | Lines | Defs | Refs | Init time | |---------|-------|------|------|-----------| | chi | 10K | 370 | 704 | 11s | | gin | 24K | 1,580 | 3,829 | 48s | | hugo | 218K | 10,221 | 22,209 | 7min |
Init is a one-time cost. Incremental resolve after edits is much faster.
Limitations
- Go only. The type-checked reference graph requires
go/types. renameuses AST-based identifier replacement — preserves comments and string literals. Local variables that shadow the definition name are detected and preserved (with a warning).
License
Apache 2.0. Built on Dolt (Apache 2.0) and adit-code research. See [INFLUENCES.md](INFLUENCES.md).
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: justinstimatze
- Source: justinstimatze/defn
- License: Apache-2.0
- Homepage: https://github.com/justinstimatze/defn
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.