The Model Context Protocol (MCP) enables Agents to interact with external systems through a standardized interface. You can connect your Agents to any MCP server, using Agno’s MCP integration.

Usage

1

Find the MCP server you want to use

You can use any working MCP server. To see some examples, you can check this GitHub repository, by the maintainers of the MCP themselves.

2

Initialize the MCP integration

Intialize the MCPTools class as a context manager. The recommended way to define the MCP server, is to use the command parameter and pass the command you would use to start the MCP server.

For example, to use the “mcp-server-git” server, you can do the following:

from agno.tools.mcp import MCPTools

async with MCPTools(command=f"uvx mcp-server-git") as mcp_tools:
    ...
3

Provide the MCPTools to the Agent

When initializing the Agent, pass the MCPTools class in the tools parameter.

The agent will now be ready to use the MCP server:

from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.tools.mcp import MCPTools

async with MCPTools(command=f"uvx mcp-server-git") as mcp_tools:
    agent = Agent(model=OpenAIChat(id="gpt-4o"), tools=[mcp_tools])

    # Run the agent
    await agent.aprint_response("What is the license for this project?", stream=True)

Example: Filesystem Agent

Here’s a filesystem agent that uses the Filesystem MCP server to explore and analyze files:

filesystem_agent.py
import asyncio
from pathlib import Path
from textwrap import dedent

from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.tools.mcp import MCPTools
from mcp import StdioServerParameters


async def run_agent(message: str) -> None:
    """Run the filesystem agent with the given message."""

    file_path = str(Path(__file__).parent.parent.parent.parent)

    # MCP server to access the filesystem (via `npx`)
    async with MCPTools(f"npx -y @modelcontextprotocol/server-filesystem {file_path}") as mcp_tools:
        agent = Agent(
            model=OpenAIChat(id="gpt-4o"),
            tools=[mcp_tools],
            instructions=dedent("""\
                You are a filesystem assistant. Help users explore files and directories.

                - Navigate the filesystem to answer questions
                - Use the list_allowed_directories tool to find directories that you can access
                - Provide clear context about files you examine
                - Use headings to organize your responses
                - Be concise and focus on relevant information\
            """),
            markdown=True,
            show_tool_calls=True,
        )

        # Run the agent
        await agent.aprint_response(message, stream=True)


# Example usage
if __name__ == "__main__":
    # Basic example - exploring project license
    asyncio.run(run_agent("What is the license for this project?"))

StdIO vs SSE Transport

By default Agno’s MCP integration uses the stdio transport.

But you can also connect your Agents to MCP servers using the SSE transport:

For example, here we set up a simple local server and connect to it using the SSE transport:

1

Setup the server

sse_server.py
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("calendar_assistant")


@mcp.tool()
def get_events(day: str) -> str:
    return f"There are no events scheduled for {day}."


@mcp.tool()
def get_birthdays_this_week() -> str:
    return "It is your mom's birthday tomorrow"


if __name__ == "__main__":
    mcp.run(transport="sse")
2

Setup the client

sse_client.py
import asyncio

from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.tools.mcp import MCPTools, MultiMCPTools

# This is the URL of the MCP server we want to use.
server_url = "http://localhost:8000/sse"


async def run_agent(message: str) -> None:
    async with MCPTools(transport="sse", url=server_url) as mcp_tools:
        agent = Agent(
            model=OpenAIChat(id="gpt-4o"),
            tools=[mcp_tools],
            markdown=True,
        )
        await agent.aprint_response(message=message, stream=True, markdown=True)


# Using MultiMCPTools, we can connect to multiple MCP servers at once, even if they use different transports.
# In this example we connect to both our example server (SSE transport), and a different server (stdio transport).
async def run_agent_with_multimcp(message: str) -> None:
    async with MultiMCPTools(
        commands=["npx -y @openbnb/mcp-server-airbnb --ignore-robots-txt"],
        urls=[server_url],
    ) as mcp_tools:
        agent = Agent(
            model=OpenAIChat(id="gpt-4o"),
            tools=[mcp_tools],
            markdown=True,
        )
        await agent.aprint_response(message=message, stream=True, markdown=True)


if __name__ == "__main__":
    asyncio.run(run_agent("Do I have any birthdays this week?"))
    asyncio.run(
        run_agent_with_multimcp(
            "Can you check when is my mom's birthday, and if there are any AirBnb listings in SF for two people for that day?"
        )
    )
3

Run the server

python sse_server.py
4

Run the client

python sse_client.py

Understanding Server Parameters

The recommended way to configure MCPTools or MultiMCPTools is to use the command or url parameters.

Alternatively, you can use the server_params parameter with MCPTools to configure the connection to the MCP server.

In the case of the StdIO transport, the server_params parameter should be an instance of StdioServerParameters. It contains the following keys:

  • command: The command to run the MCP server.
    • Use npx for mcp servers that can be installed via npm (or node if running on Windows).
    • Use uvx for mcp servers that can be installed via uvx.
  • args: The arguments to pass to the MCP server.
  • env: Optional environment variables to pass to the MCP server. Remember to include all current environment variables in the env dictionary. If env is not provided, the current environment variables will be used. e.g.
{
    **os.environ,
    "GOOGLE_MAPS_API_KEY": os.getenv("GOOGLE_MAPS_API_KEY"),
}

In the case of the SSE transport, the server_params parameter should be an instance of SSEClientParams. It contains the following fields:

  • url: The URL of the MCP server.
  • headers: Headers to pass to the MCP server (optional).
  • timeout: Timeout for the connection to the MCP server (optional).
  • sse_read_timeout: Timeout for the SSE connection itself (optional).

