Graphify
An agent that lands in an unfamiliar repository does what you would do: grep for a name, open a file, follow an import, open another. That works, and it burns a lot of context on files it turns out not to need.
Graphify gives it something better to start from. It parses the workspace into a graph of functions, classes and the calls between them, adds what your docs and diagrams say, and answers questions against that instead of against the file system. “What calls this?” comes back as a handful of nodes and edges rather than five files.
The parsing runs in the container. Code goes through tree-sitter, so it is deterministic and involves no model at all, and there is no account to create and no index hosted anywhere.
Catalog name graphify. The CLI is useful on its own, and with an AI agent in the
same workbench it also registers itself there as a skill.
Add it
Section titled “Add it”On your machine:
monoceros add-feature acme graphifyApply the workbench and the CLI is on the PATH as graphify, for you and for
every agent in the container.
Three places, one tool
Section titled “Three places, one tool”Commands in this page run in one of three places, and it matters which:
| Where | Looks like | Example |
|---|---|---|
| Your machine | monoceros … | monoceros apply acme |
| The container shell | graphify … | graphify . --code-only |
| Inside the agent | /graphify … | /graphify . |
The last two are the same program. /graphify is the skill Graphify registers
with the agent, and it runs the very same CLI with the same flags, so anything
below that works on the shell works in the agent with a slash in front. The one
real difference is the semantic pass over docs and images: driven by the agent it
uses the agent’s own model, on the shell it needs a key or a flag. That is the
next section.
Get into the container shell with:
monoceros shell acmeHow the agent uses it
Section titled “How the agent uses it”On every container start, Graphify registers itself with the AI agents that are
actually in this workbench. It looks for them rather than reading a list you
maintain, so adding the claude or
opencode feature is all it takes. A workbench
without an agent gets the CLI alone.
In the agent, one command builds the graph:
/graphify .From then on the agent asks the graph:
/graphify query "what connects the checkout flow to the payment client?"The workbench briefing tells the agent to ask before it reads, so this usually happens without you prompting for it.
On a large repository an answer can come back marked TRUNCATED. That is a token
budget, not an empty graph: the nodes are printed before the edges, so the edges
are what falls off the end. Raise it generously, or ask a narrower question with
two or three terms instead of a sentence full of them.
/graphify query "ActionService executeNode" --budget 40000No API key needed
Section titled “No API key needed”Graphify does not ask you for an API key, and you should not give it one.
Code extraction is structural, so it needs no model. Docs, PDFs and images do get
a semantic pass, and when the agent drives the run, the agent is the model doing
it. Graphify itself never reads ANTHROPIC_API_KEY or OPENAI_API_KEY.
One case does need something: building a graph from the container shell over a folder that holds docs, PDFs or images, without an agent in the loop. Then either skip those files, which keeps the run local and deterministic:
graphify . --code-onlyOr set GEMINI_API_KEY in the container and let it do the semantic pass. Without
either, a folder with a single README stops with a message about a missing key.
The output is build output
Section titled “The output is build output”A run writes graphify-out/ next to your code: the graph, the report, an
interactive HTML view, and a cache so a re-run only re-reads what changed. None
of it belongs in a commit, and you don’t have to do anything about that.
The workbench keeps it out of every repository in the container through git’s
core.excludesFile, so git status stays clean and your project’s own
.gitignore is never touched. That file is yours, and build output is not a
reason for us to write a line into it.
Choosing extras
Section titled “Choosing extras”Graphify keeps its heavier parsers behind extras. The default set reads SQL schemas and PDF text, and computes the community labels that group related parts of the graph.
You change the set on the feature entry:
features: - ref: ghcr.io/getmonoceros/monoceros-features/graphify:1 options: extras: 'sql,pdf,leiden,office,terraform'monoceros add-feature acme graphify -- extras=sql,pdf,leiden,office,terraformBoth describe the same workbench: the command writes exactly that block. Apply again and the new set is installed.
Worth knowing before you extend the list: office reads Word and Excel files,
terraform and pascal add those languages, postgres reads a live schema
instead of a SQL file, svg exports a diagram. The model backends (gemini,
openai, anthropic, bedrock, ollama) only matter for a run you start from
the container shell, never for the agent path above.
Making the graph the first stop
Section titled “Making the graph the first stop”Telling an agent to prefer the graph is not enough on its own. We tried it: the same question, asked three times against the same graph, went to the graph once and to grep twice.
So when the workbench has both Graphify and claude,
Monoceros wires two hooks into Claude Code inside the container. Before a read,
a grep or a glob, they remind the agent that a graph exists and what to run
against it. You don’t configure this and it needs nothing in your repository: the
hooks sit in the container’s own Claude settings, and they stay quiet in a
directory where no graph was built.
That’s a reminder, and a reminder can be ignored. To make it binding, set
strict:
features: - ref: ghcr.io/getmonoceros/monoceros-features/graphify:1 options: strict: truemonoceros add-feature acme graphify -- strict=trueNow the first raw file read of a session is refused, with a pointer to query the
graph first. It fires once per session and then goes back to reminding, so it
can’t strand an agent mid-task. To switch it off for a single session, export
GRAPHIFY_HOOK_STRICT=0 in the container shell before you start the agent.
Keeping the graph current
Section titled “Keeping the graph current”The graph is a snapshot. After a batch of edits, refresh only what changed. In the agent, where the semantic pass is free:
/graphify . --updateOr from the container shell, code only:
graphify . --update --code-onlyThere’s also a git hook that rebuilds after every commit. It lands in your repository, so like strict mode it’s yours to install, from the container shell in the repo:
graphify hook install