Skip to main content
Glama

🧠 CGIS: Code Graph Intelligence System

A code graph your AI agent can query instead of guess

Continuous Integration Graph Integrity PyPI

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 Β· Go (structure and metrics only; its impact answers are a lead to confirm by reading β€” exp4, measured on one library, golang/crypto, mostly its ssh package; not measured on applications) Β· JSON and YAML (data key declarations only, when data keys are enabled with --data-keys: no symbols, calls or impact)

  • 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-brain

That 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 output

Or 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: mcp-reposkein

πŸ“ˆ 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

cgis_ingest

Build or incrementally refresh the graph

cgis_overview

Where to start: sizes and the largest packages, when you have no FQN yet

cgis_find_symbol

Partial name β†’ candidate FQNs

cgis_analyze_impact

What breaks upstream if this changes?

cgis_trace_flow

What does this call, transitively?

cgis_get_structure

Class / module hierarchy

cgis_context

A compact GraphRAG context package for one symbol

cgis_metrics

Coupling, god classes, PageRank, package cohesion

cgis_audit_reachability

Authz / IDOR coverage β€” does every handler reach its guard?

cgis_drift

How far each domain has moved from its declared pattern

cgis_validate

Graph integrity: resolved vs unresolved edges

All 16 tools, with parameters: MCP_REFERENCE.md.


πŸ—οΈ How It Works

  1. Extract β€” tree-sitter parsers turn each file into nodes and raw call edges.

  2. Resolve β€” the ResolverEngine maps raw calls to fully qualified names, or leaves them explicitly unresolved.

  3. 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 --> G

The 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 / Claude 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 --inline

# Or a Claude skeptic over a Mistral finder: Claude Haiku 5.5 unless GUARDIAN_SKEPTIC_MODEL names
# another, at GUARDIAN_ANTHROPIC_EFFORT=low unless set (low|medium|high|xhigh|max). Claude models
# reject a sampling temperature, so GUARDIAN_TEMPERATURE must be unset.
GUARDIAN_SKEPTIC=anthropic ANTHROPIC_API_KEY=... MISTRAL_API_KEY=... \
  uv run python scripts/guardian_review.py --pr 123 --db graph.db --inline

No 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 pytest

See 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

17 tools
cgis_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``. Test callers are left out unless ``include_tests``
asks for them, and counted in ``excluded_tests``. A file that imports a
symbol is listed, but the walk does not continue to the files importing
that file; a file's own impact still does. At most ``max_nodes`` nodes come
back, nearest first, and a cut is reported in ``truncated``. 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="text"`` returns an indented tree of callers, one line
per node β€” the compact form to read; ``"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.
NameRequiredDescriptionDefault
fqnYesFully 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.
depthNoMaximum edge hops upstream, over callers, importers, subclasses, type references and DI dependents (plus the enclosing class or file with include_structure). A hop from an override to the base or interface method it implements costs no depth, so a caller through the interface is at depth 1.
db_pathNoSQLite 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
max_nodesNoMost nodes to return, nearest levels first. A level that does not fit is cut and the walk stops there; the answer says where and how many were left out, so a smaller depth or a narrower FQN can follow.
include_testsNoAlso return test code. Off by default: on a large repo tests outnumber the production code an answer is about. The answer says how many were left out β€” a floor when it is also truncated, since levels past the cut are not walked. A root that is itself a test keeps them.
output_formatNo"text" for an indented tree, one line per node β€” the cheapest to read; "mermaid" for a diagram; or "json" for a payload with real FQNs, to compute with (case-insensitive). Any other value returns an error.mermaid
include_externalNoAlso 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_structureNoAlso 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

NameRequiredDescription
resultYes

TDQS

A4.8/5.0
Behavior5/5

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 does: it discloses traversal exclusions (containment, stdlib/third-party, tests), the file-import boundary rule, max_nodes truncation with 'nearest first' and the truncated flag, the excluded_tests count, and the coverage/top_unresolved upper-bound caveat with the reason (common-name collisions). That is unusually complete behavioral detail for a graph walker.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Information-dense and roughly front-loaded (core definition first, siblings near the end, output formats last), but the prose is long and relies on stacked clauses and parentheticals; some parenthetical caveats could be trimmed without losing meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an 8-parameter graph-analysis tool with no annotations, the description covers traversal semantics, exclusions, truncation behavior, output shapes, and the meaning of coverage/top_unresolved; an output_schema exists, so return-format explanation is a bonus rather than a requirement. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3; the description still adds value by explaining what each flag actually changes in the result set (include_structure follows CONTAINS/DECLARES, include_external adds runtime-resolved targets, include_tests is counted in excluded_tests, output_format=json yields a joinable {root,nodes,edges,coverage} payload enabling set-difference queries).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence states a precise verb+resource+scope ('Upstream subgraph of one FQN ... within depth hops') and the second names the exact edge types traversed, so the agent knows this computes reverse dependencies ('what breaks if I change X?'). It also distinguishes itself from cgis_trace_flow (dependencies), cgis_get_structure (members) and cgis_context (editing brief).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit routing: '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.' Defaults (tests, external, structure excluded) are stated with the reasons and the same view as the CLI's `impact`, so when-to-use and when-not-to-use are both covered.

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`` (the ``ROUTE_HANDLER`` role β€” FastAPI handlers on
a router built in the same module β€” or a NodeType like ``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).
NameRequiredDescriptionDefault
depthNoMaximum reachability depth; a longer path is reported as a gap.
targetYesFQN of the checkpoint every source must reach, e.g. an ownership check. A unique dot-boundary suffix also resolves.
db_pathNoSQLite 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_typeNoNodeType or role of the sources to audit (any case): ROUTE_HANDLER selects FastAPI handlers on a router built in the same module; a structural type such as FUNCTION selects by type. Give this, from_prefix, or both.
from_prefixNoOnly 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

NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior5/5

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: it discloses that reachability follows CALLS *and* FastAPI Depends() DEPENDS_ON edges, that depth overrun is reported as a gap, the exact JSON shape ({target, covered, gaps}), and the non-obvious behavior that an empty selection returns a ❌ message rather than a misleading empty-but-passing result. These are genuine behavioral traits 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.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The headline constraint is front-loaded and the paragraphs are tightly scoped to selection, edge semantics, and error behavior. It is on the longer side with some markdown emphasis, but each block earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 5-param audit tool with an output schema but zero annotations, the description covers the missing pieces: graph edge semantics, selection requirements, depth behavior, and the failure case. An agent can call this correctly without opening anything else.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so 3 is the baseline. The description adds real value on top: it imposes the 'at least one of from_type/from_prefix is required' constraint that the schema (which lists only target as required) does not capture, and explains the ROUTE_HANDLER role semantics and whole-dot-segment prefix matching.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first line states a specific verb and resource β€” 'Reachability/authorization audit β€” which sources never reach a checkpoint' β€” and immediately narrows to the flagship use case (IDOR/authz coverage). It is clearly distinguishable from siblings like cgis_trace_flow and cgis_analyze_impact because it audits coverage gaps rather than tracing a flow or impact.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a clear when-to-use anchor ('the headline use is IDOR/authz coverage: list every route handler that does NOT transitively reach an ownership check') and explains how to repurpose it for validators, event tracking, or service-layer boundaries. It does not name sibling tools to route against, so it stops short of explicit alternatives.

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".
NameRequiredDescriptionDefault
fqnYesFully 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.
depthNoCall hops around the focal node; 1 means direct callers and callees.
db_pathNoSQLite 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_rootNoDirectory 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

NameRequiredDescription
resultYes

TDQS

A4.9/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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_diff_checkA

What else depends on what a diff changed: subclasses, callers and data keys.

Call this before review or merge. It reads the lines ``base..head`` changed,
finds the graph symbols they fall in (and symbols the diff removed, read from
the base text), and lists the classes that extend a changed class and the
functions that call a changed or removed function. For each data key the
changed lines read, write or declare (``doc["avatar"]``, a mapping field) it
lists the key's other readers, writers and declarers, reads of a dotted path
a mapping does not declare, and reads of a declaration the diff removed;
common keys (``id``, ``name``, or used in many files) are left out. Key items
need a graph ingested with data keys on (``cgis_ingest(data_keys=True)`` or
``cgis ingest --data-keys``); on a graph without them the answer says so and
lists subclasses and callers only. Sites in test files are counted, not
listed. An empty list means no static dependants were found, not that the
change is safe: dispatch the graph cannot see is not covered. How to read
the list: caller and subclass items are leads to read; data-key items are
noisy β€” measured on one application (owner-api), about a quarter of listed
items were worth a look (docs/lab-notes/2026-10-19-data-key-diff-check.md).
Before judging a code site that reads or writes a key unaffected, read its
callers (cgis_analyze_impact): they decide what values reach it.
NameRequiredDescriptionDefault
capNoItems listed; the rest are only counted.
baseNoBase revision of the diff, e.g. origin/main or a sha.origin/main
headNoHead revision of the diff.HEAD
prefixNoThe path of the ingested directory inside the repository (e.g. 'src' after cgis_ingest of ./src); empty when the repository root was ingested. Left out, it comes from the root the graph recorded at ingest.
db_pathNoSQLite 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
repo_pathYesGit repository holding the diff; prefer an absolute path.
output_formatNo'text' or 'json'.text

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior5/5

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: it discloses the data-key prerequisite (graph ingested with data_keys=True), the degraded behavior when keys are absent, that test-file sites are counted not listed, that common keys are omitted, and a measured precision caveat (~a quarter of data-key items worth a look). These are exactly the operational traits an agent needs before trusting output.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core idea is front-loaded in the first sentence, and most sentences carry distinct operational information. It is dense and long with some run-on clauses, but there is little that could be dropped without losing a real constraint.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and the description still covers prerequisites, edge cases (empty list, missing data keys), scope limits (test files, common keys) and interpretation guidance. Nothing an agent needs to call or trust the tool is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 cap, base, head, prefix, db_path and output_format, making 3 the baseline. The description adds little parameter-level syntax beyond mentioning the base text is read for removed symbols, so it does not rise above baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb+resource: it lists what else depends on lines a diff changed (subclasses, callers, data keys). It clearly distinguishes itself from siblings by naming cgis_analyze_impact as the follow-up for judging a site and cgis_ingest for building the required graph.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says when to call it ('before review or merge') and when its output is insufficient ('an empty list means no static dependants were found, not that the change is safe'). It routes the agent to cgis_analyze_impact for the decision a caller makes, giving both when-to-use and an alternative.

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).
NameRequiredDescriptionDefault
db_pathNoSQLite 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
profileNoScore only domains with this profile, plus profile-less ones β€” e.g. one language when patterns.yaml mixes several.
max_driftNoDrift tolerance for domains that declare no drift_tolerance of their own.
max_residualNoDistance to the nearest template beyond which a domain's fit band is "none" (no template fits).
patterns_pathNopatterns.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

NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior5/5

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.

Conciseness4/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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).