Multiple MCP Servers

You can use multiple MCP servers in a single agent by using the MultiMCPTools class.

multiple_mcp_servers.py
import asyncio
import os

from agno.agent import Agent
from agno.tools.mcp import MultiMCPTools


async def run_agent(message: str) -> None:
    """Run the Airbnb and Google Maps agent with the given message."""

    env = {
        **os.environ,
        "GOOGLE_MAPS_API_KEY": os.getenv("GOOGLE_MAPS_API_KEY"),
    }

    async with MultiMCPTools(
        [
            "npx -y @openbnb/mcp-server-airbnb --ignore-robots-txt",
            "npx -y @modelcontextprotocol/server-google-maps",
        ],
        env=env,
    ) as mcp_tools:
        agent = Agent(
            tools=[mcp_tools],
            markdown=True,
            show_tool_calls=True,
        )

        await agent.aprint_response(message, stream=True)


# Example usage
if __name__ == "__main__":
    # Pull request example
    asyncio.run(
        run_agent(
            "What listings are available in Cape Town for 2 people for 3 nights from 1 to 4 August 2025?"
        )
    )

More Flexibility

You can also create the MCP server yourself and pass it to the MCPTools constructor.

filesystem_agent.py
import asyncio
from pathlib import Path
from textwrap import dedent

from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.tools.mcp import MCPTools
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client


async def create_filesystem_agent(session):
    """Create and configure a filesystem agent with MCP tools."""
    # Initialize the MCP toolkit
    mcp_tools = MCPTools(session=session)
    await mcp_tools.initialize()

    # Create an agent with the MCP toolkit
    return Agent(
        model=OpenAIChat(id="gpt-4o"),
        tools=[mcp_tools],
        instructions=dedent("""\
            You are a filesystem assistant. Help users explore files and directories.

            - Navigate the filesystem to answer questions
            - Use the list_allowed_directories tool to find directories that you can access
            - Provide clear context about files you examine
            - Use headings to organize your responses
            - Be concise and focus on relevant information\
        """),
        markdown=True,
        show_tool_calls=True,
    )


async def run_agent(message: str) -> None:
    """Run the filesystem agent with the given message."""

    # Initialize the MCP server
    server_params = StdioServerParameters(
        command="npx",
        args=[
            "-y",
            "@modelcontextprotocol/server-filesystem",
            str(Path(__file__).parent.parent.parent.parent),  # Set this to the root of the project you want to explore
        ],
    )

    # Create a client session to connect to the MCP server
    async with stdio_client(server_params) as (read, write):
        async with ClientSession(read, write) as session:
            agent = await create_filesystem_agent(session)

            # Run the agent
            await agent.aprint_response(message, stream=True)


# Example usage
if __name__ == "__main__":
    # Basic example - exploring project license
    asyncio.run(run_agent("What is the license for this project?"))

Running MCP in Playground

You can also run MCP servers in the Agno Playground, which provides a web interface for interacting with your agents. Here’s an example of a GitHub agent running in the Playground:

github_playground.py
import asyncio
from os import getenv
from textwrap import dedent

import nest_asyncio
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from agno.playground import Playground, serve_playground_app
from agno.storage.agent.sqlite import SqliteAgentStorage
from agno.tools.mcp import MCPTools

# Allow nested event loops
nest_asyncio.apply()

agent_storage_file: str = "tmp/agents.db"


async def run_server() -> None:
    """Run the GitHub agent server."""
    github_token = getenv("GITHUB_TOKEN") or getenv("GITHUB_ACCESS_TOKEN")
    if not github_token:
        raise ValueError("GITHUB_TOKEN environment variable is required")

    # Create a client session to connect to the MCP server
    async with MCPTools("npx -y @modelcontextprotocol/server-github") as mcp_tools:
        agent = Agent(
            name="MCP GitHub Agent",
            tools=[mcp_tools],
            instructions=dedent("""\
                You are a GitHub assistant. Help users explore repositories and their activity.

                - Use headings to organize your responses
                - Be concise and focus on relevant information\
            """),
            model=OpenAIChat(id="gpt-4o"),
            storage=SqliteAgentStorage(
                table_name="basic_agent",
                db_file=agent_storage_file,
                auto_upgrade_schema=True,
            ),
            add_history_to_messages=True,
            num_history_responses=3,
            add_datetime_to_instructions=True,
            markdown=True,
        )

        playground = Playground(agents=[agent])
        app = playground.get_app()

        # Serve the app while keeping the MCPTools context manager alive
        serve_playground_app(app)


if __name__ == "__main__":
    asyncio.run(run_server())

Best Practices

  1. Error Handling: Always include proper error handling for MCP server connections and operations.

  2. Resource Cleanup: Use MCPTools or MultiMCPTools as an async context manager to ensure proper cleanup of resources:

async with MCPTools(command) as mcp_tools:
    # Your agent code here
  1. Clear Instructions: Provide clear and specific instructions to your agent:
instructions = """
You are a filesystem assistant. Help users explore files and directories.
- Navigate the filesystem to answer questions
- Use the list_allowed_directories tool to find accessible directories
- Provide clear context about files you examine
- Be concise and focus on relevant information
"""

More Information

  • Find a collection of MCP servers here.
  • Read the MCP documentation to learn more about the Model Context Protocol.
  • Checkout the Agno Cookbook for more examples of Agents that use MCP.