Unofficial extension library for FastMCP 2.0 with patterns, practices, and utilities for building MCP servers.
- MCP Server Factory:
mcp_server()helper that creates FastMCP instances with built-in server info resources, MCP asset discovery (optional), and credential resolution. - MCP Annotation Constants: Standard annotation hints (
readOnlyHint,destructiveHint,idempotentHint,openWorldHint) following the FastMCP 2.2.7+ specification - Deferred Registration Decorators:
@mcp_tool,@mcp_prompt,@mcp_resourcedecorators for organizing tools by domain with automatic domain detection. - Registration Utilities: Functions to register tools, prompts, and resources with a FastMCP app, filtered by domain.
- Tool Testing Utilities: Helpers for testing MCP tools directly with JSON arguments (stdio and HTTP transports).
- Tool List Measurement: Utilities for measuring tool list size to track context truncation issues.
- Prompt Helpers: Generic
get_prompt_texthelper for agents that cannot access prompt assets directly.
pip install fastmcp-extensionsOr with uv:
uv add fastmcp-extensionsThe mcp_server function creates a FastMCP instance with built-in server info resources and optional credential resolution:
from fastmcp_extensions import mcp_server, MCPServerConfigArg
app = mcp_server(
name="my-mcp-server",
package_name="my-package",
advertised_properties={
"docs_url": "https://github.com/org/repo",
"release_history_url": "https://github.com/org/repo/releases",
},
server_config_args=[
MCPServerConfigArg(
name="api_key",
http_header_key="X-API-Key",
env_var="MY_API_KEY",
required=True,
sensitive=True,
),
],
)
# Server info resource is automatically registered at {name}://server/info
# Get credentials from HTTP headers or environment variables
from fastmcp_extensions import get_mcp_config
api_key = get_mcp_config(app, "api_key")from fastmcp_extensions import (
READ_ONLY_HINT,
DESTRUCTIVE_HINT,
IDEMPOTENT_HINT,
OPEN_WORLD_HINT,
)
# Use in tool annotations
annotations = {
READ_ONLY_HINT: True,
IDEMPOTENT_HINT: True,
}from fastmcp import FastMCP
from fastmcp_extensions import mcp_tool, mcp_resource, register_mcp_tools, register_mcp_resources
# Define tools with the decorator (domain auto-detected from filename)
@mcp_tool(read_only=True, idempotent=True)
def list_items() -> list[str]:
"""List all available items."""
return ["item1", "item2"]
@mcp_resource("myserver://version", "Server version", "application/json")
def get_version() -> dict:
"""Get server version info."""
return {"version": "1.0.0"}
# Register with FastMCP app
app = FastMCP("my-server")
register_mcp_tools(app)
register_mcp_resources(app)import asyncio
from fastmcp_extensions.measurement import measure_tool_list_detailed
async def check_tool_size():
measurement = await measure_tool_list_detailed(app, server_name="my-server")
print(measurement)
# Output:
# MCP Server: my-server
# Tool count: 10
# Total characters: 5,432
# Average chars per tool: 543
asyncio.run(check_tool_size())from fastmcp_extensions.testing import call_mcp_tool, run_tool_test
import asyncio
# Call a tool programmatically
result = asyncio.run(call_mcp_tool(app, "list_items", {}))
# Or use the CLI helper
run_tool_test(app, "list_items", '{}')from fastmcp_extensions.prompts import get_prompt_text
import asyncio
# Get prompt text for agents that can't access prompts directly
text = asyncio.run(get_prompt_text(app, "my_prompt", {"arg": "value"}))This library provides template scripts for common MCP development tasks. Copy these to your project and customize:
bin/test_mcp_tool.py- Test tools with JSON arguments via stdiobin/test_mcp_tool_http.py- Test tools over HTTP transportbin/measure_mcp_tool_list.py- Measure tool list size
Add to your poe_tasks.toml:
[tool.poe.tasks.mcp-tool-test]
help = "Test MCP tools directly with JSON arguments"
cmd = "python bin/test_mcp_tool.py"
[tool.poe.tasks.mcp-tool-test-http]
help = "Test MCP tools over HTTP transport"
cmd = "python bin/test_mcp_tool_http.py"
[tool.poe.tasks.mcp-measure-tools]
help = "Measure the size of the MCP tool list output"
cmd = "python bin/measure_mcp_tool_list.py"mcp_server- Create a FastMCP instance with built-in server info resource and auto-registration of decorated tools and assets.MCPServerConfigArg- Configuration for credential resolution and other server settings.get_mcp_config- Get a credential from HTTP headers or environment variables.
| Constant | Description | FastMCP Default |
|---|---|---|
READ_ONLY_HINT |
Tool only reads data | False |
DESTRUCTIVE_HINT |
Tool modifies/deletes data | True |
IDEMPOTENT_HINT |
Repeated calls have same effect | False |
OPEN_WORLD_HINT |
Tool interacts with external systems | True |
@mcp_tool(domain, read_only, destructive, idempotent, open_world, extra_help_text)- Tag a tool for deferred registration@mcp_prompt(name, description, domain)- Tag a prompt for deferred registration@mcp_resource(uri, description, mime_type, domain)- Tag a resource for deferred registration
register_mcp_tools(app, domain, exclude_args)- Register tools with FastMCP appregister_mcp_prompts(app, domain)- Register prompts with FastMCP appregister_mcp_resources(app, domain)- Register resources with FastMCP app
call_mcp_tool(app, tool_name, args)- Call a tool asynchronouslylist_mcp_tools(app)- List all available toolsrun_tool_test(app, tool_name, json_args)- Run a tool test with JSON argsrun_http_tool_test(http_server_command, port, tool_name, args, env)- Test over HTTP
measure_tool_list(app)- Get (tool_count, total_chars) tuplemeasure_tool_list_detailed(app, server_name)- Get detailed measurementget_tool_details(app)- Get per-tool size breakdown
get_prompt_text(app, prompt_name, arguments)- Get prompt text contentlist_prompts(app)- List all available prompts
# Install dependencies
uv sync --extra dev
# Run tests
uv run poe test
# Format and lint
uv run poe fix
# Run all checks
uv run poe checkMIT License - see LICENSE for details.