codegraph-brain
This MCP server gives AI agents a queryable code dependency graph: build it from a local repo, then explore impact, structure, architecture quality, and dead code instead of grepping or reading whole files.
cgis_ingest β Scan a local directory to build or incrementally refresh the SQLite graph DB.
cgis_overview β Get symbol counts, edge totals, unresolved ratios, and the largest packages as a starting point.
cgis_find_symbol β Resolve a partial name to candidate fully-qualified symbol names.
cgis_analyze_impact β Find everything upstream that reaches a symbol: callers, importers, subclasses, DI dependents (βwhat breaks if I change this?β).
cgis_trace_flow β Find everything a symbol reaches downstream: calls, imports, inheritance, references (βwhat does this depend on?β).
cgis_get_structure β Show module/class/method containment hierarchy.
cgis_context β Get a compact, prompt-ready brief with source, enclosing class, direct callers/callees, and domain.
cgis_metrics β Compute global hotspots: coupling bottlenecks, god classes, PageRank, with scoping/exclusion options.
cgis_audit_reachability β Audit which route handlers or sources never reach a required checkpoint, e.g. an ownership/authz guard.
cgis_find_orphans β Detect classes nothing in production constructs, extends, or names β dead-code candidates.
cgis_drift β Report per-domain architectural drift against declared ideal patterns.
cgis_suggest_packages β Suggest sub-package boundaries (split/consolidate) from dependency communities.
cgis_validate β Check graph integrity as resolved-vs-unresolved edge ratios and a health verdict.
cgis_fractal β Report a motif census across structural tiers to characterize hierarchy/flatness/scale-invariance.
cgis_init_ontology β Propose a starter patterns.yaml from measured graph scores, read-only.
π§ CGIS: Code Graph Intelligence System
A code graph your AI agent can query instead of guess
Ask "what breaks if I change this?" and get the call chain, not a guess.
CGIS parses a repository with tree-sitter into a graph of fully qualified symbols and the calls, imports and containment between them, stores it in SQLite, and serves it to AI agents over MCP. An agent that would otherwise grep and read whole files asks the graph instead.
Languages: Python Β· TypeScript / TSX
Runs: locally β no account, no telemetry; the graph never leaves your disk (the one opt-in exception)
$ cgis ingest src --output graph.db
$ cgis impact cgis.query.engine.QueryEngine.get_flow_graph --db graph.db --depth 2
π Analyzing transitive upstream callers of: cgis.query.engine.QueryEngine.get_flow_graph
METHOD cgis.query.engine.QueryEngine.get_flow_graph (cgis/query/engine.py:215)
βββ FUNCTION cgis.query.context.context_service._collect_callees (cgis/query/context/context_service.py:44)
β βββ FUNCTION cgis.query.context.context_service.build_context (cgis/query/context/context_service.py:96)
βββ METHOD cgis.guardian.collector.ContextCollector._graph_sections (cgis/guardian/collector.py:174)
βββ METHOD cgis.guardian.collector.ContextCollector.collect_graph_context (cgis/guardian/collector.py:213)
βββ METHOD cgis.guardian.collector.ContextCollector.collect_for_chunk (cgis/guardian/collector.py:303)Real output β CGIS run on its own source.
π Quickstart
In Claude Code (fastest)
/plugin marketplace add zaebee/codegraph-brain
/plugin install cgis@codegraph-brainThat ships the MCP server, a skill that teaches the agent when to query the graph instead of reading files, and /cgis:ingest to build the graph on first use. The server is pulled from PyPI on demand via uvx, so there is nothing to clone or build.
Any other MCP client (Cursor, Claude Desktop, β¦)
{
"mcpServers": {
"cgis": { "command": "uvx", "args": ["--from", "codegraph-brain", "cgis-mcp"] }
}
}From the terminal
# No install needed β uvx fetches it from PyPI
uvx --from codegraph-brain cgis ingest ./my-project --output graph.db
uvx --from codegraph-brain cgis impact "my_module.core_function" --db graph.db --depth 5 # who calls this
uvx --from codegraph-brain cgis trace "my_module.MyClass.run" --db graph.db --depth 3 # what this calls
# add --format mermaid (or json) to either for a diagram or machine-readable outputOr install it for good: pip install codegraph-brain (Python 3.12+), then use cgis directly. The full command list is in CLI_USAGE.md.
Related MCP server: loctree-mcp
π Proof at Real Scale
CGIS runs on a working twelve-repository estate β four languages, 8,146 commits, shipping daily. On its FastAPI backend it classifies 82.7% of 87,845 edges definitively and prints the remaining 17.3% rather than inventing targets for them β including the part that is CGIS's own gap.
That share rose from 11.4% in #459, which stopped counting calls to missing symbols as resolved. About 4 points of what is left is a known resolver gap, not something undiscoverable: ingesting app/ strips the app. prefix its imports carry, and the import path does not yet reconcile the two β the same backend ingested at its package root reports 13.2%. The number is what the tool admits it cannot place today, and it is allowed to move the unflattering way.
Read the case study β β every figure measured and reproducible, including what CGIS doesn't cover.
π€ Why a graph, and how this differs
Text retrieval hands an agent chunks that look related. It cannot say which of three functions named save a call reaches, or what sits five callers up. CGIS resolves every call site to a fully qualified name when the source allows it β and when it does not, the edge stays marked unresolved and is counted, never filled with a plausible guess.
If you use⦠| CGIS adds |
grep / file reads in the agent | Transitive callers and callees in one call, without spending context on whole files |
LSP-backed symbol tools (e.g. Serena) | A persisted whole-repo graph for multi-hop impact, coupling, PageRank and drift |
A repo map (e.g. aider) | Resolved edges you can traverse and audit, with the resolved/unresolved ratio reported |
π€ MCP Tools
The main tools:
Tool | Answers |
| Build or incrementally refresh the graph |
| Where to start: sizes and the largest packages, when you have no FQN yet |
| Partial name β candidate FQNs |
| What breaks upstream if this changes? |
| What does this call, transitively? |
| Class / module hierarchy |
| A compact GraphRAG context package for one symbol |
| Coupling, god classes, PageRank, package cohesion |
| Authz / IDOR coverage β does every handler reach its guard? |
| How far each domain has moved from its declared pattern |
| Graph integrity: resolved vs unresolved edges |
All 14 tools, with parameters: MCP_REFERENCE.md.
ποΈ How It Works
Extract β tree-sitter parsers turn each file into nodes and raw call edges.
Resolve β the
ResolverEnginemaps raw calls to fully qualified names, or leaves them explicitly unresolved.Store β SQLite holds the graph; queries are breadth-first traversals over it.
graph LR
A[Source Code] --> B[Extractors]
B --> C[Resolver Engine]
C --> D[(SQLite Graph DB)]
D --> E[MCP Server]
D --> F[Prompt Compiler]
E --> G[AI Agents]
F --> GThe details β and a pipeline graph CGIS regenerates from its own source on every change β are in HOW_IT_WORKS.md.
π‘οΈ Guardian: Graph-Aware Code Review
Guardian is CGIS's built-in LLM reviewer β it reviews pull requests using the graph as context, not just the diff text. It runs in CI and posts inline comments anchored to the exact line.
Two-stage, recall-first: a finder surfaces every plausible defect (optimised for recall), then a separate skeptic pass filters false positives β closer to how human reviewers work, and far more reliable than a single precision-gated prompt.
Local or cloud, no lock-in: point it at Ollama (
qwen2.5-coder,llama3.1,granite-code, β¦) for free local inference, or at Mistral / Gemini in the cloud. You can even mix them β a strong cloud finder with a free local cross-model skeptic.Graph-aware context: the reviewer sees impact graphs, architectural drift, and project ontology β so it catches structural and convention defects a flat-diff reviewer can't.
Deterministic anchoring: every inline comment is positioned by a verbatim quote from the diff, not the model's (often wrong) line guess.
Dogfooded & measured: Guardian reviews CGIS's own pull requests, and a benchmark harness scores it against curated ground truth β so prompt changes are validated, not guessed.
# Build the graph, then review a PR with a local model (no API key)
cgis ingest ./src --output graph.db
GUARDIAN_PROVIDER=ollama GUARDIAN_MODEL=qwen2.5-coder:14b \
uv run python scripts/guardian_review.py --pr 123 --db graph.db --inlineNo GPU on hand? Benchmark it on a notebook GPU β β free end to end, since the fixtures score without an LLM judge. Or point Guardian at a remote Ollama β β over an frp stcp tunnel, no public port, and a guard that refuses a review of a silently truncated prompt.
π Privacy
CGIS collects nothing: no telemetry, no analytics, no account. Your code and the graph built from it stay on your machine. The one exception is opt-in: Guardian, if you run it with a cloud model, sends the reviewed diff to the provider you chose. See PRIVACY.md.
π οΈ Development
Requires Python 3.12+ and uv.
git clone https://github.com/zaebee/codegraph-brain && cd codegraph-brain
uv sync
make pytestSee CONTRIBUTING.md for the standards: strict MyPy, linting, ontology compliance.
πΌ Architecture Audit
CGIS is free and you can run it yourself. If you would rather have the analysis than the tool, I run a fixed-price audit of your codebase's structure β authorisation coverage, blast radius, coupling, architectural drift β delivered in five working days, $2,400 fixed, with an explicit list of what the analysis cannot see. Read what's included β
Available Tools
15 toolscgis_analyze_impactA
Upstream subgraph of one FQN: everything that reaches it within depth hops.
Follows every edge except containment β in practice callers, importers,
subclasses, type references and DI dependents β within internal code, so this
answers "what breaks if I change X?". The
enclosing class or file and stdlib/third-party nodes are left out unless
``include_structure`` / ``include_external`` ask for them β the same view as
the CLI's ``impact``. For what X depends on use
``cgis_trace_flow``; for only the members of a module or class,
``cgis_get_structure``; for a source-included brief to read before editing
one symbol, ``cgis_context``.
``output_format="mermaid"`` (default)
returns a diagram; ``"json"`` returns a joinable ``{root, nodes, edges,
coverage}`` payload with real FQNs β letting an agent compute set
differences (e.g. "which route handlers never reach ``verify_ownership``?")
directly. ``coverage`` counts unresolved calls whose name matches a
traversed function, method or class: callers that may be missing, named in
``top_unresolved``. It is an upper bound β a common name matches calls on
unrelated objects, which the names make visible.
| Name | Required | Description | Default |
|---|---|---|---|
| fqn | Yes | Fully qualified name, e.g. pkg.module.Class.method. A unique dot-boundary suffix also resolves; an ambiguous one returns candidates. Use cgis_find_symbol to look a name up. | |
| depth | No | Maximum edge hops upstream, over callers, importers, subclasses, type references and DI dependents (plus the enclosing class or file with include_structure). | |
| db_path | No | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's β prefer an absolute path. | graph.db |
| output_format | No | "mermaid" for a diagram, or "json" for a payload with real FQNs (case-insensitive). Any other value returns an error. | mermaid |
| include_external | No | Also return stdlib, third-party and unresolved call targets β calls on values whose type is decided at runtime. Off by default, as in the CLI, because they dominate the payload; in json, coverage/top_unresolved still counts what was dropped. | |
| include_structure | No | Also follow containment (CONTAINS/DECLARES): a module's or class's own members, and the class or file enclosing a symbol. Off by default, as in the CLI; cgis_get_structure is the tool for members alone. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden and handles it thoroughly. It discloses edge traversal rules, exclusions of structure/external nodes, default behavior matching the CLI, output format differences, and the semantics of unresolved-call 'coverage' as an upper bound with potential false positives. This is highly transparent about what the operation actually does.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place. It front-loads the core definition, then moves to exclusions and sibling routing, then parameter-specific behavior and output semantics. There is no filler or repetition of schema fields.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with six parameters, multiple output modes, and nuanced filtering behavior, the description is remarkably complete. It covers scope, edge types, output payload shape, unresolved-call semantics, CLI equivalence, and alternatives. Even though an output schema exists, the description's own explanation of return values and coverage is a helpful addition rather than a redundancy.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema coverage is 100%, the description meaningfully enriches each parameter: fqn ambiguity and candidate resolution, db_path resolution being relative to the server's working directory, output_format being case-insensitive and rejecting other values, and include_structure/include_external clarifying containment and runtime-typed call targets. This goes well beyond the schema's baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening line states a specific verb and resource, 'Upstream subgraph of one FQN,' and immediately clarifies the exact graph relationship and depth hop limit. It explicitly distinguishes itself from sibling tools by naming cgis_trace_flow, cgis_get_structure, and cgis_context, so an agent can select this tool versus alternatives without inspecting their schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly states when this tool is appropriate: it answers 'what breaks if I change X?' and gives explicit alternatives for related needs: cgis_trace_flow for dependencies, cgis_get_structure for members, cgis_context for editing one symbol. It also states which edges are excluded by default and how to opt into them, leaving no ambiguity about when to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cgis_audit_reachabilityA
Reachability/authorization audit β which sources never reach a checkpoint.
The headline use is **IDOR/authz coverage**: list every route handler that does
NOT transitively reach an ownership check. Reachability follows behavioral edges
(CALLS *and* FastAPI ``Depends()`` DEPENDS_ON), so a guard wired via DI counts.
Select sources with ``from_type`` (a NodeType like ``ROUTE_HANDLER`` /
``API_ENDPOINT`` / ``FUNCTION``) and/or ``from_prefix`` (FQN prefix) β at least
one is required. Returns JSON ``{target, covered, gaps}`` where each gap carries
``fqn``/``file``/``line``. Generalizes to validators, event tracking, or
service-layer-boundary rules by pointing ``target`` at the required node.
A selection that matches no source returns a β message, not an empty
``{covered: [], gaps: []}`` that would read as a passing audit (#467).
| Name | Required | Description | Default |
|---|---|---|---|
| depth | No | Maximum reachability depth; a longer path is reported as a gap. | |
| target | Yes | FQN of the checkpoint every source must reach, e.g. an ownership check. A unique dot-boundary suffix also resolves. | |
| db_path | No | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's β prefer an absolute path. | graph.db |
| from_type | No | NodeType of the sources to audit, e.g. ROUTE_HANDLER, API_ENDPOINT or FUNCTION (any case). Give this, from_prefix, or both. | |
| from_prefix | No | Only audit sources at or under this FQN prefix, matched on whole dot-segments. A selection matching no source is an error naming the whole-segment prefixes it may have meant. Combined with from_type when both are given. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full behavioral burden and does so thoroughly: it discloses that reachability follows CALLS and DEPENDS_ON edges, that DI-wired guards count, that output is {target, covered, gaps}, and that no-match selections raise a β error rather than an empty passing result. It also warns of a known edge case (#467). This is more transparency than typical.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but tightly packed: each paragraph covers one concern (headline use, selection, output/edge case) and the main verb appears in the first line. No filler or repetition of schema defaults. The front-loaded headline sentence makes the tool's purpose instantly scannable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, the description covers purpose, use cases, source selection, edge behavior, and return shape; the output schema and parameter descriptions fill in return and depth details. The only mild omission is explicit sibling guidance, but the rich use-case section compensates. The definition gives an agent enough to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema covers all five parameters, so the baseline is 3, and the description adds real meaning: it explains the at-least-one-of from_type/from_prefix selection constraint, how prefixes are matched on whole dot-segments, and that target points at the checkpoint. It does not add much for depth or db_path, but those are already well documented in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description defines a specific verb and resource: it audits reachability to a checkpoint and lists sources that never arrive. It names a concrete headline use (IDOR/authz coverage) and distinguishes its traversal semantics (CALLS plus Depends()) from a plain graph query. This is enough to separate it from siblings like cgis_trace_flow or cgis_find_orphans.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly frames when to use the tool: for IDOR/authz coverage audits, and it generalizes to validators, event tracking, and service-layer-boundary rules. It also gives selection rules (from_type and/or from_prefix) but does not name sibling tools to avoid or state a when-not-to-use condition. That is clear context without exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cgis_contextA
Prompt-ready brief on one FQN: its source, class, direct callers and callees.
Call this before editing a symbol, instead of reading its files. It follows
calls only, one hop by default. Source is included when the file is found
(see ``source_root``), and the domain when the graph was tagged with one.
For a multi-hop subgraph
over calls, imports, inheritance and references without source, use
``cgis_trace_flow`` (downstream) or
``cgis_analyze_impact`` (upstream).
Returns an XML-tagged prompt β the focal node's source, its enclosing class,
its architectural domain boundary, direct callers (upstream ripple) and
callees (downstream dependencies) β meant to be injected into your context
window in place of raw file dumps. Far more token-efficient than reading
whole files, and structured so boundaries stay unambiguous.
Use ``cgis_ingest`` first if the database does not exist. ``source_root``
locates source files on disk when the graph was ingested from a
sub-directory (e.g. ``"src"`` after ``cgis ingest ./src``); it is safe to
pass even when the stored paths already start with that segment (#228).
When no candidate exists the ``<source>`` block degrades gracefully to
"unavailable".
| Name | Required | Description | Default |
|---|---|---|---|
| fqn | Yes | Fully qualified name, e.g. pkg.module.Class.method. A unique dot-boundary suffix also resolves; an ambiguous one returns candidates. Use cgis_find_symbol to look a name up. | |
| depth | No | Call hops around the focal node; 1 means direct callers and callees. | |
| db_path | No | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's β prefer an absolute path. | graph.db |
| source_root | No | Directory the graph's stored file paths are relative to β normally the project_path given to cgis_ingest; prefer an absolute path. Empty means the server's working directory, so source shows as unavailable when the server runs elsewhere. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so thoroughly: it discloses that only calls are followed, depth defaults to one hop, source is included only when found, source_root behavior including the #228 edge case, and graceful degradation to 'unavailable'. This is rich behavioral disclosure beyond what any schema field states.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The first sentence immediately states the core deliverable and scope. Subsequent paragraphs each add distinct value: usage guidance, alternative routing, return format rationale, prerequisites, and parameter edge cases. Nothing is wasted, and the most decision-relevant information is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 4-parameter tool with no annotations, the description covers prerequisites, alternatives, parameter edge cases, output format, and failure behavior. Even with an output schema present, the description's explanation of the XML-tagged prompt and token efficiency adds value an agent cannot infer from the schema alone.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so baseline is 3, but the description adds meaningful parameter nuance: source_root is safe to pass even when stored paths already start with that segment, emptiness means the server's working directory, and depth one hop means direct callers/callees. This goes beyond the schema's own parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: returns a prompt-ready brief on one FQN covering source, class, direct callers, and callees. It also distinguishes itself from siblings by naming cgis_trace_flow and cgis_analyze_impact as multi-hop alternatives, so an agent can tell the tools apart.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says when to use it ('before editing a symbol, instead of reading its files'), when not to (for multi-hop subgraphs use cgis_trace_flow or cgis_analyze_impact), and what prerequisite to check ('Use cgis_ingest first if the database does not exist'). This leaves no ambiguity about placement among siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cgis_driftA
Report per-domain architectural drift against declared ideal patterns.
Returns JSON: ``any_critical`` verdict, per-domain reports (each carrying a
``fit`` block β nearest alphabet template + residual + good/weak/none band),
the observe-only quotient layer, and ``coverage`` (graph prefixes bound by no
domain). Call after ``cgis_ingest`` to learn whether your edits pushed a
domain past its drift tolerance.
``max_drift`` is now the default tolerance only for domains that omit
``drift_tolerance`` β it no longer caps domains that declare their own
(see #170).
``profile``: when set, score only domains with this profile (plus
profile-less ones). Use when your patterns.yaml mixes languages but the
graph holds one language β avoids false EMPTY reports for other-language
domains that would otherwise fail the gate.
``max_residual``: a domain whose nearest template is farther than this gets
``fit.band = "none"`` ("no template fits") β a grab-bag module or an
alphabet gap, independent of drift tolerance (#177).
| Name | Required | Description | Default |
|---|---|---|---|
| db_path | No | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's β prefer an absolute path. | graph.db |
| profile | No | Score only domains with this profile, plus profile-less ones β e.g. one language when patterns.yaml mixes several. | |
| max_drift | No | Drift tolerance for domains that declare no drift_tolerance of their own. | |
| max_residual | No | Distance to the nearest template beyond which a domain's fit band is "none" (no template fits). | |
| patterns_path | No | patterns.yaml (.yaml or .yml) declaring each domain's expected pattern and tolerance, relative to the server's working directory. cgis_init_ontology proposes one. | docs/ontology/patterns.yaml |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully discloses behavior. It details the return JSON structure (any_critical, per-domain reports with fit blocks, quotient layer, coverage), explains the nuanced behavior of max_drift (now a default tolerance only for domains without their own), and clarifies max_residual's independence from drift tolerance. This goes beyond a simple report description and covers edge cases and parameter effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is moderately long but well-structured with paragraphs and code formatting. It front-loads the purpose and return format, then addresses parameter nuances. Each sentence carries informational weight, and the use of backticks and references (#170, #177) adds precision without excessive verbosity. It could be slightly tighter, but it is not padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, the description is thorough. It covers the return format, when to call it (after cgis_ingest), parameter behaviors, and even notes the change in max_drift semantics. The presence of an output schema reduces the need to detail return values, and the description fills the remaining gaps. No essential information for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so all parameters are already documented. The description adds value by clarifying semantics beyond the schema: max_drift's role as a default only for domains lacking their own tolerance, profile's purpose for filtering by language, and max_residual's meaning for fit.band classification. This extra context elevates the description above the baseline 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Report per-domain architectural drift against declared ideal patterns.' It uses a specific verb ('report'), a clear resource ('per-domain architectural drift'), and the context ('against declared ideal patterns'). This distinguishes it from sibling tools like cgis_validate or cgis_metrics, which serve different analytical purposes.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit usage context: 'Call after cgis_ingest to learn whether your edits pushed a domain past its drift tolerance.' It also provides conditional usage for the 'profile' parameter ('Use when your patterns.yaml mixes languages...'). While it doesn't explicitly mention when not to use the tool or name alternatives, the clear trigger condition and parameter-specific guidance make the usage intent strong.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cgis_find_orphansA
Classes nothing in production builds, extends or names β dead-code candidates.
Finds classes that no test, type checker or linter flags, because each is
still imported somewhere: a package re-export keeps a class importable long
after its last real caller is gone. On one mid-sized backend this reported
43 of 1 789 classes, and the hand-written equivalent's findings were all
real and all deleted.
Two filters decide the answer. **Tests are not users** β a class built only
by its own test is exactly the shape being hunted. **A re-export is not a
use** β ``IMPORTS_SYMBOL`` does not count, or nothing is ever reported. What
counts is construction (``CALLS``), inheritance (``EXTENDS``) and being named
(``REFERENCES`` β an annotation, or a class handed to a framework); the last
keeps abstract ports and Protocols off the list.
``prefix`` narrows to one package on a dot boundary. ``include_tests`` counts
test code as a user, turning the report into "unreachable from anywhere".
Machine-generated classes are **hidden by default**, and ``include_generated``
puts them back. The query is right about them β nothing constructs a
betterproto stub β but nobody hand-deletes one either, so they are noise
rather than a finding. Measured on owner-api at b7d02fe6, five of six
reported orphans were generated entities and the sixth a nested pydantic
``Config``: the unfiltered report had no actionable row in it (#432).
Returns JSON ``{orphans, considered, test_sources, generated_excluded}``;
each orphan carries ``fqn``/``file``/``line``. **A listing is a candidate for
deletion, not a proof** β a class named only inside a decorator (#429) or
arriving through a star import is invisible here, so the sweep errs towards
reporting a live class rather than hiding a dead one. ``test_sources: 0`` in a
repository that has tests means the graph predates the ``is_test`` column:
re-ingest. ``generated_excluded`` counts every generated class left out of
the population under the same ``prefix``, referenced or not β so ``0`` on a
repository with generated code means the same for ``is_generated``, which has
no backfill: the marker is in the file header, not in the database.
| Name | Required | Description | Default |
|---|---|---|---|
| prefix | No | Only consider classes under this FQN prefix, cut on a dot boundary. | |
| db_path | No | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's β prefer an absolute path. | graph.db |
| include_tests | No | Count test code as a user, so the report means "unreachable from anywhere". | |
| include_generated | No | Include machine-generated classes, which are hidden by default. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden β and it excels. It discloses the return shape {orphans, considered, test_sources, generated_excluded}, the error bias (errs toward reporting a live class rather than hiding a dead one), the invisible cases (decorator-only names, star imports), the test_sources: 0 meaning re-ingest, the generated_excluded counting semantics, and the machine-generated hidden-by-default behavior with a measured example. This is exceptionally rich behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long and dense. Most content earns its place β the caveats about decorators, star imports, and re-ingest are genuinely important. But it carries some bloat: the commit hash b7d02fe6, issue numbers (#432, #429), and the '43 of 1 789 classes' anecdote add authenticity but length without changing agent behavior. The first sentence is awkward. It is structured in digestible paragraphs and reasonably front-loaded, but not lean.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex dead-code analysis tool, this is complete. Even though an output schema exists, the description goes beyond it by explaining the failure modes (test_sources: 0 meaning stale graph, generated_excluded: 0 with generated code meaning missing backfill), the false-positive bias, and the filtering semantics. An agent has everything needed to invoke it correctly and interpret results β nothing critical is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema's own parameter descriptions are already strong. The tool description adds meaningful nuance on top: prefix's dot-boundary cutting, include_tests converting the report to 'unreachable from anywhere', and include_generated framing generated classes as noise rather than findings. This goes beyond the schema baseline of 3, though the schema already did heavy lifting, so the increment is moderate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly identifies the tool's job: finding dead-code candidates (orphan classes). The second paragraph clarifies the purpose precisely β classes kept importable by re-exports but with no real callers. However, the opening sentence 'Classes nothing in production builds, extends or names' is awkwardly phrased and reads like a fragment; the intent is recoverable but the first line hurts clarity. The description does distinguish this from siblings by framing it as a dead-code sweep rather than a reachability/impact query.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains the tool's philosophy deeply β tests are not users, re-exports are not uses, what counts is CALLS/EXTENDS/REFERENCES β which implicitly tells an agent when this tool applies. It also explains how flags change the semantics (include_tests becomes 'unreachable from anywhere'). However, it never explicitly names sibling alternatives or states when NOT to use this tool in favor of, say, cgis_audit_reachability or cgis_analyze_impact. The usage context is strong but the exclusion/alternative routing is absent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cgis_find_symbolA
Resolve a partial symbol name to candidate FQNs (substring match, ranked).
Call this BEFORE ``cgis_trace_flow`` / ``cgis_analyze_impact`` /
``cgis_get_structure`` when you know a short name (e.g.
``get_reservation_prices``) but not its full FQN β it removes the
read-the-file-first guesswork. Returns JSON ``[{fqn, name, type, file,
line}]`` ranked exact > prefix > substring. ``kind`` filters by node type
(FUNCTION / METHOD / CLASS / β¦); ``fqn_prefix`` scopes the search.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No | Only return this node type, e.g. FUNCTION, METHOD or CLASS (any case). An unknown type matches nothing rather than raising an error. | |
| limit | No | Maximum number of candidates to return. | |
| query | Yes | Leaf symbol name to search for, without dots (e.g. get_flow_result) β not an FQN. Case-insensitive substring match, ranked exact > prefix > substring. | |
| db_path | No | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's β prefer an absolute path. | graph.db |
| fqn_prefix | No | Only return symbols at or under this FQN prefix, matched on whole dot-segments: app.svc does not match app.svc_alt, and a partial segment matches nothing. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses the ranking order (exact > prefix > substring), the JSON return shape, and that kind/fqn_prefix filter results. It does not explicitly state the operation is read-only, but as a lookup tool this is implied. It adds meaningful behavioral context beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences with no filler. The purpose is front-loaded, usage guidance follows immediately, and the return format and key filters are mentioned compactly. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 5-parameter tool with an output schema and no annotations, the description covers the core purpose, when to use it, return format, and two of the filtering parameters. It omits explicit mention of 'limit' and 'db_path', but those are fully described in the schema. Error behavior (e.g., unknown kind) is covered in the schema, not the description, which is acceptable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents all five parameters. The description adds marginal value by relating 'kind' and 'fqn_prefix' to their filtering effects, but it does not elaborate on 'limit' or 'db_path'. This is baseline 3 with slight extra context.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise verb+resource: 'Resolve a partial symbol name to candidate FQNs (substring match, ranked).' It explicitly names the sibling tools it precedes (cgis_trace_flow, cgis_analyze_impact, cgis_get_structure), making differentiation clear without reading schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit condition for use: 'Call this BEFORE cgis_trace_flow / cgis_analyze_impact / cgis_get_structure when you know a short name but not its full FQN.' It even states the alternative it removes ('read-the-file-first guesswork'), leaving no ambiguity about when to invoke this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cgis_fractalA
Report the motif census across the repository's structural tiers.
Coarsens the graph along its own structure β symbol, class, module, then
directory levels trimmed from the leaf end β and measures the 13-triad
census at every rung. Returns JSON: one entry per layer (IMPORTS, CALLS)
with the full per-rung curve (groups, triads, entropy in bits, dominant
motif, tangle ratio) and the fit.
``verdict`` is the sign of ``slope`` (entropy bits per halving of the group
count) outside a ``2 * std_error`` dead-band: ``hierarchical`` means
coarsening ADDS motif diversity, ``flat`` means it destroys it,
``scale_invariant`` means the mix is the same at every scale, and
``no_signal`` means fewer than three rungs carried enough triads to fit.
Read the curve, not just the verdict β the fit is a lossy summary of a
non-linear curve. Observe-only: this tool enforces nothing and no gate
reads it. Call after ``cgis_ingest``.
| Name | Required | Description | Default |
|---|---|---|---|
| db_path | No | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's β prefer an absolute path. | graph.db |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure, and it delivers: it explains that the tool is observe-only, enforces nothing, is read by no gate, and that the verdict is a lossy summary of a non-linear curve. This goes well beyond a basic 'returns JSON' statement and tells the agent what to trust and what to interpret carefully.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence in the description earns its place: purpose, method, output shape, verdict semantics, interpretation warning, observability, and prerequisite. The first line is front-loaded as a crisp summary, and the rest expands only where the agent genuinely needs more context.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description fully covers what the tool does, how the analysis works, what the output contains, how to interpret the verdict, and when to call it. Given the tool's complexity, this is a complete operational explanation; the input schema is simple and fully documented, and the return shape is itemized in detail.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the input schema fully documents db_path, including the relative-path resolution behavior. The description adds no extra parameter details and does not need to; the schema already carries the load, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise verb-resource pair: 'Report the motif census across the repository's structural tiers.' This uniquely identifies the tool's function and clearly separates it from siblings like cgis_metrics or cgis_get_structure by naming a specific analytic artifact (motif census) and a specific method (coarsening along structural tiers).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives clear context for invocation: 'Call after cgis_ingest' and 'Observe-only: this tool enforces nothing and no gate reads it.' It does not explicitly name alternatives or state when not to use it, so it stops short of a 5, but the sequencing and observational caveat provide solid practical guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cgis_get_structureA
Members of a module or class β or, for a package prefix, the modules it holds.
Follows containment (CONTAINS/DECLARES) only, so no call or import appears.
A package is not a node in the graph (#487), so its row and the edges to its
modules are synthesized for the answer and marked with a virtual file path.
For how the code connects use ``cgis_trace_flow`` (what it depends on) or
``cgis_analyze_impact`` (what depends on it).
Matches the CLI ``structure`` command. ``output_format="mermaid"`` (default) returns a
diagram of the hierarchy rooted at the given FQN; ``"json"`` returns the
joinable ``{root, nodes, edges}`` payload with real FQNs.
| Name | Required | Description | Default |
|---|---|---|---|
| fqn | Yes | Fully qualified name, e.g. pkg.module.Class.method. A unique dot-boundary suffix also resolves; an ambiguous one returns candidates. Use cgis_find_symbol to look a name up. | |
| depth | No | Maximum containment levels to descend (module β class β method). | |
| db_path | No | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's β prefer an absolute path. | graph.db |
| output_format | No | "mermaid" for a diagram, or "json" for a payload with real FQNs (case-insensitive). Any other value returns an error. | mermaid |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full behavioral burden, and it does so thoroughly: package nodes are synthesized with virtual file paths, the output shape depends on output_format, and it matches the CLI structure command. It discloses notable edge cases such as packages not being graph nodes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with a crisp one-line definition, followed by scope constraints, alternatives, and output details. Every sentence earns its place; even the package-node nuance and sibling references are necessary for correct invocation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with no annotations, sample schema descriptions, and an output schema indicated, the description covers the important behaviors, alternatives, and parameter-specific output semantics. Nothing needed for correct selection or invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already describes all four parameters well. The description adds extra meaning beyond the schema for output_format by specifying the JSON payload as 'joinable {root, nodes, edges}' and clarifying that the mermaid diagram is rooted at the given FQN.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb+resource: it returns members of a module/class or modules held by a package prefix, and explicitly states it follows containment only. It distinguishes itself from cgis_trace_flow and cgis_analyze_impact by name, so an agent can select the correct tool without inspecting the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states when to use alternatives: use cgis_trace_flow for dependencies or cgis_analyze_impact for dependents when code connectivity is the question. It also clarifies containment-only semantics (no calls/imports), which defines the boundary of this tool's scope.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cgis_ingestA
Scan a local directory, extract all symbols, resolve links, and build the graph DB.
Use this to initialise or refresh the code knowledge graph for a project.
Node FQNs are normalised relative to the workspace root so the graph is
portable across machines.
``db_path`` must name a database β it has to end in ``.db``, ``.sqlite`` or
``.sqlite3``, live in a directory that already exists, and not point at an
existing file that is not a SQLite database. cgis will not create parent
directories.
By default the ingest is **incremental**: only changed/new files are
re-scanned, and the summary reports both what changed this run and the
whole-graph total. When a change alters what other files resolve against β a
renamed, removed or added symbol, a deleted or new file, a changed base class
or re-export β the incremental run rebuilds the whole graph itself, so edges
in unchanged files never point at symbols that no longer exist. Set
``full_rebuild=True`` to force a re-scan of every file from scratch.
| Name | Required | Description | Default |
|---|---|---|---|
| db_path | No | Where to write the graph: must end in .db, .sqlite or .sqlite3, in a directory that already exists, and must not be an existing non-SQLite file. A relative path resolves against the server's working directory. | graph.db |
| full_rebuild | No | Re-scan every file from scratch instead of the incremental default. | |
| project_path | Yes | Root directory of the project to scan. A relative path resolves against the MCP server's working directory. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden, and it does so thoroughly. It discloses that ingest is incremental by default, that the whole graph is rebuilt when resolution changes occur, that full_rebuild=True forces a full rescan, that the graph is portable due to FQN normalisation, and that cgis will not create parent directories.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and then adds necessary caveats and behavioral details in a logical order. Every sentence contributes either to usage, path constraints, or incremental rebuild semantics; nothing is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists and the parameter count is only three, the description is complete. It covers the operation, default behavior, rebuild behavior, path constraints, and even what the summary reports, leaving no critical gap for invoking the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3, but the description adds substantial meaning beyond the schema: db_path constraints are elaborated, the incremental-vs-full-rebuild behavior is explained, and the relative-path resolution for both db_path and project_path is clarified. This exceeds what the schema alone provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a concrete action chain β scan a directory, extract symbols, resolve links, and build the graph DB β and explicitly says it initializes or refreshes a project's code knowledge graph. This clearly separates it from the sibling analysis tools like cgis_trace_flow or cgis_analyze_impact.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a clear usage context: 'Use this to initialise or refresh the code knowledge graph for a project.' It does not explicitly enumerate when not to use it or name alternative tools, but the context is specific enough that an agent can identify the appropriate situation.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cgis_init_ontologyA
Propose a starter patterns.yaml from the measured graph (read-only).
Returns the YAML text β save it yourself (e.g. to patterns.yaml), review
the proposed labels, then run ``cgis_drift`` with it. Tolerances are the
measured scores plus ``margin``: a baseline to ratchet down, not a verdict.
No files are written; the caller decides where to persist the output.
| Name | Required | Description | Default |
|---|---|---|---|
| depth | No | Fixed FQN segment depth for domain discovery (positive); omit to pick it automatically. | |
| margin | No | Headroom added to each measured score to form the proposed tolerance. | |
| db_path | No | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's β prefer an absolute path. | graph.db |
| min_nodes | No | Domains with fewer nodes stay hygiene-only instead of getting a label. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It explicitly states the operation is read-only, that 'No files are written', and that the caller decides where to persist the output. This fully discloses the behavioral impact, leaving no hidden side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and front-loaded: purpose first, then output and persistence behavior, then margin semantics. Every sentence earns its place, with no redundant filler beyond the deliberate repetition of the read-only/no-write guarantee for emphasis.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given an output schema exists and all parameters have schema descriptions, the description still covers the essential workflow context: what the tool returns, how to use it downstream, and the absence of side effects. Nothing an agent needs to correctly call and interpret this tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds meaningful interpretation beyond the schema by explaining that tolerances are 'measured scores plus margin' and framing them as a ratcheting baseline rather than a verdict. This gives strategic context for margin, though it does not add additional semantics for depth, db_path, or min_nodes.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The first sentence states a specific action ('propose a starter patterns.yaml'), the resource ('from the measured graph'), and the read-only nature. It clearly differentiates itself from sibling tools like cgis_drift by framing the output as a starting artifact to be consumed by cgis_drift.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives an explicit workflow: generate the YAML, save it, review the labels, then run cgis_drift with it. It also explains the semantic role of the output ('a baseline to ratchet down, not a verdict'), which helps the agent decide when this tool is appropriate. It lacks explicit when-not-to-use guidance or named alternatives, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cgis_metricsA
Whole-graph architectural metrics β coupling bottlenecks, God classes, PageRank.
Returns JSON ``{bottlenecks, god_classes, critical}`` computed with vectorized
DuckDB aggregations over the whole graph (fan-in/fan-out coupling,
declared-member counts, PageRank) β the global "what are the hotspots?" view
that complements the node-local trace/impact/context tools. Requires the
optional ``duckdb`` extra; an unavailable dependency is reported as a normal
β message.
``exclude`` drops any node whose FQN contains one of the given dot-segments
(e.g. ``["tests"]`` removes both ``tests.*`` and ``domains.*.tests.*``) so
test/vendor scaffolding stays out of the rankings.
``scope`` is its complement: it keeps only nodes under one of the given
dot-prefixes, anchored and cut on a dot boundary, so
``["domains.reservation"]`` is that subtree and not
``domains.reservation_archive``. Use it for a per-domain review. The two
compose, and they differ where it matters for PageRank β ``exclude`` removes
nodes from the propagation graph, ``scope`` filters the rows and lets rank
propagate over the whole graph, so a scoped run reports how central the
subtree is *globally*. Coupling in-degree likewise keeps counting callers
from outside the scope, which is the ripple a domain review is after (#239).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Top-N rows returned per section. | |
| scope | No | Keep only nodes under any of these dot-prefixes, e.g. ["domains.billing"]; rank still propagates over the whole graph. | |
| db_path | No | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's β prefer an absolute path. | graph.db |
| exclude | No | Drop nodes whose FQN contains any of these dot-segments, e.g. ["tests"]; they are removed from PageRank propagation too. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does so thoroughly: it discloses the optional duckdb dependency, how unavailable dependencies are reported, how exclude removes nodes from PageRank propagation, how scope differs in propagation semantics, and that coupling in-degree still counts callers outside the scope. This goes far beyond the schema and annotative defaults.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose and result shape, then dives into parameter semantics and behavioral nuances. It is longer than a minimal definition, but most sentences earn their place because they clarify subtle ranking behavior that materially affects invocation and interpretation. A slightly tighter ending would make it even cleaner.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's algorithmic complexity and the absence of annotations, the description is remarkably complete: it covers return shape, dependency risk, error behavior, parameter semantics, composition rules, and the graph-propagation model. An agent has enough information to select, invoke, and interpret the results correctly without additional documentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema coverage is 100%, the description adds substantial meaning beyond the schema: it gives concrete examples for exclude (tests.* and domains.*.tests.*), explains dot-boundary anchoring for scope, describes how the two parameters compose, and clarifies their differing effect on PageRank and coupling measurements. This is exactly the kind of semantic enrichment the schema alone cannot provide.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb and resource: computes whole-graph architectural metrics (coupling bottlenecks, God classes, PageRank). It explicitly distinguishes itself from node-local trace/impact/context tools, so an agent can identify what this tool is for without inspecting the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It clearly states when to use this toolβfor the global hotspot view and per-domain reviewsβand contrasts it with node-local tools as complementary rather than substitutable. It does not list specific sibling alternatives by name for exclusion, but the context and scope/exclude guidance give strong directional usage cues.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cgis_overviewA
Where to start in a graph you know nothing about: sizes and a package map.
Call this first in an unfamiliar repository β every other tool needs a name,
and this is the one that hands you some. Returns JSON: symbol counts by type,
file and edge totals, the unresolved-edge ratio, and the largest packages with
production and tests listed separately. Each ``prefix`` goes straight into
``cgis_get_structure`` (the modules it holds), ``cgis_find_symbol``
(``fqn_prefix``) or ``cgis_metrics`` (``scope``).
Listings are capped; ``packages_omitted`` appears when rows were cut. Entry
points are deliberately not reported β "nothing calls it" is not one on a
framework codebase, where most handlers have no incoming call edge.
| Name | Required | Description | Default |
|---|---|---|---|
| depth | No | FQN segments per package prefix; 1 is the top level. | |
| limit | No | Maximum packages listed per section. | |
| db_path | No | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's β prefer an absolute path. | graph.db |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the full disclosure burden and does a strong job: it lists what the JSON contains, warns that listings are capped and packages_omitted may appear, and explains a non-obvious omission (entry points) plus its rationale. It stops short of explicitly stating whether the operation is side-effect-free or how it behaves on an empty/missing graph, but the delivered context is well above the baseline.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the most important guidance β where to start and what it returns β and every sentence adds value, from the cap behavior to the deliberate omission of entry points. It is compact for the amount of context it conveys and keeps the agent's workflow front and center.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that an output schema exists and the parameters are fully documented, the description covers the remaining decision-relevant context: what to expect, how to route results into sibling tools, that listings are bounded, and why certain data is intentionally absent. An agent has enough to call this tool correctly and interpret its output meaningfully.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already documents all three parameters with 100% coverage, so the baseline is 3. The description adds useful context about how returned prefixes connect to other tools, but it does not clarify depth, limit, or db_path semantics beyond what the schema already states. Since the schema covers all parameters, this is an appropriate score.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a concrete definition β 'sizes and a package map' β and clearly states the tool's role as the starting point in an unfamiliar graph. It names the exact outputs (symbol counts, file/edge totals, unresolved-edge ratio, largest packages) and explicitly frames itself against the other cgis_* tools by saying it is the one that provides the names they need. This is a specific verb+resource with clear differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives an explicit when-to-use rule: 'Call this first in an unfamiliar repository.' It also explains the workflow relationship by stating that every other tool needs a name and pointing out that each returned prefix feeds into cgis_get_structure, cgis_find_symbol, or cgis_metrics. It even includes a deliberate exclusion β entry points are not reported β with reasoning, which helps an agent avoid misinterpreting missing incoming edges.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cgis_suggest_packagesA
Suggest sub-package boundaries for a package from its dependency communities.
Returns JSON: modularity_q, divergence, direction (under/over/matched),
verdict (split/consolidate/aligned/leave/borderline/no_signal), the detected
communities (id + member files), the cross-community bridge edges (cost of
splitting), and the thresholds used. Default layer is IMPORTS; set
``with_calls`` for the combined import+call graph. Run ``cgis_ingest`` first.
A mis-rooted graph (import targets resolve to no internal file) returns
``no_signal`` with a diagnostic note rather than a silent clean verdict.
| Name | Required | Description | Default |
|---|---|---|---|
| min_q | No | Modularity threshold: at or above it, a package whose layout disagrees with its communities is flagged split (or consolidate, if over-split). | |
| prefix | No | FQN prefix of the package to analyse, e.g. cgis.query, matched on whole dot-segments. Needed in practice: without it the verdict is no_signal. | |
| db_path | No | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's β prefer an absolute path. | graph.db |
| with_calls | No | Use the combined import + call graph instead of imports only. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden, and it delivers: it discloses the exact return payload (modularity_q, divergence, direction, verdict, communities, bridge edges, thresholds), the default graph layer, and the mis-rooted-graph fallback (returns no_signal with a diagnostic note rather than a silent clean verdict). This is strong behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core purpose, then a compact return-value summary, then the default-layer and prerequisite notes, ending with a one-line caveat. Every sentence earns its place with zero waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, and the description still explains the returned JSON fields and verdict values, names the prerequisite tool, and covers the failure mode (mis-rooted graph). An agent has everything needed to call it correctly; the only minor gap is not describing the shape of the communities/bridge-edge entries, but the output schema presumably covers that.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds practical value: it flags that prefix is 'Needed in practice: without it the verdict is no_signal' and warns that relative db_path resolves against the MCP server's working directory. These notes go beyond the schema text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Suggest sub-package boundaries for a package from its dependency communities') that clearly distinguishes this from siblings like cgis_ingest (graph construction), cgis_drift, and cgis_metrics. An agent can tell at a glance this is the community-detection/refactoring advisor.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names the prerequisite ('Run cgis_ingest first') and explains the default layer (IMPORTS) with how to switch it (with_calls). It doesn't enumerate exclusions or alternative tools, but the when-to-use context is clear and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cgis_trace_flowA
Downstream subgraph of one FQN: everything it reaches within depth hops.
Follows every edge except containment β in practice calls, imports,
inheritance, DI dependencies and references β between internal code, so this
answers "what does X depend on?". Containment and
stdlib/third-party nodes are left out unless ``include_structure`` /
``include_external`` ask for them (external covers stdlib, third-party and
unresolved call targets) β the same view as the CLI's ``trace``.
For what depends on X use
``cgis_analyze_impact``; for only the members of a module or class,
``cgis_get_structure``; for a source-included brief to read before editing
one symbol, ``cgis_context``.
``output_format="mermaid"`` (default) returns a human-readable diagram;
``"json"`` returns a joinable ``{root, nodes, edges, coverage}`` payload
with real FQNs (not display hashes) for agent/CI use. ``coverage`` counts
the calls the traversed functions make that resolved to nothing, and
``top_unresolved`` names the most frequent. Read the names, not only the
ratio: in Python most are methods on untyped locals (``logger.info``,
``items.append``), which cut nothing short. Use ``cgis_ingest`` first if
the database does not exist yet.
| Name | Required | Description | Default |
|---|---|---|---|
| fqn | Yes | Fully qualified name, e.g. pkg.module.Class.method. A unique dot-boundary suffix also resolves; an ambiguous one returns candidates. Use cgis_find_symbol to look a name up. | |
| depth | No | Maximum edge hops downstream, over calls, imports, inheritance, DI dependencies and references (plus containment with include_structure). | |
| db_path | No | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's β prefer an absolute path. | graph.db |
| output_format | No | "mermaid" for a diagram, or "json" for a payload with real FQNs (case-insensitive). Any other value returns an error. | mermaid |
| include_external | No | Also return stdlib, third-party and unresolved call targets β calls on values whose type is decided at runtime. Off by default, as in the CLI, because they dominate the payload; in json, coverage/top_unresolved still counts what was dropped. | |
| include_structure | No | Also follow containment (CONTAINS/DECLARES): a module's or class's own members, and the class or file enclosing a symbol. Off by default, as in the CLI; cgis_get_structure is the tool for members alone. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden of behavioral disclosure. It discloses that containment edges are excluded by default, that stdlib/third-party/unresolved nodes are excluded unless flags ask for them, that output_format='mermaid' is the default and 'json' returns a joinable payload with real FQNs, and that coverage counts calls that resolved to nothing. It also warns about interpreting top_unresolved ('Read the names, not only the ratio'). The only minor gap is that it doesn't explicitly state the operation is read-only, but the description's framing as a traversal/query makes that reasonably clear.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well-organized: the core definition is front-loaded in the first sentence, followed by edge-type details, then sibling routing, then output format details. Every sentence earns its place. It is longer than the HIGH calibration example, but the tool is more complex (6 params, multiple output formats, sibling relationships), so the length is justified. It loses one point for being somewhat dense in the middle section where edge types and exclusions are packed together.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (6 parameters, two output formats, multiple sibling relationships, and a database prerequisite), the description covers everything an agent needs: what the tool does, when to use it, what the output formats return, how to interpret the coverage field, and the prerequisite (cgis_ingest). The output schema exists, so return values need not be spelled out. The description is complete for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all six parameters. The description adds value beyond the schema by explaining the semantics of the output_format values ('mermaid' for human-readable diagram, 'json' for agent/CI use with real FQNs), clarifying what include_external covers ('stdlib, third-party and unresolved call targets'), and noting that coverage/top_unresolved still counts dropped calls in json mode. It also explains the depth parameter's edge types. This goes beyond the baseline 3 for full schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a precise definition: 'Downstream subgraph of one FQN: everything it reaches within depth hops.' It names the specific verb (trace), the resource (downstream subgraph of one FQN), and the edge types followed. It also explicitly distinguishes itself from siblings: cgis_analyze_impact for reverse dependencies, cgis_get_structure for members only, and cgis_context for a source-included brief. This is a model of sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: 'this answers "what does X depend on?"' and then names the alternatives with their conditions: 'For what depends on X use cgis_analyze_impact; for only the members of a module or class, cgis_get_structure; for a source-included brief to read before editing one symbol, cgis_context.' It also tells the agent to run cgis_ingest first if the database does not exist yet. This is complete usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
cgis_validateA
Report graph integrity as JSON: edge resolution stats + health verdict.
Check this before trusting ``cgis_analyze_impact`` output β a high
unresolved ratio means callers are missing from the graph.
| Name | Required | Description | Default |
|---|---|---|---|
| db_path | No | SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's β prefer an absolute path. | graph.db |
| threshold | No | Highest unresolved-edge ratio (0-1) still reported as healthy. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the burden of behavioral disclosure. The word 'Report' and the output description imply a read-only diagnostic, but the description never explicitly states that the tool does not modify the graph or database, nor does it mention permissions, failure modes, or side effects. Partial transparency at best.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact sentences, with the core purpose front-loaded and the usage guidance in the second sentence. Every word adds value, and there is no filler or repetition of schema details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With a full output schema and 100% parameter coverage, the description supplies the essential usage trigger and output flavor. It could be more complete by explicitly stating that the tool is non-mutating, but the read-oriented language and existing schema are sufficient for an agent to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Parameter schema coverage is 100%, with db_path and threshold already well documented. The description adds some interpretive value by linking 'high unresolved ratio' to missing callers, which gives context to the threshold parameter, but it mostly restates what the schema already conveys. This meets the baseline of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource, 'Report graph integrity as JSON: edge resolution stats + health verdict', which clearly states what the tool produces. It also differentiates itself from siblings by positioning itself as a pre-check for cgis_analyze_impact, so an agent can tell when to pick this tool.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides explicit usage context: 'Check this before trusting cgis_analyze_impact output' and explains the consequence of a high unresolved ratio. However, it does not mention when to avoid this tool or point to alternative validation workflows, so it falls short of full when/when-not coverage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.21.6- Changed
cgis_analyze_impact3 fields changed- changed
Input schema / properties / depth / descriptionPrevious value: -"Maximum edge hops upstream. Every edge type counts as a hop β callers, importers, subclasses, type references, DI dependents and the enclosing class or file all appear alongside each other."New value: +"Maximum edge hops upstream, over callers, importers, subclasses, type references and DI dependents (plus the enclosing class or file with include_structure)." - added
Input schema / properties / include_externalAdded value: +{ + "default": false, + "description": "Also return stdlib, third-party and unresolved call targets β calls on values whose type is decided at runtime. Off by default, as in the CLI, because they dominate the payload; in json, coverage/top_unresolved still counts what was dropped.", + "title": "Include External", + "type": "boolean" +} - added
Input schema / properties / include_structureAdded value: +{ + "default": false, + "description": "Also follow containment (CONTAINS/DECLARES): a module's or class's own members, and the class or file enclosing a symbol. Off by default, as in the CLI; cgis_get_structure is the tool for members alone.", + "title": "Include Structure", + "type": "boolean" +}
- Added
cgis_overview - Changed
cgis_trace_flow3 fields changed- changed
Input schema / properties / depth / descriptionPrevious value: -"Maximum edge hops downstream. Every edge type counts as a hop β calls, imports, inheritance, DI dependencies, references and containment β so from a module or class the first hop is mostly its own members and imports."New value: +"Maximum edge hops downstream, over calls, imports, inheritance, DI dependencies and references (plus containment with include_structure)." - added
Input schema / properties / include_externalAdded value: +{ + "default": false, + "description": "Also return stdlib, third-party and unresolved call targets β calls on values whose type is decided at runtime. Off by default, as in the CLI, because they dominate the payload; in json, coverage/top_unresolved still counts what was dropped.", + "title": "Include External", + "type": "boolean" +} - added
Input schema / properties / include_structureAdded value: +{ + "default": false, + "description": "Also follow containment (CONTAINS/DECLARES): a module's or class's own members, and the class or file enclosing a symbol. Off by default, as in the CLI; cgis_get_structure is the tool for members alone.", + "title": "Include Structure", + "type": "boolean" +}
2 tool updates
v0.21.5- Changed
cgis_analyze_impact1 field changed- changed
Input schema / properties / depth / descriptionPrevious value: -"Maximum edge hops upstream. Every edge type counts as a hop β CALLS, but also IMPORTS, CONTAINS and REFERENCES β so modules importing the target and the file containing it appear alongside its callers."New value: +"Maximum edge hops upstream. Every edge type counts as a hop β callers, importers, subclasses, type references, DI dependents and the enclosing class or file all appear alongside each other."
- Changed
cgis_trace_flow1 field changed- changed
Input schema / properties / depth / descriptionPrevious value: -"Maximum edge hops downstream. Every edge type counts as a hop β CALLS, but also IMPORTS, CONTAINS and REFERENCES β so from a module the first hops are mostly imports and structure."New value: +"Maximum edge hops downstream. Every edge type counts as a hop β calls, imports, inheritance, DI dependencies, references and containment β so from a module or class the first hop is mostly its own members and imports."
1 tool update
v0.21.4- Changed
cgis_audit_reachability1 field changed- changed
Input schema / properties / from_prefix / descriptionPrevious value: -"Only audit sources at or under this FQN prefix, matched on whole dot-segments β a partial segment selects nothing and returns an empty audit, not a clean one. Combined with from_type when both are given."New value: +"Only audit sources at or under this FQN prefix, matched on whole dot-segments. A selection matching no source is an error naming the whole-segment prefixes it may have meant. Combined with from_type when both are given."
14 tool updates
v0.21.1- Changed
cgis_analyze_impact4 fields changed- added
Input schema / properties / db_path / descriptionAdded value: +"SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's β prefer an absolute path." - added
Input schema / properties / depth / descriptionAdded value: +"Maximum edge hops upstream. Every edge type counts as a hop β CALLS, but also IMPORTS, CONTAINS and REFERENCES β so modules importing the target and the file containing it appear alongside its callers." - added
Input schema / properties / fqn / descriptionAdded value: +"Fully qualified name, e.g. pkg.module.Class.method. A unique dot-boundary suffix also resolves; an ambiguous one returns candidates. Use cgis_find_symbol to look a name up." - added
Input schema / properties / output_format / descriptionAdded value: +"\"mermaid\" for a diagram, or \"json\" for a payload with real FQNs (case-insensitive). Any other value returns an error."
- Changed
cgis_audit_reachability5 fields changed- added
Input schema / properties / db_path / descriptionAdded value: +"SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's β prefer an absolute path." - added
Input schema / properties / depth / descriptionAdded value: +"Maximum reachability depth; a longer path is reported as a gap." - added
Input schema / properties / from_prefix / descriptionAdded value: +"Only audit sources at or under this FQN prefix, matched on whole dot-segments β a partial segment selects nothing and returns an empty audit, not a clean one. Combined with from_type when both are given." - added
Input schema / properties / from_type / descriptionAdded value: +"NodeType of the sources to audit, e.g. ROUTE_HANDLER, API_ENDPOINT or FUNCTION (any case). Give this, from_prefix, or both." - added
Input schema / properties / target / descriptionAdded value: +"FQN of the checkpoint every source must reach, e.g. an ownership check. A unique dot-boundary suffix also resolves."
- Changed
cgis_context4 fields changed- added
Input schema / properties / db_path / descriptionAdded value: +"SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's β prefer an absolute path." - added
Input schema / properties / depth / descriptionAdded value: +"Call hops around the focal node; 1 means direct callers and callees." - added
Input schema / properties / fqn / descriptionAdded value: +"Fully qualified name, e.g. pkg.module.Class.method. A unique dot-boundary suffix also resolves; an ambiguous one returns candidates. Use cgis_find_symbol to look a name up." - added
Input schema / properties / source_root / descriptionAdded value: +"Directory the graph's stored file paths are relative to β normally the project_path given to cgis_ingest; prefer an absolute path. Empty means the server's working directory, so source shows as unavailable when the server runs elsewhere."
- Changed
cgis_drift5 fields changed- added
Input schema / properties / db_path / descriptionAdded value: +"SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's β prefer an absolute path." - added
Input schema / properties / max_drift / descriptionAdded value: +"Drift tolerance for domains that declare no drift_tolerance of their own." - added
Input schema / properties / max_residual / descriptionAdded value: +"Distance to the nearest template beyond which a domain's fit band is \"none\" (no template fits)." - added
Input schema / properties / patterns_path / descriptionAdded value: +"patterns.yaml (.yaml or .yml) declaring each domain's expected pattern and tolerance, relative to the server's working directory. cgis_init_ontology proposes one." - added
Input schema / properties / profile / descriptionAdded value: +"Score only domains with this profile, plus profile-less ones β e.g. one language when patterns.yaml mixes several."
- Changed
cgis_find_orphans4 fields changed- added
Input schema / properties / db_path / descriptionAdded value: +"SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's β prefer an absolute path." - added
Input schema / properties / include_generated / descriptionAdded value: +"Include machine-generated classes, which are hidden by default." - added
Input schema / properties / include_tests / descriptionAdded value: +"Count test code as a user, so the report means \"unreachable from anywhere\"." - added
Input schema / properties / prefix / descriptionAdded value: +"Only consider classes under this FQN prefix, cut on a dot boundary."
- Changed
cgis_find_symbol5 fields changed- added
Input schema / properties / db_path / descriptionAdded value: +"SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's β prefer an absolute path." - added
Input schema / properties / fqn_prefix / descriptionAdded value: +"Only return symbols at or under this FQN prefix, matched on whole dot-segments: app.svc does not match app.svc_alt, and a partial segment matches nothing." - added
Input schema / properties / kind / descriptionAdded value: +"Only return this node type, e.g. FUNCTION, METHOD or CLASS (any case). An unknown type matches nothing rather than raising an error." - added
Input schema / properties / limit / descriptionAdded value: +"Maximum number of candidates to return." - added
Input schema / properties / query / descriptionAdded value: +"Leaf symbol name to search for, without dots (e.g. get_flow_result) β not an FQN. Case-insensitive substring match, ranked exact > prefix > substring."
- Changed
cgis_fractal1 field changed- added
Input schema / properties / db_path / descriptionAdded value: +"SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's β prefer an absolute path."
- Changed
cgis_get_structure4 fields changed- added
Input schema / properties / db_path / descriptionAdded value: +"SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's β prefer an absolute path." - added
Input schema / properties / depth / descriptionAdded value: +"Maximum containment levels to descend (module β class β method)." - added
Input schema / properties / fqn / descriptionAdded value: +"Fully qualified name, e.g. pkg.module.Class.method. A unique dot-boundary suffix also resolves; an ambiguous one returns candidates. Use cgis_find_symbol to look a name up." - added
Input schema / properties / output_format / descriptionAdded value: +"\"mermaid\" for a diagram, or \"json\" for a payload with real FQNs (case-insensitive). Any other value returns an error."
- Changed
cgis_ingest3 fields changed- added
Input schema / properties / db_path / descriptionAdded value: +"Where to write the graph: must end in .db, .sqlite or .sqlite3, in a directory that already exists, and must not be an existing non-SQLite file. A relative path resolves against the server's working directory." - added
Input schema / properties / full_rebuild / descriptionAdded value: +"Re-scan every file from scratch instead of the incremental default." - added
Input schema / properties / project_path / descriptionAdded value: +"Root directory of the project to scan. A relative path resolves against the MCP server's working directory."
- Changed
cgis_init_ontology4 fields changed- added
Input schema / properties / db_path / descriptionAdded value: +"SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's β prefer an absolute path." - added
Input schema / properties / depth / descriptionAdded value: +"Fixed FQN segment depth for domain discovery (positive); omit to pick it automatically." - added
Input schema / properties / margin / descriptionAdded value: +"Headroom added to each measured score to form the proposed tolerance." - added
Input schema / properties / min_nodes / descriptionAdded value: +"Domains with fewer nodes stay hygiene-only instead of getting a label."
- Changed
cgis_metrics4 fields changed- added
Input schema / properties / db_path / descriptionAdded value: +"SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's β prefer an absolute path." - added
Input schema / properties / exclude / descriptionAdded value: +"Drop nodes whose FQN contains any of these dot-segments, e.g. [\"tests\"]; they are removed from PageRank propagation too." - added
Input schema / properties / limit / descriptionAdded value: +"Top-N rows returned per section." - added
Input schema / properties / scope / descriptionAdded value: +"Keep only nodes under any of these dot-prefixes, e.g. [\"domains.billing\"]; rank still propagates over the whole graph."
- Changed
cgis_suggest_packages4 fields changed- added
Input schema / properties / db_path / descriptionAdded value: +"SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's β prefer an absolute path." - added
Input schema / properties / min_q / descriptionAdded value: +"Modularity threshold: at or above it, a package whose layout disagrees with its communities is flagged split (or consolidate, if over-split)." - added
Input schema / properties / prefix / descriptionAdded value: +"FQN prefix of the package to analyse, e.g. cgis.query, matched on whole dot-segments. Needed in practice: without it the verdict is no_signal." - added
Input schema / properties / with_calls / descriptionAdded value: +"Use the combined import + call graph instead of imports only."
- Changed
cgis_trace_flow4 fields changed- added
Input schema / properties / db_path / descriptionAdded value: +"SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's β prefer an absolute path." - added
Input schema / properties / depth / descriptionAdded value: +"Maximum edge hops downstream. Every edge type counts as a hop β CALLS, but also IMPORTS, CONTAINS and REFERENCES β so from a module the first hops are mostly imports and structure." - added
Input schema / properties / fqn / descriptionAdded value: +"Fully qualified name, e.g. pkg.module.Class.method. A unique dot-boundary suffix also resolves; an ambiguous one returns candidates. Use cgis_find_symbol to look a name up." - added
Input schema / properties / output_format / descriptionAdded value: +"\"mermaid\" for a diagram, or \"json\" for a payload with real FQNs (case-insensitive). Any other value returns an error."
- Changed
cgis_validate2 fields changed- added
Input schema / properties / db_path / descriptionAdded value: +"SQLite graph built by cgis_ingest. A relative path resolves against the MCP server's working directory, not the agent's β prefer an absolute path." - added
Input schema / properties / threshold / descriptionAdded value: +"Highest unresolved-edge ratio (0-1) still reported as healthy."
14 tool updates
v0.21.0- First observed
cgis_analyze_impact - First observed
cgis_audit_reachability - First observed
cgis_context - First observed
cgis_drift - First observed
cgis_find_orphans - First observed
cgis_find_symbol - First observed
cgis_fractal - First observed
cgis_get_structure - First observed
cgis_ingest - First observed
cgis_init_ontology - First observed
cgis_metrics - First observed
cgis_suggest_packages - First observed
cgis_trace_flow - First observed
cgis_validate
TDQS
Scored across 15 tools
Each tool targets a distinct concern: ingestion, validation, symbol lookup, downward/upward traversal, structure, context, global metrics, drift, community detection, orphans, reachability, and motif analysis. Potentially overlapping traversal tools are explicitly cross-referenced in their descriptions, making selection unambiguous.
All tools share the cgis_ prefix and snake_case, and most follow a verb_noun pattern (trace_flow, find_symbol, audit_reachability). A few noun-only names (overview, context, metrics, drift, fractal) deviate from the pattern, but the convention remains readable and predictable.
15 tools is well within the ideal range and each tool earns its place across the code-graph analysis lifecycle. The count feels comprehensive without being bloated.
The surface covers the full workflow: ingest, validate, orient, navigate, inspect, analyze impact/flow, compute metrics, detect drift, suggest boundaries, find dead code, and audit reachability. No obvious gaps or dead ends for the stated purpose of code knowledge graph analysis.
Maintenance
Related MCP Connectors
Codebase graphs, caller impact analysis, and recorded project context for AI coding agents.
Code intelligence platform for AI agents. 20 tools for architecture, security & impact analysis.
AI Agent with Architectural Memory. Impact analysis (free), tests and code from the graph (pro).
Codebase intelligence for AI agents β dead code, blast radius, ownership.
Related MCP Servers
- AlicenseNot gradedqualityNot gradedmaintenanceCodeGraph β Open-source code intelligence MCP server. Builds a semantic graph of your codebase (functions, classes, imports, call chains) and exposes it through 31 tools. Callers, callees, impact analysis, complexity metrics, unused code detection, AI context assembly, persistent memory, cross-project search. 15 languages via tree-sitter. Single Rust binary, local-first.248 npm-

loctree-mcpofficial
FlicenseNot gradedqualityAmaintenanceStructural code intelligence for AI agents. Scan once, query everything β dead exports, circular imports, dependency graphs, and more. CLI + MCP server.6 npm9-- AlicenseNot gradedqualityAmaintenanceSupercharges AI coding agents with a pre-indexed semantic code graph, enabling instant symbol relationships, impact analysis, and context retrieval across 20+ languages.70,850 npm71,313MIT

mcp-reposkeinofficial
AlicenseAqualityAmaintenanceDeterministic code-graph (GraphRAG) over your repo for LLM agents β local-first, git-native, zero-infra, served via MCP. Python, TS/JS, Rust, Go, Java, C#.812Apache 2.0