Agently Docs

Agently documentation for building AI applications with stable outputs, observable actions, and durable workflows.

View the Project on GitHub AgentEra/Agently

MCP

Languages: English · 中文

MCP (Model Context Protocol) exposes external tools to AI agents. Agently wires MCP servers into the action runtime via MCPActionExecutor so the model sees MCP tools and your own @agent.action_func actions through the same interface.

Use URL / Streamable HTTP MCP endpoints for service integrations, and stdio command configs for local development, desktop clients, or single-user local servers. SSE endpoints remain a legacy compatibility path.

Minimal example

import os
import asyncio
from dotenv import load_dotenv, find_dotenv
from agently import Agently

load_dotenv(find_dotenv())

Agently.set_settings("OpenAICompatible", {
    "base_url": "${ENV.OPENAI_BASE_URL}",
    "api_key": "${ENV.OPENAI_API_KEY}",
    "model": "${ENV.OPENAI_MODEL}",
})

agent = Agently.create_agent()


async def main():
    result = (
        await agent.use_mcp(f"https://mcp.amap.com/mcp?key={os.environ.get('AMAP_API_KEY')}")
        .input("What's the weather like in Shanghai today?")
        .async_start()
    )
    print(result)


asyncio.run(main())

use_mcp(url) registers all tools the MCP server exposes. The agent then plans tool calls against the union of {@agent.action_func, use_tool, use_mcp tools} as if they were one set.

API

Method Behavior
await agent.use_mcp(url) connect to the server, list tools, register them; returns the agent for chaining
await agent.use_mcp(url, headers={...}) with custom HTTP headers (auth tokens, etc.)
await agent.use_mcp({"mcpServers": {...}}) use an MCP config with one or more HTTP or stdio servers

For the default executor, headers= with a URL is normalized to an MCP config before FastMCP sees it.

await agent.use_mcp(
    "https://example.com/mcp",
    headers={"Authorization": f"Bearer {token}"},
)

For local stdio servers, pass MCP config directly:

await agent.use_mcp({
    "mcpServers": {
        "filesystem": {
            "command": "npx",
            "args": ["-y", "@modelcontextprotocol/server-filesystem", "./workspace"],
        }
    }
})

Mixing MCP with custom actions

@agent.action_func
async def lookup_internal(id: str):
    """Look up a record in the internal database."""
    ...


await agent.use_mcp("https://example-mcp/server")
agent.use_actions(lookup_internal)

# The model now sees MCP tools + lookup_internal in the same plan
result = await agent.input(question).async_start()

There’s no precedence between MCP-provided tools and locally-defined actions. The model picks based on names, descriptions, and the prompt context.

Inspecting what was called

After a request, see what tools the model actually invoked:

records = agent.get_action_result()
for r in records:
    print(r)

Action records are also written to extra.action_logs (or extra.tool_logs on the compat surface).

Common pitfalls

See also