Skip to main content
Glama
impact-mcp
by 0xmortuex

impact-mcp

Ask "what depends on this file, and what breaks if I change it?" and get an answer that tells you how much to trust it.

impact-mcp is an MCP server that builds the import graph of a Python and/or JavaScript/TypeScript project and answers blast-radius questions: who imports this file, who uses this one symbol, which tests reach it, which entry points are downstream, where the cycles are, what looks dead.

What is different from the other code-graph MCP servers (codegraph-mcp, code-impact-mcp, ts-review-graph, dep-graph-guard and friends):

  • Zero extra dependencies and fully offline. Only mcp. Python is read with the stdlib ast; JS/TS with a small hand-written tokenizer. No Node, no TypeScript compiler, no ts-morph, no SQLite, no network, nothing executed, nothing written inside your repo.

  • It tells you what it could not see. Every answer ends with a Graph confidence line: resolved edges, external packages, unresolved project-looking imports, dynamic non-literal imports, syntax-error files. Dynamic importlib / import(x) / require(x) is reported as UNRESOLVED, never guessed. impact also warns when unresolved imports end in the name of the file you are about to change.

  • Python and JS/TS resolution that matches how projects are really laid out: src/ layouts, namespace packages, __init__.py re-exports and __all__, TYPE_CHECKING, tsconfig extends / baseUrl / paths, monorepo workspace packages, .js -> .ts ESM style imports, index.ts directories, export * from, import type.

  • Symbol-level answers that follow re-exports: symbol_users("pkg/core.py", "Engine") also finds the file that imports Engine from the package __init__.py that re-exports it.

What it looks like

> impact path=mort/lexer.py
Impact of changing mort/lexer.py
Direct dependents: 2; transitive: 10; max depth: 4
  mort/lsp.py  -- line 10: from-import {Lexer}
  mortc.py [entry]  -- line 36: from-import {Lexer}
Tests that reach it through imports (4) - a superset to run, not proof of coverage:
  kernel/test_exec.py
  tests/test_mort.py
  ...
Entry points affected (4):
  mortc.py  (console script in pyproject.toml)
  ...
Risk: HIGH
  - 10 transitive dependent file(s) = 31% of 32 files
  - 4 entry point(s) are downstream (a break can surface at startup)
Graph confidence: 32 files (32 py, 0 js/ts) | 52 resolved internal edges | external packages not tracked: 4 (+37 stdlib/builtin) | UNRESOLVED project-looking imports: 0 | dynamic non-literal imports: 0 | syntax-error files: 0

Related MCP server: Axon

Install

You need uv. Point --dir at the project you want analyzed.

Claude Code

claude mcp add impact -- uvx impact-mcp --dir /path/to/your/project

Claude Desktop (claude_desktop_config.json)

{
  "mcpServers": {
    "impact": {
      "command": "uvx",
      "args": ["impact-mcp", "--dir", "C:\\path\\to\\your\\project"]
    }
  }
}

--dir defaults to the current directory (or IMPACT_MCP_DIR). One server instance analyzes one project.

Tools

Tool

What it answers

project_map

Languages, module count, packages, guessed entry points, cycle count, unresolved/dynamic imports. Start here.

dependents(path_or_module, depth=3, limit=100)

Who imports this file, transitively, grouped by depth, with the import line, names and flags.

dependencies(path_or_module, depth=1, limit=100)

What this file imports from the project; lists its unresolved and dynamic imports.

impact(path, symbol=None, limit=40)

Blast radius: dependents, tests that reach it, entry points affected, LOW/MEDIUM/HIGH risk with reasons. With symbol, the direct users are narrowed to that name.

find_cycles(limit=10)

Strongly connected components (Tarjan) with the shortest cycle written out edge by edge; notes lazy/type-only edges that soften a cycle.

orphans_and_hubs(limit=15)

Dead-code candidates (with caveats) and the most depended-on files.