Only **module-level** classes are considered by default; ``include_nested``
adds classes defined inside a class or function. Across eight measured
repositories none of the 46 nested rows was dead: most were a ``Meta`` /
``Config`` a metaclass reads, the rest live classes reached as
``self.Nested(...)``, which the resolver does not follow (#432).

Returns JSON ``{orphans, considered, test_sources, generated_excluded,
nested_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.
NameRequiredDescriptionDefault
prefixNoOnly consider classes under this FQN prefix, cut on a dot boundary.
db_pathNoSQLite 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_testsNoCount test code as a user, so the report means "unreachable from anywhere".
include_nestedNoInclude classes nested in a class or function, which are hidden by default.
include_generatedNoInclude machine-generated classes, which are hidden by default.

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and delivers: it names the graph relationships that count as a use, discloses the default hiding of generated and nested classes with measured justification, and warns 'a listing is a candidate for deletion, not a proof' with the specific blind spots (decorator-only references, star imports). It even documents staleness signals such as test_sources: 0 meaning a pre-is_test graph that needs re-ingestion.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded correctly, but the description runs several hundred words and includes anecdotal evidence ('43 of 1 789 classes', 'five of six reported orphans were generated entities') and issue citations that read as justification prose rather than invocation guidance. Much of the length is defensible behavioral disclosure, but the anecdotes could be trimmed without losing selection value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 5-parameter analysis tool with subtle semantics, the description covers the detection model, default exclusions, caveats about false negatives, and failure modes in the backing data. An output schema exists, yet the inline description of the returned JSON keys adds interpretive context (what a 0 in generated_excluded implies) that the schema alone would not convey.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

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 prose adds real meaning beyond the schema: prefix cuts on a dot boundary to one package, include_tests redefines the report as 'unreachable from anywhere', and include_generated/include_nested are given the rationale for their defaults. Only db_path (covered adequately by the schema) is unaddressed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence states a specific verb and resource β€” 'Classes nothing in production builds, extends or names β€” dead-code candidates' β€” and the detail about CALLS/EXTENDS/REFERENCES usage makes the target precise. No sibling tool in the cgis_* family overlaps with orphan detection, so an agent can select this unambiguously.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives strong context on when the output is meaningful vs. noise: tests-as-users, re-exports, generated classes, and nested classes are each explained with the interpretation they enable. What it lacks is an explicit routing statement against alternatives (e.g., cgis_analyze_impact or cgis_audit_reachability), so it earns a 4 rather than a 5.

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. A prefix
that starts with the directories the graph was ingested below (``src.cgis``
for a graph of ``src/``) and covers no code is read without them.
NameRequiredDescriptionDefault
kindNoOnly return this node type, e.g. FUNCTION, METHOD or CLASS (any case). An unknown type matches nothing rather than raising an error.
limitNoMaximum number of candidates to return.
queryYesLeaf symbol name to search for, without dots (e.g. get_flow_result) β€” not an FQN. Case-insensitive substring match, ranked exact > prefix > substring.
db_pathNoSQLite 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_prefixNoOnly 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

NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden and does disclose ranking semantics (exact > prefix > substring), the returned JSON shape, kind filtering, and an unusual prefix-resolution quirk where a directory-style prefix is read without ingested path segments. It never explicitly states read-only/no-mutation behavior, but for a symbol lookup that is low risk.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose and workflow position, then parameters, then the prefix caveat. Efficient overall, though the final sentence about prefixes starting with ingested directories is awkwardly worded and takes a second read.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need no elaboration, and the description still summarizes them. Usage, filtering and the prefix quirk are covered; only the read-only nature and any cost/rate characteristics are absent, which is minor for this tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description adds real meaning beyond the schema: how kind narrows node types, how fqn_prefix scopes the search, and the non-obvious prefix-vs-ingest-directory interaction. The limit parameter is left to the schema, which already documents it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (resolve) and resource (partial symbol name -> candidate FQNs), plus the matching strategy (substring, ranked). It explicitly names the sibling tools it precedes, so an agent can place it in the workflow without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit precondition: call this BEFORE cgis_trace_flow / cgis_analyze_impact / cgis_get_structure when you know a short name but not its FQN. It also states the payoff (removes read-the-file-first guesswork), leaving nothing to inference.

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``.
NameRequiredDescriptionDefault
db_pathNoSQLite 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

NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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="text"`` returns the
hierarchy as an indented tree, one line per member; ``"mermaid"`` (default) a
diagram of the hierarchy rooted at the given FQN; ``"json"`` the
joinable ``{root, nodes, edges}`` payload with real FQNs.
NameRequiredDescriptionDefault
fqnYesFully 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.
depthNoMaximum containment levels to descend (module β†’ class β†’ method).
db_pathNoSQLite 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_formatNo"text" for an indented tree, one line per node β€” the cheapest to read; "mermaid" for a diagram; or "json" for a payload with real FQNs, to compute with (case-insensitive). Any other value returns an error.mermaid

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior5/5

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 well: it discloses that only CONTAINS/DECLARES edges appear, that packages are not real graph nodes (#487) so their rows and edges are synthesized and marked with a virtual file path. These are exactly the non-obvious behaviors an agent needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded, followed by containment caveats, routing guidance, and format notes in a logical order. It is slightly verbose in re-describing output_format, which the schema already covers, but no sentence is truly wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-shape explanation is unnecessary, and the description still covers containment semantics, package virtualization, and format choices. Combined with 100% schema coverage, an agent has everything needed to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

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 fqn, depth, db_path, and output_format. The description's output_format gloss largely restates the schema entry rather than adding syntax or format detail beyond it, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence states a specific verb and resource: the members of a module or class, or the modules held by a package prefix. It distinguishes itself from siblings by explicitly noting it follows containment only, and names the alternatives for connectivity queries.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It routes the agent explicitly: use cgis_trace_flow for what the code depends on and cgis_analyze_impact for what depends on it, leaving no inference about when not to use this tool. The CLI parity note ('Matches the CLI structure command') further anchors context.

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.

Data keys are opt-in (``data_keys=True``): they cost every ingest time and
graph size, and make JSON and YAML edits mark the graph stale.
NameRequiredDescriptionDefault
db_pathNoWhere 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
data_keysNoExtract data keys (Python dict keys, JSON and YAML declarations) for cgis_diff_check. Off by default. Left out, an existing graph keeps the mode it was built in, and a new one takes CGIS_DATA_KEYS=1 from the server's environment. Switching it rebuilds the graph.
full_rebuildNoRe-scan every file from scratch instead of the incremental default.
project_pathYesRoot directory of the project to scan. A relative path resolves against the MCP server's working directory.

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior5/5

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 well: it discloses the incremental-by-default model, the automatic whole-graph rebuild triggers (renamed/removed/added symbols, deleted/new files, changed base class or re-export), the full_rebuild override, the cost of data_keys in time and graph size plus its staleness side effect on JSON/YAML edits, and the constraint that parent directories will not be created.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then conditions, then the incremental/full-rebuild distinction and the data_keys caveat β€” a sensible ordering with no filler sentences. It loses a point because the db_path restrictions are restated almost verbatim from the schema rather than summarised once.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need no explanation. Against a 4-parameter mutation-style ingest tool with zero annotations, the description covers process, incremental semantics, rebuild triggers, opt-in features and failure conditions β€” nothing an agent needs in order to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description goes beyond it by explaining the consequences of data_keys (cost, staleness, mode inheritance, rebuild-on-switch) and the semantics of full_rebuild rather than just restating the flag. The db_path paragraph largely duplicates the schema, keeping this just above baseline rather than clearly exceptional.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence names a specific verb chain and resource: scan a directory, extract symbols, resolve links, build the graph DB. That is clearly distinguishable from the read-only analysis siblings (cgis_find_symbol, cgis_analyze_impact, cgis_overview), which the agent can tell apart without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"Use this to initialise or refresh the code knowledge graph for a project" gives clear context, and the data_keys note routes the agent toward cgis_diff_check when that feature is needed. However, it never states when NOT to use this tool versus an analysis sibling, nor prerequisites like having a workspace already in place; the guidance is contextual but not exclusionary.

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.
NameRequiredDescriptionDefault
depthNoFixed FQN segment depth for domain discovery (positive); omit to pick it automatically.
marginNoHeadroom added to each measured score to form the proposed tolerance.
db_pathNoSQLite 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_nodesNoDomains with fewer nodes stay hygiene-only instead of getting a label.

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior5/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters4/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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, file_coupling, class_cohesion,
resolution}``
computed with vectorized DuckDB aggregations over the whole graph (fan-in/fan-out
coupling, declared-member counts, PageRank, per-file Ca/Ce/instability) β€” 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.

``file_coupling`` counts *files*, not calls: Ca is how many other files
depend on a file (by IMPORTS or CALLS), Ce how many it depends on, and
instability ``I = Ce / (Ca + Ce)`` runs from 0 (stable, expensive to change)
to 1 (volatile); it is null for a file linked to no other.

``class_cohesion`` ranks classes by LCOM4: the number of groups their instance
methods fall into when linked by a shared ``self`` attribute or a call. 1 is
cohesive; 2+ is a class doing unrelated jobs. Dunders (``__init__`` above
all), abstract, static and class methods are not counted.

``resolution`` is the share of edges the resolver could not place, by the
same rule as ``cgis validate``. Read the rankings through it: a node whose
calls are mostly unresolved looks uncoupled because its edges point nowhere.
Under ``scope``/``exclude`` it counts the edges the selected code *emits*.

``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).
NameRequiredDescriptionDefault
limitNoTop-N rows returned per section.
scopeNoKeep only nodes under any of these dot-prefixes, e.g. ["domains.billing"]; rank still propagates over the whole graph.
db_pathNoSQLite 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
excludeNoDrop nodes whose FQN contains any of these dot-segments, e.g. ["tests"]; they are removed from PageRank propagation too.

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.6/5.0
Behavior5/5

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 richly: it discloses the optional duckdb dependency and its ❌ error path, explains that scope vs exclude differ because exclude removes nodes from PageRank propagation while scope only filters rows, and clarifies that resolution affects how rankings should be read. These are exactly the non-obvious behaviors an agent needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded and each section explains a real output key or parameter behavior, so most sentences earn their place. It is dense and slightly over-long, with some overlap against the already-descriptive schema for scope/exclude.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Complete for this tool: an output schema exists so return values needn't be re-explained, no annotations need compensating, and the description covers dependency requirements, parameter interactions, and ranking interpretation. Nothing an agent needs to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description adds genuine meaning: anchored dot-boundary matching ('domains.reservation' not 'domains.reservation_archive'), dot-segment containment for exclude, and the semantic divergence between the two flags for PageRank and coupling in-degree.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening line states a specific verb+resource and enumerates the concrete outputs (coupling bottlenecks, God classes, PageRank), then explicitly positions it as 'the global what-are-the-hotspots view that complements the node-local trace/impact/context tools.' An agent can distinguish it from cgis_trace_flow/cgis_analyze_impact/cgis_context without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context: use it for whole-graph hotspot analysis, and the scope/exclude paragraph tells the agent to reach for it during a 'per-domain review.' It routes between scope and exclude well, but stops short of explicit when-not conditions or naming a specific sibling to avoid.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

cgis_module_graphA

How one package is built inside: its modules and the dependencies between them.

Nodes are the package's direct children, each sub-package one node (``expand``
lists every module instead). Edges are imports ``-->``, inheritance ``==>``
and calls ``-.->``, each kind transitively reduced so the direct layering
shows; an edge that closes a cycle is never dropped. Dependencies on code
outside the package are summarised per module under the diagram, not drawn.
Test modules and type-only imports are left out. The json form is
``{prefix, nodes, subpackages, edges:[{source,target,kind}], dropped, covered, outside}``;
``covered`` counts the imports not drawn because a drawn ``==>`` joins the
same pair: that arrow then also stands for the import, so read an import
closure over imports and extends together. An import that closes an import
cycle is always drawn.
Run ``cgis_ingest`` first.
NameRequiredDescriptionDefault
expandNoEvery module below the package instead of one node per sub-package.
layersNoEdge kinds to draw. Calls make the picture much denser.
prefixYesFQN prefix of the package as the graph names it, e.g. cgis.query (cgis_find_symbol shows it), matched on whole dot-segments. A directory above the ingest root, such as src., is dropped.
reduceNoDrop each edge implied by a longer path, per kind; cycles stay.
db_pathNoSQLite 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_testsNoLeave test modules out.
output_formatNomermaid: a diagram plus a table of outside dependencies; json: data.mermaid

