Replace tool timeout parameter with Docket's native Timeout dependency.
Components declaring Docket deps (Timeout, Retry, etc.) are now:
- Registered with Docket at startup
- Auto-routed through Docket even for foreground calls
Known limitations to discuss:
- Context not available in Docket workers
- Registration bug: register_with_docket still checks supports_tasks()
- Error propagation: ToolError wrapped in McpError
- Performance: every call goes through Redis+worker
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>