Skip to main content
Glama

sessions_create

Start a Python debugging session to set breakpoints, step through code execution, and inspect variables for script analysis.

Instructions

Create a new debug session for a Python script

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
entryYesProject-relative path to Python script
pythonPathYesAbsolute path to Python interpreter (must have debugpy installed)
argsNoCommand-line arguments for the script
envNoEnvironment variables

Implementation Reference

  • Registration of the 'sessions_create' tool in list_tools(), including input schema definition and description.
    Tool(
        name="sessions_create",
        description="Create a new debug session for a Python script",
        inputSchema={
            "type": "object",
            "properties": {
                "entry": {
                    "type": "string",
                    "description": "Project-relative path to Python script",
                },
                "pythonPath": {
                    "type": "string",
                    "description": "Absolute path to Python interpreter (must have debugpy installed)",
                },
                "args": {
                    "type": "array",
                    "items": {"type": "string"},
                    "description": "Command-line arguments for the script",
                },
                "env": {
                    "type": "object",
                    "additionalProperties": {"type": "string"},
                    "description": "Environment variables",
                },
            },
            "required": ["entry", "pythonPath"],
        },
    ),
  • MCP tool handler _handle_sessions_create: validates input with StartSessionRequest, calls SessionManager.create_session_async, returns sessionId or error.
    async def _handle_sessions_create(self, arguments: dict) -> list[TextContent]:
        """
        Handler for sessions_create tool.
        
        Creates a new debug session for a Python script.
        """
        try:
            request = StartSessionRequest(**arguments)
            response = await self.session_manager.create_session_async(request)
    
            return [
                TextContent(
                    type="text",
                    text=json.dumps({
                        "sessionId": response.sessionId,
                    }),
                )
            ]
        except FileNotFoundError as e:
            return [
                TextContent(
                    type="text",
                    text=json.dumps({
                        "error": {
                            "type": "FileNotFoundError",
                            "message": str(e),
                        }
                    }),
                )
            ]
        except ValueError as e:
            return [
                TextContent(
                    type="text",
                    text=json.dumps({
                        "error": {
                            "type": "ValueError",
                            "message": str(e),
                        }
                    }),
                )
            ]
        except Exception as e:
            logger.exception("Error creating session")
            return [
                TextContent(
                    type="text",
                    text=json.dumps({
                        "error": {
                            "type": type(e).__name__,
                            "message": str(e),
                        }
                    }),
                )
            ]
  • Pydantic model StartSessionRequest for input validation of sessions_create tool, with field validators for args and env.
    class StartSessionRequest(BaseModel):
        """Request to start a new debug session."""
        entry: str = Field(..., description="Project-relative path to script")
        pythonPath: str = Field(..., description="Absolute path to Python interpreter (must have debugpy installed)")
        args: list[str] | None = Field(default=None, description="Command-line arguments")
        env: dict[str, str] | None = Field(default=None, description="Environment variables")
        useDap: bool | None = Field(default=True, description="Use DAP (debugpy) instead of bdb - recommended for all use cases")
    
        @field_validator('args')
        @classmethod
        def validate_args(cls, v: list[str] | None) -> list[str] | None:
            """Validate args list constraints."""
            if v is not None:
                from .utils import MAX_ARG_LENGTH, MAX_ARGS_COUNT
                if len(v) > MAX_ARGS_COUNT:
                    raise ValueError(f"Too many args (max {MAX_ARGS_COUNT})")
                for arg in v:
                    if len(arg) > MAX_ARG_LENGTH:
                        raise ValueError(f"Arg too long (max {MAX_ARG_LENGTH} chars)")
            return v
    
        @field_validator('env')
        @classmethod
        def validate_env(cls, v: dict[str, str] | None) -> dict[str, str] | None:
            """Validate env map constraints."""
            if v is not None:
                from .utils import MAX_ENV_ENTRIES, MAX_ENV_KEY_LENGTH, MAX_ENV_VALUE_LENGTH
                if len(v) > MAX_ENV_ENTRIES:
                    raise ValueError(f"Too many env vars (max {MAX_ENV_ENTRIES})")
                for key, val in v.items():
                    if len(key) > MAX_ENV_KEY_LENGTH:
                        raise ValueError(f"Env key too long (max {MAX_ENV_KEY_LENGTH} chars)")
                    if len(val) > MAX_ENV_VALUE_LENGTH:
                        raise ValueError(f"Env value too long (max {MAX_ENV_VALUE_LENGTH} chars)")
            return v
  • Core implementation in SessionManager.create_session: validates paths, creates DebugSession instance, generates UUID sessionId, stores in sessions dict.
    def create_session(self, request: StartSessionRequest) -> StartSessionResponse:
        """
        Create a new debug session.
    
        Args:
            request: Session creation request
    
        Returns:
            Response with new session ID
    
        Raises:
            ValueError: If entry path is invalid
            FileNotFoundError: If entry script doesn't exist
        """
        # Validate and resolve entry path
        entry_path = resolve_workspace_path(self.workspace_root, request.entry)
        if not entry_path.exists():
            raise FileNotFoundError(f"Entry script not found: {request.entry}")
    
        if not entry_path.is_file():
            raise ValueError(f"Entry path is not a file: {request.entry}")
    
        if entry_path.suffix != ".py":
            raise ValueError(f"Entry must be a Python file (.py): {request.entry}")
    
        # Determine workspace root for this session
        # If entry is absolute path, find the workspace root from the entry path
        session_workspace = self._find_workspace_root(entry_path)
    
        # Validate Python path (required)
        python_path = Path(request.pythonPath)
        if not python_path.exists():
            raise FileNotFoundError(f"Python interpreter not found: {request.pythonPath}")
        if not python_path.is_file():
            raise ValueError(f"Python path is not a file: {request.pythonPath}")
    
        # Generate session ID
        session_id = str(uuid.uuid4())
    
        # Create session with DAP enabled by default
        use_dap = request.useDap if request.useDap is not None else True
    
        session = DebugSession(
            session_id=session_id,
            entry=entry_path,
            python_path=request.pythonPath,
            workspace_root=session_workspace,
            args=request.args or [],
            env=request.env or {},
            use_dap=use_dap,
        )
    
        self.sessions[session_id] = session
    
        return StartSessionResponse(sessionId=session_id)
  • DebugSession class: holds session state, status, timings, breakpoints; used by SessionManager for sessions_create.
    class DebugSession:
        """Represents an active debug session."""
    
        def __init__(
            self,
            session_id: str,
            entry: Path,
            python_path: str,
            workspace_root: Path,
            args: list[str] | None = None,
            env: dict[str, str] | None = None,
            use_dap: bool = True,
        ):
            self.id = session_id
            self.entry = entry
            self.workspace_root = workspace_root
            self.args = args or []
            self.env = env or {}
            self.python_path = python_path
            self.use_dap = use_dap
            self.status = SessionStatus.IDLE
            self.created_at = datetime.now()
            self.updated_at = datetime.now()
            self.last_breakpoint: BreakpointTarget | None = None
            self.timings = SessionTimings()
    
            # bdb mode (legacy)
            self.process: subprocess.Popen | None = None
            self.reader_task = None  # Background task for reading subprocess output
    
            # DAP mode (default)
            self.dap_wrapper = None  # Will be set if use_dap=True
    
        def update_status(self, status: SessionStatus) -> None:
            """Update session status and timestamp."""
            self.status = status
            self.updated_at = datetime.now()
    
        def update_breakpoint(self, file: str, line: int) -> None:
            """Update last breakpoint information."""
            if self.last_breakpoint and self.last_breakpoint.file == file and self.last_breakpoint.line == line:
                self.last_breakpoint.hitCount += 1
            else:
                self.last_breakpoint = BreakpointTarget(file=file, line=line, hitCount=1)
            self.updated_at = datetime.now()
    
        def update_timings(self, last_run_ms: float) -> None:
            """Update timing information."""
            self.timings.lastRunMs = last_run_ms
            self.timings.totalCpuTimeMs += last_run_ms
            self.updated_at = datetime.now()
    
        def to_state_response(self) -> SessionStateResponse:
            """Convert to state response model."""
            return SessionStateResponse(
                status=self.status,
                lastBreakpoint=self.last_breakpoint,
                timings=self.timings,
            )
Behavior2/5

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

With no annotations provided, the description carries full burden for behavioral disclosure. It states the action ('Create') but doesn't describe what happens after creation, whether the session starts automatically, what permissions are needed, or any side effects. This leaves significant gaps for a creation tool.

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 a single, efficient sentence that directly states the tool's purpose without any wasted words. It's appropriately sized and front-loaded with the core functionality.

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

Completeness2/5

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

For a creation tool with no annotations and no output schema, the description is insufficient. It doesn't explain what a 'debug session' entails, what gets returned, or any behavioral context beyond the basic creation action, leaving important gaps in understanding.

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 description coverage is 100%, so the schema already documents all 4 parameters thoroughly. The description doesn't add any additional meaning about parameters beyond what's in the schema, which meets the baseline expectation when schema coverage is high.

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 specific action ('Create a new debug session') and the target resource ('for a Python script'), distinguishing it from sibling tools like sessions_breakpoint or sessions_end which operate on existing sessions rather than creating new ones.

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. While the description implies this is for initial session creation, it doesn't specify prerequisites, timing considerations, or contrast with other session management tools in the sibling list.

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

Install Server

Other Tools

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/Kaina3/Debug-MCP'

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