Skip to content

Describe

describe

DescribeTool — full API surface dump.

DescribeTool

Bases: AXMTool

Describe a package: signatures, docstrings, all.

Registered as ast_describe via axm.tools entry point.

Source code in packages/axm-ast/src/axm_ast/tools/describe.py
Python
class DescribeTool(AXMTool):
    """Describe a package: signatures, docstrings, __all__.

    Registered as ``ast_describe`` via axm.tools entry point.
    """

    agent_hint: str = (
        "Show module API: signatures, docstrings, classes, __all__."
        " Use detail=toc for overview, modules=[...] to filter."
        " Replaces 10+ view_file."
    )

    @property
    def name(self) -> str:
        """Return tool name for registry lookup."""
        return "ast_describe"

    @safe_execute
    def execute(
        self,
        *,
        path: str = ".",
        compress: bool = False,
        detail: str = "summary",
        modules: list[str] | None = None,
        **kwargs: object,
    ) -> ToolResult:
        """Describe a Python package.

        Args:
            path: Path to package directory.
            compress: If True, return compressed AI-friendly view.
                Mutually exclusive with ``detail`` values other than
                the default (``summary``).  Passing both ``compress=True``
                and an explicit ``detail`` returns an error.
            detail: Detail level — ``toc`` (names + counts only),
                ``summary`` (signatures only),
                or ``detailed`` (+ docstrings, params, return types).
                Defaults to ``summary`` (signatures only, no docstrings).
            modules: Optional list of module name substrings to filter.
                Case-insensitive.  ``None`` or empty returns all modules.

        Returns:
            ToolResult with module descriptions.
        """
        if detail == "full":
            return ToolResult(
                success=False,
                error=(
                    "detail='full' has been removed — it crashes MCP transport "
                    "on large packages. Use detail='detailed' for docstrings and "
                    "params, or ast_inspect(source=true) for full symbol source."
                ),
            )

        if compress and detail != "summary":
            return ToolResult(
                success=False,
                error=(
                    f"compress=True and detail={detail!r} are mutually exclusive. "
                    "Use compress=True alone (implies its own format) "
                    f"or detail={detail!r} without compress."
                ),
            )

        project_path = Path(path).resolve()
        if not project_path.is_dir():
            return ToolResult(success=False, error=f"Not a directory: {project_path}")

        from axm_ast.core.cache import get_package
        from axm_ast.formatters import (
            filter_modules,
            format_compressed,
            format_json,
            format_toc,
        )

        pkg = get_package(project_path)
        pkg = filter_modules(pkg, modules)

        result_data: dict[str, object]
        if detail == "toc":
            toc = format_toc(pkg)
            result_data = {
                "modules": toc,
                "module_count": len(toc),
            }
            result_text = render_describe_text(result_data, "toc")
        elif compress:
            body = format_compressed(pkg)
            header = f"ast_describe | compress | {len(pkg.modules)} modules"
            text = f"{header}\n{body}"
            result_data = {
                "compressed": text,
                "module_count": len(pkg.modules),
            }
            result_text = text
        else:
            data = format_json(pkg, detail=detail)
            result_data = {
                "modules": data["modules"],
                "module_count": len(pkg.modules),
            }
            result_text = render_describe_text(result_data, detail)

        return ToolResult(success=True, data=result_data, text=result_text)
name property

Return tool name for registry lookup.

execute(*, path='.', compress=False, detail='summary', modules=None, **kwargs)

Describe a Python package.

Parameters:

Name Type Description Default
path str

Path to package directory.

'.'
compress bool

If True, return compressed AI-friendly view. Mutually exclusive with detail values other than the default (summary). Passing both compress=True and an explicit detail returns an error.

False
detail str

Detail level — toc (names + counts only), summary (signatures only), or detailed (+ docstrings, params, return types). Defaults to summary (signatures only, no docstrings).

'summary'
modules list[str] | None

Optional list of module name substrings to filter. Case-insensitive. None or empty returns all modules.

None

Returns:

Type Description
ToolResult

ToolResult with module descriptions.

Source code in packages/axm-ast/src/axm_ast/tools/describe.py
Python
@safe_execute
def execute(
    self,
    *,
    path: str = ".",
    compress: bool = False,
    detail: str = "summary",
    modules: list[str] | None = None,
    **kwargs: object,
) -> ToolResult:
    """Describe a Python package.

    Args:
        path: Path to package directory.
        compress: If True, return compressed AI-friendly view.
            Mutually exclusive with ``detail`` values other than
            the default (``summary``).  Passing both ``compress=True``
            and an explicit ``detail`` returns an error.
        detail: Detail level — ``toc`` (names + counts only),
            ``summary`` (signatures only),
            or ``detailed`` (+ docstrings, params, return types).
            Defaults to ``summary`` (signatures only, no docstrings).
        modules: Optional list of module name substrings to filter.
            Case-insensitive.  ``None`` or empty returns all modules.

    Returns:
        ToolResult with module descriptions.
    """
    if detail == "full":
        return ToolResult(
            success=False,
            error=(
                "detail='full' has been removed — it crashes MCP transport "
                "on large packages. Use detail='detailed' for docstrings and "
                "params, or ast_inspect(source=true) for full symbol source."
            ),
        )

    if compress and detail != "summary":
        return ToolResult(
            success=False,
            error=(
                f"compress=True and detail={detail!r} are mutually exclusive. "
                "Use compress=True alone (implies its own format) "
                f"or detail={detail!r} without compress."
            ),
        )

    project_path = Path(path).resolve()
    if not project_path.is_dir():
        return ToolResult(success=False, error=f"Not a directory: {project_path}")

    from axm_ast.core.cache import get_package
    from axm_ast.formatters import (
        filter_modules,
        format_compressed,
        format_json,
        format_toc,
    )

    pkg = get_package(project_path)
    pkg = filter_modules(pkg, modules)

    result_data: dict[str, object]
    if detail == "toc":
        toc = format_toc(pkg)
        result_data = {
            "modules": toc,
            "module_count": len(toc),
        }
        result_text = render_describe_text(result_data, "toc")
    elif compress:
        body = format_compressed(pkg)
        header = f"ast_describe | compress | {len(pkg.modules)} modules"
        text = f"{header}\n{body}"
        result_data = {
            "compressed": text,
            "module_count": len(pkg.modules),
        }
        result_text = text
    else:
        data = format_json(pkg, detail=detail)
        result_data = {
            "modules": data["modules"],
            "module_count": len(pkg.modules),
        }
        result_text = render_describe_text(result_data, detail)

    return ToolResult(success=True, data=result_data, text=result_text)