MCP in 2026
The MCP specification has evolved significantly since FastMCP was first built. This covers the spec changes that affect how you build and deploy MCP servers.
Governance Change
MCP was donated to the Agentic AI Foundation (AAIF), a Linux Foundation directed fund, in December 2025. Co-founded by Anthropic, Block, and OpenAI. Spec changes now go through an open RFC process with multi-vendor consensus.
This matters for FastMCP because:
- The spec is now vendor-neutral, reducing risk of Anthropic-specific drift
- New features are designed for cross-platform compatibility
- Enterprise adoption is accelerating, increasing demand for production-ready servers
Streamable HTTP Transport
The original remote transport was SSE (Server-Sent Events). The new standard is streamable HTTP:
from fastmcp import FastMCP
mcp = FastMCP("MyServer")
# New recommended transport for remote servers
mcp.run(transport="streamable-http", host="0.0.0.0", port=8000)
Why the Change
| SSE | Streamable HTTP | |
|---|---|---|
| Connection | Long-lived, stateful | Request-response with optional streaming |
| Load balancing | Difficult (sticky sessions required) | Standard HTTP load balancers |
| Firewalls | Often blocked (long-lived connections) | Standard HTTPS, universally allowed |
| Resumability | Manual reconnection logic | Built into the protocol |
| Server complexity | Manage connection state | Stateless by default |
Migration
# Before (SSE)
mcp.run(transport="sse", host="0.0.0.0", port=8000)
# After (streamable HTTP)
mcp.run(transport="streamable-http", host="0.0.0.0", port=8000)
For local development, stdio remains the default and recommended transport.
Tasks Primitive
Long-running operations that don’t fit the request-response model:
@mcp.tool
async def process_dataset(path: str, context: Context) -> str:
"""Process a large dataset. May take several minutes."""
task = await context.create_task(
name="process-dataset",
timeout=3600,
retry={"max_attempts": 3, "backoff_ms": 1000},
)
for i, chunk in enumerate(read_chunks(path)):
await task.report_progress(i / total_chunks)
process(chunk)
await task.complete()
return f"Processed {total_chunks} chunks"
Tasks support:
- Progress reporting - clients show progress bars or status updates
- Cancellation - clients can cancel running tasks
- Retry semantics - automatic retry with exponential backoff
- Expiry policies - tasks auto-cancel after a timeout
- Status polling - clients check task state without blocking
MCP Apps
Tools can return interactive UI components instead of plain text:
@mcp.tool
def show_metrics(service: str) -> dict:
"""Show service metrics in an interactive dashboard."""
data = fetch_metrics(service)
return {
"type": "app",
"component": "data-table",
"props": {
"columns": ["Metric", "Value", "Trend"],
"rows": data,
"sortable": True,
"filterable": True,
}
}
The client renders the component natively. Currently supported component types vary by client, but common ones include data tables, charts, and forms.
Elicitation
Servers can request structured input from users during tool execution:
@mcp.tool
async def deploy(service: str, context: Context) -> str:
"""Deploy a service to the target environment."""
env = await context.elicit(
message="Which environment?",
type="select",
options=["staging", "production"],
)
if env == "production":
confirmed = await context.elicit(
message=f"Confirm production deployment of {service}?",
type="confirm",
)
if not confirmed:
return "Deployment cancelled"
return await run_deployment(service, env)
Supported elicitation types:
text- free-form text inputselect- single choice from optionsmulti-select- multiple choicesconfirm- yes/no confirmation
Enterprise Features
Audit Trails
mcp = FastMCP("MyServer", audit=True)
# Every tool call is logged with:
# - Timestamp, caller identity
# - Input parameters, output summary
# - Duration, success/failure
SSO Integration
from fastmcp.auth import OAuthProvider
mcp = FastMCP("MyServer", auth=OAuthProvider(
provider="okta",
scopes=["read:data", "write:data"],
))
Gateway Compatibility
FastMCP servers work behind MCP gateways that provide rate limiting, access control, and usage metering at the infrastructure level.
Cross-Reference
For Claude-specific MCP integration patterns (how Claude Code discovers and uses MCP servers, how skills orchestrate MCP tools), see claude/deep-dives/mcp-ecosystem.md.