Skip to main content
Glama
okeefeco

PyEye Server

by okeefeco

PyEye 👁️

PyEye Server

CI codecov Python 3.10+ Code style: black Ruff Pre-commit

An extensible MCP (Model Context Protocol) server that provides intelligent Python code analysis, navigation, and understanding capabilities for AI assistants like Claude.

Related MCP server: FastAPI Architect MCP

Features

  • 🔍 Semantic Code Navigation: Resolve any identifier to a stable canonical handle, then inspect or outline it

  • 📊 Structural Traversal: Walk members, callees, imports, imported_by, subclasses, superclasses, and submodules — one hop with expand, many with trace

  • 🤝 Honest by Construction: Unsupported questions (notably "who calls this") are refused, not guessed; absent counts mean "not measured", never "zero"

  • 🏗️ Multi-Project Support: Analyze multiple projects and dependencies simultaneously

  • 📦 Namespace Packages: Handle packages distributed across multiple repositories

  • 📝 Standalone Scripts: Analyze notebooks, scripts, and examples alongside formal packages

  • 🔄 Auto-Update: Automatically detects and reflects file changes with smart cache invalidation

  • ⚙️ Configuration System: Flexible configuration via files, env vars, or auto-discovery

  • 🔌 Extensible Plugin System: Framework-specific analyzers (Pydantic, Django, Flask)

  • 🚀 Fast & Cached: Intelligent caching with LRU eviction and performance optimization

  • 🎯 Type-Aware: Full understanding of Python type hints and annotations

  • 📈 Performance Monitoring: Built-in metrics tracking with p50/p95/p99 latencies

  • 🛡️ Input Validation: Secure parameter validation and path checking

  • 🤖 Development Automation: Release automation, dogfooding metrics, and worktree safety

Installation

PyEye can be installed in three ways: as a Claude Code plugin (zero-config), into your project's venv, or globally.

Option 0: Claude Code Plugin (zero-config)

When PyEye is installed as a Claude Code plugin, dependencies install automatically into a per-user venv on first session start — no manual pip install needed.

  • First session start: a SessionStart hook runs uv sync --no-dev --frozen against the plugin checkout, with the venv built at ${CLAUDE_PLUGIN_DATA}/.venv (typically ~/.claude/plugins/data/<plugin-id>/.venv).

  • Subsequent sessions: the hook compares uv.lock in the plugin checkout against the last-installed copy in ${CLAUDE_PLUGIN_DATA} and is a silent no-op unless the lockfile changed.

  • Requirement: uv must be on your PATH. See uv installation.

Both the install hook and the MCP server invocation use uv run, so this works on Linux, macOS, and Windows without OS-specific configuration.

Install directly into your Python project's virtual environment:

# Activate your project's virtual environment
source /path/to/your/project/venv/bin/activate

# Install from PyPI
pip install pyeye-mcp

# Or install from source
git clone https://github.com/okeefeco/pyeye-mcp.git
pip install -e ./pyeye-mcp

Then create a .mcp.json file in your project root:

{
  "mcpServers": {
    "pyeye": {
      "type": "stdio",
      "command": "python",
      "args": ["-m", "pyeye.mcp"],
      "env": {}
    }
  }
}

This way, the MCP server uses your project's environment and has access to all your project's dependencies.

Option 2: Global Installation

For analyzing multiple projects or using with global Python:

# Install globally with pipx (recommended for isolation)
pipx install pyeye-mcp

# Or with pip
pip install --user pyeye-mcp

# Or from source
git clone https://github.com/okeefeco/pyeye-mcp.git
cd pyeye-mcp
pip install --user .

Configure with Claude Code (Global)

# Add the MCP server globally (available in all projects)
claude mcp add pyeye -s user -- python -m pyeye.mcp

# Verify it's connected
claude mcp list

Configure with Claude Desktop

Add to your Claude Desktop configuration (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):

{
  "mcpServers": {
    "pyeye": {
      "command": "python",
      "args": ["-m", "pyeye.mcp"],
      "env": {}
    }
  }
}

Note: Use the full path to Python if needed (e.g., /usr/local/bin/python3 or C:\\Python311\\python.exe).

Configure with GitHub Copilot (VS Code)

As of 2025, GitHub Copilot has full MCP support in VS Code, JetBrains, Eclipse, and Xcode. Follow these steps to use this PyEye server with GitHub Copilot:

Prerequisites

  • GitHub Copilot Business or Enterprise subscription (required for MCP support)

  • VS Code version 1.102 or later (MCP support is GA)

  • Organization MCP policy enabled by your admin

Step 1: Enable MCP in Your Organization

Your GitHub Copilot administrator needs to enable the MCP servers policy:

  1. Go to your organization settings on GitHub

  2. Navigate to CopilotPolicies

  3. Enable "MCP servers in Copilot" policy

  4. Save changes

Step 2: Install the MCP Server

Install the PyEye server in your project or globally:

# Option A: Install in your project's virtual environment (recommended)
pip install pyeye-mcp

# Option B: Install globally with pipx
pipx install pyeye-mcp

# Option C: Install from source
git clone https://github.com/okeefeco/pyeye-mcp.git
pip install -e ./pyeye-mcp

Step 3: Configure VS Code

Add the MCP server configuration to your VS Code settings:

User Settings (applies to all projects):

// File: ~/.config/Code/User/settings.json (Linux/Mac)
// or %APPDATA%\Code\User\settings.json (Windows)
{
  "github.copilot.chat.mcpServers": {
    "pyeye": {
      "command": "python",
      "args": ["-m", "pyeye.mcp"],
      "env": {}
    }
  }
}

Workspace Settings (project-specific):

// File: .vscode/settings.json in your project root
{
  "github.copilot.chat.mcpServers": {
    "pyeye": {
      "command": "${workspaceFolder}/.venv/bin/python",
      "args": ["-m", "pyeye.mcp"],
      "env": {
        "PYTHONPATH": "${workspaceFolder}"
      }
    }
  }
}

Step 4: Verify Connection

  1. Open VS Code in your Python project

  2. Open the GitHub Copilot Chat panel

  3. Type: @mcp list to see available MCP servers

  4. You should see pyeye in the list

  5. Test with: @mcp pyeye resolve MyClass

Troubleshooting

MCP not available:

  • Ensure you have Copilot Business/Enterprise (not Free/Pro)

  • Check that your organization admin enabled the MCP policy

  • Update VS Code to version 1.102 or later

Server not connecting:

  • Verify Python path in the configuration

  • Check that pyeye is installed: python -m pyeye.mcp --help

  • Look for errors in VS Code Output panel → GitHub Copilot Logs

Import errors:

  • If using a virtual environment, ensure the path points to the venv Python

  • Add PYTHONPATH to the env configuration if needed

Other IDEs

JetBrains IDEs (IntelliJ, PyCharm, etc.):

  • MCP support is GA - configure in Settings → Tools → GitHub Copilot → MCP Servers

Visual Studio:

  • MCP support is in preview - configure in Tools → Options → GitHub Copilot → MCP Servers

Eclipse & Xcode:

  • MCP support is GA - see IDE-specific documentation for configuration

Configuration

The server can be configured to analyze packages in other locations. Create a .pyeye.json file in your project:

{
  "packages": [
    "../my-shared-library",
    "~/repos/company-utils",
    "/absolute/path/to/package"
  ],
  "namespaces": {
    "mycompany": [
      "~/repos/mycompany-auth",
      "~/repos/mycompany-api"
    ]
  }
}

Configuration Methods

Configuration is loaded in the following order (later sources override earlier ones):

  1. Global Config: ~/.config/pyeye/config.json or ~/.pyeye.json - User defaults

  2. Project Config: .pyeye.json in project root or [tool.pyeye] in pyproject.toml

  3. Override File: .pyeye.override.json - Local development overrides (git-ignored)

  4. Auto-Discovery: Automatically detects source layouts and sibling packages if no packages configured

Using Override Files

Override files are perfect for local development configurations that shouldn't be committed:

// .pyeye.override.json (git-ignored)
{
  "packages": [
    "../my-local-dev-package",
    "~/dev/experimental"
  ],
  "namespaces": {
    "company.feature": ["/home/user/feature-branch"]
  }
}

Performance Settings

All performance-critical settings can be configured via environment variables to tune for your specific workload:

Environment Variable

Default

Description

Valid Range

PYEYE_MAX_PROJECTS

10

Maximum number of projects in memory

1-1000

PYEYE_CACHE_TTL

300

Cache time-to-live in seconds

0-86400 (24h)

PYEYE_WATCHER_DEBOUNCE

0.5

File watcher debounce delay in seconds

0.0-10.0

PYEYE_MAX_FILE_SIZE

1048576

Maximum file size to analyze (bytes)

1KB-100MB

PYEYE_MAX_WORKERS

4

Maximum concurrent analysis workers

1-32

PYEYE_ANALYSIS_TIMEOUT

30.0