symbol_users(module, symbol, limit=100)

Who imports or accesses one name, including through re-exports. Best effort, labeled as such.

path_or_module accepts a project-relative path (src/app/util.py, packages/ui/src/Button.tsx), a dotted Python module (app.util), an absolute path inside the project, or an extensionless JS path.

Try asking

  • "I'm about to change src/billing/invoice.py. What could break and which tests should I run?"

  • "Who uses parse_config from app.config?"

  • "Are there import cycles in this repo? Show me the shortest one."

  • "What are the most depended-on files here? Which files look dead?"

  • "Which entry points are affected if I rename Button in packages/ui/src/Button.tsx?"

  • "Give me an overview of this project and how much I can trust the import graph."

What it cannot resolve (read this)

The graph is static. These are counted in the confidence line where they are detectable, and the impact and dependents add hints when they could be hiding a dependent of the file you asked about.

Python

  • importlib.import_module(name) / __import__(name) with a non-literal argument, exec, plugin discovery by entry points or string names, getattr on modules. A literal import_module("pkg.mod") is resolved and flagged dynamic.

  • Implicit parent-package execution is not modeled: import a.b.c is an edge to a/b/c.py only, not also to a/__init__.py and a/b/__init__.py.

  • Which directories act as import roots is inferred (project root, src/, dirs with pyproject.toml/setup.py, and the dir above each top-level package); a custom PYTHONPATH or sys.path edit is invisible.

  • from x import * is an edge; which names it brings in is taken from __all__ / top-level definitions.

  • Re-exports renamed with as inside __init__.py are not followed by symbol tracking.

