Remove send_notification_sync() method, notification queue, and background flusher task. Component add/remove operations happen outside sessions and no longer need notifications.
Change version parameter from str to VersionSpec in enable()/disable()
to support range-based version filtering.
- Add match_none parameter to VersionSpec.matches() for controlling
whether unversioned components match (defaults to True for backward
compatibility, False for enable/disable filtering)
- Update Enabled transform to use VersionSpec and call matches() with
match_none=False so unversioned components don't match version specs
- Update enable()/disable() signatures to accept VersionSpec
- Add comprehensive tests for version range matching
Examples:
- disable(version=VersionSpec(eq="v2")) - disable only v2
- disable(version=VersionSpec(gte="v2")) - disable v2 and later
- disable(version=VersionSpec(gte="v1", lt="v3")) - disable v1, v2
Rename Visibility to Enabled, collapse VisibilityRule into the transform,
and move enabled filtering from Provider to Server level so server-level
transforms can override provider-level disables.
Server authors opt-in by setting list_page_size on FastMCP.
Client convenience methods auto-fetch all pages transparently.
Use _mcp methods with cursor parameter for manual pagination.
FastMCPProvider now calls _get_* methods instead of get_* to ensure
nested server transforms are applied during lookups. Also converts
string versions to VersionSpec in MCP handlers.
- get_*() now does aggregation + component auth (raises AuthorizationError)
- Deleted _get_*() overrides - inherited from Provider applies transforms
- Simplified AuthMiddleware to global auth only
- Changed version params to VersionSpec | None (not str | None)
- Updated tests to use _get_*() where visibility filtering is expected
Replace _get_all_transforms() with a .transforms property that returns
[*self._transforms, self._visibility]. This cleanly separates user transforms
from visibility filtering while keeping visibility applied last (outermost).
Also:
- AuthMiddleware now uses get_* instead of _get_* for proper component auth
- Remove redundant _is_component_enabled checks (visibility is a transform)
- Delete dead code (get_component method)
- Add versions field to FastMCPMeta
- Replace asserts with NotFoundError in component_service
- Add None checks in auth and tool transform tests
- Add assertions in component_service.py for None returns
- Add type ignore comments for max() with version_sort_key
- Override _get_tool/resource/template/prompt in FastMCP to apply
server transforms over provider aggregation
- Update FastMCPProvider get_* methods to check for None (not
NotFoundError since get_* now returns None)
- Update versioning tests to expect None instead of NotFoundError
when requesting filtered/nonexistent versions
Resolved conflicts to combine Provider inheritance refactor with versioning feature:
- FastMCP now properly inherits from Provider
- get_tool/resource/template/prompt return None instead of raising NotFoundError
- Deduplication uses version_sort_key to keep highest version per name/URI
- _source_* methods eliminated in favor of inherited _* methods
FastMCP now properly inherits from Provider, eliminating ~200 lines of
duplicated _source_* methods. Key changes:
- get_tool/resource/prompt return None instead of raising NotFoundError
- Visibility filter separated from transforms (applied last)
- Nested server middleware runs on both list and execution operations
- Resource auth failure doesn't fall back to templates
- AggregateProvider kept as user-facing utility class
Updates FastMCP's telemetry to align with the new MCP semantic conventions
from open-telemetry/semantic-conventions#2083. This gives us interoperability
with other MCP implementations while keeping fastmcp.* attributes for things
unique to our framework.
Changes:
- Span names now follow `{method} {target}` format (e.g., `tools/call greet`)
- Added `mcp.method.name` and `mcp.resource.uri` attributes
- Renamed `fastmcp.session.id` to standard `mcp.session.id`
- Kept fastmcp.* attributes for server name, component info, provider details
🤖 Generated with Claude Code
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Validates that session_id is captured on both client and server
spans when using HTTP transport, and that they share the same ID.
🤖 Generated with Claude Code
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix potential None session_id in span attributes
- Add return type annotation to _get_parent_trace_context
- Fix type checker issue with ClientFactoryT await pattern
🤖 Generated with Claude Code
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
A few improvements based on code review:
- Don't override existing trace context in `extract_trace_context` - if we're
already in a valid trace (e.g., from HTTP propagation), preserve it rather
than extracting from MCP meta
- Add exception recording to `delegate_span` to match `server_span` pattern
- Remove unused `get_meter` function (metrics not implemented yet)
- Return `None` instead of `{}` from `inject_trace_context` when nothing to inject
- Clean up trivial tests that were just testing OpenTelemetry's own API
🤖 Generated with Claude Code
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The test was checking caplog.records length but OpenTelemetry emits
internal warning logs that were getting captured. Filter to only the
test's logger to avoid flaky failures.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds opt-in distributed tracing via OpenTelemetry for observability into
FastMCP server and client operations.
Server spans are created for tool calls, resource reads, and prompt
renders with attributes like component key, component type, provider
type, session ID, and auth context. Client spans wrap outgoing calls
with trace context propagation via W3C headers in request meta.
Components provide their own span attributes through a `get_span_attributes()`
method that subclasses override - this lets LocalProvider, FastMCPProvider,
and ProxyProvider each include relevant context (original names, backend URIs).
To enable: configure an OpenTelemetry SDK with a TracerProvider before
importing fastmcp. Traces export to any OTLP-compatible backend.
Closes ENG-2813
🤖 Generated with Claude Code
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Tasks belong in capabilities.tasks (first-class field) per SEP-1686,
not capabilities.experimental.tasks. This fixes VS Code Copilot 1.107+
integration which checks capabilities.tasks?.requests?.tools?.call.
Changes:
- Update get_task_capabilities() to return ServerTasksCapability types
- Override get_capabilities() in LowLevelServer to set tasks field
- Remove experimental_capabilities parameter usage
- Update test to verify correct location
Fixes#2870