- Python 100%
* Add guard-mode MRTR server support (SEP-2322) * Add server-side MRTR guard tests * Add MRTR guard docs, exports, and output-schema handling * Apply formatting to MRTR guard changes * Fix MRTR review round 1: middleware-safe suspend, Annotated strip, stable audience - ToolInputRequired subclasses BaseException (CancelledError precedent) so error middleware's broad except Exception cannot swallow a suspension - Strip InputRequiredResult arms inside Annotated return types - Reject a custom RequestStateSecurity without a stable audience (random per-replica server names would break shared-key verification) * Fix static analysis: rewrite tuple([...]) as tuple literal (C409) * Recognize InputRequiredResult inside Annotated union arms _is_input_required_type now peels Annotated first, so a metadata-carrying guard arm (str | Annotated[InputRequiredResult, Field(...)]) is stripped and the data arm's output schema survives. * docs: frame multi-round tools as elicitation on the modern protocol Fold multi-round-tools.mdx into elicitation.mdx as two eras of one capability; drop pause/suspend framing for the stateless per-round model. * Transport MRTR asks as InputRequiredToolResult, not a raised signal An input-required result is the full result of a stateless MRTR leg, so it flows through the middleware chain as an ordinary ToolResult subclass instead of a raised ToolInputRequired(BaseException). Middleware observes it, caching skips it, and response-limiting leaves it untouched. * Document MRTR middleware interaction and the isinstance pattern * Update MRTR change-register verify note to InputRequiredToolResult * Align test module docstring with result-cycle framing * Fix MRTR review: bypass cache on continuation legs; soften audience guard - ResponseCachingMiddleware skips read AND write on continuation legs: the cache key is name+arguments only, so a continuation's final result would be served to later fresh calls, which would never be asked - The stable-audience check is a warning, not an error: a policy object cannot reveal whether its keys are shared, and single-process customization (ephemeral ttl, custom codec) is legitimate unnamed * Treat state-only rounds as continuations in the response cache A round carrying request_state but no questions retries with input_responses=None; request_state alone must bypass the cache or its terminal result is stored under the fresh-call key. * Fix MRTR review round: preserve asks through transforms, empty-name audience, docs predicate - TransformedTool.run returns an InputRequiredToolResult intact instead of reshaping it into an empty ToolResult for non-object output schemas - audience warning uses a falsy-name check (empty string also autogenerates a per-replica name) - the elicitation docs continuation predicate checks request_state too * Add create_proxy(mode=) opt-in for guard round-tripping through proxies An auto-created proxy client stays handshake-era by default (a dual-era backend serves both, and one proxy session is one era; handshake preserves server-initiated push forwarding). Pass create_proxy(target, mode="auto") to negotiate modern so an upstream guard's InputRequiredResult round-trips — the two are mutually exclusive per session. * Wrap raw InputRequiredResult returned by a transform_fn A custom transform function may return the raw ask directly, like any tool body — wrap it into InputRequiredToolResult so it survives output normalization and reaches the wire, not only pre-wrapped forwarded guards. * Reject input-required results from background tasks * Unwrap type aliases before stripping guard arms * Apply ruff format * Recursively strip guard arms through nested and composed aliases * Reflect MRTR continuation fields on the middleware message * Suppress output schema for InputRequiredResult subclasses * Forward progress on modern proxy tool calls * Suppress output schema for bare aliased guard returns * Suppress output schema for any surviving guard return wrapping |
||
|---|---|---|
| .claude | ||
| .cursor/rules | ||
| .github | ||
| docs | ||
| examples | ||
| fastmcp_remote | ||
| fastmcp_slim | ||
| scripts | ||
| skills/fastmcp-client-cli | ||
| tests | ||
| v3-notes | ||
| .ccignore | ||
| .coderabbit.yaml | ||
| .gitignore | ||
| .pre-commit-config.yaml | ||
| .python-version | ||
| AGENTS.md | ||
| CLAUDE.md | ||
| CODE_OF_CONDUCT.md | ||
| CONTRIBUTING.md | ||
| justfile | ||
| LICENSE | ||
| logo.py | ||
| loq.toml | ||
| pyproject.toml | ||
| README.md | ||
| SECURITY.md | ||
| uv.lock | ||
The Model Context Protocol (MCP) connects LLMs to tools and data. FastMCP gives you everything you need to go from prototype to production:
from fastmcp import FastMCP
mcp = FastMCP("Demo 🚀")
@mcp.tool
def add(a: int, b: int) -> int:
"""Add two numbers"""
return a + b
if __name__ == "__main__":
mcp.run()
Why FastMCP
Building an effective MCP application is harder than it looks. FastMCP handles all of it. Declare a tool with a Python function, and the schema, validation, and documentation are generated automatically. Connect to a server with a URL, and transport negotiation, authentication, and protocol lifecycle are managed for you. You focus on your logic, and the MCP part just works: with FastMCP, best practices are built in.
That's why FastMCP is the standard framework for working with MCP. FastMCP 1.0 was incorporated into the official MCP Python SDK in 2024. Today, the actively maintained standalone project is downloaded a million times a day, and some version of FastMCP powers 70% of MCP servers across all languages.
FastMCP has three pillars:
Servers Expose tools, resources, and prompts to LLMs. |
Apps Give your tools interactive UIs rendered directly in the conversation. |
Clients Connect to any MCP server — local or remote, programmatic or CLI. |
Servers wrap your Python functions into MCP-compliant tools, resources, and prompts. Clients connect to any server with full protocol support. And Apps give your tools interactive UIs rendered directly in the conversation.
Ready to build? Start with the installation guide or jump straight to the quickstart.
Run FastMCP in production with Horizon
FastMCP is the standard way to build MCP servers. Prefect Horizon is the enterprise MCP gateway for running them safely.
Built by the FastMCP team, Horizon packages the best practices we've learned shipping the world's most popular MCP framework.
Deploy FastMCP servers from GitHub with branch previews and instant rollback. Create a private registry of every MCP your company uses. Secure access with SSO and tool-level RBAC. Get audit logs, observability, and governance across your MCP stack. Remix approved tools into purpose-built endpoints for teams and agents.
Start with FastMCP. Scale with Horizon →
Installation
We recommend installing FastMCP with uv:
uv pip install fastmcp
For full installation instructions, including verification and upgrading, see the Installation Guide.
Upgrading? We have guides for:
Note
If
import fastmcpfails right after apipupgrade from FastMCP 3.2 or earlier, runpip install --force-reinstall fastmcp. See Troubleshooting for why this happens (uvis unaffected).
📚 Documentation
FastMCP's complete documentation is available at gofastmcp.com, including detailed guides, API references, and advanced patterns.
Documentation is also available in llms.txt format, which is a simple markdown standard that LLMs can consume easily:
llms.txtis essentially a sitemap, listing all the pages in the documentation.llms-full.txtcontains the entire documentation. Note this may exceed the context window of your LLM.
Community: Join our Discord server to connect with other FastMCP developers and share what you're building.
Contributing
We welcome contributions! See the Contributing Guide for setup instructions, testing requirements, and PR guidelines.