Skip to main content
MCP connections in PraisonAI Agents support context managers and explicit shutdown() so subprocesses, streams, and sockets close reliably.
from praisonaiagents import Agent, MCP

with MCP("uvx mcp-server-time") as mcp:
    agent = Agent(name="TimeAgent", instructions="Report the current time.", tools=mcp)
    agent.start("What time is it in UTC?")
The user runs an agent inside an MCP context manager; connections shut down cleanly when the session ends.

Quick Start

1

Simple Usage

from praisonaiagents import Agent, MCP

with MCP("uvx mcp-server-time") as mcp:
    agent = Agent(
        name="TimeAgent",
        instructions="Get the current time",
        tools=mcp
    )
    print(agent.start("What time is it?"))
# Connection closed automatically
2

With Configuration

import os
from praisonaiagents import Agent, MCP

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

How It Works

PhaseWhat happens
1. EnterThe with block opens the MCP connection
2. UseThe agent calls MCP-provided tools
3. Exitshutdown() closes subprocesses, streams, and sockets

Manual Cleanup

For cases where a context manager is not suitable:
from praisonaiagents import MCP

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

try:
    tools = mcp.get_tools()
finally:
    mcp.shutdown()

Lifecycle Methods

Authenticating the HTTP transport

When api_key is configured on the MCP HTTP-stream server, all of GET, POST, and DELETE require:
Authorization: Bearer <key>
Comparison uses constant-time hmac.compare_digest (timing-attack resistant). Missing or wrong tokens return 401 Unauthorized with {"error": "Unauthorized"}. DELETE returning 401 instead of 405 prevents information disclosure about whether sessions exist.
curl -H "Authorization: Bearer ${MCP_API_KEY:?Set MCP_API_KEY}" https://localhost:8080/mcp

__enter__ / __exit__

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

shutdown()

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

__del__

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

Connection Types

MCP supports multiple connection types, all with proper cleanup:
# Stdio
with MCP("uvx mcp-server-time") as mcp: ...

# SSE
with MCP("http://localhost:8080/sse") as mcp: ...

# HTTP Stream
with MCP("http://localhost:8080") as mcp: ...

# WebSocket
with MCP("ws://localhost:8080") as mcp: ...

Best Practices

Prefer with MCP(...) as mcp: — cleanup runs even when an exception is raised.
Wrap tool calls in try/except inside the with block; __exit__ still closes the connection.
Open each MCP in its own with block or nest them — both instances shut down in reverse order.
Use the env= parameter with os.getenv(...) rather than hard-coding API keys in recipe files.

MCP CLI

Run and inspect MCP servers from the terminal

MCP Transports

Stdio, SSE, HTTP stream, and WebSocket options