Output Schema

NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior5/5

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 transitive reduction rules, that cycle-closing edges are never dropped, that test modules and type-only imports are excluded, that external dependencies are summarised rather than drawn, and how `covered` should be interpreted.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded and the content is dense and useful, but the cycle rule is stated three separate times ("never dropped", "always drawn", plus the `covered` aside), and the json return shape is spelled out despite an output schema existing.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter analysis tool with a full schema and an output schema, the description covers the prerequisites, exclusions, reduction semantics and output modes well; it only omits failure behaviour for an unknown prefix or missing database.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and every parameter is already documented in the schema, including the same expand/reduce/cycles semantics the description restates; the description adds marginal interpretive value (e.g. that calls make the picture denser) rather than new parameter meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence names a specific resource (a package's internal module/dependency graph) and the description then pins down exactly what nodes and edges represent, so an agent can distinguish it from package-level siblings like cgis_overview or cgis_get_structure without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives one hard prerequisite ("Run cgis_ingest first") and notes that `expand` lists every module instead, but never says when to choose this over alternative structural tools such as cgis_overview or cgis_fractal, and offers no when-not guidance.

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.
NameRequiredDescriptionDefault
depthNoFQN segments per package prefix; 1 is the top level.
limitNoMaximum packages listed per section.
db_pathNoSQLite 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

NameRequiredDescription
resultYes

TDQS

A4.5/5.0
Behavior4/5

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.

Conciseness5/5

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.

Completeness5/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines5/5

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 + members), 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.

