Commit graph

534 commits

Author SHA1 Message Date
Jeremiah Lowin
87b4a6fb99 Refactor Client class into mixins for better organization
Split the monolithic Client class into focused mixin classes:
- ClientToolsMixin (tools_client.py)
- ClientPromptsMixin (prompts.py)
- ClientResourcesMixin (resources.py)
- ClientTaskManagementMixin (task_management.py)

Also:
- Extract timeout normalization helpers to utilities/timeout.py
- Split SSETransport into its own module (transports/sse.py)
- Clean up unused imports across client modules
- Fix bare except clauses to catch specific McpError

Note: ty reports unresolved-attribute errors on mixin classes because
it doesn't understand that mixins will be composed with Client. This is
a known limitation of mixin typing in Python. The code is functionally
correct and all tests pass.
2026-01-19 09:21:38 -05:00
Jeremiah Lowin
71d6f49e14
Bump dependencies (#2931) 2026-01-19 08:38:48 -05:00
Jeremiah Lowin
b25ac3f5fa
Move session visibility logic to enabled.py (#2924) 2026-01-19 08:29:23 -05:00
Jeremiah Lowin
d8ab493664
Add session-specific visibility control via Context (#2917) 2026-01-18 22:31:06 -05:00
Jeremiah Lowin
c3111a8978
Unify discovery API: deduplicate at protocol layer only (#2919) 2026-01-18 21:01:53 -05:00
Jeremiah Lowin
ed0587d683
Immutable transform wrapping for providers (#2913) 2026-01-18 19:37:29 -05:00
Jeremiah Lowin
510738b52e Support VersionSpec in enable/disable for range-based filtering
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
2026-01-18 16:00:05 -05:00
Jeremiah Lowin
c4f506b097 Update test_local_provider.py 2026-01-18 15:01:51 -05:00
Jeremiah Lowin
84d7d3b281 Support plural names/keys in enable/disable API
Change enable() and disable() to accept sets: names, keys, tags.
Use key-based disable for decorator enabled=False to scope exactly.
2026-01-18 14:58:29 -05:00
Jeremiah Lowin
50ba6ea5a4 Refactor visibility to mark-based enabled system
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.
2026-01-18 14:36:33 -05:00
Jeremiah Lowin
17d43d7991 Address review feedback: validation and edge cases 2026-01-17 19:50:33 -05:00
Jeremiah Lowin
dada8893a9 Add MCP-compliant pagination for list operations
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.
2026-01-17 19:30:24 -05:00
Jeremiah Lowin
de1bf9864a fix: update remaining test to use get_prompt 2026-01-17 14:46:58 -05:00
Jeremiah Lowin
850f0a0050 fix: update all tests to use get_prompt instead of _get_prompt 2026-01-17 14:46:21 -05:00
Jeremiah Lowin
2c9cae9a98 refactor: reverse visibility for get_prompt/_get_prompt methods 2026-01-17 14:42:45 -05:00
Jeremiah Lowin
b9e32ca6a6 refactor: reverse visibility for list_resource_templates/_list_resource_templates methods 2026-01-17 14:41:08 -05:00
Jeremiah Lowin
61d98b41d1 refactor: reverse visibility for get_resource/_get_resource methods 2026-01-17 14:40:16 -05:00
Jeremiah Lowin
d6a334257c refactor: reverse visibility for list_resources/_list_resources methods 2026-01-17 14:39:41 -05:00
Jeremiah Lowin
b13e1c7caf refactor: reverse visibility for get_tool/_get_tool methods 2026-01-17 14:38:07 -05:00
Jeremiah Lowin
5fe471dc60 refactor: reverse visibility for list_tools/_list_tools methods 2026-01-17 14:32:53 -05:00
Jeremiah Lowin
3d98862995 Fix auth test to expect None instead of AuthorizationError 2026-01-17 14:25:29 -05:00
Jeremiah Lowin
78ab933dc5 Fix transform application in FastMCPProvider and MCP handlers
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.
2026-01-17 12:37:37 -05:00
Jeremiah Lowin
5b24ea393d Refactor FastMCP to use inherited _get_* methods from Provider
- 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
2026-01-17 12:15:01 -05:00
Jeremiah Lowin
5ade5a4838 Simplify Provider transform architecture
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
2026-01-17 11:35:47 -05:00
Jeremiah Lowin
ddd2058f97 Merge remote-tracking branch 'origin/main' into refactor-provider-inheritance-v2
# Conflicts:
#	src/fastmcp/server/server.py
2026-01-17 08:41:58 -05:00
Jeremiah Lowin
33c371cb37
Add version discovery and calling a certain version for components (#2897) 2026-01-17 08:27:39 -05:00
Jeremiah Lowin
6ba5e5d194 Fix type errors and add type ignore comments
- 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
2026-01-17 07:23:29 -05:00
Jeremiah Lowin
d3ae0ed450 Fix transform application and update tests for None return values
- 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
2026-01-16 22:21:40 -05:00
Jeremiah Lowin
66d713b367 Merge main into refactor-provider-inheritance-v2
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
2026-01-16 22:13:29 -05:00
Jeremiah Lowin
53e220a99e
Rename _fastmcp metadata namespace to fastmcp and make non-optional (#2895) 2026-01-16 21:35:53 -05:00
Jeremiah Lowin
a6cd764b5f
Add component versioning and VersionFilter transform (#2894) 2026-01-16 20:53:18 -05:00
Jeremiah Lowin
85f32959b1 Refactor FastMCP to inherit from Provider
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
2026-01-16 16:50:56 -05:00
Jeremiah Lowin
c8c84ff911
Add session-scoped state persistence (#2873) 2026-01-16 14:11:21 -05:00
Marcus Shu
083999ca14
Add client_secret_post authentication to IntrospectionTokenVerifier (#2884) 2026-01-16 13:07:33 -05:00
Chris Guidry
eaf2906916 Adopt OpenTelemetry MCP semantic conventions
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>
2026-01-15 14:08:15 -05:00
Chris Guidry
07b056b0ab Address CodeRabbit feedback
- 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>
2026-01-14 09:55:11 -05:00
Chris Guidry
046f845ddf Add OpenTelemetry tracing support
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>
2026-01-14 09:45:41 -05:00
Jeremiah Lowin
b61c76b19b Fix task capabilities location (issue #2870)
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
2026-01-13 22:26:13 -05:00
Jeremiah Lowin
2b6a0faf1c
Add loq file size limits and clean up type ignores (#2859) 2026-01-13 07:29:12 -05:00
Jeremiah Lowin
07d89c4038
Add transform system for modifying components in provider chains (#2836)
* Consolidate tool transformation logic into TransformingProvider

Tool transformations were previously scattered across LocalProvider,
ProxyProvider, and MCPConfig. This consolidates all transformation
logic into TransformingProvider via with_transforms(tool_transforms={...}).

- Add tool_transforms parameter to TransformingProvider
- Add tool_transforms to Provider.with_transforms()
- Remove transformation storage from LocalProvider and ProxyProvider
- Remove add_tool_transformation() and remove_tool_transformation() from FastMCP
- Add tool_transforms parameter to factory methods (from_openapi, from_fastapi, create_proxy)
- Update tests to use new patterns

* Fix: reject tool lookups by pre-transform name

* Add collision validation for tool_transforms and fix docstring examples

- Validate duplicate target names in tool_transforms raise ValueError
- Fix docstring examples to use arguments/ArgTransformConfig (not args/ArgTransform)
- Add test for collision validation

* Add server-level tool transform APIs and fix task registration

- Add AggregateProvider to present multiple providers as one
- Add _get_root_provider() to apply server-level transforms uniformly
- Fix _docket_lifespan to use root provider (ensures renamed tools
  register with correct keys for background execution)
- Add tool_transforms kwarg to __init__ (non-deprecated)
- Add add_tool_transform(), remove_tool_transform(), tool_transforms property
- Deprecate old API names (tool_transformations, add_tool_transformation, etc.)
- Update tests to use new API

* Add graceful degradation for provider errors in AggregateProvider

* Match original behavior: parallel queries with DEBUG logging

* Refactor transforms to middleware-style call_next pattern

Replaces the ad-hoc transformation system with a unified Transform
abstraction using the same call_next pattern as server middleware.

Key changes:
- New src/fastmcp/server/transforms/ module with Transform base class
- Namespace, ToolTransform, Visibility all implement the same interface
- Transforms compose via functools.partial chain building
- Visibility is now just the first transform in provider._transforms
- Server-level transforms apply after provider aggregation
- Task registration now applies full transform chain

Removes TransformingProvider, _BoundTransform, ComponentSource protocol.
User-facing API unchanged: mount(), add_transform(), enable/disable all
work as before.

* Add comprehensive transforms and visibility documentation

New docs/servers/providers/transforms.mdx covering:
- Mental model for middleware-style transform pattern
- Built-in transforms (Namespace, ToolTransform)
- Server vs provider-level transforms and ordering
- Tool modification (immediate vs deferred)
- Custom transform creation

New docs/servers/visibility.mdx covering:
- Enable/disable API for runtime visibility control
- Keys and tags for targeting components
- Allowlist mode with only=True
- Server vs provider visibility layering

Updates existing docs to reference new pages and simplifies
redundant content. Visibility is documented as a user feature,
not as an implementation detail.

* Restructure transforms docs and delete tool-transformation pattern

* Cleanup: simplify get_tasks and remove unused Provider.get_component

* Update loq

* Update loq limits and add loq note to AGENTS.md

* Deprecate add_tool_transformation and tool_transformations param

* Address PR review feedback: remove redundant imports, fix path reference

* Add missing imports to code examples in v3-features.mdx
2026-01-12 22:11:16 -05:00
Jeremiah Lowin
1b723f302d
Decorators return functions instead of component objects (#2856) 2026-01-12 21:58:07 -05:00
Jeremiah Lowin
766641a1a5
Add authorization checks to components and servers (#2855) 2026-01-12 19:56:52 -05:00
Jeremiah Lowin
bf3df4dcd5
Add transport property to Context (#2850) 2026-01-12 15:33:59 -05:00
Jeremiah Lowin
8e1fd1d700
Make pydocket optional and unify DI systems (#2835) 2026-01-10 16:23:32 -05:00
Jeremiah Lowin
4765f5725a
Add PingMiddleware for keepalive connections (#2838) 2026-01-10 16:12:35 -05:00
Jeremiah Lowin
daa2dace2f
Add standalone decorators and eliminate fastmcp.fs module (#2832) 2026-01-10 12:16:35 -05:00
Jeremiah Lowin
3163e61ee4
Replace FastMCP.as_proxy() with create_proxy() function (#2829) 2026-01-10 11:39:06 -05:00
Jeremiah Lowin
d8351993f7
Add composable lifespans (#2828) 2026-01-10 11:16:50 -05:00
Jeremiah Lowin
befaad8a08
Configure ty to fail on warnings (#2804) 2026-01-07 11:17:49 -05:00
Jeremiah Lowin
10fb217f73
Return 401 for invalid_grant token errors per MCP spec (#2800) 2026-01-06 17:51:33 -05:00