py-ast-mcp
Click on "Install 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, bareexcept, late-binding loop closures, 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; 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: AST MCP Server
Installation
Requires Python 3.10+.
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, bare |
|
| 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. |
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:
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
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Alicense-qualityDmaintenanceProvides comprehensive codebase analysis including project structure evaluation, cross-language duplicate detection, microservices validation, and configuration optimization with AI-powered pattern learning that generates actionable improvement reports.Last updatedMIT
- Alicense-qualityDmaintenanceProvides 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.Last updated34MIT
- Flicense-qualityCmaintenanceProvides deterministic Python code quality analysis using flake8, mypy, McCabe, and vulture, enabling LLMs to access real linting and type checking results.Last updated1
- Alicense-qualityCmaintenanceEnables deterministic static analysis of Python code, providing tools to inspect classes, functions, imports, dependencies, and more, without executing the code.Last updatedMIT
Related MCP Connectors
Enterprise code intelligence for M&A, security audits, and tech debt. Hosted server with 200k free.
AI Agent with Architectural Memory. Impact analysis (free), tests and code from the graph (pro).
Screens public GitHub repos and PRs to generate risk maps, findings, and merge-readiness signals.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/gclluch/py-ast-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server