|  | 
|  | 1 | +For gpt expected container tool, here's an incomplete example | 
|  | 2 | +Note that the SweRexManager or swe_rex are dummies, you need to implement your own container tool with session management | 
|  | 3 | +``` | 
|  | 4 | +from mcp.server.fastmcp import fastmcp | 
|  | 5 | +# dummy showing how to import container tool | 
|  | 6 | +from swe_rex import SweRexManager | 
|  | 7 | +
 | 
|  | 8 | +# Pass lifespan to server | 
|  | 9 | +mcp = FastMCP( | 
|  | 10 | +    name="container", | 
|  | 11 | +    instructions=r""" | 
|  | 12 | +Utilities for interacting with a container, for example, a Docker container.\n | 
|  | 13 | +(container_tool, version 1.X.X)\n | 
|  | 14 | +(lean_terminal, version 1.X.X) | 
|  | 15 | +""".strip(), | 
|  | 16 | +) | 
|  | 17 | +
 | 
|  | 18 | +swe_rex_manager = SweRexManager() | 
|  | 19 | +
 | 
|  | 20 | +def _get_session_id(ctx: Context) -> str: | 
|  | 21 | +    """Extract session ID from headers, URL query parameter or fallback to client_id""" | 
|  | 22 | +    request = ctx.request_context.request | 
|  | 23 | +    return request.headers.get("session_id") or request.query_params.get( | 
|  | 24 | +        "session_id" | 
|  | 25 | +    ) or ctx.client_id | 
|  | 26 | +
 | 
|  | 27 | +@mcp.tool( | 
|  | 28 | +    name="exec", | 
|  | 29 | +    title="container exec", | 
|  | 30 | +    description=""" | 
|  | 31 | +Returns the output of the command. | 
|  | 32 | +Allocates an interactive pseudo-TTY if (and only if) 'session_name' is set. | 
|  | 33 | +    """, | 
|  | 34 | +    ) | 
|  | 35 | +async def exec( | 
|  | 36 | +    ctx: Context, | 
|  | 37 | +    cmd: list[str], | 
|  | 38 | +    session_name: Optional[str] = None, | 
|  | 39 | +    workdir: Optional[str] = None, | 
|  | 40 | +    timeout: Optional[int] = None, | 
|  | 41 | +    env: Optional[dict[str, str]] = None, | 
|  | 42 | +    user: Optional[str] = None, | 
|  | 43 | +) -> str: | 
|  | 44 | +    session_id = _get_session_id(ctx) | 
|  | 45 | +    try: | 
|  | 46 | +        logger.debug(f"cmd for container exec: {cmd}") | 
|  | 47 | +
 | 
|  | 48 | +        res = await swe_rex_manager.execute_in_session( | 
|  | 49 | +            session_id, | 
|  | 50 | +            cmd=cmd, | 
|  | 51 | +            workdir=workdir, | 
|  | 52 | +            env=env, | 
|  | 53 | +            execution_timeout=360 if timeout is None else timeout, | 
|  | 54 | +            # Below fields are not used right now | 
|  | 55 | +            session_name=session_name, # This could be overriding session_id | 
|  | 56 | +            user=user, | 
|  | 57 | +        ) | 
|  | 58 | +        logger.info(f"container execution result: {res}") | 
|  | 59 | +        return res | 
|  | 60 | +
 | 
|  | 61 | +@mcp.tool( | 
|  | 62 | +    name="cleanup_session", | 
|  | 63 | +    title="clean container session", | 
|  | 64 | +    description="cleanup a specific session", | 
|  | 65 | +    annotations={ | 
|  | 66 | +        "include_in_prompt": False, | 
|  | 67 | +    }) | 
|  | 68 | +async def cleanup_session(ctx: Context) -> None: | 
|  | 69 | +    """Cleanup a specific session""" | 
|  | 70 | +    session_id = _get_session_id(ctx) | 
|  | 71 | +    logger.info(f"Cleaning up session: {session_id}") | 
|  | 72 | +    await swe_rex_manager.cleanup_session(session_id) | 
|  | 73 | +``` | 
0 commit comments