Members are the package's direct children by default, each sub-package one
node, so the verdict says whether to regroup them; ``level`` in the result
says which. ``all_descendants`` clusters every file below the package.

A mis-rooted graph (import targets resolve to no internal file) returns
``no_signal`` with a diagnostic note rather than a silent clean verdict.
NameRequiredDescriptionDefault
min_qNoModularity threshold: at or above it, a package whose layout disagrees with its communities is flagged split (or consolidate, if over-split).
prefixNoFQN 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_pathNoSQLite 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_callsNoUse the combined import + call graph instead of imports only.
all_descendantsNoCluster every file below the package and compare with its sub-directories, instead of treating each sub-package as one node.

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.1/5.0
Behavior5/5

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: it discloses the JSON payload shape, the default layer, the recursive all_descendants mode, and notably the failure mode that a mis-rooted graph returns no_signal with a diagnostic note rather than a silent clean verdict. That edge-case disclosure is exactly the kind of behavior an agent needs before trusting the output.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the purpose, then the return shape, then the configuration and precondition. Efficient overall, but the detailed return-field enumeration duplicates what the output schema already carries, which is some wasted space.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Preconditions (cgis_ingest first, prefix needed in practice) and failure behavior are covered, which is what the agent needs to call it correctly. Since an output schema exists, the lengthy return-value listing is partly redundant but not harmful.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the parameters (min_q, prefix, db_path, with_calls, all_descendants) are already documented in the schema. The description mostly restates those semantics (with_calls, all_descendants) rather than adding syntax or format detail, so the baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Suggest sub-package boundaries for a package from its dependency communities.' This is clearly distinguishable from analysis siblings like cgis_metrics or cgis_get_structure, but no sibling is named or contrasted, so it falls short of the top band.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a clear prerequisite ('Run cgis_ingest first') and the layering choice ('Default layer is IMPORTS; set with_calls for the combined import+call graph'), so an agent knows how to configure it. It never states when to prefer this over a sibling tool (e.g. cgis_fractal), so no exclusions or alternatives are offered.

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``.

Test code is left out unless ``include_tests`` asks for it, and at most
``max_nodes`` nodes come back, nearest first, as for impact.

``output_format="text"`` returns the subgraph as an indented tree, one line
per node with children in call-site order, so a flow reads top down β€” about
a fifth of the json for the same answer; ``"mermaid"`` (default) a diagram;
``"json"`` 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.
NameRequiredDescriptionDefault
fqnYesFully 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.
depthNoMaximum edge hops downstream, over calls, imports, inheritance, DI dependencies and references (plus containment with include_structure). A hop from a base or interface method to its overrides costs no depth.
db_pathNoSQLite 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
max_nodesNoMost nodes to return, nearest levels first. A level that does not fit is cut and the walk stops there; the answer says where and how many were left out, so a smaller depth or a narrower FQN can follow.
include_testsNoAlso return test code. Off by default: on a large repo tests outnumber the production code an answer is about. The answer says how many were left out β€” a floor when it is also truncated, since levels past the cut are not walked. A root that is itself a test keeps them.
output_formatNo"text" for an indented tree, one line per node β€” the cheapest to read; "mermaid" for a diagram; or "json" for a payload with real FQNs, to compute with (case-insensitive). Any other value returns an error.mermaid
include_externalNoAlso 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_structureNoAlso 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