Analysis timeout in seconds

1.0-300.0

PYEYE_ENABLE_MEMORY_PROFILING

false

Enable memory profiling

true/false

PYEYE_ENABLE_PERFORMANCE_METRICS

false

Enable performance metrics

true/false

Connection Pooling

Optimize multi-project workflows

PYEYE_ENABLE_CONNECTION_POOLING

true

Enable connection pooling for multiple projects

true/false

PYEYE_POOL_MAX_CONNECTIONS

10

Maximum pooled project connections

1-100

PYEYE_POOL_TTL

3600

Connection time-to-live in seconds

60-86400

Performance Tuning Examples

Large codebase with stable files:

export PYEYE_MAX_PROJECTS=50        # Handle more projects
export PYEYE_CACHE_TTL=1800         # 30 minute cache
export PYEYE_WATCHER_DEBOUNCE=2.0   # Less frequent updates

Active development with frequent changes:

export PYEYE_MAX_PROJECTS=5         # Fewer projects, faster switching
export PYEYE_CACHE_TTL=60           # 1 minute cache
export PYEYE_WATCHER_DEBOUNCE=0.1   # Near real-time updates

Memory-constrained environment:

export PYEYE_MAX_PROJECTS=3         # Minimal project cache
export PYEYE_MAX_FILE_SIZE=524288   # 512KB file limit
export PYEYE_MAX_WORKERS=2          # Fewer workers

This file is automatically ignored by git and takes precedence over all other configuration sources.

Auto-Detection of Source Layouts

PyEye automatically detects source layouts from pyproject.toml build backend metadata, supporting projects that use the src/ directory pattern. This works with multiple build backends:

Setuptools:

[tool.setuptools.packages.find]
where = ["src"]

Poetry:

[[tool.poetry.packages]]
include = "mypackage"
from = "src"

Hatch:

[tool.hatch.build.targets.wheel]
sources = ["src"]

PDM:

[tool.pdm.build]
package-dir = "src"

If no configuration is found in pyproject.toml, PyEye will also check for the presence of a src/ directory containing Python packages and automatically add it to the package paths.

Note: Explicit [tool.pyeye] configuration always takes precedence over auto-detected layouts.

Core Tools

PyEye exposes a small set of progressive-disclosure primitives that work on canonical handles (a re-exported path collapses to its definition site). They are cheap by default — they return structural facts and pointers, never source content. For the full mechanics, the authoritative list of supported edges, and worked examples, see the python-explore skill (skills/python-explore/SKILL.md).

Navigation & Inspection

  • resolve - Resolve a name or dotted path to canonical handle(s); the usual entry point

  • resolve_at - Resolve the symbol at a file:line:column location

  • inspect - Structured facts for a handle: signature, type, docstring, edge counts

  • outline - Structural outline of a module, package, or class and its members

  • expand - Follow one relationship edge from a handle (e.g. members, imports, imported_by, subclasses); the skill lists the full supported-edge set

  • trace - Multi-hop traversal across edges (e.g. follow=["imports"] for the dependency closure, follow=["subclasses"] for the full hierarchy)

Multi-Project

  • configure_packages - Register additional package locations to analyze alongside the project

Known limitation: no reverse references

