Skip to main content

MCP Lifecycle Management

PraisonAI Agents v0.5.0+ includes improved lifecycle management for MCP (Model Context Protocol) connections with context manager support and explicit cleanup.

Context Manager Support

Use MCP as a context manager for automatic cleanup:
from praisonaiagents import Agent
from praisonaiagents.mcp import MCP

# Using context manager - automatic cleanup
with MCP("uvx mcp-server-time") as mcp:
    agent = Agent(
        name="TimeAgent",
        instructions="Get the current time",
        tools=mcp
    )
    response = agent.chat("What time is it?")
    print(response)
# MCP connection automatically closed here

Manual Cleanup

For cases where context manager isn’t suitable:
from praisonaiagents.mcp import MCP

mcp = MCP("uvx mcp-server-time")

try:
    # Use MCP
    tools = mcp.get_tools()
    # ... do work ...
finally:
    # Explicit cleanup
    mcp.shutdown()

Lifecycle Methods

__enter__ / __exit__

Context manager protocol for automatic resource management:
with MCP(command) as mcp:
    # MCP is initialized and ready
    pass
# __exit__ calls shutdown() automatically

shutdown()

Explicitly close all connections and cleanup resources:
mcp = MCP("uvx mcp-server-time")
# ... use mcp ...
mcp.shutdown()  # Clean up

__del__

Destructor ensures cleanup even if shutdown() wasn’t called:
mcp = MCP("uvx mcp-server-time")
del mcp  # __del__ calls shutdown()

Connection Types

MCP supports multiple connection types, all with proper cleanup:

Stdio (Command-based)

with MCP("uvx mcp-server-time") as mcp:
    # Subprocess is managed
    pass
# Process terminated on exit

SSE (Server-Sent Events)

with MCP("http://localhost:8080/sse") as mcp:
    # SSE connection managed
    pass
# Connection closed on exit

HTTP Stream

with MCP("http://localhost:8080") as mcp:
    # HTTP stream managed
    pass
# Stream closed on exit

WebSocket

with MCP("ws://localhost:8080") as mcp:
    # WebSocket managed
    pass
# WebSocket closed on exit

Best Practices

Always Use Context Manager

# Good - automatic cleanup
with MCP(command) as mcp:
    agent = Agent(tools=mcp)
    agent.chat("Hello")

# Avoid - manual cleanup required
mcp = MCP(command)
agent = Agent(tools=mcp)
agent.chat("Hello")
mcp.shutdown()  # Easy to forget

Handle Exceptions

from praisonaiagents.mcp import MCP

try:
    with MCP("uvx mcp-server-time") as mcp:
        # Work that might fail
        result = mcp.call_tool("get_time", {})
except Exception as e:
    print(f"Error: {e}")
# Cleanup happens even on exception

Multiple MCP Instances

with MCP("uvx mcp-server-time") as time_mcp:
    with MCP("uvx mcp-server-fetch") as fetch_mcp:
        agent = Agent(
            name="MultiMCP",
            tools=[time_mcp, fetch_mcp]
        )
        agent.chat("Get time and fetch a URL")
# Both cleaned up properly

Environment Variables

Pass environment variables to MCP servers:
import os

with MCP(
    command="npx",
    args=["-y", "@modelcontextprotocol/server-brave-search"],
    env={"BRAVE_API_KEY": os.environ.get("BRAVE_API_KEY")}
) as mcp:
    agent = Agent(tools=mcp)
    agent.chat("Search for Python tutorials")

Timeout Configuration

Set timeouts for MCP operations:
with MCP("uvx mcp-server-time", timeout=30) as mcp:
    # Operations timeout after 30 seconds
    result = mcp.call_tool("get_time", {})