NameRequiredDescription
resultYes

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the whole burden and does so: it discloses that containment edges are skipped by default, that tests/external/unresolved targets are dropped by default, that results are truncated at max_nodes with the walk stopping mid-level, that rounded coverage counts can be misleading in Python, and that an unknown output_format returns an error. That is unusually rich behavioral context for an analysis tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded: the first sentence defines the tool, then routing to siblings, then option semantics. However, it re-explains several parameters (output_format, max_nodes, include_tests) that already have 100%-covered schema descriptions, adding length without new information. Still readable and every section is relevant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given an output schema exists, return-shape detail is optional, yet the description clarifies the json payload ('joinable {root, nodes, edges, coverage}'), what coverage counts and how to read top_unresolved. Combined with edge-type and default-exclusion coverage, an agent has everything needed to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description goes further by giving the tradeoff behind output_format ('about a fifth of the json for the same answer'), explaining that max_nodes truncation reports where the cut fell, and clarifying that include_external covers stdlib, third-party and unresolved call targets. It largely restates rather than extends the schema on the boolean flags, so it is above baseline but not maximal.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource and scope: 'Downstream subgraph of one FQN: everything it reaches within depth hops.' It then enumerates exactly which edge kinds are followed and which are excluded, and explicitly names the sibling tools for adjacent questions (cgis_analyze_impact, cgis_get_structure, cgis_context). An agent can distinguish it from every sibling without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit routing rules: '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... cgis_context.' It also states the prerequisite ('Use cgis_ingest first if the database does not exist yet') and the default-exclusion conditions that select the include_* flags.

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.
NameRequiredDescriptionDefault
db_pathNoSQLite 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
thresholdNoHighest unresolved-edge ratio (0-1) still reported as healthy.

Output Schema

NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

  1. 1 tool updatev0.21.17
    • Addedcgis_module_graph
  2. 2 tool updatesv0.21.15
    • Addedcgis_diff_check
    • Changedcgis_ingest1 field changed
      • addedInput schema / properties / data_keys
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "boolean"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Extract data keys (Python dict keys, JSON and YAML declarations) for cgis_diff_check. Off by default. Left out, an existing graph keeps the mode it was built in, and a new one takes CGIS_DATA_KEYS=1 from the server's environment. Switching it rebuilds the graph.",
        +  "title": "Data Keys"
        +}
  3. 2 tool updatesv0.21.14
    • Changedcgis_analyze_impact1 field changed
      • changedInput schema / properties / depth / description
        Previous value: -"Maximum edge hops upstream, over callers, importers, subclasses, type references and DI dependents (plus the enclosing class or file with include_structure)."New value: +"Maximum edge hops upstream, over callers, importers, subclasses, type references and DI dependents (plus the enclosing class or file with include_structure). A hop from an override to the base or interface method it implements costs no depth, so a caller through the interface is at depth 1."
    • Changedcgis_trace_flow1 field changed
      • changedInput schema / properties / depth / description
        Previous value: -"Maximum edge hops downstream, over calls, imports, inheritance, DI dependencies and references (plus containment with include_structure)."New value: +"Maximum edge hops downstream, over calls, imports, inheritance, DI dependencies and references (plus containment with include_structure). A hop from a base or interface method to its overrides costs no depth."
  4. 1 tool updatev0.21.13
    • Changedcgis_audit_reachability1 field changed
      • changedInput schema / properties / from_type / description
        Previous value: -"NodeType of the sources to audit, e.g. ROUTE_HANDLER, API_ENDPOINT or FUNCTION (any case). Give this, from_prefix, or both."New value: +"NodeType or role of the sources to audit (any case): ROUTE_HANDLER selects FastAPI handlers on a router built in the same module; a structural type such as FUNCTION selects by type. Give this, from_prefix, or both."
  5. 3 tool updatesv0.21.12
    • Changedcgis_analyze_impact3 fields changed
      • addedInput schema / properties / include_tests
        Added value: +{
        +  "default": false,
        +  "description": "Also return test code. Off by default: on a large repo tests outnumber the production code an answer is about. The answer says how many were left out β€” a floor when it is also truncated, since levels past the cut are not walked. A root that is itself a test keeps them.",
        +  "title": "Include Tests",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / max_nodes
        Added value: +{
        +  "default": 100,
        +  "description": "Most nodes to return, nearest levels first. A level that does not fit is cut and the walk stops there; the answer says where and how many were left out, so a smaller depth or a narrower FQN can follow.",
        +  "minimum": 1,
        +  "title": "Max Nodes",
        +  "type": "integer"
        +}
      • changedInput schema / properties / output_format / description
        Previous value: -"\"mermaid\" for a diagram, or \"json\" for a payload with real FQNs (case-insensitive). Any other value returns an error."New value: +"\"text\" for an indented tree, one line per node β€” the cheapest to read; \"mermaid\" for a diagram; or \"json\" for a payload with real FQNs, to compute with (case-insensitive). Any other value returns an error."
    • Changedcgis_get_structure1 field changed
      • changedInput schema / properties / output_format / description
        Previous value: -"\"mermaid\" for a diagram, or \"json\" for a payload with real FQNs (case-insensitive). Any other value returns an error."New value: +"\"text\" for an indented tree, one line per node β€” the cheapest to read; \"mermaid\" for a diagram; or \"json\" for a payload with real FQNs, to compute with (case-insensitive). Any other value returns an error."
    • Changedcgis_trace_flow3 fields changed
      • addedInput schema / properties / include_tests
        Added value: +{
        +  "default": false,
        +  "description": "Also return test code. Off by default: on a large repo tests outnumber the production code an answer is about. The answer says how many were left out β€” a floor when it is also truncated, since levels past the cut are not walked. A root that is itself a test keeps them.",
        +  "title": "Include Tests",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / max_nodes
        Added value: +{
        +  "default": 100,
        +  "description": "Most nodes to return, nearest levels first. A level that does not fit is cut and the walk stops there; the answer says where and how many were left out, so a smaller depth or a narrower FQN can follow.",
        +  "minimum": 1,
        +  "title": "Max Nodes",
        +  "type": "integer"
        +}
      • changedInput schema / properties / output_format / description
        Previous value: -"\"mermaid\" for a diagram, or \"json\" for a payload with real FQNs (case-insensitive). Any other value returns an error."New value: +"\"text\" for an indented tree, one line per node β€” the cheapest to read; \"mermaid\" for a diagram; or \"json\" for a payload with real FQNs, to compute with (case-insensitive). Any other value returns an error."
  6. 2 tool updatesv0.21.9
    • Changedcgis_find_orphans1 field changed
      • addedInput schema / properties / include_nested
        Added value: +{
        +  "default": false,
        +  "description": "Include classes nested in a class or function, which are hidden by default.",
        +  "title": "Include Nested",
        +  "type": "boolean"
        +}
    • Changedcgis_suggest_packages1 field changed
      • addedInput schema / properties / all_descendants
        Added value: +{
        +  "default": false,
        +  "description": "Cluster every file below the package and compare with its sub-directories, instead of treating each sub-package as one node.",
        +  "title": "All Descendants",
        +  "type": "boolean"
        +}
  7. 3 tool updatesv0.21.6
    • Changedcgis_analyze_impact3 fields changed
      • changedInput schema / properties / depth / description
        Previous 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)."
      • addedInput schema / properties / include_external
        Added 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"
        +}
      • addedInput schema / properties / include_structure
        Added 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"
        +}
    • Addedcgis_overview
    • Changedcgis_trace_flow3 fields changed
      • changedInput schema / properties / depth / description
        Previous 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)."
      • addedInput schema / properties / include_external
        Added 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"
        +}
      • addedInput schema / properties / include_structure
        Added 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"
        +}
  8. 2 tool updatesv0.21.5
    • Changedcgis_analyze_impact1 field changed
      • changedInput schema / properties / depth / description
        Previous 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."
    • Changedcgis_trace_flow1 field changed
      • changedInput schema / properties / depth / description
        Previous 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."
  9. 1 tool updatev0.21.4
    • Changedcgis_audit_reachability1 field changed
      • changedInput schema / properties / from_prefix / description
        Previous 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."
  10. 14 tool updatesv0.21.1
    • Changedcgis_analyze_impact4 fields changed
      • addedInput schema / properties / db_path / description
        Added 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."
      • addedInput schema / properties / depth / description
        Added 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."
      • addedInput schema / properties / fqn / description
        Added 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."
      • addedInput schema / properties / output_format / description
        Added value: +"\"mermaid\" for a diagram, or \"json\" for a payload with real FQNs (case-insensitive). Any other value returns an error."
    • Changedcgis_audit_reachability5 fields changed
      • addedInput schema / properties / db_path / description
        Added 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."
      • addedInput schema / properties / depth / description
        Added value: +"Maximum reachability depth; a longer path is reported as a gap."
      • addedInput schema / properties / from_prefix / description
        Added 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."
      • addedInput schema / properties / from_type / description
        Added value: +"NodeType of the sources to audit, e.g. ROUTE_HANDLER, API_ENDPOINT or FUNCTION (any case). Give this, from_prefix, or both."
      • addedInput schema / properties / target / description
        Added value: +"FQN of the checkpoint every source must reach, e.g. an ownership check. A unique dot-boundary suffix also resolves."
    • Changedcgis_context4 fields changed
      • addedInput schema / properties / db_path / description
        Added 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."
      • addedInput schema / properties / depth / description
        Added value: +"Call hops around the focal node; 1 means direct callers and callees."
      • addedInput schema / properties / fqn / description
        Added 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."
      • addedInput schema / properties / source_root / description
        Added 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."
    • Changedcgis_drift5 fields changed
      • addedInput schema / properties / db_path / description
        Added 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."
      • addedInput schema / properties / max_drift / description
        Added value: +"Drift tolerance for domains that declare no drift_tolerance of their own."
      • addedInput schema / properties / max_residual / description
        Added value: +"Distance to the nearest template beyond which a domain's fit band is \"none\" (no template fits)."
      • addedInput schema / properties / patterns_path / description
        Added 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."
      • addedInput schema / properties / profile / description
        Added value: +"Score only domains with this profile, plus profile-less ones β€” e.g. one language when patterns.yaml mixes several."
    • Changedcgis_find_orphans4 fields changed
      • addedInput schema / properties / db_path / description
        Added 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."
      • addedInput schema / properties / include_generated / description
        Added value: +"Include machine-generated classes, which are hidden by default."
      • addedInput schema / properties / include_tests / description
        Added value: +"Count test code as a user, so the report means \"unreachable from anywhere\"."
      • addedInput schema / properties / prefix / description
        Added value: +"Only consider classes under this FQN prefix, cut on a dot boundary."
    • Changedcgis_find_symbol5 fields changed
      • addedInput schema / properties / db_path / description
        Added 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."
      • addedInput schema / properties / fqn_prefix / description
        Added 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."
      • addedInput schema / properties / kind / description
        Added value: +"Only return this node type, e.g. FUNCTION, METHOD or CLASS (any case). An unknown type matches nothing rather than raising an error."
      • addedInput schema / properties / limit / description
        Added value: +"Maximum number of candidates to return."
      • addedInput schema / properties / query / description
        Added 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."
    • Changedcgis_fractal1 field changed
      • addedInput schema / properties / db_path / description
        Added 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."
    • Changedcgis_get_structure4 fields changed
      • addedInput schema / properties / db_path / description
        Added 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."
      • addedInput schema / properties / depth / description
        Added value: +"Maximum containment levels to descend (module β†’ class β†’ method)."
      • addedInput schema / properties / fqn / description
        Added 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."
      • addedInput schema / properties / output_format / description
        Added value: +"\"mermaid\" for a diagram, or \"json\" for a payload with real FQNs (case-insensitive). Any other value returns an error."
    • Changedcgis_ingest3 fields changed
      • addedInput schema / properties / db_path / description
        Added 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."
      • addedInput schema / properties / full_rebuild / description
        Added value: +"Re-scan every file from scratch instead of the incremental default."
      • addedInput schema / properties / project_path / description
        Added value: +"Root directory of the project to scan. A relative path resolves against the MCP server's working directory."
    • Changedcgis_init_ontology4 fields changed
      • addedInput schema / properties / db_path / description
        Added 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."
      • addedInput schema / properties / depth / description
        Added value: +"Fixed FQN segment depth for domain discovery (positive); omit to pick it automatically."
      • addedInput schema / properties / margin / description
        Added value: +"Headroom added to each measured score to form the proposed tolerance."
      • addedInput schema / properties / min_nodes / description
        Added value: +"Domains with fewer nodes stay hygiene-only instead of getting a label."
    • Changedcgis_metrics4 fields changed
      • addedInput schema / properties / db_path / description
        Added 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."
      • addedInput schema / properties / exclude / description
        Added value: +"Drop nodes whose FQN contains any of these dot-segments, e.g. [\"tests\"]; they are removed from PageRank propagation too."
      • addedInput schema / properties / limit / description
        Added value: +"Top-N rows returned per section."
      • addedInput schema / properties / scope / description
        Added value: +"Keep only nodes under any of these dot-prefixes, e.g. [\"domains.billing\"]; rank still propagates over the whole graph."
    • Changedcgis_suggest_packages4 fields changed
      • addedInput schema / properties / db_path / description
        Added 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."
      • addedInput schema / properties / min_q / description
        Added value: +"Modularity threshold: at or above it, a package whose layout disagrees with its communities is flagged split (or consolidate, if over-split)."
      • addedInput schema / properties / prefix / description
        Added 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."
      • addedInput schema / properties / with_calls / description
        Added value: +"Use the combined import + call graph instead of imports only."
    • Changedcgis_trace_flow4 fields changed
      • addedInput schema / properties / db_path / description
        Added 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."
      • addedInput schema / properties / depth / description
        Added 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."
      • addedInput schema / properties / fqn / description
        Added 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."
      • addedInput schema / properties / output_format / description
        Added value: +"\"mermaid\" for a diagram, or \"json\" for a payload with real FQNs (case-insensitive). Any other value returns an error."
    • Changedcgis_validate2 fields changed
      • addedInput schema / properties / db_path / description
        Added 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."
      • addedInput schema / properties / threshold / description
        Added value: +"Highest unresolved-edge ratio (0-1) still reported as healthy."
  11. 14 tool updatesv0.21.0
    • First observedcgis_analyze_impact
    • First observedcgis_audit_reachability
    • First observedcgis_context
    • First observedcgis_drift
    • First observedcgis_find_orphans
    • First observedcgis_find_symbol
    • First observedcgis_fractal
    • First observedcgis_get_structure
    • First observedcgis_ingest
    • First observedcgis_init_ontology
    • First observedcgis_metrics
    • First observedcgis_suggest_packages
    • First observedcgis_trace_flow
    • First observedcgis_validate

