FastMCP

Installation

Scout APM provides automatic instrumentation for FastMCP servers to track tool executions, performance metrics, and errors. FastMCP is a Python framework for building Model Context Protocol (MCP) servers that expose tools, resources, and prompts to LLM clients.

The latest scout-apm package supports FastMCP 2.9.0+.

AInstall the scout-apm package and FastMCP:

pip install scout-apm fastmcp>=2.9.0

BConfigure Scout and install instrumentation in your FastMCP server:

from fastmcp import FastMCP
from scout_apm.api import Config
from scout_apm.fastmcp import ScoutMiddleware

Config.set(
    key="[AVAILABLE IN THE SCOUT UI]",
    name="A FRIENDLY NAME FOR YOUR APP",
    monitor=True,
)

# Create your FastMCP server
mcp = FastMCP(name="MyServer")

# Add Scout APM middleware
mcp.add_middleware(ScoutMiddleware())

# Define your tools
@mcp.tool
def my_tool(arg: str) -> str:
    """My tool description."""
    return f"Processed: {arg}"

If you wish to configure Scout via environment variables, use SCOUT_MONITOR, SCOUT_NAME, and SCOUT_KEY and remove the call to Config.set.

Heroku Customers: If you've installed Scout via the Heroku Addon, the provisioning process automatically sets SCOUT_MONITOR and SCOUT_KEY via config vars. Only SCOUT_NAME is additionally required.

CDeploy.

It takes approximately five minutes for your data to first appear within the Scout UI.

What Scout Tracks

Scout automatically captures the following information from your FastMCP tools:

Operation Naming

Tool executions appear in Scout APM with the operation name format: Controller/{tool_name}.

For example:

Tool Metadata

Scout APM automatically captures metadata from your tool definitions:

@mcp.tool(
    name="search_products",
    description="Search the product catalog",
    tags={"catalog", "search", "products"},
    annotations={
        "readOnlyHint": True,      # Tool doesn't modify data
        "idempotentHint": True,    # Safe to retry
        "openWorldHint": True,     # Interacts with external systems
        "destructiveHint": False,  # Non-destructive
    },
    meta={
        "version": "2.0",
        "author": "product-team",
    }
)
def search_products(query: str, limit: int = 10) -> list:
    """Search for products matching the query."""
    # Implementation...

This metadata is captured as Scout APM tags for filtering and analysis.