Skip to main content
Glama

debugpy_context

Attach debugpy to Python processes in Docker containers for debugging and inspection. Enables process injection and breakpoint planning based on logs.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
containerYes
portNo
python_binNopython

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • The main handler function for the 'debugpy_context' tool. It gathers comprehensive context about a container including process information, debugpy status, Python version, working directory, port mappings, and environment variables. The function is decorated with @mcp.tool() which registers it as an MCP tool.
    @mcp.tool()
    def debugpy_context(container: str, port: int = DEFAULT_PORT, python_bin: str = "python") -> dict[str, Any]:
        if not docker_inspect_running(container):
            return DebugContextResult(ok=False, container=container, notes=["Container is not running or does not exist."]).model_dump()
        installed, version = detect_debugpy_installed(container, python_bin=python_bin)
        processes = get_process_table(container)
        suggested_pid, pid_notes = choose_pid(processes)
        working_dir = get_working_dir(container, suggested_pid) if suggested_pid else None
        listening = port_is_listening(container, port)
        mapped_port = docker_port_mapping(container, port)
        py_ver = get_python_version(container, python_bin=python_bin)
        ports_snapshot = capture_ports_snapshot(container)
        env_subset = get_env_subset(container)
        notes = list(pid_notes)
        if not installed:
            notes.append("debugpy is not currently installed inside the container.")
        notes.append(f"Port {port} is {'already' if listening else 'not'} listening inside the container.")
        return DebugContextResult(ok=True, container=container, working_dir=working_dir, python_version=py_ver, debugpy_version=version, debugpy_listening=listening, mapped_port=mapped_port, processes=processes, suggested_pid=suggested_pid, ports_snapshot=ports_snapshot, env_subset=env_subset, notes=notes).model_dump()
  • The DebugContextResult Pydantic model that defines the output schema for the debugpy_context tool. It includes fields for container info, working directory, Python/debugpy versions, listening status, port mappings, process list, and diagnostic notes.
    class DebugContextResult(BaseModel):
        ok: bool
        container: str
        working_dir: str | None = None
        python_version: str | None = None
        debugpy_version: str | None = None
        debugpy_listening: bool = False
        mapped_port: str | None = None
        processes: list[ProcessInfo] = Field(default_factory=list)
        suggested_pid: int | None = None
        ports_snapshot: str | None = None
        env_subset: dict[str, str] = Field(default_factory=dict)
        notes: list[str] = Field(default_factory=list)
  • The @mcp.tool() decorator registers the debugpy_context function as an MCP tool, making it available for invocation by MCP clients.
    @mcp.tool()
  • Helper function get_process_table that retrieves the process table from a Docker container and classifies processes by type (uvicorn, gunicorn-master, gunicorn-worker, python, other). This is used by debugpy_context to identify candidate processes for debugging.
    def get_process_table(container: str) -> list[ProcessInfo]:
        proc = docker_exec(container, "ps -eo pid,ppid,args", timeout=20, check=False)
        if proc.returncode != 0:
            raise ToolError(f"Unable to read process table in container {container}:\n{proc.stderr}")
        results: list[ProcessInfo] = []
        for line in proc.stdout.splitlines()[1:]:
            line = line.strip()
            if not line:
                continue
            parts = line.split(None, 2)
            if len(parts) < 3:
                continue
            pid_s, ppid_s, cmd = parts
            try:
                pid = int(pid_s)
                ppid = int(ppid_s)
            except ValueError:
                continue
            lowered = cmd.lower()
            kind: Literal["uvicorn", "gunicorn-master", "gunicorn-worker", "python", "other"] = "other"
            if "gunicorn" in lowered and "master" in lowered:
                kind = "gunicorn-master"
            elif "gunicorn" in lowered and "worker" in lowered:
                kind = "gunicorn-worker"
            elif "uvicorn" in lowered:
                kind = "uvicorn"
            elif "python" in lowered:
                kind = "python"
            if any(token in lowered for token in ["python", "uvicorn", "gunicorn", "fastapi"]):
                results.append(ProcessInfo(pid=pid, ppid=ppid, cmd=cmd, kind=kind))
        return results
  • Helper function detect_debugpy_installed that checks if debugpy is installed in the container and retrieves its version. This is called by debugpy_context to determine if the debugger is available.
    def detect_debugpy_installed(container: str, python_bin: str = "python") -> tuple[bool, str | None]:
        cmd = (
            f"{shlex.quote(python_bin)} - <<'PY'\n"
            "import importlib.util\n"
            "spec = importlib.util.find_spec('debugpy')\n"
            "print('YES' if spec else 'NO')\n"
            "PY"
        )
        proc = docker_exec(container, cmd, timeout=20, check=False)
        if proc.returncode != 0:
            return False, None
        installed = proc.stdout.strip() == "YES"
        if not installed:
            return False, None
        ver_cmd = (
            f"{shlex.quote(python_bin)} - <<'PY'\n"
            "import debugpy\n"
            "print(getattr(debugpy, '__version__', 'unknown'))\n"
            "PY"
        )
        ver_proc = docker_exec(container, ver_cmd, timeout=20, check=False)
        version = ver_proc.stdout.strip() if ver_proc.returncode == 0 else None
        return True, version

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/will-garrett/debugpy-mcp'

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