TDQS

A4.3/5.0

Scored across 17 tools

Disambiguation4/5

Each tool targets a distinct analysis taskβ€”ingest, overview, symbol lookup, structure, downstream vs. upstream traversal, context brief, metrics, drift, etc.β€”and descriptions explicitly cross-reference alternatives. A few whole-graph analytics (metrics, fractal, drift, suggest_packages) sit near each other conceptually, but their outputs and intended questions differ enough to keep boundaries clear.

Naming Consistency4/5

All names use a consistent cgis_ snake_case prefix and are readable. The suffix convention mixes verb_noun forms (find_symbol, trace_flow, analyze_impact) with noun phrases (metrics, fractal, context, diff_check), so it is not a strict verb_noun pattern throughout.

Tool Count4/5

17 tools is slightly above the typical 3–15 range, but the server’s purpose is broad code-graph analysis and each tool covers a distinct operation or report. It does not feel padded, though a few specialized analyses are arguably optional.

Completeness5/5

The surface covers initialization, discovery, structure, traversal in both directions, context generation, validation, metrics, dead-code detection, auth reachability, drift, package suggestions, ontology initialization, and diff impact. From ingest through analysis and validation there are no obvious dead ends for the stated code-intelligence domain.

Maintenance

ActivityActive
ResponsivenessResponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    Supercharges AI coding agents with a pre-indexed semantic code graph, enabling instant symbol relationships, impact analysis, and context retrieval across 20+ languages.
    113,205 npm
    75,178
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    Deterministic 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#.
    8
    12
    Apache 2.0
  • A
    license
    A
    quality
    B
    maintenance
    Indexes any TypeScript / React / Next.js repo into a queryable code graph and exposes 13 MCP tools β€” who-renders, who-calls, find-references, blast-radius, find-cycles, dead-code orphans, and local semantic search β€” so agents query structure instead of reading whole files. Built on ts-morph, so edges are resolved, not grepped.
    14
    2
    MIT