The interface does not answer "who calls / references this". Reverse-reference support is deferred to a planned Pyright backend (#333). When you ask for a callers or references edge, pyeye reports it as unsupported rather than guessing, and inspect's edge_counts omits those keys entirely instead of reporting 0. Delegate caller questions to a language server; pyeye's resolve gives you the definition-site position an LSP reference query needs.

Forward and structural questions are answered: callees (what a function calls), imported_by / imports, subclasses / superclasses, members, submodules.

Removed in v2.0. find_references, get_call_hierarchy, and analyze_dependencies were removed in #505 — not deprecated — because they returned confidently wrong answers rather than merely incomplete ones. See the CHANGELOG's migration map for replacements.

Framework-Specific Tools (Auto-Activated)

Django (when Django is detected)

  • find_django_models - Find all Django models

  • find_django_views - Find all views

  • find_django_urls - Find URL patterns

  • find_django_templates - Find templates

  • find_django_migrations - Find migrations

Pydantic (when Pydantic is detected)

  • find_pydantic_models - Discover all BaseModel classes

  • get_model_schema - Extract complete model schema

  • find_validators - Locate all validation methods

  • find_field_validators - Find field-specific validators

  • find_model_config - Extract model configurations

  • trace_model_inheritance - Map model inheritance hierarchies

  • find_computed_fields - Find computed_field and @property fields

Flask (when Flask is detected)

  • find_flask_routes - Discover all route decorators with methods and endpoints

  • find_flask_blueprints - Locate Blueprint definitions and registrations

  • find_flask_views - Find view functions and MethodView classes

  • find_flask_templates - Locate Jinja2 templates and render_template calls

  • find_flask_extensions - Identify Flask extensions (SQLAlchemy, Login, CORS, etc.)

  • find_flask_config - Find configuration files and app.config usage

  • find_error_handlers - Locate @app.errorhandler decorators

  • find_cli_commands - Find Flask CLI commands (@app.cli.command)

Advanced Features

Multi-Project Support

Analyze your main project along with local dependencies:

# Configure to analyze multiple packages
configure_packages(
    packages=["../my-lib", "~/repos/shared-utils"],
    namespaces={"company": ["~/repos/company-*"]}
)

Namespace Packages

Handle packages distributed across multiple repositories:

# company.auth in repo A, company.api in repo B
configure_packages(
    namespaces={"company": ["~/repos/company-auth", "~/repos/company-api"]}
)

Auto-Update on File Changes

The server uses file watching to automatically update when code changes:

  • Detects modifications in real-time

  • Invalidates cache for changed files

  • Maintains separate watchers per project

Architecture

PyEye
├── Core Server (FastMCP)
│   └── MCP tools (primitives + auto-activated framework plugins)
├── Project Manager
│   ├── Multi-project support (LRU cache, max 10)
│   ├── Connection pooling (optional optimization)
│   ├── Namespace resolver
│   └── Configuration loader (multiple sources)
├── Analysis Engine
│   └── Jedi (semantic analysis & type inference)
├── Caching & Performance
│   ├── File watchers (watchdog with debouncing)
│   ├── Granular cache (5min TTL with smart invalidation)
│   ├── Metrics collection (p50/p95/p99 latencies)
│   └── Performance monitoring & reporting
├── Validation & Security
│   ├── Input validation (MCP tool parameters)
│   ├── Path security checks
│   └── Safe file operations
├── Plugin System
│   ├── Base plugin class (AnalyzerPlugin)
│   ├── Pydantic plugin (7 specialized tools)
│   ├── Django plugin (5 specialized tools)
│   └── Flask plugin (8 specialized tools)
├── Utility Systems
│   ├── Dependency tracking & circular detection
│   ├── Import analysis & re-export resolution
│   ├── Scope management (main/all/namespace scoping)
│   ├── Async utilities (concurrent operations)
│   └── Cross-platform path handling
└── Development & Automation
    ├── Release automation agent
    ├── Dogfooding metrics tracking
    └── Worktree safety management

Plugin Development

Create custom plugins for your project patterns:

from pyeye.plugins.base import AnalyzerPlugin

class MyProjectPlugin(AnalyzerPlugin):
    def name(self) -> str:
        return "MyProject"

    def detect(self) -> bool:
        # Return True if this plugin should activate
        return (self.project_path / "my_framework.conf").exists()

    def find_patterns(self, pattern_name: str):
        # Find your custom patterns
        pass

Performance Monitoring Details

The server includes comprehensive performance monitoring to help identify bottlenecks and optimize performance for large-scale deployments.

Connection Pooling for Multi-Project Workflows

Connection pooling is enabled by default to optimize performance when working with multiple projects. You can customize the pooling behavior:

# Customize connection pooling (already enabled by default)
export PYEYE_POOL_MAX_CONNECTIONS=20  # Increase pool size for many projects
export PYEYE_POOL_TTL=7200            # Increase TTL to 2 hours

# Or disable pooling if needed
export PYEYE_ENABLE_CONNECTION_POOLING=false

# Start the server
uv run mcp dev src/pyeye/server.py

Connection pooling provides significant performance improvements:

  • Reduced initialization time for frequently accessed projects

  • Shared connections across multiple analysis operations

  • Automatic eviction of idle connections based on TTL

  • Memory-efficient pooling with configurable limits

Metrics Tracked

  • Operation Latencies: p50, p95, p99 percentiles for all MCP tools

  • Cache Performance: Hit rate, miss rate, evictions

  • Connection Pool Stats: Pool size, hits, misses, evictions, reuse rate

  • Memory Usage: RSS, VMS, percentage used

  • Error Rates: Track failures per operation

  • Throughput: Operations per second

Performance Baselines

The following performance baselines are enforced in CI:

Operation

p50 (ms)

p95 (ms)

p99 (ms)

symbol_search

50

100

200

goto_definition

30

75

150

cache_lookup

0.1

0.5

1.0

Development

# Install development dependencies
uv add --dev pytest black ruff mypy

# Run tests
uv run pytest

# Format code
uv run black src/
uv run ruff check src/

# Test the server
uv run mcp dev src/pyeye/server.py

Documentation

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License - see LICENSE file for details

Acknowledgments

Built on top of:

  • Jedi - Python static analysis and type inference

  • FastMCP - MCP server framework

  • Watchdog - File system monitoring

Available Tools

25 tools
analyze_dependenciesA

Python: Map module dependencies and detect circular imports. Semantic analysis grep can't do.

Deprecated: Replaced by future trace(handle, follow=["imports"]) in the redesigned API. See docs/superpowers/specs/2026-05-02-progressive-disclosure-api-design.md for the migration plan. This method will be removed once the legacy MCP tools are deprecated (Phase B of the migration).

For general use, prefer lookup() which accepts any identifier form. This tool provides circular dependency detection and scope filtering for targeted queries.

Args: module_path: Import path of the module (e.g., "pyeye.mcp") project_path: Root path of the project scope: Search scope - "main", "all", "namespace:name", or list

ParametersJSON Schema
NameRequiredDescriptionDefault
module_pathYes
project_pathNo.
scopeNoall

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior3/5

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

No annotations provided; description mentions deprecation and replacement but lacks explicit statement about read-only nature or side effects. The tool appears read-only but not confirmed.

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

Conciseness4/5

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

The description is concise but the first sentence includes an unclear phrase 'Semantic analysis grep can't do'. Deprecation notice is front-loaded appropriately, and args are listed clearly.

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

Completeness4/5

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

Has output schema so return info not needed. Parameters explained. Lacks prerequisites or error info, but sufficient for a deprecated tool with alternatives given.

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

Parameters3/5

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

Schema descriptions are 0%, but the description's Args section adds basic meaning with examples for module_path and possible values for scope. However, it doesn't explain defaults or scope list format in detail.

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

Purpose5/5

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

The description clearly states the tool maps module dependencies and detects circular imports, and distinguishes from siblings like trace and lookup by noting this tool is deprecated and replaced.

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

Usage Guidelines5/5

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

Explicitly recommends alternatives for general use (lookup) and future use (trace), and specifies when to use this tool for targeted circular dependency queries.

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

configure_packagesA

Python: Configure additional packages, namespaces, and standalone scripts for analysis.

Args: packages: List of package paths to include namespaces: Namespace packages with their repo paths standalone_dirs: Directories containing standalone Python scripts recursive: Scan standalone directories recursively file_pattern: Glob pattern for standalone files exclude_patterns: Patterns to exclude from standalone scanning save: Save configuration to .pyeye.json

ParametersJSON Schema
NameRequiredDescriptionDefault
packagesNo
namespacesNo
standalone_dirsNo
recursiveNo
file_patternNo*.py
exclude_patternsNo
saveNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior3/5

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

With no annotations provided, the description must fully convey behavioral traits. It explains the configuration action and mentions saving to .pyeye.json, but does not disclose side effects, idempotency, or permissions. This adds some transparency but not comprehensive.

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

Conciseness5/5

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

The description is concise: a single sentence stating purpose followed by a well-structured parameter list. No wasted words, front-loaded with the main action.

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

Completeness4/5

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

Given the tool has 7 parameters and an output schema (mentioned but not shown), the description adequately covers the configuration purpose and parameter meanings. It lacks usage context or behavior details but is sufficient for a configuration tool.

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

Parameters4/5

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

The input schema has 7 parameters with 0% description coverage. The description includes an 'Args' section that provides brief but meaningful descriptions for each parameter (e.g., 'packages: List of package paths to include'), adding semantic value beyond the schema titles.

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

Purpose5/5

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

The description starts with a clear verb+resource: 'Configure additional packages, namespaces, and standalone scripts for analysis.' It distinctly describes what the tool does and differentiates it from sibling tools like 'analyze_dependencies'.

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

Usage Guidelines2/5

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

No explicit guidance on when to use this tool vs alternatives. The description implies it is for configuration before analysis, but does not mention prerequisites, limitations, or comparison with similar tools.

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

expandA

Python: Expand one outbound edge from a canonical handle (single hop).

The traversal primitive that walks ONE edge from a source handle and returns adjacent symbols as lightweight Stubs. Use resolve()/inspect() first to obtain a canonical handle, then call expand() to traverse.

Supported edges (the complete static/outbound set):

  • members — class/module → direct members (attributes, methods, nested classes). stubs: [] means the class/module was found but has no members; that is NOT the same as unsupported. Static-surface ceiling: members are read from source; runtime-injected members (metaclass / setattr / __getattr__ / type() / __init_subclass__) are NOT captured — e.g. a Django Model shows none of its metaclass-injected _meta / objects / DoesNotExist.

  • callees — function/method → forward static call targets. Includes project symbols and stdlib/external symbols reachable via Jedi's goto. Dynamic calls (un-inferable parameters, getattr, lambdas, etc.) are counted in unresolved_call_sites rather than invented.

  • imported_by — module → the project modules that import it (module Stubs), computed by static AST import-graph reversal (no reverse symbol search). Covers importers anywhere in the project including tests and standalone scripts. Non-module handles return the unsupported branch with reason: "not_yet_implemented" (symbol-level imported_by is not yet implemented). Ceiling: runtime-dynamic imports (importlib/__import__ with computed targets) are not detected.

  • subclasses — class → the project classes that directly subclass it (class Stubs), computed by an AST class-graph walk + forward goto (no reverse symbol search). Returns the DIRECT (depth-1) subclasses only (#422) — one hop, symmetric with superclasses; the full transitive closure is served by trace(follow=["subclasses"], max_depth=k, max_nodes=N), which carries the cap + truncated contract. A class result includes a static transitive_hint field pointing to that trace route. subclasses is an expand-only edge: inspect does NOT measure it (dropped in #392); a cheap direct count is gated on the Pyright reference backend / class-graph cache (#333/#397), because even the direct count is a reverse query needing the same project-wide scan as callers/references. stubs: [] means the class has no project subclasses (measured-none). A non-class handle also returns the supported branch with stubs: [] (and no transitive_hint) — only a class CAN be subclassed, so [] is true by definition, not an absence-vs-zero lie. Static-surface ceiling: the result is complete only over literal class B(A): subclassing; dynamically-created subclasses (type('B', (A,), {}), factory-built classes, __init_subclass__ registration) are NOT captured.

  • superclasses — class → its base classes (class Stubs), resolved by Jedi from the class definition (no reverse search). A non-class handle returns stubs: [] ([] true by definition, as with subclasses).

  • imports — module → the symbols/modules it imports (Stubs), computed by static AST + forward goto. stubs: [] is measured-none. A non-module handle returns the unsupported branch with reason: "not_yet_implemented" (mirrors imported_by).

  • enclosing_scope — symbol → its immediate lexical enclosing scope (the inverse of members), resolved by Jedi parent(): a method → its class, a nested def/class → its enclosing def/class, a top-level def/class/variable → its module. At most ONE Stub. A module returns stubs: [] (a module has no enclosing lexical scope — packages are not lexical scopes); [] is therefore measured-empty, never unsupported.

Unsupported edges return the unsupported branch (never raise):

  • Inbound/reference edges (callers, references, overrides, …) require the Pyright reference backend (#333) and return unsupported: true, reason: "deferred_reference_backend".

  • Wrong-kind handles (e.g. imported_by on a non-module) return the unsupported branch with reason: "not_yet_implemented".

  • Unrecognised edge names return reason: "unknown_edge".

Response shape — discriminated union:

Supported branch ("unsupported" key absent): ::

{ "source": str,                 # canonical source handle
  "edge":   str,
  "stubs":  [Stub, ...],         # [] == measured-empty (NOT unsupported)
  "unresolved_call_sites": int   # callees ONLY; absent for members }

Unsupported branch ("stubs" key absent): ::

{ "source": str,
  "edge":   str,
  "unsupported": True,
  "reason":  str,               # deferred_reference_backend |
                                # not_yet_implemented | unknown_edge
  "detail":  str }              # human-readable explanation

Each Stub carries: handle, kind, scope, line_start, line_end, and signature when Jedi yields one (always for class/function/method; also any name whose inferred type is callable).

Relationship to deprecated tools: members supersedes the deprecated find_subclasses/find_symbol pattern for enumerating class members. callees supersedes manual get_call_hierarchy usage for forward edges. Both deprecated tools remain registered until Phase B migration.

Args: handle: Canonical Python dotted-name string (from resolve/inspect). edge: The outbound edge to expand (e.g. "members", "callees"). project_path: Project root path (default: current directory).

Returns: ExpandResult dict — supported branch or unsupported branch (see above). Never raises; unresolvable source handles yield graceful supported-empty results consistent with inspect()'s minimal-node contract.

ParametersJSON Schema
NameRequiredDescriptionDefault
handleYes
edgeYes
project_pathNo.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

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

Despite no annotations, the description comprehensively details behavioral traits for each edge: static-surface ceilings, response shape, error handling (never raises), and exact conditions for unsupported branches. It discloses limitations like runtime-injected members and dynamic imports.

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

Conciseness3/5

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

The description is very lengthy and could be more concise. While it is well-structured with bullet points and code blocks, the verbosity may hinder quick comprehension. However, it front-loads the one-sentence summary.

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

Completeness5/5

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

Given the tool's complexity and many sibling tools (22 listed), the description covers all necessary context: when to use, inputs, outputs for each branch, edge-specific details, behavioral ceilings, and relationship to deprecated tools. It is exceptionally complete.

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

Parameters4/5

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

The input schema has 0% description coverage, but the description adds meaning by explaining that handle is a canonical dotted name, edge is a specific outbound edge with enumerated possibilities, and project_path defaults to current directory. Though not all parameters are explicitly described in a structured way, the context provided is sufficient.

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

Purpose5/5

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

The description clearly states it expands one outbound edge from a canonical handle, lists all supported edges with examples, and distinguishes from sibling tools like resolve(), inspect(), and trace(). It also mentions superseding deprecated tools.

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

Usage Guidelines5/5

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

Explicitly instructs to use resolve()/inspect() first, then expand(). Explains when to use trace() for transitive closure. Lists unsupported edges and why they are unsupported, providing clear guidance on when not 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.

find_blueprintsA

Find all Flask blueprints in the project.

Args: scope: Search scope (default "main"): - "main": Only the main project (default for plugins) - "all": Include configured namespaces - "namespace:name": Specific namespace

ParametersJSON Schema
NameRequiredDescriptionDefault
scopeNomain

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior3/5

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

No annotations are provided, so the description carries the full burden. It implies a read-only search operation but does not explicitly state non-destructive behavior or other traits like required permissions.

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

Conciseness5/5

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

The description is very concise, using a single sentence plus a clear list for the parameter options. Every part adds value, and the structure is easily scannable.

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

Completeness5/5

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

Given the tool has only one optional parameter and an output schema exists, the description adequately covers purpose and parameter behavior without needing to describe return values.

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

Parameters4/5

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

With 0% schema description coverage, the description adds significant value by explaining the scope parameter's possible values and their meanings, compensating for the lack of schema-level documentation.

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

Purpose5/5

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

The description uses the specific verb 'Find' and resource 'all Flask blueprints in the project', clearly distinguishing it from sibling tools that target different aspects (e.g., find_routes, find_models).

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

Usage Guidelines4/5

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

The description provides explicit guidance on the scope parameter with three well-defined options (main, all, namespace:name), but does not explicitly state when not to use this tool or mention alternative tools.

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

find_cli_commandsB

Find Flask CLI commands.

Args: scope: Search scope (default "main"): - "main": Only the main project (default for plugins) - "all": Include configured namespaces - "namespace:name": Specific namespace

ParametersJSON Schema
NameRequiredDescriptionDefault
scopeNomain

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

B3.4/5.0
Behavior2/5

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

No annotations are provided, so the description carries full burden for behavioral disclosure. It does not state whether the tool is read-only, what it returns, any side effects, or required permissions. The description only explains the scope parameter, leaving behavior largely implicit.

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

Conciseness5/5

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

The description is concise, starting with the purpose, followed by a well-structured Args block. Each sentence adds value without redundancy. It is appropriately sized for a single-parameter tool.

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

Completeness3/5

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

Given the tool's simplicity and the presence of an output schema (not shown), the description covers the main usage. However, it lacks information on edge cases, error conditions, or prerequisites. For a simple find tool, the completeness is adequate but not exceptional.

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

Parameters4/5

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

The parameter schema has 0% description coverage, but the description adds significant meaning by explaining the scope options (main, all, namespace:name) and default behavior. This goes beyond what the schema provides, compensating for the lack of schema-level descriptions.

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

Purpose4/5

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

The description clearly states 'Find Flask CLI commands', which is a specific verb and resource. It distinguishes from sibling tools like find_blueprints or find_routes by focusing on CLI commands. However, it does not explicitly contrast with siblings, so it's a 4 rather than 5.

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

Usage Guidelines3/5

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

The description explains the scope parameter with three options, providing some guidance on search granularity. However, it does not specify when to use this tool versus alternatives (e.g., when to use find_cli_commands vs. other find tools), nor does it mention any prerequisites or exclusions.

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

find_computed_fieldsA

Find all computed fields (properties, computed_field decorator).

Args: scope: Search scope (default "main"): - "main": Only the main project (default for plugins) - "all": Include configured namespaces - "namespace:name": Specific namespace

ParametersJSON Schema
NameRequiredDescriptionDefault
scopeNomain

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior2/5

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

No annotations are provided, and the description does not disclose whether the operation is read-only, requires authentication, or has any side effects. As a find tool, it is likely safe, but this is not stated.

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

Conciseness5/5

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

The description is extremely concise: one sentence for purpose and a short argument list. No extra words, well-structured with an 'Args' section.

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

Completeness3/5

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

With an output schema present, return values need not be explained, but the description lacks behavioral context (e.g., read-only hint) and any prerequisites, which would improve completeness given no annotations.

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

Parameters4/5

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

The input schema has 0% description coverage, but the description adds significant meaning by explaining the scope parameter's default and enumerated values ('main', 'all', 'namespace:name'), guiding the agent effectively.

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

Purpose5/5

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

The description clearly states the tool finds computed fields, specifying 'properties' and 'computed_field decorator', which distinguishes it from sibling tools like find_models and find_field_validators.

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

Usage Guidelines3/5

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

The description explains the scope parameter options and defaults, giving clear usage context, but does not explicitly state when not to use the tool or mention alternatives.

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

find_configA

Find Flask configuration files and app.config usage.

Args: scope: Search scope (default "main"): - "main": Only the main project (default for plugins) - "all": Include configured namespaces - "namespace:name": Specific namespace

ParametersJSON Schema
NameRequiredDescriptionDefault
scopeNomain

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

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

No annotations are provided, so the description carries full burden. It describes the tool's operation (finding config) but does not disclose behavioral traits such as read-only nature, potential side effects, or error handling.

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

Conciseness5/5

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

The description is extremely concise, with the purpose stated in the first sentence followed by compact parameter documentation. No extraneous information is present.

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

Completeness4/5

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

Given the tool's simplicity, the output schema existence, and the detailed parameter explanation, the description covers essential usage details. Minor gaps like behavior on invalid scope are acceptable for a search tool.

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

Parameters4/5

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

The input schema has no descriptions (0% coverage), but the description adds significant meaning by enumerating valid scope values and their semantics, which the schema does not provide.

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

Purpose5/5

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

The description clearly states the tool finds Flask configuration files and app.config usage, making the verb and resource explicit. It distinguishes from sibling tools like find_model_config, which likely handles model-specific config.

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

Usage Guidelines3/5

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

The description details scope parameter options but lacks explicit when-to-use or when-not-to-use guidance compared to similar tools like find_model_config. The inferred usage is adequate but not explicitly contrasted.

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

find_error_handlersA

Find error handler functions.

Args: scope: Search scope (default "main"): - "main": Only the main project (default for plugins) - "all": Include configured namespaces - "namespace:name": Specific namespace

ParametersJSON Schema
NameRequiredDescriptionDefault
scopeNomain

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior2/5

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

No annotations provided, so the description carries full burden. It does not disclose what happens if no handlers are found, the return format, or any side effects. More behavioral context is needed.

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

Conciseness5/5

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

The description is concise at about 50 words, front-loaded with the purpose, and uses a bulleted list for scope options. Every sentence adds value.

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

Completeness3/5

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

The tool has an output schema, so return values need not be detailed. However, the description could mention the output structure or typical results. It is minimally adequate for a simple search tool.

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

Parameters4/5

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

The input schema has 0% coverage, but the description adds meaning by listing possible scope values and their meanings, going beyond the schema's type definition. This compensates partially for the schema gap.

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

Purpose5/5

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

The description clearly states the tool finds error handler functions. The verb 'Find' and resource 'error handlers' are specific and distinct from sibling tools like 'find_blueprints' or 'find_cli_commands'.

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

Usage Guidelines4/5

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

The description explains the scope parameter options ('main', 'all', 'namespace:name') with clear defaults, guiding usage. However, it does not explicitly state when to choose this tool over other 'find' siblings.

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

find_extensionsA

Find Flask extensions in use.

Args: scope: Search scope (default "main"): - "main": Only the main project (default for plugins) - "all": Include configured namespaces - "namespace:name": Specific namespace

ParametersJSON Schema
NameRequiredDescriptionDefault
scopeNomain

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior2/5

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

No annotations provided, so the description carries full burden. It does not disclose that the tool is read-only, safe, or has any behavioral traits. The description only states what it finds, not implications for the agent.

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

Conciseness5/5

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

The description is concise: one sentence for purpose, followed by a well-structured list for the parameter. No redundant information, and the critical part (purpose) is front-loaded.

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

Completeness4/5

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

Given the output schema exists, return values are covered. The description adequately explains the single parameter. Lacking a brief note on what the output contains (e.g., extension names) but is otherwise complete for the tool's simplicity.

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

Parameters5/5

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

The description elaborates on the 'scope' parameter with three explicit values and meanings, providing context beyond the schema which only defines type and default. This fully compensates for the 0% schema description coverage.

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

Purpose5/5

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

The description clearly states 'Find Flask extensions in use' – a specific verb and resource. It distinguishes from sibling tools like find_models or find_routes by targeting extensions specifically.

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

Usage Guidelines2/5

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

No explicit guidance on when to use this tool vs alternatives like analyze_dependencies or find_references. The description does not state when to use or avoid this tool, nor does it mention alternative tools.

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

find_field_validatorsA

Find all field-specific validators.

Args: scope: Search scope (default "main"): - "main": Only the main project (default for plugins) - "all": Include configured namespaces - "namespace:name": Specific namespace

ParametersJSON Schema
NameRequiredDescriptionDefault
scopeNomain

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.3/5.0
Behavior3/5

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

With no annotations provided, the description carries the burden of behavioral disclosure. It explains the behavior of the 'scope' parameter, but does not mention any side effects, permissions, rate limits, or output structure beyond what is implied by the tool name. The presence of an output schema partially mitigates the need to describe return values.

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

Conciseness5/5

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

The description is extremely concise, consisting of three lines including the 'Args' header. It uses a bullet-point list for the parameter options, making it easy to scan. Every sentence serves a purpose with no superfluous text.

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

Completeness4/5

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

For a tool with one well-documented parameter and an output schema (not shown), the description is largely complete. It could be improved by briefly noting what the output contains or mentioning any constraints, but the current level is adequate for the tool's simplicity.

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

Parameters5/5

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

The schema coverage is 0%, so the description must compensate. It fully explains the single 'scope' parameter, including its default value and three possible values with clear meanings. This adds significant value beyond the schema, which only defines type and default.

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

Purpose5/5

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

The description starts with 'Find all field-specific validators,' which clearly states the tool's purpose. It distinguishes from sibling tools like 'find_validators' by specifying 'field-specific', making the tool's role unambiguous.

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

Usage Guidelines4/5

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

The description provides detailed guidance on the 'scope' parameter with three explicit options and their semantics. However, it does not explicitly compare this tool to alternatives like 'find_validators' or specify when to choose one over the other, which would strengthen this dimension.

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

find_model_configA

Find all model configurations.

Args: scope: Search scope (default "main"): - "main": Only the main project (default for plugins) - "all": Include configured namespaces - "namespace:name": Specific namespace

ParametersJSON Schema
NameRequiredDescriptionDefault
scopeNomain

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior3/5

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

No annotations are provided, so the description carries the burden of behavioral disclosure. It details the scope parameter but omits side effects, return format, permissions, or rate limits. The transparency is adequate for a read-only tool but lacks richness.

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

Conciseness5/5

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

The description is concise and front-loaded with the main purpose, followed by a well-structured bullet list for the parameter. Every sentence adds necessary information without redundancy.

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

Completeness4/5

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

Given the tool's simplicity (1 optional parameter) and the existence of an output schema, the description covers the essential usage. It lacks detail on output format or additional behavioral constraints, but these are partially handled by the output schema.

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

Parameters4/5

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

Schema description coverage is 0%, yet the description adds significant value by explaining the three scope options with examples. This compensates for the missing schema descriptions, making parameter usage clear.

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

Purpose5/5

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

The description explicitly states 'Find all model configurations,' which clearly identifies the action and resource. It differentiates from siblings like 'find_models' and 'find_config' by specificity.

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

Usage Guidelines3/5

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

The description explains the scope parameter with options, providing clear context for usage. However, it does not contrast with alternative tools (e.g., when to use find_config instead), leaving usage guidance incomplete.

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

find_modelsA

Find all Pydantic models in the project.

Args: scope: Search scope (default "main"): - "main": Only the main project (default for plugins) - "all": Include configured namespaces - "namespace:name": Specific namespace

ParametersJSON Schema
NameRequiredDescriptionDefault
scopeNomain

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior2/5

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

No annotations are provided, so the description must carry the full burden. It only states it 'finds' models, providing no behavioral details like side effects, permissions, or whether it makes external calls.

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

Conciseness5/5

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

The description is front-loaded with the primary purpose, then concisely documents the parameter in a structured format (Args:) without any superfluous information.

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

Completeness4/5

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

The tool has only one optional parameter and an output schema exists, so the description adequately covers the parameter and context. It could mention the output type or that it searches the project, but it's sufficient.

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

Parameters5/5

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

Schema description coverage is 0%, but the description fully compensates by detailing the scope parameter with its valid values ('main', 'all', 'namespace:name') and defaults, which is critical for correct usage.

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

Purpose5/5

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

The description states 'Find all Pydantic models in the project' which clearly identifies the tool's action and target resource. It distinguishes itself from sibling tools like find_blueprints or find_routes.

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

Usage Guidelines3/5

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

The description explains the scope parameter options but lacks explicit guidance on when to use this tool versus alternatives or when not to use it.

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

find_referencesA

Python: Find ALL usages of a symbol. Understands inheritance - grep misses subclass refs.

For general use, prefer lookup() which accepts any identifier form. This tool provides fields filtering, include_subclasses, and symbol_name for full reference lists.

Two calling conventions (coordinates take precedence if both provided):

  1. Coordinates: file + line + column (precise, unambiguous)

  2. Symbol name: symbol_name only (convenient; fails if name is ambiguous)

If symbol_name matches multiple symbols, returns error with a "matches" list so you can pick the right one and retry with coordinates.

Args: file: Path to the file (required with line and column) line: Line number (1-indexed, required with file and column) column: Column number (0-indexed, required with file and line) symbol_name: Symbol name (alternative to file+line+column) project_path: Root path of the project include_definitions: Include definitions in results include_subclasses: Also find references to all subclasses (polymorphic search) fields: Fields to include per reference. Valid: name, type, line, column, description, full_name, file, is_definition. Default: all fields.

ParametersJSON Schema
NameRequiredDescriptionDefault
fileNo
lineNo
columnNo
project_pathNo.
include_definitionsNo
include_subclassesNo
fieldsNo
symbol_nameNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4.9/5.0
Behavior5/5

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

Despite no annotations, the description fully discloses behavioral traits: it understands inheritance, returns error with matches list if ambiguous, and explains precedence of coordinates over symbol name. It also details output fields and defaults. No contradictions.

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

Conciseness4/5

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

The description is well-structured with a summary, usage guidance, conventions, and parameter details. It is front-loaded with key information. However, it is somewhat lengthy and could be slightly trimmed without losing clarity, but it remains effective.

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

Completeness5/5

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

Given 8 parameters, no annotations, and complex features (two conventions, inheritance, error handling), the description covers all necessary aspects. It also has an output schema (not shown) so return values are handled. The description is complete for an agent to use correctly.

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

Parameters5/5

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

The description adds significant meaning beyond the schema, which has 0% coverage. It explains each parameter, including indexing conventions (line 1-indexed, column 0-indexed), the interaction between coordinate parameters and symbol_name, and the valid values for fields. This is essential for correct usage.

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

Purpose5/5

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

The description clearly states the tool finds all usages of a symbol in Python, understands inheritance, and distinguishes itself from grep. It also mentions an alternative tool (lookup()) and explains two calling conventions, making the purpose very specific.

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

Usage Guidelines5/5

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

The description explicitly advises to prefer lookup() for general use, explains when to use coordinates vs symbol name, and warns that symbol name can fail if ambiguous. This gives clear guidance on when to use this tool vs alternatives.

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

find_routesA

Find all Flask routes in the project.

Args: scope: Search scope (default "main"): - "main": Only the main project (default for plugins) - "all": Include configured namespaces - "namespace:name": Specific namespace

ParametersJSON Schema
NameRequiredDescriptionDefault
scopeNomain

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.9/5.0
Behavior2/5

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

No annotations are provided, so the description carries full burden. It does not disclose behavioral traits such as read-only nature, side effects, or performance implications. For a find operation, it is likely safe, but this is not stated.

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

Conciseness5/5

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

The description is concise: one sentence for purpose followed by a bullet list for parameter details. No superfluous content, and the main purpose is front-loaded.

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

Completeness4/5

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

The description covers the input parameter well and, since an output schema exists, return values need not be explained. However, it lacks details on error conditions or prerequisites, which would improve completeness.

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

Parameters5/5

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

Despite 0% schema coverage, the description thoroughly explains the 'scope' parameter with enumerated options (main, all, namespace:name) and their meanings, adding significant value beyond the schema definition.

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

Purpose5/5

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

The description clearly states the tool finds all Flask routes in the project, using a specific verb and resource. This distinguishes it from sibling tools like find_views or find_blueprints, which target different entities.

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

Usage Guidelines3/5

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

The description provides scope options but does not explicitly state when to use this tool over alternatives (e.g., find_views). Usage context is implied but not directive.

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

find_templatesA

Find all Flask templates and render_template calls.

Args: scope: Search scope (default "main"): - "main": Only the main project (default for plugins) - "all": Include configured namespaces - "namespace:name": Specific namespace

ParametersJSON Schema
NameRequiredDescriptionDefault
scopeNomain

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior2/5

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

No annotations are present, so the description must convey all behavioral traits. It does not mention side effects, read-only nature, or what the tool returns. The description focuses only on parameter semantics, leaving behavioral aspects unclear.

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

Conciseness4/5

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

The description is reasonably concise with a short summary followed by a structured parameter list. However, it could be more front-loaded by stating the main purpose before the parameter details.

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

Completeness4/5

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

Given that an output schema exists, the description need not explain return values. The single parameter is well-documented, but the lack of any behavioral or safety context (e.g., read-only, no side effects) leaves minor gaps.

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

Parameters5/5

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

With 0% schema description coverage, the description fully compensates by explaining the scope parameter in detail, including its default value and three possible values with meanings. This adds significant value beyond the schema structure.

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

Purpose5/5

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

The description clearly states it finds Flask templates and render_template calls, with a specific verb 'find' and resource. It is distinct from sibling tools like find_blueprints or find_routes.

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

Usage Guidelines4/5

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

The description provides a detailed explanation of the scope parameter with three clear options, helping the agent decide when to use different scopes. However, it does not explicitly compare with alternative tools or state when not 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.

find_validatorsA

Find all Pydantic validators in the project.

Args: scope: Search scope (default "main"): - "main": Only the main project (default for plugins) - "all": Include configured namespaces - "namespace:name": Specific namespace

ParametersJSON Schema
NameRequiredDescriptionDefault
scopeNomain

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A4/5.0
Behavior2/5

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

No annotations are provided, so the description carries the full burden of behavioral disclosure. It does not mention whether the tool is read-only, has authorization requirements, or any side effects, leaving transparency lacking.

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

Conciseness5/5

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

The description is brief and front-loaded with the main purpose. The parameter documentation is presented in a concise docstring format with no wasted words.

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

Completeness4/5

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

Given the tool's simplicity (one parameter) and the presence of an output schema, the description covers the essential information. It does not mention limitations or side effects, but is otherwise complete.

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

Parameters4/5

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

With 0% schema description coverage, the description adds significant meaning to the scope parameter by explaining its possible values and default behavior, going beyond the schema which only defines the type.

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

Purpose5/5

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

The description clearly states it finds all Pydantic validators in the project, using a specific verb and resource. This distinguishes it from siblings like find_field_validators which may be more specific.

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

Usage Guidelines4/5

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

The description documents the scope parameter with its default and options, providing clear context for usage. However, it does not explicitly mention when to use this tool versus alternatives like find_field_validators.

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

find_viewsA

Find all Flask view functions and classes.

Args: scope: Search scope (default "main"): - "main": Only the main project (default for plugins) - "all": Include configured namespaces - "namespace:name": Specific namespace

ParametersJSON Schema
NameRequiredDescriptionDefault
scopeNomain

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior2/5

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

No annotations are provided, so the description must carry the burden of behavioral disclosure. It does not mention that the tool is read-only, safe, or what happens on errors/empty results. Only notes scope filtering behavior.

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

Conciseness5/5

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

The description is concise, front-loads the main purpose, and presents parameter details in a clean list format without extraneous text.

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

Completeness4/5

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

Given the tool has only one parameter with an output schema, the description sufficiently covers the parameter. However, it could be slightly more complete by indicating the tool is read-only or providing a brief note on return type, but that is mitigated by the output schema.

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

Parameters4/5

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

The input schema has 0% description coverage, so the description must compensate. It adds significant meaning by listing the three possible values for 'scope' with explanations, beyond what the schema provides (only type and default).

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

Purpose5/5

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

The description clearly states 'Find all Flask view functions and classes', using a specific verb and resource. This distinct purpose differentiates it from sibling tools like find_routes, find_blueprints, etc.

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

Usage Guidelines2/5

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

The description does not provide guidance on when to use this tool vs alternatives. It only explains the scope parameter options, but no context on when to choose this over siblings like find_routes or find_blueprints.

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

get_call_hierarchyA

Python: Trace function callers and callees through the codebase.

Deprecated: Replaced by inspect(handle).edge_counts.callers for the count and future expand(handle, edge="callers") for the list in the redesigned API. See docs/superpowers/specs/2026-05-02-progressive-disclosure-api-design.md for the migration plan. This method will be removed once the legacy MCP tools are deprecated (Phase B of the migration).

For general use, prefer lookup() which accepts any identifier form. This tool provides full call graph traversal beyond the default limit.

Args: function_name: Name of the function file: Optional file to search in (searches whole project if not specified) project_path: Root path of the project

ParametersJSON Schema
NameRequiredDescriptionDefault
function_nameYes
fileNo
project_pathNo.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior3/5

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

No annotations are provided, so the description must disclose behavioral traits. It reveals the tool is legacy and will be removed, but it does not mention permissions, destructive potential, rate limits, or return format. While the tool appears read-only, this is not explicitly stated, leaving some transparency gaps.

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

Conciseness3/5

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

The description is somewhat lengthy due to the deprecation notice and file reference, which takes space away from the core purpose. It is structured with a brief intro followed by an Args list, but the migration details could be condensed or moved to a notes section.

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

Completeness3/5

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

Given the complexity of call graph traversal and the lack of schema descriptions, the description explains what the tool does and its parameters, but it omits details about the output format, error handling, or any limitations beyond 'beyond default limit'. The presence of an output schema mitigates this slightly, but more context would help.

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

Parameters4/5

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

Despite 0% schema description coverage, the 'Args' section explains each parameter's role: function_name as the function to trace, file as an optional search scope, and project_path as the root path. This adds meaningful context beyond the raw schema, though the description could clarify that function_name is required.

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

Purpose4/5

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

The description clearly states that the tool traces function callers and callees through the codebase, and it distinguishes itself from siblings like `inspect` and `expand` by offering full call graph traversal beyond the default limit. However, the immediate deprecation notice and reference to replacements muddles the primary purpose slightly.

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

Usage Guidelines5/5

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

The description explicitly states that the tool is deprecated, replaced by `inspect(handle).edge_counts.callers` and `expand(handle, edge="callers")`, and advises preferring `lookup()` for general use. This provides clear when-to-use and when-not-to-use guidance, along with named alternatives.

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

get_model_schemaA

Get the schema for a specific Pydantic model.

Args: model_name: Name of the model to get schema for scope: Search scope (default "main"): - "main": Only the main project (default for plugins) - "all": Include configured namespaces - "namespace:name": Specific namespace

ParametersJSON Schema
NameRequiredDescriptionDefault
model_nameYes
scopeNomain

Output Schema

ParametersJSON Schema
NameRequiredDescription
resultYes

TDQS

A3.6/5.0
Behavior2/5

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

No annotations are provided, so the description bears full responsibility for behavioral disclosure. It only explains the function and parameters, with no mention of side effects, error conditions, performance, or authorization needs. This leaves significant gaps for safe invocation.

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

Conciseness4/5

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

The description is reasonably concise, using an Args section with bullet points for scope options. Every sentence contributes information, though it could be slightly tighter. Structurally clear.

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

Completeness3/5

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

Given that an output schema exists, the description does not need to explain return values. It adequately covers inputs. However, it lacks any mention of errors or expected behavior when the model is not found, leaving some contextual gaps.

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

Parameters4/5

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

The input schema has 0% description coverage, but the description compensates by providing clear semantics for both parameters: model_name as 'Name of the model' and scope with enumerated options and defaults. This adds value beyond the bare schema titles.

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

Purpose5/5

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

The description clearly states the verb 'Get' and the resource 'schema for a specific Pydantic model', making the purpose unmistakable. It distinguishes itself from siblings like 'find_models' which locate models rather than retrieving their schema.

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

Usage Guidelines3/5

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

The description explains the scope parameter options but does not explicitly state when to use this tool versus alternatives like 'find_models' or 'trace_model_inheritance'. Usage is implied but lacks explicit guidance on exclusions or preferred contexts.

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

inspectA

Python: Inspect a canonical handle and return a structural Node.

The "what is this?" operation. Returns the symbol's kind, location, signature, docstring, and kind-dependent fields. Cheap by default — no source content, no exhaustive enumerations. Edge counts and highlights come in later phases.

Args: handle: Canonical Python dotted-name string (from resolve/resolve_at). project_path: Project root path (default: current directory)

Returns: Node dict with universal fields (handle, kind, scope, location, docstring, edge_counts={}) plus kind-dependent fields: - class: signature (constructor), superclasses (list of Handle strings) - function/method: signature, parameters, return_type?, is_async, is_classmethod, is_staticmethod - module: is_package, package? - attribute/property/variable: type?, default? (simple literals only)

ParametersJSON Schema
NameRequiredDescriptionDefault
handleYes
project_pathNo.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

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

With no annotations provided, the description fully carries the transparency burden. It explicitly states the tool is cheap, returns no source content or exhaustive enumerations, and details the return structure including universal and kind-dependent fields. There is no ambiguity about behavior or safety.

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

Conciseness4/5

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

The description is well-structured with a clear opening sentence, followed by a bulleted list of return fields. While it is somewhat lengthy, every sentence adds value and the bullet format improves readability for an AI agent parsing the return types.

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

Completeness5/5

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

Given the presence of an output schema and the complexity of the tool with kind-dependent fields, the description is highly complete. It covers all necessary aspects: purpose, parameter details, return structure with examples for each kind, and behavioral notes (cheap, no source content). No major gaps are present.

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

Parameters4/5

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

Although schema description coverage is 0%, the description adds meaningful context for both parameters: handle is described as a 'Canonical Python dotted-name string (from resolve/resolve_at)' and project_path as 'Project root path (default: current directory)'. This compensates well for the lack of schema descriptions.

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

Purpose5/5

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

The description clearly states the tool inspects a canonical handle and returns a structural Node, explicitly framing it as the 'what is this?' operation. It distinguishes from siblings by referencing resolve/resolve_at for obtaining handles and noting this tool is cheap by default without source content or exhaustive enumerations.

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

Usage Guidelines4/5

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

The description provides clear context on when to use: it is cheap, returns kind-dependent fields, and notes that edge counts and highlights come in later phases. It implicitly contrasts with more expensive operations but does not explicitly name alternatives like expand or outline for when more detail is needed.

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

outlineA

Python: Structural skeleton of a module or class — names, kinds, signatures, line spans.

Returns a nested OutlineTree — the members hierarchy of handle as a tree of lightweight structural nodes (Stub). Each node carries handle, kind, scope, line_start, line_end, and signature when Jedi yields one. No source content anywhere in the tree.

Use resolve() or inspect() first to obtain a canonical handle, then outline() to see the complete structural skeleton in one call — the single-call answer to "show me the structure of this scope."

Static-surface ceiling. The tree walks the members edge, so it is complete over what is statically defined in source but not over runtime. Runtime-injected members (metaclass / setattr / __getattr__ / type() / __init_subclass__) are NOT captured — e.g. outline of a Django Model omits its metaclass-injected _meta / objects / DoesNotExist. An absent member is "not in source," not "not at runtime."

Absence contracts — an agent MUST read these before consuming the tree.

Contract 1 — children absent ⇔ not expanded.

children present (including children: []) means measured: the complete set of direct members of this node. children: [] is a genuine leaf — a container with no members, or a non-container (function/method/ variable). children absent means a cap fired and this node was not walked — treat it as "unknown," never as empty.

Contract 2 — truncated absent-not-false.

truncated: true is present only on a node that a cap cut off; it always co-occurs with truncation_reason and an absent children. Fully-walked nodes omit truncated entirely — truncated: false never appears.

Truncation reasons (one string per node — not a list):

  • "max_depth" — at the depth frontier; resolve_members was peeked once and found members (a genuine empty container at the frontier gets children: [] instead).

  • "max_nodes" — total-node budget exhausted; no peek performed.

  • "external" — external-scope container at depth ≥ 1; no deeper walk into third-party code.

When both max_nodes AND a depth/external cap could apply to the same node, truncation_reason is "max_nodes" (the harder global bound).

Args: handle: Canonical Python dotted-name string (from resolve/inspect). project_path: Project root path (default: current directory). max_depth: Maximum depth from the root (root is depth 0). None means unbounded within scope; the external cap and max_nodes still apply. At the frontier, resolve_members is peeked once to distinguish a genuine empty container from a cut-off one. max_nodes: Total-node budget for the tree (root counts as 1, default 200). Containers that exceed the budget are marked truncated: "max_nodes" without peeking.

Returns: OutlineTree dict — {"node": Stub, "children": [OutlineTree, ...]}. Never raises; an unresolvable handle yields a minimal single-node tree with children: []. Children within each parent are in source order (sorted by (line_start, handle)); BFS inclusion order bounds the budget gracefully (all of depth 1 before any of depth 2, etc.).

ParametersJSON Schema
NameRequiredDescriptionDefault
handleYes
project_pathNo.
max_depthNo
max_nodesNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

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

Despite no annotations, the description discloses key behaviors: static-surface ceiling (no runtime members), absence contracts for children truncation, truncation reasons, and error handling (never raises, minimal tree on unresolvable handle).

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

Conciseness4/5

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

The description is lengthy but well-structured with clear sections (purpose, returns, usage, behavioral notes, args). Some redundancy could be trimmed, but it remains organized and front-loaded with core purpose.

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

Completeness5/5

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

Given the complexity (4 params, output schema, behavioral nuances, sibling variety), the description covers all necessary aspects: parameters, return structure, edge cases, contracts, and ordering. An output schema exists, reducing the burden, but the description adds thorough context.

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

Parameters5/5

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

With 0% schema coverage, the description provides thorough explanations for all four parameters, including defaults, semantics of max_depth and max_nodes, and the role of project_path. Adds significant value beyond the schema.

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

Purpose5/5

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

The description clearly states the tool returns a structural skeleton (names, kinds, signatures, line spans) and distinguishes it from siblings by positioning it as the single-call answer to 'show me the structure of this scope.'

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

Usage Guidelines4/5

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

Explicitly advises using resolve() or inspect() first to obtain a canonical handle, then call outline(). Provides clear context but lacks explicit when-not-to-use or alternatives for structural inspection.

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

resolveA

Python: Resolve any identifier form to a canonical Handle.

Accepts bare names, FQN dotted paths, re-exported public paths, file:line coordinates, or file paths. Returns the definition-site canonical handle along with kind and scope ("project" or "external").

Args: identifier: The identifier to resolve. Forms supported: - Bare name: "Config" - FQN: "a.b.c.Config" - Re-exported: "package.Config" (collapses to definition site) - File:line: "src/foo.py:42" - File only: "src/foo.py" project_path: Project root path (default: current directory)

Returns: ResolveResult dict — one of: - Success: {"found": True, "handle": str, "kind": str, "scope": "project"|"external"} - Ambiguous: {"found": True, "ambiguous": True, "candidates": [...]} - Not found: {"found": False, "reason": str}

ParametersJSON Schema
NameRequiredDescriptionDefault
identifierYes
project_pathNo.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations provided, the description fully explains the return behavior (success, ambiguous, not found) and the meaning of the result. It does not mention any side effects, which is acceptable for a resolution tool, but could be more explicit about read-only nature.

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

Conciseness4/5

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

The description is well-structured with a brief introductory sentence followed by parameter details and return value explanation. It is slightly long but not verbose; every sentence adds value.

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

Completeness4/5

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

The description covers accepted inputs, return formats, and parameter details. It omits preconditions like requiring a Python project or environment, and does not explain the output schema fields in detail. However, given the output schema exists, the description is adequately complete.

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

Parameters5/5

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

Schema description coverage is 0%, but the description compensates thoroughly by detailing the identifier forms (bare name, FQN, re-exported, file:line, file only) and explaining the project_path default. This adds significant meaning beyond the schema's type definitions.

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

Purpose5/5

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

The description explicitly states it resolves any identifier form to a canonical Handle, listing specific accepted forms. This clearly distinguishes it from sibling tools like 'find_references' or 'resolve_at' by focusing on identifier resolution to definition-site handle.

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

Usage Guidelines3/5

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

The description implies usage through the listed identifier forms, but lacks explicit guidance on when to use this tool versus alternatives (e.g., 'resolve_at') and does not specify when not to use it.

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

resolve_atA

Python: Resolve a (file, line, column) position to a canonical Handle.

Used when you have coordinates (from a stack trace, error report, or pasted excerpt) rather than a name. Returns the same shape as resolve().

Args: file: Absolute or project-relative path to the source file. line: 1-indexed line number. column: 0-indexed column number. Pass 0 for the start of the line — this is valid; do not coerce to a default. project_path: Project root path (default: current directory)

Returns: ResolveResult dict (see resolve() for shape).

ParametersJSON Schema
NameRequiredDescriptionDefault
fileYes
lineYes
columnYes
project_pathNo.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior3/5

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

With no annotations, the description carries full burden. It describes the operation and return shape (like resolve()) but omits failure behavior, side effects, or safety assurances. Adequate but not fully transparent.

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

Conciseness5/5

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

Two concise paragraphs plus bullet-like argument list. Every sentence earns its place. No redundancy, well front-loaded with purpose and usage context.

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

Completeness5/5

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

Given output schema existence, description needn't detail return values beyond referencing resolve(). Covers all four parameters, usage context, and coordination with sibling. Complete for this tool.

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

Parameters5/5

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

Schema coverage is 0%, so description must explain all parameters. It provides clear semantics: file path type, 1-indexed line, 0-indexed column with coercion warning, and project_path default. Adds significant value beyond schema.

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

Purpose5/5

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

The description clearly states it resolves a (file, line, column) position to a canonical Handle, specifically for coordinates from stack traces or error reports. It distinguishes itself from the sibling 'resolve' tool by emphasizing coordinate-based input rather than name-based.

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

Usage Guidelines4/5

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

Explicitly states when to use ('when you have coordinates from a stack trace, error report, or pasted excerpt rather than a name'). Links to sibling 'resolve' for return shape. Lacks explicit when-not-to-use, but context is clear.

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

traceA

Python: Bounded multi-hop BFS traversal — returns a typed Subgraph.

The composition primitive: it walks the follow edges outward from start across multiple hops, deduping by canonical handle, and returns a Subgraph of the reachable structure. Use resolve()/inspect() to obtain canonical handles first, then trace() to see structure across hops (call chains, reverse-import closures, member trees).

Composes the same edge registry as expand; the implemented edges (members, callees, imported_by, subclasses, superclasses, imports, enclosing_scope) are traversed. Any other edge named in follow (deferred reference edges, unknown names) is reported in unsupported_edges rather than silently dropped — a silent drop would falsely read as "no such neighbours".

Response shape — Subgraph::

{ "nodes": { handle: Stub, ... },        # deduped by canonical handle
  "edges": [ {"from": h, "to": h, "kind": edge}, ... ],
  "truncated": bool,                     # a cap cut off reachable nodes
  "truncation_reasons": ["max_depth"?, "max_nodes"?],  # which cap(s) fired
  "unsupported_edges": [ {"edge", "reason", "detail"}, ... ] }

Edges are NOT deduped across kinds; edges to already-visited handles are recorded (so cycles stay visible) but never re-expanded, guaranteeing termination on cyclic graphs. truncated is true ONLY when max_depth or max_nodes cut off reachable handles before natural termination — not merely because a cap was set.

Args: start: One canonical handle, or a list of them, as BFS roots. follow: Edge names to traverse at every hop (e.g. ["members"], ["callees"], ["imported_by"]). project_path: Project root path (default: current directory). max_depth: Maximum hop distance from a root before a node becomes a non-expanded frontier leaf (default 3). max_nodes: Maximum number of distinct nodes in the subgraph; reaching it sets truncated (default 50). stop_when: Optional StopPredicate (exclude_external / module_pattern / exclude_tests); a matching adjacent is a pruned boundary. Roots are never pruned. exclude_external stops at stdlib/site-packages nodes — keeps a trace inside the project (the common callees case).

Returns: A Subgraph dict (plain, JSON-serialisable). Never raises; an unresolvable root simply contributes no node.

ParametersJSON Schema
NameRequiredDescriptionDefault
startYes
followYes
project_pathNo.
max_depthNo
max_nodesNo
stop_whenNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

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

With no annotations, the description fully discloses key behaviors: deduping by canonical handle, no silent drops (unsupported edges reported), edges not deduped across kinds, cycle guarantee (never re-expands visited nodes), truncation triggers (max_depth/max_nodes), and that it never raises. This transparency is exceptional.

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

Conciseness4/5

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

The description is fairly long but well-organized into logical sections: summary, composition context, response shape, and parameter details. Every sentence serves a purpose, explaining behavior or constraints. A minor reduction in redundancy could improve conciseness, but it's already efficient for the complexity.

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

Completeness5/5

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

Given the tool has 6 parameters, an output schema, and no annotations, the description covers all critical aspects: input semantics, output format with fields (nodes, edges, truncated, unsupported_edges), edge behaviors, termination guarantees, and error handling (never raises). The output schema exists but the description adds necessary context beyond the raw schema.

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

Parameters5/5

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

Schema description coverage is 0%, so the description must carry the entire parameter documentation burden. It does so thoroughly: start accepts a single handle or list; follow lists edge names; project_path defaults to current dir; max_depth and max_nodes have defaults; stop_when is a StopPredicate with examples (exclude_external, module_pattern, exclude_tests). This greatly enriches the bare schema.

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

Purpose5/5

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

The description opens with a clear statement: 'Python: Bounded multi-hop BFS traversal — returns a typed Subgraph.' It then explains its role as a composition primitive distinct from sibling tools like expand and resolve. The verb 'traverses' and resource 'Subgraph' are specific, 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.

Usage Guidelines4/5

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

The description advises using resolve()/inspect() first to get canonical handles, then trace() for structural exploration. It mentions the common callees case and describes stop_when for excluding external packages. While it doesn't explicitly state when not to use, the context is sufficient for an AI agent to decide.

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

trace_model_inheritanceB

Trace the inheritance hierarchy of a Pydantic model.

Args: model_name: Name of the model to trace scope: Search scope (default "main"): - "main": Only the main project (default for plugins) - "all": Include configured namespaces - "namespace:name": Specific namespace

ParametersJSON Schema
NameRequiredDescriptionDefault
model_nameYes
scopeNomain

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.4/5.0
Behavior3/5

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

No annotations exist, so the description carries the behavioral burden. It implies a read-only operation (tracing) without declaring side effects, permissions, or rate limits. This is neutral but insufficient to score higher; no contradictions.

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

Conciseness4/5

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

The description is relatively short and structured with an Args block. However, the header 'Trace the inheritance hierarchy of a Pydantic model.' is somewhat redundant with the tool's name, and the docstring format could be tighter.

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

Completeness4/5

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

Given the presence of an output schema (not shown but signaled), the description adequately covers the input parameters and basic purpose. It does not explain return value details, but the output schema likely handles that. For a single-purpose tool, this is sufficient.

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

Parameters4/5

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

Schema coverage is 0%, meaning the description must compensate. It explains both parameters, especially detailing the scope values ('main', 'all', 'namespace:name'). However, it omits that scope can also be an array of strings, which limits completeness.

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

Purpose4/5

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

The description uses a specific verb 'Trace' and identifies the resource 'inheritance hierarchy of a Pydantic model', making the purpose clear. While it distinguishes from siblings like 'trace' (more generic) and 'get_model_schema' (schema vs hierarchy), it does not explicitly highlight the uniqueness, 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.

Usage Guidelines2/5

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. The description only explains the parameters, not the context or when-not-to-use. Sibling tools like 'find_models' or 'trace' are not mentioned, leaving the agent to infer usage.

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

TDQS

A3.9/5.0
Disambiguation5/5

Each tool has a clearly distinct purpose, from dependency analysis to framework-specific finders and structural queries. Even similar-sounding tools like 'expand' and 'outline' are precisely differentiated by their descriptions (single-hop vs full skeleton). The deprecated tools are noted but do not cause confusion.

Naming Consistency4/5

Tools predominantly use underscore_case and descriptive verb-noun patterns (e.g., find_*, get_*, trace_*). However, there is some variation: single verbs like 'expand' and 'inspect' coexist with 'find_blueprints' and 'get_model_schema'. The consistency is high but not perfect, with no mixed casing.

Tool Count4/5

25 tools is on the higher side but well-scoped for a comprehensive Python code analysis server covering dependency, symbol resolution, structural queries, and framework-specific finders (Flask, Pydantic). The count feels justified given the breadth of functionality, though a slight reduction could improve coherence.

Completeness4/5

The tool set covers a wide range of analysis needs: dependency mapping, symbol resolution, structural inspection, multihop traversal, and framework-specific queries. The presence of deprecated tools (analyze_dependencies, get_call_hierarchy) indicates API transition, but the current surface is largely complete for the domain. Minor gaps exist (e.g., no tool for runtime-injected members beyond static analysis limits).

Maintenance

ActivityMaintained
ResponsivenessResponsive

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    A Model Context Protocol server that enables AI assistants like Claude to perform Python development tasks through file operations, code analysis, project management, and safe code execution.
    9
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    An MCP server that gives Claude Code IDE-level intelligence for FastAPI projects — semantic code navigation, safe renaming, route inspection, dependency trees, and Pydantic model analysis. Instead of Claude reading files blindly, it calls structured tools backed by Jedi (Python language server) and Python's AST.
    9
    1
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Code intelligence MCP server for Claude Code providing multi-project code graph, semantic search, session history, knowledge base, and web search.
    15
    3
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Universal MCP server that analyzes any codebase and provides structured context to AI assistants. Dynamic, accurate, and token-efficient.
    14
    MIT

Latest Blog Posts

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/okeefeco/pyeye-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server