Skip to main content
The Model Context Protocol (MCP) is an open standard for sharing tools between AI systems. AFK supports both exposing your tools via an MCP server and consuming tools from external MCP servers.

Architecture

Expose tools via MCP server

Make your AFK tools available to any MCP-compatible client:
1

Define your tools

from pydantic import BaseModel
from afk.tools import tool

class SearchArgs(BaseModel):
    query: str
    limit: int = 10

@tool(args_model=SearchArgs, name="search_docs", description="Search the documentation.")
def search_docs(args: SearchArgs) -> dict:
    return {"results": ["doc1", "doc2"]}

class CalcArgs(BaseModel):
    expression: str

@tool(args_model=CalcArgs, name="calculate", description="Evaluate a math expression.")
def calculate(args: CalcArgs) -> dict:
    return {"result": eval(args.expression)}
2

Create the MCP server

from afk.mcp import MCPServer

server = MCPServer(
    name="my-tools",
    tools=[search_docs, calculate],
    host="0.0.0.0",
    port=3001,
)
3

Start serving

await server.start()
# Server is now accepting MCP connections on port 3001

Consume tools from external MCP servers

Discover and use tools from any MCP server:
1

Connect to an MCP server

from afk.mcp import MCPStore

store = MCPStore()
await store.connect("https://tools.example.com:3001")
2

Discover available tools

tools = await store.list_tools()
for t in tools:
    print(f"{t.name}: {t.description}")
3

Attach to an agent

from afk.agents import Agent

agent = Agent(
    name="assistant",
    model="gpt-5.2-mini",
    instructions="Use available tools to help the user.",
    tools=tools,  # ← MCP tools work like local tools
)
MCP tools are transparent. Once attached to an agent, MCP tools behave exactly like local tools — same validation, same policy gates, same telemetry. The agent doesn’t know (or care) whether a tool is local or remote.

Security

Require auth tokens for all MCP connections:
server = MCPServer(
    name="my-tools",
    tools=[search_docs],
    auth_provider=TokenAuthProvider(
        valid_tokens={"client-a": "token-abc"},
    ),
)
Configure allowed origins for browser-based clients:
server = MCPServer(
    name="my-tools",
    tools=[search_docs],
    cors_origins=["https://app.example.com"],
)
Apply policy rules to MCP-exposed tools:
from afk.agents import PolicyEngine, PolicyRule

policy = PolicyEngine(rules=[
    PolicyRule(
        rule_id="gate-mutations",
        condition=lambda e: not e.tool_read_only,
        action="deny",
        reason="MCP clients cannot call mutating tools",
    ),
])

server = MCPServer(
    name="my-tools",
    tools=[search_docs, calculate],
    policy_engine=policy,
)
Limit request rates per client:
server = MCPServer(
    name="my-tools",
    tools=[search_docs],
    rate_limit={"requests_per_minute": 60, "per_client": True},
)
Always authenticate MCP servers in production. An unauthenticated server exposes your tools to anyone who can reach the endpoint.

MCP server vs A2A

FeatureMCP ServerA2A
SharesIndividual toolsFull agents
ProtocolMCP standardAFK A2A protocol
Use caseTool sharing between systemsAgent-to-agent communication
Client seesTool schemas and resultsAgent responses
InteropAny MCP clientAFK agents

Next steps