Skip to main content

MCPAPIRouter

MCPAPIRouter provides a FastAPI-like decorator API for registering MCP tools, prompts, and resources. It handles JSON-RPC protocol communication and automatic schema generation.

Class Definition

from agentor.mcp.api_router import MCPAPIRouter

class MCPAPIRouter
Inspired by FastMCP from the official MCP Python SDK.

Constructor

router = MCPAPIRouter(
    prefix="/mcp",
    name="agentor-mcp-server",
    version="0.1.0",
    instructions=None,
    website_url=None,
    icons=None,
    dependencies=None,
)
prefix
str
default:"/mcp"
URL prefix for MCP endpoints
name
str
default:"agentor-mcp-server"
Server name returned in MCP initialize response
version
str
default:"0.1.0"
Server version
instructions
str
Instructions for using the server, sent to clients during initialization
website_url
str
Server website URL
icons
List[Icon]
Server icons (from mcp.types.Icon)
dependencies
List[Callable]
FastAPI dependencies to apply to all MCP endpoints

Decorators

@tool()

Register a tool that can be called by MCP clients.
@router.tool(
    name=None,
    description=None,
    input_schema=None,
)
def tool_function(param1: str, param2: int) -> str:
    """Tool description from docstring"""
    return "result"
name
str
Tool name. Defaults to function name.
description
str
Tool description shown to LLMs. Defaults to function docstring.
input_schema
dict
JSON schema for tool parameters. Auto-generated from function signature if not provided.

Example: Basic Tool

@app.tool(description="Get weather for a location")
def get_weather(location: str) -> str:
    """Get current weather for a location"""
    return f"Weather in {location}: Sunny, 72°F"

Example: Tool with Dependencies

from fastapi import Depends
from agentor.mcp.api_router import Context, get_context

@app.tool()
def authenticated_tool(
    location: str,
    ctx: Context = Depends(get_context)
) -> str:
    """Tool that accesses request context"""
    user_agent = ctx.headers.get("user-agent")
    session_id = ctx.cookies.get("session_id")
    return f"Processing {location} for session {session_id}"

Example: Async Tool

@app.tool()
async def fetch_data(url: str) -> str:
    """Asynchronously fetch data from URL"""
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            return await response.text()

@prompt()

Register a prompt template that can be retrieved by MCP clients.
@router.prompt(
    name=None,
    description=None,
    arguments=None,
)
def prompt_function(param1: str, param2: str = "default") -> str:
    """Prompt description"""
    return "prompt text"
name
str
Prompt name. Defaults to function name.
description
str
Prompt description. Defaults to function docstring.
arguments
List[dict]
List of argument definitions. Auto-generated from function signature if not provided.Each argument dict should have:
  • name (str): Argument name
  • description (str): Argument description
  • required (bool): Whether the argument is required

Example: Basic Prompt

@app.prompt(description="Generate a greeting")
def greeting(name: str, style: str = "formal") -> str:
    """Generate a personalized greeting"""
    if style == "formal":
        return f"Good day, {name}. How may I assist you today?"
    else:
        return f"Hey {name}! What's up?"

Example: Prompt with Message Structure

@app.prompt()
def code_review(code: str, language: str) -> list:
    """Generate a code review prompt"""
    return [
        {
            "role": "user",
            "content": {
                "type": "text",
                "text": f"Review this {language} code:\n\n{code}"
            }
        }
    ]

@resource()

Register a resource that can be read by MCP clients.
@router.resource(
    uri="resource://path",
    name=None,
    description=None,
    mime_type=None,
)
def resource_function(uri: str) -> str:
    """Resource description"""
    return "resource content"
uri
str
required
Resource URI identifier. Used by clients to request the resource.
name
str
Resource display name. Defaults to URI.
description
str
Resource description. Defaults to function docstring.
mime_type
str
MIME type of resource content (e.g., “application/json”, “text/plain”)

Example: Basic Resource

@app.resource(
    uri="config://settings",
    name="Settings",
    mime_type="application/json"
)
def get_settings(uri: str) -> str:
    """Get application settings"""
    return '{"theme": "dark", "language": "en"}'

Example: Dynamic Resource

@app.resource(
    uri="file://data",
    name="Data File",
    mime_type="text/plain"
)
def get_file_data(uri: str) -> dict:
    """Get file data with metadata"""
    return {
        "uri": uri,
        "mimeType": "text/plain",
        "text": "File content here"
    }

@method()

Register a custom MCP JSON-RPC method handler.
@router.method("custom/method")
async def custom_handler(body: dict):
    """Handle custom MCP method"""
    params = body.get("params", {})
    return {"result": "custom response"}
method_name
str
required
JSON-RPC method name to handle

Context and Dependencies

Context

Access request-level data in tool functions.
from agentor.mcp.api_router import Context, get_context
from fastapi import Depends

@app.tool()
def my_tool(location: str, ctx: Context = Depends(get_context)) -> str:
    user_agent = ctx.headers.get("user-agent")
    session_id = ctx.cookies.get("session_id")
    return f"Processing {location}"
headers
Dict[str, str]
HTTP headers from the request
cookies
Dict[str, str]
Cookies from the request

get_context()

Dependency function to retrieve the current request context.
def get_context() -> Context
Returns a Context object with headers and cookies. Returns empty context if called outside a request.

get_headers()

Get HTTP headers from the current request.
def get_headers() -> Dict[str, str]

get_cookies()

Get cookies from the current request.
def get_cookies() -> Dict[str, str]

get_token()

Extract bearer token from Authorization header.
def get_token() -> str
Returns the token without the “Bearer ” prefix, or None if no token is found.

Methods

get_fastapi_router()

Get the underlying FastAPI router instance.
fastapi_router = router.get_fastapi_router()
Returns an APIRouter instance that can be included in FastAPI applications.

Complete Example

from agentor.mcp.api_router import MCPAPIRouter, Context, get_context
from fastapi import Depends, FastAPI

# Create router
router = MCPAPIRouter(
    prefix="/mcp",
    name="example-server",
    version="1.0.0",
    instructions="Example MCP server with tools, prompts, and resources",
)

# Register tool
@router.tool(description="Calculate sum of two numbers")
def add(a: int, b: int) -> int:
    """Add two numbers together"""
    return a + b

# Register tool with context
@router.tool()
def user_info(ctx: Context = Depends(get_context)) -> str:
    """Get user agent from request"""
    return ctx.headers.get("user-agent", "unknown")

# Register prompt
@router.prompt(description="Code review template")
def review_prompt(language: str, code: str) -> str:
    """Generate code review prompt"""
    return f"Review this {language} code:\n\n{code}"

# Register resource
@router.resource(
    uri="docs://readme",
    name="README",
    mime_type="text/markdown"
)
def readme(uri: str) -> str:
    """Get README content"""
    return "# Example Server\n\nThis is an example MCP server."

# Use with FastAPI
app = FastAPI()
app.include_router(router.get_fastapi_router())

See Also

Last modified on March 4, 2026