py-ast-mcp
Provides deep structural analysis of Python source code, including function/class extraction, signatures, call graphs, complexity metrics, code smells, dead code detection, protocol conformance, docstring parsing, and structural diffing.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@py-ast-mcpShow me the call graph for calculate_total in app.py"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
py-ast-mcp
An MCP (Model Context Protocol) server for deep structural analysis of Python source code.
It is the Python counterpart to ts-ast-mcp and mirrors its 20-tool surface as closely as Python semantics allow. Everything is built on the standard library ast module — no compilation, no type checker, no project configuration required. jedi is an optional extra used only for cross-file semantic resolution, and every tool degrades gracefully when it is not installed.
Unlike grep, this server understands actual structure: function signatures, class hierarchies, call relationships, cyclomatic complexity and unreferenced code.
Features
Real AST, not regex — signatures with annotations and defaults, decorators, async flags, positional-only and keyword-only parameters, nested definitions.
Python-aware classification — dataclasses, enums,
Protocol,TypedDict,NamedTuple, ABCs, exceptions andTypeAliasare recognised as distinct kinds.Call graphs as Mermaid — file-scoped or package-scoped flowcharts, rooted at a function, with optional external call edges.
Quality tooling — cyclomatic complexity with ranks, scored to match
radon/mccabe, code smells, and Python-specific hazards (mutable default arguments, mutable@dataclassfield defaults, bareexcept, unreachableexceptclauses, late-binding closures,isagainst a literal, unawaited coroutines,assertused for validation).Dead code across a directory — unreferenced private and module-level symbols, with a confidence split between private and public names.
Protocol conformance — finds implementations both explicitly (base class, including indirect subclasses) and structurally (method-set match).
Docstring parsing — Google and NumPy styles are split into summary / params / returns / raises.
Structural diffing — signature-level, not text-level: what actually changed in the API.
Model-friendly output — dense, scannable plain text with line numbers everywhere, not raw JSON dumps.
Never crashes on bad input — syntax errors come back as a readable error with line and column, flagged
isErrorso a client can tell failure from analysis; the server stays up.Parse caching — modules are cached by path + mtime + size, so repeated tool calls in one turn are cheap.
Related MCP server: code-quality-mcp
Installation
Requires Python 3.10+. Prefer the newest Python you have installed: the server can only parse syntax its own interpreter understands (see Known limitations).
git clone <this-repo> py-ast-mcp
cd py-ast-mcp
pip install -e .
# optional: cross-file semantic resolution
pip install -e ".[semantic]"
# development (pytest + jedi)
pip install -e ".[dev]"This installs a py-ast-mcp console script that runs the stdio server. python -m py_ast_mcp works too.
Tools
All path arguments accept absolute paths or paths relative to the server's working directory.
Structural
Tool | Parameters | Description |
|
| High-level summary of every symbol: classes (with dataclass/enum/Protocol/TypedDict classification), functions, async functions, methods and module-level assignments. |
|
| All functions and methods with full signatures (annotations, defaults, return type, decorators, async flag) and line ranges. |
|
| Full numbered source of a function or method. Supports |
|
| All methods of a class: declared, properties, class/static methods, class attributes, and members inherited from base classes defined in the same file. |
|
| Extract a class / |
|
| Module-level assignments with annotated or inferred types. |
|
| Public API: respects |
|
| All imports with bound name, module path, relative-import level and aliases, grouped into stdlib / third-party / relative. |
|
| Every occurrence with surrounding source lines: reads, assignments, parameters, attribute access, imports, |
Call analysis
Tool | Parameters | Description |
|
| Mermaid flowchart of call relationships. |
|
| Reverse call graph: direct callers with call sites, transitive callers, and the entry points that reach the function. |
Quality
Tool | Parameters | Description |
|
| Cyclomatic complexity per function with an A–F rank. Counts |
|
| Long functions, deep nesting, god classes, too many parameters, mutable default arguments, mutable |
|
| Python-specific hazards: bare/broad |
|
| Unreferenced private and module-level symbols across a directory. If |
|
| Classes implementing a Protocol/ABC — explicit (direct or indirect base class) and structural (method-set match), plus near misses. The argument is |
Docs & multi-file
Tool | Parameters | Description |
|
| Docstring extraction for a function, |
|
| Directory-level summary of every |
|
| Structural diff: added / removed / modified functions, methods, classes, base classes, decorators, module variables, imports and |
|
| The AST node at a cursor position, the full node chain, and the enclosing scope chain. Adds jedi-resolved definitions when available. |
Configuration
Claude Code
Add a .mcp.json at the root of your project (this file is picked up automatically):
{
"mcpServers": {
"py-ast": {
"command": "py-ast-mcp",
"args": []
}
}
}If you installed into a virtualenv, point at it explicitly so the server does not depend on your shell's PATH:
{
"mcpServers": {
"py-ast": {
"command": "/absolute/path/to/venv/bin/python",
"args": ["-m", "py_ast_mcp"]
}
}
}Or run it straight from a checkout without installing, using uv:
{
"mcpServers": {
"py-ast": {
"command": "uvx",
"args": ["--from", "/absolute/path/to/py-ast-mcp", "py-ast-mcp"]
}
}
}You can also register it from the CLI:
claude mcp add py-ast -- py-ast-mcpClaude Desktop
Edit claude_desktop_config.json:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.jsonLinux:
~/.config/Claude/claude_desktop_config.json
{
"mcpServers": {
"py-ast": {
"command": "py-ast-mcp",
"args": []
}
}
}Because Claude Desktop does not inherit your shell environment, an absolute path is usually safer:
{
"mcpServers": {
"py-ast": {
"command": "/absolute/path/to/venv/bin/py-ast-mcp",
"args": []
}
}
}Restart Claude Desktop after editing the file.
Straight from GitHub
No checkout, no install - uv fetches and runs it:
{
"mcpServers": {
"py-ast": {
"command": "uvx",
"args": ["--from", "git+https://github.com/gclluch/py-ast-mcp", "py-ast-mcp"]
}
}
}Add --with jedi to the args for cross-file semantic resolution.
Example output
call_graph on a small package:
# call_graph (package) samplepkg/core.py [16 functions, 11 edges]
## mermaid
```mermaid
flowchart TD
n2_core_Engine_store["core.Engine.store L57"]
n9_util_normalize["util.normalize L4"]
n2_core_Engine_store --> n9_util_normalizeedges
Engine.store -> validate @L58
Engine.store -> normalize @L59
run_pipeline -> Engine.store @L70
`code_complexity` on the standard library's `argparse`:
complexity /usr/lib/python3.11/argparse.py [138 functions, module total 350]
average 3.7 max 46 functions over 10: 10
function lines cc rank len depth
ArgumentParser._parse_known_args L1930-2187 46 F 258 6 HelpFormatter._format_actions_usage L406-519 28 D 114 5
## Development
```bash
pip install -e ".[dev]"
# unit tests
pytest
# end-to-end: spawn the real server and drive it over stdio with a
# handwritten JSON-RPC client (initialize -> tools/list -> tools/call)
python scripts/stdio_smoke_test.pyLayout:
src/py_ast_mcp/
server.py MCP tool registration (FastMCP, stdio transport)
parse.py shared parse + cache by path/mtime/size, AST navigation
format.py shared output formatting
analyze.py analyze_file, analyze_package, find_node_at_position
functions.py list_functions, get_function_body, list_methods
types.py get_type_definition, list_declarations
imports.py list_imports, list_exports
usages.py find_usages
callgraph.py call_graph, get_callers
complexity.py code_complexity
smells.py code_smells
errors.py find_errors
deadcode.py dead_code
protocols.py find_implementations
doc.py get_doc
diff.py diff_ast
jedi_support.py optional cross-file resolutionKnown limitations
These are heuristics over a syntax tree, not a type checker:
The server parses with its own interpreter's grammar.
astcan only read syntax the running Python understands, so a server on 3.11 reportsPEP 695code (type X = ...,def f[T]()) as a syntax error even though the file is valid. Run the server on the newest Python you have, regardless of what the target project targets — parse errors say so when the interpreter may be the cause.Call resolution is name-based.
obj.method()is matched by method name; when several classes in scope define the same name the first one wins.self.method()resolves within the enclosing class and then across classes in the file.Cross-module call edges in
scope="package"are resolved throughimportstatements only. Dynamic dispatch, factories and callbacks are not followed.dead_codematches by name, not by scope.getattr, plugin registries, entry points and re-exports from outside the scan produce false positives; public symbols are reported separately as lower confidence. The larger risk is the other direction: any attribute access or string literal sharing a symbol's name marks it live, so the tool under-reports. Treat hits as candidates to confirm.jediresolution is scoped to the detected project root, found by walking up for.git/setup.py/requirements.txt. Files outside that root are invisible tofind_usages' cross-file section.unawaited-coroutineis best effort. It flags calls toasync deffunctions declared in the same file that are neither awaited nor wrapped in a recognisedasynciohelper.Inherited members are only resolved for base classes defined in the same file; bases from other modules are listed as unresolved.
list_declarationstype inference is literal-shaped, not a real inference engine: it reports what a reader would infer from the right-hand side.
License
MIT
Available Tools
20 toolsanalyze_fileA
High-level summary of every symbol in a Python file.
Lists classes (with dataclass/enum/Protocol/TypedDict classification), functions, async functions, methods and module-level assignments with line numbers. Start here when exploring an unfamiliar module.
Args: path: Path to a .py file.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description is the sole source of behavioral info. It explains what the tool lists and includes line numbers, but it does not disclose potential limitations (e.g., handling of malformed files) or explicitly confirm read-only behavior. Adequate but not detailed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and front-loaded. It begins with the primary purpose, then details the contents, then gives usage guidance and the parameter description. Every sentence contributes useful information without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the presence of an output schema (which likely describes return values) and only one parameter, the description sufficiently covers purpose, usage context, and parameter semantics. It does not address error handling or edge cases, but for a high-level analysis tool this is acceptable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides no description for 'path' (0% coverage), but the description compensates with an Args section: 'path: Path to a .py file.' This clarifies the expected type and format, adding meaning beyond the bare schema property.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'High-level summary of every symbol in a Python file.' It enumerates specific symbol categories (classes, functions, async functions, methods, module-level assignments), which distinguishes it from sibling tools that focus on individual symbol types.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly advises 'Start here when exploring an unfamiliar module,' which establishes a clear use case. It does not explicitly mention alternatives or exclusions, but the guidance is strong enough to indicate when to use this tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
analyze_packageA
Directory-level summary of every .py file: sizes, class/function counts, docstrings and per-file symbol lists.
Args: path: Directory to analyse. include_tests: Include test files (default False).
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| include_tests | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses that the tool analyzes directories and outputs specific summary information, but it does not state whether traversal is recursive, whether files are modified (though 'analyze' implies read-only), or mention potential edge cases/errors. This is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences plus concise arg explanations, front-loading the core purpose. Every line earns its place with no redundancy or fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the essential inputs and the nature of the output summary. An output schema exists to handle return-value details, so the description need not explain those. It lacks explicit mention of recursion depth or handling of non-.py files, which are minor gaps for a directory analysis tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description is the sole source of parameter meaning. It explains 'path' as the directory to analyze and clarifies 'include_tests' with its default behavior, fully compensating for the lack of schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool produces a directory-level summary of every .py file, listing specific metrics like sizes, class/function counts, docstrings, and per-file symbol lists. This distinguishes it from sibling tools such as analyze_file (single file analysis) and list_functions (function-level listing).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool versus alternatives. The description implies it is for whole-package analysis, but it does not mention exclusions or name alternative tools for different scopes, leaving the agent to infer usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
call_graphA
Emit a Mermaid flowchart of the call relationships in a file or package.
Args: path: Path to a .py file. function: Optional root; only calls reachable from it are drawn. direction: Mermaid layout direction: TD, TB, LR, RL or BT. include_external: Include calls to names not defined in scope. scope: "file" (default) or "package" to walk every .py file in the containing directory.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| scope | No | file | |
| function | No | ||
| direction | No | TD | |
| include_external | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the transparency burden. It discloses the output type (Mermaid flowchart), the effect of parameters like function and include_external, and that package scope walks all .py files. However, it does not discuss error handling, performance, or whether any modifications occur, leaving some behavioral aspects undisclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description opens with a clear purpose sentence and proceeds to a structured Args list. While the parameter list is somewhat long, it is necessary and each line serves a purpose. The information is well-organized and not redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the purpose, all parameters, and important scope semantics. Since an output schema exists, the return format does not need to be detailed. It misses potential edge cases or when to choose package over file scope, but overall it is sufficiently complete for invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has no descriptions, but the description's Args section clearly documents all five parameters, including defaults and options. This fully compensates for the lack of schema coverage and adds meaning beyond the raw schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool emits a Mermaid flowchart of call relationships in a file or package, which specifies both the action and resource. It does not explicitly differentiate from sibling tools like get_callers or list_functions, so it falls short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for visualizing call relationships and explains scope options, but it does not provide explicit when-to-use or alternative guidance compared to sibling tools. This is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
code_complexityA
Cyclomatic complexity per function, with rank and decision-point breakdown.
Counts if/elif, for, while, except, comprehension fors and ifs, boolean
operators, ternaries, and match cases other than the irrefutable one.
Scores match radon cc --no-assert.
with and assert are deliberately not counted: neither branches. with
still adds nesting depth.
Args: path: Path to a .py file. function: Optional single function to analyse in detail.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| function | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and excels: it details exactly which constructs are counted (if/elif, for, while, except, comprehensions, booleans, ternaries, match cases) and which are not (with, assert), and even references radon compatibility. This is thorough and transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the main purpose, then provides concise, well-organized technical details and an Args section. Every sentence contributes value, and unnecessary fluff is absent.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the existence of an output schema, the description only needs to explain behavioral nuances, which it does comprehensively (counting rules, exclusions, and radon match). It is complete for a complexity-analysis tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides only titles, but the description clarifies that path is a .py file and function is an optional single function for detailed analysis. This adds meaning beyond the schema, though it could specify function name format.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Cyclomatic complexity per function, with rank and decision-point breakdown.' This is a specific verb+resource that distinguishes it from sibling tools like list_functions or code_smells, which focus on different aspects.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides implied usage context (for analyzing cyclomatic complexity), but it lacks explicit when-to-use or alternatives. There is no mention of preferring this over analyze_file or code_smells, or any exclusions, so guidance is only implied.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
code_smellsA
Detect long functions, deep nesting, god classes, too many parameters,
mutable default arguments, mutable @dataclass field defaults, high
complexity, bare excepts and shadowed builtins.
Args: path: Path to a .py file. function: Optional single function to analyse.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| function | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden for behavioral disclosure. It does enumerate the exact code smell categories and the scope (path or optional function), which is useful, but it does not mention whether the operation is read-only, what the return format is, or whether any side effects (e.g., file writes) occur. This is a moderate disclosure for a static 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.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and well-structured: a concise list of detectable smells followed by an Args section. Every sentence carries useful information, with no filler or redundancy, and the primary action is front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the input semantics and the scope of analysis, and the existence of an output schema means it does not need to detail return values. However, it does not mention whether a directory is accepted or how the optional function is resolved, leaving minor gaps that an agent might need to probe. Overall, it is sufficiently complete for the tool's complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides no descriptions for its parameters (0% coverage), so the description must compensate. It does so by explaining that 'path' is a Python file and 'function' is an optional single function to analyze, adding meaningful semantic context beyond the raw parameter names. However, it could specify the expected format of the function parameter (e.g., name vs. qualified path), which prevents a 5.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb 'Detect' and lists concrete code smell categories, making it clear what resource and action are involved. However, it does not explicitly distinguish itself from the sibling tool 'code_complexity' or other analyzer tools, so it falls short of a perfect 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus alternatives like 'code_complexity' or 'analyze_file'. The description implies it should be used for smell detection, but does not state prerequisites, exclusions, or preferred contexts, leaving the agent to infer usage from the parameter list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
dead_codeA
Find unreferenced private and module-level symbols across a directory.
If path is a file, its containing directory is scanned so that cross-file
references are seen.
Args: path: A .py file or a directory. include_tests: Also scan test files (default False).
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| include_tests | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of behavioral disclosure. It reveals important non-obvious behavior: file paths expand to their containing directory, and cross-file references are considered. This goes beyond a simple 'find dead code' statement and gives meaningful insight into how the tool operates, though it could further clarify what counts as 'unreferenced' or 'private' (e.g., underscore convention).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and well-structured: a one-sentence purpose, a brief behavioral note, and an Args list. Every sentence adds value; there is no repetition of schema already present. The front-loaded purpose makes the tool's intent immediately clear.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the presence of an output schema and moderate complexity, the description adequately covers the tool's purpose, path handling, and both parameters. It could further differentiate from sibling tools like code_smells or analyze_file, but all necessary operational details for invocation are present, so it is nearly complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It does so with an Args block: 'path: A .py file or a directory' and 'include_tests: Also scan test files (default False).' This adds meaning beyond the raw schema, clarifying accepted path types and the purpose of the boolean flag, though it doesn't delve into edge cases or expected formats.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Find unreferenced private and module-level symbols across a directory,' using a specific verb ('Find') and a well-defined resource ('unreferenced private and module-level symbols'). This clearly distinguishes it from siblings like find_usages or find_implementations, which target references and implementations rather than dead code.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It provides clear usage context: 'If `path` is a file, its containing directory is scanned so that cross-file references are seen.' This explains the directory/file behavior and implies when to use the tool (for dead code analysis across files). It does not explicitly name alternatives or when not to use it, but the context is unambiguous enough for a 4.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
diff_astA
Structural diff between two Python files: added, removed and modified
functions, classes, methods, module variables, imports and __all__.
Signature-level, not text-level.
Args: old_path: Path to the original file. new_path: Path to the updated file.
| Name | Required | Description | Default |
|---|---|---|---|
| new_path | Yes | ||
| old_path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It discloses that the diff is structural and signature-level, and what elements are considered. However, it does not mention any assumptions, limitations, or side effects (e.g., whether files must be syntactically valid, or whether it only reads files). This leaves some gaps but covers the primary behavioral traits of the tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured: a one-sentence summary of functionality followed by a clear Args list. Every sentence adds value, and there is no repetition of schema fields beyond the necessary parameter explanations.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool logically requires two file paths as inputs, and the description covers these sufficiently. Given an output schema exists, the return value structure is presumably documented elsewhere. The description could mention any prerequisites (e.g., valid Python files) but is otherwise complete for a diff tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides only titles ('Old Path', 'New Path') with no descriptions, so the description's Args section adds meaning by clarifying 'Path to the original file' and 'Path to the updated file'. This helps establish parameter order and intent, though the addition is minimal compared to what could be said about path handling (e.g., existence, format).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool performs a structural diff between two Python files, enumerating specific elements (functions, classes, methods, module variables, imports, `__all__`). It distinguishes itself from sibling tools by focusing on comparison rather than listing or analysis, and clarifies it is signature-level rather than text-level.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a clear context for use: comparing two Python files structurally to see added, removed, and modified components. It implies when to use this tool (when a semantic diff is needed) but does not explicitly name alternatives or exclusion criteria. The 'signature-level, not text-level' note provides a key guideline for choosing this over textual diff tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_errorsA
Find Python-specific hazards: bare/broad except, except: pass, handlers
made unreachable by an earlier one, mutable default args, mutable
@dataclass field defaults (an import-time ValueError), unawaited
coroutines (best effort), assert used for runtime validation,
late-binding closures over a loop or comprehension variable, == against
None/True/False, is against a literal, and methods that never use self.
Args: path: Path to a .py file. function: Optional single function to analyse.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| function | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Given no annotations, the description carries the full burden of behavioral disclosure. It provides a detailed inventory of checks, including nuances like 'best effort' for unawaited coroutines and 'import-time ValueError' for mutable dataclass defaults. However, it does not explicitly state that the tool is read-only or describe side effects, though the nature of 'find errors' implies analysis.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the purpose, then lists hazards in a compact bulleted style within a paragraph, and closes with concise parameter docs. Every sentence serves a purpose, and the list is dense but not verbose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is thorough in listing checks and parameter meanings. Since an output schema exists, the absence of return-value details is acceptable. It lacks explicit guidance on when to use this over sibling tools, but the core behavior is well specified for a static-analysis tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has zero description coverage, but the description's Args section compensates by defining each parameter: 'path' as a .py file and 'function' as an optional single function to analyze. This adds clarity beyond the schema's bare titles.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Find Python-specific hazards' and enumerates specific error-prone patterns, distinguishing it from siblings like code_smells and dead_code by focusing on concrete Python hazards. The verb+resource structure is explicit and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for static analysis of a .py file via the parameter docs, but it does not explicitly state when to use this tool versus alternatives like code_smells or analyze_file, nor does it mention exclusions. The context is clear enough to infer a typical use case, but no alternatives or when-not-to-use guidance is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_implementationsA
Find classes implementing a Protocol or ABC, both explicitly (as a base class, including indirect subclasses) and structurally (method-set match).
Args:
path: A .py file or directory; the containing directory is scanned.
interface: Name of the Protocol/ABC/base class. Named interface
rather than protocol to match the identical tool in the
TypeScript server, so one vocabulary works across both.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| interface | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It clearly discloses behavioral details: containing directory scanning, explicit and indirect subclasses, and structural method-set matching. This gives the agent a good sense of what the tool does beyond the name.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured. The main purpose is front-loaded, and the Args section provides necessary parameter details without verbose or redundant content. Every sentence earns its place, including the naming note.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter tool with an output schema, the description covers all essential aspects: purpose, parameter semantics, and scanning behavior. It does not need to describe return values because the output schema exists. The tool is simple enough that this is complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description fully compensates. It explains that `path` can be a .py file or directory and that the containing directory is scanned, and it clarifies that `interface` is the Protocol/ABC/base class name. It even explains the naming rationale for cross-server consistency.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Find classes implementing a Protocol or ABC'. It also clarifies the scope (explicit and structural) and distinguishes itself from sibling tools like find_usages by targeting implementations rather than generic usages.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool (when you need implementers of a Protocol/ABC) but does not explicitly state alternatives or exclusions. It provides clear context about path handling, but no direct comparison with sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_node_at_positionA
Identify the AST node at a cursor position with its enclosing scope chain.
Args: path: Path to a .py file. line: 1-based line number. column: 0-based column offset.
| Name | Required | Description | Default |
|---|---|---|---|
| line | Yes | ||
| path | Yes | ||
| column | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It does provide crucial details such as line being 1-based and column being 0-based, and notes the output includes the scope chain. However, it omits error behavior (e.g., invalid file path or out-of-range coordinates) and does not explicitly state it is a read-only operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence for the core purpose followed by a compact, well-formatted argument list. It front-loads the key action and wastes no words, making it easy to parse quickly.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with only three parameters and an existing output schema, the description covers the main operation and parameter semantics adequately. It is slightly incomplete in that it does not mention what happens on invalid input or no matching node, but it provides enough for basic correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema contains no descriptions (0% coverage), so the inline argument documentation is vital. The description explains that path points to a .py file, line is 1-based, and column is 0-based, fully clarifying meaning and coordinate conventions. This precisely compensates for the schema's lack of detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function with a specific verb and resource—'Identify the AST node at a cursor position'—and adds the distinguishing detail that it also returns the enclosing scope chain. This sets it apart from sibling tools that list declarations or find usages, making the purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit usage guidance is provided; there is no mention of when to use this tool versus alternatives or any exclusions. The mention of 'cursor position' hints at an editor or IDE context, so usage is only implied rather than directly stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_usagesA
Find every occurrence of an identifier with surrounding source lines.
Covers reads, assignments, parameters, attribute access, imports and
global/nonlocal declarations. Always reports a project-wide references
section: either the cross-file hits, or that there are none, or that jedi
is not installed and cross-file references were therefore not checked. An
empty result and an unchecked one are not the same answer.
Args: path: Path to a .py file. identifier: Name to search for. context: Lines of context to show around each hit (default 1).
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| context | No | ||
| identifier | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the transparency burden and does so well. It discloses that the tool always reports a project-wide references section, handles the case where jedi is not installed, and clarifies that an empty result differs from an unchecked one. This goes beyond a simple 'find' statement and gives the agent useful behavioral expectations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is clearly structured with a summary, a coverage list, a behavioral note, and an Args section. Each part adds information, though the project-wide behavior paragraph is slightly dense and could be tightened without losing meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given that an output schema exists, the description does not need to explain return values. It covers the tool's purpose, coverage, edge cases, and parameters. The main missing piece is explicit guidance on when to choose this over sibling tools, but overall the description is complete enough for an agent to use it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% parameter description coverage, but the description's Args section provides meaningful semantics for all three parameters: path is a .py file, identifier is the name to search for, and context is the number of lines around each hit. This fully compensates for the schema's lack of detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: 'Find every occurrence of an identifier with surrounding source lines.' It also enumerates the kinds of usages covered (reads, assignments, parameters, attribute access, imports, global/nonlocal declarations), which clearly differentiates it from sibling tools like list_declarations or get_callers.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use the tool (when you need all references to an identifier) but does not explicitly mention sibling tools or state when not to use it. No alternatives are named, so the agent must infer placement from the tool name and purpose alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_callersA
Reverse call graph: who calls this function, directly and transitively.
Args:
path: Path to a .py file.
function: Function name or Class.method.
scope: "file" (default) or "package".
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| scope | No | file | |
| function | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses key behavioral traits: the result includes direct and transitive callers, and scope can be restricted to file or package. It does not mention edge cases (e.g., missing files) or return format, but the presence of an output schema covers return format to some extent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description opens with a one-sentence summary that captures the tool's essence, followed by a compact, well-structured Args list. Every word is purposeful; no redundant or vague phrasing is present.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers purpose, parameters, and key behavioral nuances (transitive, scope). It lacks examples or caveats about failure modes, but given the presence of an output schema and only three parameters, it is sufficient for an agent to invoke correctly. It could be enhanced with a brief example or note about handling missing functions.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has no descriptions (0% coverage), but the description's Args section provides clear, essential meanings for each parameter. It explains that path is a .py file, function accepts 'Class.method', and scope has a default of 'file' or 'package'. This fully compensates for the schema gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool computes a reverse call graph and lists direct and transitive callers of a given function. This specific verb+resource scope distinguishes it from siblings like 'call_graph' and 'find_usages' which have broader or different focus.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The purpose implies usage when one needs to know who calls a function, but there is no explicit guidance on when to use this tool versus alternatives, nor any exclusions or prerequisites. It does not mention that 'call_graph' or 'find_usages' might serve different needs.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_docA
Extract a docstring and parse it into summary/params/returns/raises when it follows Google or NumPy style.
Args:
path: Path to a .py file.
name: Symbol name, Class.method, or "module" for the module docstring.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden. It discloses that parsing only works for Google/NumPy styles and defines the special 'module' name, but lacks details on failure modes or behavior for non-standard docstrings.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short paragraphs with a clear purpose statement and an Args list. No filler, front-loaded with the main verb and resource.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return structure is covered. The description adequately covers parameters and core behavior; the only minor gap is handling of non-matching styles, but overall sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% description coverage, and the description fully compensates by documenting both params, including the format for symbol names like 'Class.method' and the special 'module' value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses specific verbs 'Extract' and 'parse' with a clear resource (docstring) and output components (summary/params/returns/raises). It clearly distinguishes from sibling tools like get_function_body or list_declarations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool vs alternatives. The style condition ('when it follows Google or NumPy style') is about parsing behavior, not selection context, and no alternative tools are mentioned.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_function_bodyA
Extract the full source of a function or method, with line numbers.
Args:
path: Path to a .py file.
name: Function name, Class.method, or a dotted nested path.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses that the result includes line numbers, but is silent on error handling, behavior when the function is not found, or whether the full source includes the function signature. It is minimal but not misleading.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the purpose, and includes just enough parameter detail without superfluous text. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity, the description covers purpose and parameters adequately. The output schema exists, so return values need not be explained in depth. However, it lacks explicit differentiation from the many sibling tools, which would improve completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The Args section adds meaningful detail beyond the bare schema: path is a .py file, and name can be a function name, Class.method, or dotted nested path. This compensates for the 0% schema description coverage, though it could clarify dotted path resolution further.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool extracts the full source of a function or method with line numbers. This specific verb-resource pairing distinguishes it from siblings like list_declarations (which just lists) and get_doc (which returns documentation).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives. It does not mention exclusions, prerequisites, or contrast with sibling tools that might also inspect functions. The description only states the core action.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_type_definitionA
Extract a class, TypeAlias, Enum, Protocol, TypedDict or NamedTuple definition with its members and source.
Args: path: Path to a .py file. name: Type name.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | ||
| path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description discloses the primary behavior—extracting definitions with members and source—but does not elaborate on edge cases, error handling, or whether the name must be fully qualified. It adds minimal behavioral context beyond the action itself.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences plus an Args block, with no wasted words. The purpose is front-loaded, and parameter explanations are concise and directly tied to the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the core functionality and both parameters, and the presence of an output schema reduces the need to detail return structure. However, it does not mention behavior for missing definitions or name resolution across files, leaving minor gaps for an extraction tool with two parameters.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema provides only param types with no descriptions, while the description adds meaningful semantic information: path is 'Path to a .py file' and name is 'Type name'. This fully compensates for the 0% schema coverage, giving clear meaning to both parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'Extract' and clearly enumerates the supported type kinds (class, TypeAlias, Enum, Protocol, TypedDict, NamedTuple), distinguishing this from sibling tools like get_function_body or list_declarations. It also states that members and source are included, making the scope unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage when needing a type definition from a Python file, and the type list differentiates it from function/method tools. However, it does not explicitly mention alternatives or exclusions, so the context is clear but not fully prescriptive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_declarationsA
List module-level assignments with annotated or inferred types.
Args: path: Path to a .py file.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It adds useful behavioral context by noting that types are 'annotated or inferred', but it does not disclose potential limitations (e.g., file must be valid Python, what happens with syntax errors) or explicitly state that it is a read-only operation. This is adequate but not rich.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise: one sentence stating purpose plus a minimal Args section. It is front-loaded with the core behavior and contains no wasteful words or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (one parameter, output schema provided) and sibling context, the description is nearly complete. It explains what the tool does and what input it expects. Minor gaps like error handling or return format are covered by the output schema and are not critical for a listing tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must compensate for parameter meaning. It does so by explaining that 'path' is 'Path to a .py file', adding the critical fact that it expects a Python file path. This is clear and sufficient for the single parameter, though it could have added details on path resolution.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('List') and resource ('module-level assignments') with a distinguishing detail ('annotated or inferred types'). This clearly differentiates it from sibling tools like list_functions, list_methods, and list_imports, which cover different code elements.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly implies when to use the tool (to inspect module-level variable assignments), but it does not explicitly contrast it with alternatives like list_exports or list_imports, nor does it mention exclusions or prerequisites. Context is sufficient for a simple listing tool but lacks explicit guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_exportsA
List the public symbols of a module.
Respects __all__ when present, otherwise reports non-underscore
module-level names, and flags re-exported imports.
Args: path: Path to a .py file.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It clearly states that `__all__` is respected, that non-underscore module-level names are reported otherwise, and that re-exported imports are flagged. This adds meaningful behavioral context beyond the schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is short and front-loaded with the main purpose. Each subsequent sentence adds valuable behavioral detail, and the Args section is minimal yet useful. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with one input parameter and an output schema available, the description provides the essential behavioral contract. It covers how exports are computed and flagged, so an agent can confidently select and invoke the tool without further clarification.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema's `path` parameter has only a title, but the description's Args section clarifies it expects 'Path to a .py file'. This directly compensates for the 0% schema description coverage by giving the parameter concrete meaning.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'List the public symbols of a module', a specific verb and resource. It adds concrete details about `__all__` handling and fallback behavior, which clearly distinguishes it from sibling tools like list_declarations and list_imports.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The intended use is implied by the tool name and first sentence, but the description does not explicitly state when to use this tool versus alternatives. It mentions no exclusions or sibling comparisons, so the usage context is present but not explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_functionsA
List all functions and methods with full signatures and line ranges.
Includes parameter annotations and defaults, return annotation, decorators, async flag, and nested function relationships.
Args: path: Path to a .py file.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses a rich set of behavioral aspects: inclusion of parameter annotations, defaults, return annotations, decorators, async flag, and nested function relationships. However, it remains silent on performance, error handling, or recursion depth, which would be useful but are not critical for a non-mutating list operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact and well-organized. The first sentence gives the core purpose, followed by a concise bullet list of included features, and a simple Args block. Every sentence earns its place, with no redundant or filler content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has a single parameter and an output schema, so the description needn't detail return structure. It nevertheless enumerates the key return elements (signatures, line ranges, annotations, decorators, nested relationships), making it sufficient for a listing tool. Minor omissions like handling of invalid paths or large files do not undermine completeness for typical usage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It does this via an explicit Args section: 'path: Path to a .py file.' This adds meaningful meaning beyond the schema's bare 'Path' title. While minimal, it fully clarifies the single parameter's purpose and type expectation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose with a specific verb ('List') and resource ('functions and methods'), and enriches it with defining details like 'full signatures and line ranges'. It also distinguishes from siblings by specifying the exact content (parameter annotations, decorators, async flag, nested relationships), making the intent unmistakable.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage by stating what it lists, but provides no explicit guidance on when to choose this over sibling tools like list_methods or list_declarations. No alternatives or exclusions are mentioned, so the agent must infer context from the purpose alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_importsB
List all imports: bound name, module path, relative level and aliases, grouped into stdlib / third-party / relative.
Args: path: Path to a .py file.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It implies a read-only listing operation but does not explicitly state side-effect-free behavior, permission requirements, or error handling. The grouping behavior is disclosed, but safety and edge-case details are absent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise and front-loaded. The main sentence states the purpose and the argument is explained in one line. Every word adds value with no repetition or fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The presence of an output schema means return values need not be described. However, the description lacks usage context (e.g., when to choose this over siblings) and does not mention any limitations or exceptional cases. It is minimally adequate for a simple one-parameter tool but leaves gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It does explain that 'path' is a path to a .py file, which adds semantic meaning beyond the schema. However, it lacks details on path validation, file existence, or handling of directories.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists imports with specific details (bound name, module path, relative level, aliases) and grouping. This is a specific verb+resource that distinguishes it from sibling tools like list_declarations or list_exports.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. It does not mention exclusions, prerequisites, or context such as 'use this when analyzing Python dependencies'. Only the parameter is described.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_methodsA
List every method of a class: declared, inherited, properties, class and static methods, plus class-level attributes.
Inherited members are only resolved for base classes defined in the same file; bases from other modules are reported as unresolved.
Args: path: Path to a .py file. type: Class name.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | ||
| type | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral disclosure burden. It provides a key limitation: inherited members are only resolved for base classes defined in the same file, and bases from other modules are reported as unresolved. It also clearly enumerates the returned member categories, which goes beyond what the minimal schema offers.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and front-loaded with the core purpose. It includes only necessary details: the enumerated member types, the inheritance limitation, and parameter guidance. Every sentence adds value, and the structure is easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has an output schema, the description does not need to explain return values. It covers purpose, parameters, and a notable behavioral limitation. However, it omits error handling details (e.g., file not found, invalid class name), but for a read-only query with two simple parameters, the description is largely complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the parameter descriptions in the Args section are essential. They add meaning beyond schema titles by specifying that 'path' is a path to a .py file and 'type' is a class name. This adequately covers both required parameters, though it could clarify whether the class name must be fully qualified.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description begins with a specific verb and resource: "List every method of a class" and enumerates exactly what is included (declared, inherited, properties, class/static methods, class-level attributes). This clearly distinguishes it from sibling tools like list_functions or list_declarations by focusing on class members.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance is given about when to choose this tool over alternatives. The description implies usage via the required path and type arguments, but it does not provide exclusions, prerequisites, or comparisons with sibling tools such as list_functions or get_type_definition.
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.
20 tool updates
v0.2.1- First observed
analyze_file - First observed
analyze_package - First observed
call_graph - First observed
code_complexity - First observed
code_smells - First observed
dead_code - First observed
diff_ast - First observed
find_errors - First observed
find_implementations - First observed
find_node_at_position - First observed
find_usages - First observed
get_callers - First observed
get_doc - First observed
get_function_body - First observed
get_type_definition - First observed
list_declarations - First observed
list_exports - First observed
list_functions - First observed
list_imports - First observed
list_methods
TDQS
Scored across 20 tools
Most tools have clearly distinct purposes, but some overlap exists: `analyze_file` vs `list_functions` vs `list_declarations` all surface symbol information, and `code_smells` vs `find_errors` both detect code issues. Descriptions are detailed enough to disambiguate, but an agent might occasionally select the wrong one.
All tool names are snake_case and follow a consistent verb-first pattern (list_*, get_*, find_*, analyze_*). A few noun-phrase names like `code_smells`, `call_graph`, and `dead_code` are exceptions, but they are still readable and fit the overall style without introducing inconsistency.
With 20 tools, the server is on the heavier side of the ideal range but stays within reason for a Python AST analysis domain. Each tool covers a distinct aspect (symbols, calls, complexity, errors, docstrings, diff), so no tool feels redundant; however, the count is slightly above the sweet spot.
The tool surface is comprehensive for static Python analysis: it covers declarations, exports, imports, functions, methods, types, usages, call graphs, complexity, error detection, dead code, implementations, docstrings, package summaries, AST diffs, and node lookup. There are no obvious dead ends for typical analysis workflows.
Maintenance
Related MCP Connectors
AI-powered codebase analysis — call graphs, security, dead code, complexity. 150+ tools.
Code intelligence platform for AI agents. 20 tools for architecture, security & impact analysis.
Evidence-backed architecture-quality analysis for Python agent applications.
Security + bug + perf + refactor audit for Python. Returns 0-10 score + MD report.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceProvides advanced code structure and semantic analysis through Abstract Syntax Trees (AST) and Abstract Semantic Graphs (ASG) across multiple programming languages. It enables tasks like incremental parsing, complexity analysis, and AST diffing to help models understand and navigate codebases.36MIT
- FlicenseNot gradedqualityDmaintenanceProvides deterministic Python code quality analysis using flake8, mypy, McCabe, and vulture, enabling LLMs to access real linting and type checking results.1-
- AlicenseNot gradedqualityCmaintenanceEnables deterministic static analysis of Python code, providing tools to inspect classes, functions, imports, dependencies, and more, without executing the code.1MIT
- AlicenseAqualityCmaintenanceProvides structural, queryable understanding of a Python codebase via MCP tools, enabling direct lookups for callers, dependencies, and class hierarchies without repeated grep/read cycles.6Apache 2.0