JavaScript / TypeScript

  • A tokenizer, not a parser. Known weak spots: JSX text containing an apostrophe can desync the rest of that line; regex-vs-division is heuristic.

  • require(x) / import(x) with a non-literal argument, require.context, bundler magic (import.meta.glob), Next.js/Nuxt file-system routing.

  • tsconfig: extends to an npm package is not followed (warned); references/include are ignored; the nearest tsconfig.json wins.

  • package.json exports is read only for the . entry and simple subpaths (conditions: import, module, default, require, node, types); imports (#alias) maps are reported as unresolved.

  • Workspace packages whose entry is a build output (dist/) resolve to src/ equivalents if the source file exists; otherwise the import counts as unresolved.

  • Namespace-import and require attribute tracking (ns.foo) is by name only; a namespace passed around as a value marks the edge as "may use anything".

  • Only .js .jsx .mjs .cjs .ts .tsx .mts .cts files are in the graph; .vue, .svelte, .astro are not.

  • Files over 2 MB (bundles) are skipped and reported.

Both

  • Symlinks and junctions are not followed (loop safe); skipped counts are reported.

  • On Windows and macOS (case-insensitive file systems) an import that only matches by case resolves and is counted.

  • Dead-code candidates are candidates: frameworks, external consumers of a library and non-code tooling can use files the graph cannot see.

Performance

Parsed results are cached by file mtime and size in a cache directory outside your repo (%LOCALAPPDATA%\impact-mcp on Windows, $XDG_CACHE_HOME/impact-mcp or ~/.cache/impact-mcp elsewhere; override with IMPACT_MCP_CACHE_DIR). A cold scan of a 2,700-file JS repo takes a few seconds; a warm scan is dominated by the directory walk. File reading is threaded; .gitignore files (nested too), .git, node_modules, venv, .venv, dist, build, __pycache__ and similar directories are skipped.

Security

  • Read-only. Source files are opened for reading and parsed; nothing is imported, executed, installed or written inside the project. The only write is the parse cache, in your user cache directory.

  • Sandboxed. All paths are resolved against --dir; absolute paths or .. that leave it are rejected. Symlinks are not followed.

  • Offline. No network access of any kind.

  • Output contains file paths, line numbers, and import names from your code, which go to whatever AI client you connected.

Develop

uv sync --extra test
uv run pytest
uv run --with ruff==0.16.0 ruff check src tests
uv run --with mypy==2.3.0 mypy --strict src

Set IMPACT_TEST_REPOS (paths separated by ; on Windows, : elsewhere) to also run read-only checks against your own repositories.

There is a from-scratch tutorial that builds a minimal version of this server: impact-mcp-the-hard-way.

MIT licensed.

Available Tools

7 tools
dependenciesB

What does this file import from inside the project (transitively up to depth)? Also lists this file's UNRESOLVED and DYNAMIC imports explicitly.

NameRequiredDescriptionDefault
depthNo
limitNo
path_or_moduleYes

Output Schema

NameRequiredDescription
resultYes

TDQS

B3.1/5.0
Behavior2/5

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

With no annotations, the description carries the entire burden. It does disclose real behavioral facts that structured fields do not: results are scoped to project-internal imports only, depth is transitive, and unresolved/dynamic imports are always listed separately. It says nothing about whether the call is read-only, how `limit` truncates or reorders results, or what happens when the path does not exist — gaps that matter for a graph-traversal tool.

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 short sentences, front-loaded with the core question and followed by the one caveat that changes how results should be read. Nothing is wasted and the emphasis on UNRESOLVED/DYNAMIC imports signals that those entries are exceptional.

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

Completeness3/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-value shape need not be described. Still, a zero-coverage three-parameter graph tool needs at least a note on `limit` semantics and the path/module input form; the description stops short of that while adequately covering the transitive-import behaviour.

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

Parameters2/5

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

Schema description coverage is 0%, so the description must compensate for all three parameters. It only explains `depth` (transitive expansion) and implicitly `path_or_module`; `limit` is never mentioned, and the path-vs-module ambiguity in `path_or_module` is left unresolved.

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?

The description names a specific question the tool answers: what a given file imports from inside the project, transitively to `depth`, plus unresolved and dynamic imports. That is concrete and materially narrower than a generic graph query. It does not, however, distinguish itself from the obvious inverse sibling `dependents`, which an agent could easily confuse with it.

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?

Use is implied by the framing ('What does this file import...'), so an agent can infer the direction of the lookup. But there is no explicit when-to-use/when-not guidance and no reference to `dependents`, `impact`, or `find_cycles`, which are the near-neighbour alternatives an agent would weigh.

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

dependentsA

Who imports this file? Transitive importers grouped by depth, with the import line, imported names, and flags (type-only / lazy / conditional). path_or_module is a project-relative path (src/app/util.py, packages/ui/src/Button.tsx), an extensionless JS path, or a dotted Python module (app.util). Depth 1 = direct importers only.

NameRequiredDescriptionDefault
depthNo
limitNo
path_or_moduleYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.5/5.0
Behavior3/5

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

No annotations are supplied, so the description carries the full behavioral burden. It discloses what the output contains (grouping, import lines, names, type-only/lazy/conditional flags), which is genuinely informative, but says nothing about whether the whole project is scanned, how unresolved or dynamic imports are handled, or the cost of deep traversal.

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 core question, then the output shape, then input formats — a sensible ordering with no filler sentences. The parenthetical path examples are dense but earn their place; slightly tighter phrasing could avoid the line-broken run-on.

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

Completeness3/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-value detail is not strictly required, yet the description spends most of its words on output shape while leaving `limit` and traversal cost unaddressed. For a three-parameter graph-traversal tool with no annotations, the missing coverage of pagination and scan scope is a real gap.

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 0%, so the description must compensate, and it largely does for the required parameter: it enumerates accepted forms (project-relative path, extensionless JS path, dotted Python module) with concrete examples. `depth` is clarified via 'Depth 1 = direct importers only', but `limit` (default 100) is never mentioned, leaving one of three parameters undocumented.

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?

The description opens with a concrete verb+resource question ('Who imports this file?') and specifies the shape of the answer (transitive importers grouped by depth, with import lines, imported names, and flags). That is enough to distinguish it from the reverse-direction sibling `dependencies`, but it never names that sibling or `impact`, leaving the agent to infer the inverse relationship.

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?

Useful operational guidance is embedded: accepted `path_or_module` formats and 'Depth 1 = direct importers only', which tells the agent how to get direct-only results. However, there is no explicit statement of when to prefer this over `dependencies`, `impact`, or `project_map`, and no exclusions or prerequisites.

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

find_cyclesA

Import cycles: strongly connected components (Tarjan), each with its shortest cycle spelled out file by file, and whether the cycle is softened by lazy/type-only imports.

NameRequiredDescriptionDefault
limitNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.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 full burden and does disclose meaningful behavior beyond the schema: results are strongly connected components, each reduced to a shortest cycle listed file by file, plus a flag for whether lazy/type-only imports soften the cycle. It does not disclose analysis scope or how many components are returned before truncation, which keeps it below 5.

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?

A single dense sentence that front-loads the resource ('Import cycles') and then qualifies the output. The parenthetical '(Tarjan)' is useful shorthand, though 'spelled out file by file' is slightly awkward phrasing.

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?

The tool is simple (one optional param) and has an output schema, so return values need not be explained here; the description covers purpose and the key nuance of softened cycles. The only real omission is the limit parameter's meaning and default behavior.

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

Parameters2/5

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

There is one parameter (limit, default 10) with 0% schema description coverage, and the description never mentions it — no indication that it caps the number of cycles reported or what happens when more exist. The description therefore does not compensate for the coverage gap.

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+resource ('Import cycles') and goes further by naming the algorithm (Tarjan SCCs) and the shape of each result ('shortest cycle spelled out file by file'). It is clearly distinct from siblings like dependencies or project_map, though it never names an alternative explicitly.

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?

Usage is only implied: an agent can infer it is for circular-import investigation, but there is no statement of when to reach for this versus dependencies/dependents, nor any prerequisite or scope guidance (whole project vs a subtree).

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

impactA

Blast radius of changing a file (or one symbol in it): direct and transitive dependents, the tests that reach it through imports (run these), entry points affected, and a LOW/MEDIUM/HIGH risk summary with reasons. With symbol, direct users are narrowed to files that import or access that name (following re-exports); the rest is an upper bound.

NameRequiredDescriptionDefault
pathYes
limitNo
symbolNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior4/5

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

With no annotations, the description must carry the behavioral burden, and it does disclose a genuinely non-obvious trait: when `symbol` is supplied, direct users are narrowed but 'the rest is an upper bound,' telling the agent the output is an over-approximation it must interpret carefully. It also explains the risk-grading output and that reasons accompany it. It does not state that the call is read-only, cheap/expensive, or how `limit` truncates results.

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?

Three sentences, front-loaded with the core concept, then outputs, then the parameter caveat. Every clause adds information — the parenthetical '(run these)' directs action and the upper-bound note prevents misreading. No filler or restatement of the tool name.

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?

Output schema exists, so return shape need not be spelled out, yet the description still orients the agent by summarizing result categories and the risk grade, which is appropriate for an analysis tool whose value is interpretive. Against a 3-parameter tool the only real hole is `limit` and the absence of any guidance about result size or truncation.

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 0% and all three parameters are bare titles, so the description must compensate. It does this well for `symbol` (narrowing to files that import or access the name, following re-exports) and adequately for `path` by framing the whole tool around a file. However, `limit` (default 40) is never mentioned, leaving a truncation parameter with no meaning attached anywhere.

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?

The description names a specific analysis ('blast radius of changing a file') and enumerates exactly what the result contains: direct and transitive dependents, tests reaching it via imports, affected entry points, and a risk summary. That is far more specific than the bare name 'impact'. It stops short of a 5 because it never names a sibling (dependents, symbol_users) to show where the boundary lies, so the agent must infer that this is the composite/richer variant.

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 decision context ('changing a file') and a concrete follow-up action ('the tests that reach it through imports (run these)'), plus a rule for choosing symbol vs. file-level mode. What is missing is any exclusion or alternative: there is no statement like 'use dependents for a cheap non-risk listing', so an agent cannot rule out the lighter siblings from this text alone.

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

orphans_and_hubsB

Dead-code candidates (files nothing imports that are not entry points, tests, init.py or configs - with caveats) and the most depended-on files (direct importers / transitive dependents).

NameRequiredDescriptionDefault
limitNo

Output Schema

NameRequiredDescription
resultYes

TDQS

B3.3/5.0
Behavior3/5

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

With no annotations, the description must carry the behavioral load, and it does disclose the exclusion rules that shape the orphan list and hints at heuristic unreliability ('with caveats'). However, it never says what those caveats are, whether the two lists are ranked/scored, or what ordering the hub ranking uses – substantial gaps for a heuristic 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?

A single front-loaded sentence that leads with the primary output and packs the exclusion criteria inline. The nested parenthetical is slightly dense but nothing is wasted.

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

Completeness3/5

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

An output schema is present, so return shape needn't be explained, and the description covers what the tool finds and what it filters out. The undisclosed 'caveats' and the missing handling of the limit parameter leave real ambiguity about what an agent will actually receive.

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?

Only one optional parameter exists in the schema, which sets the baseline at 4 regardless of description.

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?

Names two concrete resources – dead-code candidates and most-depended-on files – with the defining criteria (files nothing imports, excluding entry points/tests/__init__.py/configs) and a metric for hubs (direct importers / transitive dependents). It is clearly not project_map or find_cycles, though the hub half overlaps conceptually with the 'dependents' sibling without being explicitly differentiated.

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

Usage Guidelines2/5

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

No when-to-use guidance and no routing to alternatives. Given siblings like dependents, impact, and symbol_users, an agent gets no signal about when to pick this combined report over the narrower tools. The 'with caveats' parenthetical flags uncertainty without resolving it.

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

project_mapA

Overview of the project: languages, module count, Python packages, guessed entry points (pyproject scripts, main.py, package.json bin/main/exports), import-cycle count, unresolved/dynamic imports, and syntax-error files. Start here.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior4/5

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

With no annotations, the description carries the full burden, and it does disclose the analysis surface: it reports guessed entry points and the specific files consulted, and it flags unresolved/dynamic imports and syntax-error files, which tells the agent the map is heuristic and may be incomplete. It does not explicitly state that the call is read-only or note cost/scale behavior for large projects, leaving a modest gap.

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?

One dense enumerative sentence plus the front-loaded imperative "Start here" — close to no waste and the routing cue is prominent. The list is long but each item is a distinct reported datum, so trimming would lose information.

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 an output schema present, the description need not explain return values, and it correctly focuses on scope of analysis and when to call it. For a zero-parameter project overview the definition is nearly complete; only an explicit read-only/side-effect statement and any project-size caveat are 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?

The tool takes zero parameters, so there is no parameter semantics to explain; the baseline for an empty schema applies. Nothing in the description misleads about inputs.

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 names a concrete resource (the project) and enumerates exactly what the overview contains: languages, module count, Python packages, guessed entry points with the heuristics used (pyproject scripts, __main__.py, package.json bin/main/exports), import-cycle count, unresolved/dynamic imports, and syntax-error files. That enumeration also cleanly distinguishes it from the narrower siblings (find_cycles, dependents, dependencies, impact, orphans_and_hubs, symbol_users), which each answer one targeted question.

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?

"Start here" is an explicit sequencing instruction that tells the agent to call this before the targeted siblings, which is meaningful routing guidance for a zero-parameter tool. It stops short of stating exclusions or when a sibling is preferable instead, so it is clear context without 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.

symbol_usersA

Who uses symbol from module? Best effort and labeled as such: from-imports, named imports, attribute access on the module alias (mod.name), wildcard imports, and re-export chains (init.py, all, export {x} from). getattr()/dynamic use is invisible.

NameRequiredDescriptionDefault
limitNo
moduleYes
symbolYes

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior4/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 substantial work: it enumerates exactly which reference forms are detected (from-imports, named imports, module-alias attribute access, wildcard imports, re-export chains) and explicitly discloses the blind spot for getattr()/dynamic use. That is real behavioral context an agent cannot get from the schema. It stops short of describing result ordering or how the limit interacts with truncation.

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 tight sentences, front-loaded with the core question, followed by the coverage caveat. Every clause adds information; nothing is redundant.

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-value explanation is unnecessary, and the description covers detection scope and known limitations well. The only meaningful gap is the unexplained `limit` parameter and any note on result ordering or truncation behavior.

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 0%, so the description must compensate. It implicitly clarifies `module` and `symbol` through examples like mod.name and __init__.py, but the `limit` parameter (default 100) is never mentioned, leaving pagination/truncation semantics undocumented.

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?

The description opens with a precise question form, 'Who uses `symbol` from `module`?', which names both the verb (find users) and the resource (a specific symbol within a module). This is clearly narrower than module-level siblings like dependents or dependencies, though it never names those siblings explicitly to draw the contrast.

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?

Usage is implied by the question framing and the 'best effort' caveat signals when results may be incomplete, but there is no explicit when-to-use versus when-to-use-a-sibling guidance (e.g., dependents vs symbol_users) and no stated prerequisites.

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. 7 tool updatesv0.1.0
    • First observeddependencies
    • First observeddependents
    • First observedfind_cycles
    • First observedimpact
    • First observedorphans_and_hubs
    • First observedproject_map
    • First observedsymbol_users

TDQS

A3.6/5.0

Scored across 7 tools

Disambiguation4/5

Each tool targets a distinct analysis: overview, cycles, forward imports, reverse imports, blast radius, hub/orphan stats, and symbol-level usage. The main risk is `dependents` vs `impact` (impact largely subsumes dependents' output plus tests and risk) and the near-homophone pair `dependents`/`dependencies`, which an agent could swap despite direction being stated in the text.

Naming Consistency3/5

Names are all lowercase snake_case, but grammatical form is mixed: verb phrases (`find_cycles`), bare nouns (`dependents`, `dependencies`, `impact`), and a conjoined noun (`orphans_and_hubs`). The pair `dependents`/`dependencies` is only one character-apart in semantics and spelling, which is a real readability hazard even though no convention is violated outright.

Tool Count5/5

Seven tools is well-scoped for an import-graph/impact-analysis server, with one tool per analysis question rather than redundant variants. Nothing feels padded or missing at the count level.

Completeness4/5

The surface covers the full lifecycle of impact analysis: orient (project_map), forward/reverse graph queries, cycles, dead code/hubs, symbol usage, and a risk-rated blast radius including affected tests and entry points. Minor gaps: no direct way to locate a file by fuzzy name or browse the test-to-source mapping outside `impact`, and no handling of dynamic/reflective edges beyond flagging them.

Maintenance

ActivityMaintained
ResponsivenessNo recent community issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables querying and analyzing code relationships by building a lightweight graph of TypeScript and Python symbols. Supports symbol lookup, reference tracking, impact analysis from diffs, and code snippet retrieval through natural language.
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A graph-powered code intelligence engine that indexes codebases into a structural knowledge graph to provide AI agents with deep context on function calls, types, and execution flows. It offers local, zero-dependency tools for hybrid search, impact analysis, and dead code detection across Python, JavaScript, and TypeScript projects.
    1,285 PyPI
    816
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI agents and terminal users to query codebases for callers, impact, tests, dependencies, and refactor previews using static AST analysis, with every match accounted for and uncertain relationships clearly marked.
    331 npm
    2
    MIT