fastmcp 2.6.1__tar.gz → 2.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {fastmcp-2.6.1 → fastmcp-2.7.0}/.github/workflows/labeler.yml +1 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/PKG-INFO +10 -9
- {fastmcp-2.6.1 → fastmcp-2.7.0}/README.md +7 -7
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/clients/auth/bearer.mdx +1 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/clients/auth/oauth.mdx +1 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/clients/transports.mdx +1 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/deployment/asgi.mdx +1 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/deployment/running-server.mdx +14 -3
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/docs.json +13 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/getting-started/quickstart.mdx +3 -3
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/getting-started/welcome.mdx +1 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/integrations/anthropic.mdx +3 -2
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/integrations/claude-desktop.mdx +1 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/integrations/gemini.mdx +2 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/integrations/openai.mdx +3 -2
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/patterns/cli.mdx +1 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/patterns/decorating-methods.mdx +73 -49
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/patterns/http-requests.mdx +2 -2
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/patterns/testing.mdx +1 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/servers/auth/bearer.mdx +2 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/servers/composition.mdx +3 -3
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/servers/context.mdx +11 -11
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/servers/fastmcp.mdx +5 -5
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/servers/prompts.mdx +10 -10
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/servers/proxy.mdx +1 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/servers/tools.mdx +29 -29
- fastmcp-2.7.0/docs/style.css +119 -0
- fastmcp-2.7.0/docs/updates.mdx +21 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/examples/complex_inputs.py +1 -1
- fastmcp-2.7.0/examples/config_server.py +46 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/examples/desktop.py +1 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/examples/echo.py +1 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/examples/memory.py +2 -2
- {fastmcp-2.6.1 → fastmcp-2.7.0}/examples/mount_example.py +3 -3
- {fastmcp-2.6.1 → fastmcp-2.7.0}/examples/sampling.py +1 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/examples/screenshot.py +1 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/examples/serializer.py +1 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/examples/simple_echo.py +1 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/examples/smart_home/src/smart_home/hub.py +1 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/examples/smart_home/src/smart_home/lights/server.py +9 -9
- {fastmcp-2.6.1 → fastmcp-2.7.0}/pyproject.toml +4 -2
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/cli/cli.py +9 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/cli/run.py +32 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/client/transports.py +13 -4
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/contrib/bulk_tool_caller/example.py +1 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/contrib/mcp_mixin/mcp_mixin.py +10 -3
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/prompts/prompt.py +65 -27
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/prompts/prompt_manager.py +13 -6
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/resources/__init__.py +1 -2
- fastmcp-2.7.0/src/fastmcp/resources/resource.py +169 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/resources/resource_manager.py +17 -6
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/resources/template.py +90 -56
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/resources/types.py +0 -44
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/server/context.py +1 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/server/openapi.py +17 -32
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/server/proxy.py +5 -8
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/server/server.py +274 -90
- fastmcp-2.7.0/src/fastmcp/tools/__init__.py +4 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/tools/tool.py +59 -19
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/tools/tool_manager.py +9 -3
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/utilities/mcp_config.py +6 -4
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/utilities/openapi.py +56 -32
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/utilities/types.py +7 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/auth/providers/test_bearer.py +1 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/auth/test_oauth_client.py +1 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/cli/test_cli.py +25 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/cli/test_run.py +36 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/client/test_client.py +8 -8
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/client/test_logs.py +2 -2
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/client/test_progress.py +1 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/client/test_roots.py +1 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/client/test_sampling.py +3 -3
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/client/test_sse.py +4 -4
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/client/test_stdio.py +1 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/client/test_streamable_http.py +4 -4
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/contrib/test_bulk_tool_caller.py +4 -3
- fastmcp-2.7.0/tests/deprecated/__init__.py +4 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/deprecated/test_deprecated.py +5 -4
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/deprecated/test_mount_separators.py +5 -2
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/deprecated/test_resource_prefixes.py +5 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/deprecated/test_route_type_ignore.py +3 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/prompts/test_prompt_manager.py +4 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/resources/test_function_resources.py +1 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/resources/test_resource_manager.py +1 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/resources/test_resource_template.py +8 -7
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/resources/test_resources.py +2 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/server/http/test_http_dependencies.py +2 -2
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/server/openapi/test_openapi_path_parameters.py +7 -7
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/server/test_file_server.py +1 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/server/test_import_server.py +19 -15
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/server/test_mount.py +19 -19
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/server/test_proxy.py +15 -8
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/server/test_run_server.py +4 -4
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/server/test_server.py +254 -41
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/server/test_server_interactions.py +68 -110
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/server/test_tool_annotations.py +6 -2
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/server/test_tool_exclude_args.py +13 -2
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/test_servers/fastmcp_server.py +4 -4
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/tools/test_tool.py +236 -8
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/tools/test_tool_manager.py +123 -69
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/utilities/openapi/test_openapi.py +111 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/utilities/test_mcp_config.py +1 -1
- {fastmcp-2.6.1 → fastmcp-2.7.0}/uv.lock +6 -1
- fastmcp-2.6.1/docs/style.css +0 -52
- fastmcp-2.6.1/src/fastmcp/resources/resource.py +0 -83
- fastmcp-2.6.1/src/fastmcp/tools/__init__.py +0 -4
- fastmcp-2.6.1/src/fastmcp/utilities/decorators.py +0 -101
- fastmcp-2.6.1/tests/tools/__init__.py +0 -0
- fastmcp-2.6.1/tests/utilities/test_decorated_function.py +0 -222
- {fastmcp-2.6.1 → fastmcp-2.7.0}/.cursor/rules/core-mcp-objects.mdc +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/.github/ISSUE_TEMPLATE/bug.yml +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/.github/ISSUE_TEMPLATE/enhancement.yml +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/.github/labeler.yml +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/.github/release.yml +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/.github/workflows/publish.yml +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/.github/workflows/run-static.yml +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/.github/workflows/run-tests.yml +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/.gitignore +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/.pre-commit-config.yaml +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/AGENTS.md +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/LICENSE +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/Windows_Notes.md +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/assets/demo-inspector.png +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/assets/favicon.ico +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/assets/logo.png +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/clients/advanced-features.mdx +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/clients/client.mdx +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/getting-started/installation.mdx +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/integrations/contrib.mdx +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/servers/openapi.mdx +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/servers/resources.mdx +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/docs/snippets/version-badge.mdx +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/examples/in_memory_proxy_example.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/examples/smart_home/README.md +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/examples/smart_home/pyproject.toml +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/examples/smart_home/src/smart_home/__init__.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/examples/smart_home/src/smart_home/__main__.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/examples/smart_home/src/smart_home/lights/__init__.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/examples/smart_home/src/smart_home/lights/hue_utils.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/examples/smart_home/src/smart_home/py.typed +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/examples/smart_home/src/smart_home/settings.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/examples/smart_home/uv.lock +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/examples/tags_example.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/examples/text_me.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/justfile +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/__init__.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/cli/__init__.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/cli/claude.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/client/__init__.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/client/auth/__init__.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/client/auth/bearer.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/client/auth/oauth.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/client/client.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/client/logging.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/client/oauth_callback.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/client/progress.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/client/roots.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/client/sampling.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/contrib/README.md +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/contrib/bulk_tool_caller/README.md +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/contrib/bulk_tool_caller/__init__.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/contrib/bulk_tool_caller/bulk_tool_caller.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/contrib/mcp_mixin/README.md +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/contrib/mcp_mixin/__init__.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/contrib/mcp_mixin/example.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/exceptions.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/prompts/__init__.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/py.typed +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/server/__init__.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/server/auth/__init__.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/server/auth/auth.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/server/auth/providers/__init__.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/server/auth/providers/bearer.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/server/auth/providers/bearer_env.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/server/auth/providers/in_memory.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/server/dependencies.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/server/http.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/settings.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/utilities/__init__.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/utilities/cache.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/utilities/exceptions.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/utilities/http.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/utilities/json_schema.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/utilities/logging.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/src/fastmcp/utilities/tests.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/__init__.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/auth/__init__.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/auth/providers/test_bearer_env.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/cli/__init__.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/client/__init__.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/client/test_openapi.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/conftest.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/contrib/__init__.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/contrib/test_mcp_mixin.py +0 -0
- {fastmcp-2.6.1/tests/deprecated → fastmcp-2.7.0/tests/prompts}/__init__.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/prompts/test_prompt.py +0 -0
- {fastmcp-2.6.1/tests/prompts → fastmcp-2.7.0/tests/resources}/__init__.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/resources/test_file_resources.py +0 -0
- {fastmcp-2.6.1/tests/resources → fastmcp-2.7.0/tests/server}/__init__.py +0 -0
- {fastmcp-2.6.1/tests/server → fastmcp-2.7.0/tests/server/http}/__init__.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/server/http/test_custom_routes.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/server/http/test_http_middleware.py +0 -0
- {fastmcp-2.6.1/tests/server/http → fastmcp-2.7.0/tests/server/openapi}/__init__.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/server/openapi/test_openapi.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/server/openapi/test_route_map_fn.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/server/test_app_state.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/server/test_auth_integration.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/server/test_context.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/server/test_logging.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/server/test_resource_prefix_formats.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/test_examples.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/test_servers/sse.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/test_servers/stdio.py +0 -0
- {fastmcp-2.6.1/tests/server/openapi → fastmcp-2.7.0/tests/tools}/__init__.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/utilities/__init__.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/utilities/openapi/__init__.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/utilities/openapi/conftest.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/utilities/openapi/test_openapi_advanced.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/utilities/openapi/test_openapi_fastapi.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/utilities/test_cache.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/utilities/test_json_schema.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/utilities/test_logging.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/utilities/test_tests.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/utilities/test_typeadapter.py +0 -0
- {fastmcp-2.6.1 → fastmcp-2.7.0}/tests/utilities/test_types.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastmcp
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.7.0
|
|
4
4
|
Summary: The fast, Pythonic way to build MCP servers.
|
|
5
5
|
Project-URL: Homepage, https://gofastmcp.com
|
|
6
6
|
Project-URL: Repository, https://github.com/jlowin/fastmcp
|
|
@@ -25,7 +25,8 @@ Requires-Dist: openapi-pydantic>=0.5.1
|
|
|
25
25
|
Requires-Dist: python-dotenv>=1.1.0
|
|
26
26
|
Requires-Dist: rich>=13.9.4
|
|
27
27
|
Requires-Dist: typer>=0.15.2
|
|
28
|
-
|
|
28
|
+
Provides-Extra: websockets
|
|
29
|
+
Requires-Dist: websockets>=15.0.1; extra == 'websockets'
|
|
29
30
|
Description-Content-Type: text/markdown
|
|
30
31
|
|
|
31
32
|
<div align="center">
|
|
@@ -61,7 +62,7 @@ from fastmcp import FastMCP
|
|
|
61
62
|
|
|
62
63
|
mcp = FastMCP("Demo 🚀")
|
|
63
64
|
|
|
64
|
-
@mcp.tool
|
|
65
|
+
@mcp.tool
|
|
65
66
|
def add(a: int, b: int) -> int:
|
|
66
67
|
"""Add two numbers"""
|
|
67
68
|
return a + b
|
|
@@ -174,7 +175,7 @@ Learn more in the [**FastMCP Server Documentation**](https://gofastmcp.com/serve
|
|
|
174
175
|
Tools allow LLMs to perform actions by executing your Python functions (sync or async). Ideal for computations, API calls, or side effects (like `POST`/`PUT`). FastMCP handles schema generation from type hints and docstrings. Tools can return various types, including text, JSON-serializable objects, and even images using the [`fastmcp.Image`](https://gofastmcp.com/servers/tools#return-values) helper.
|
|
175
176
|
|
|
176
177
|
```python
|
|
177
|
-
@mcp.tool
|
|
178
|
+
@mcp.tool
|
|
178
179
|
def multiply(a: float, b: float) -> float:
|
|
179
180
|
"""Multiplies two numbers."""
|
|
180
181
|
return a * b
|
|
@@ -203,10 +204,10 @@ Learn more in the [**Resources & Templates Documentation**](https://gofastmcp.co
|
|
|
203
204
|
|
|
204
205
|
### Prompts
|
|
205
206
|
|
|
206
|
-
Prompts define reusable message templates to guide LLM interactions. Decorate functions with `@mcp.prompt
|
|
207
|
+
Prompts define reusable message templates to guide LLM interactions. Decorate functions with `@mcp.prompt`. Return strings or `Message` objects.
|
|
207
208
|
|
|
208
209
|
```python
|
|
209
|
-
@mcp.prompt
|
|
210
|
+
@mcp.prompt
|
|
210
211
|
def summarize_request(text: str) -> str:
|
|
211
212
|
"""Generate a prompt asking for a summary."""
|
|
212
213
|
return f"Please summarize the following text:\n\n{text}"
|
|
@@ -231,7 +232,7 @@ from fastmcp import FastMCP, Context
|
|
|
231
232
|
|
|
232
233
|
mcp = FastMCP("My MCP Server")
|
|
233
234
|
|
|
234
|
-
@mcp.tool
|
|
235
|
+
@mcp.tool
|
|
235
236
|
async def process_data(uri: str, ctx: Context):
|
|
236
237
|
# Log a message to the client
|
|
237
238
|
await ctx.info(f"Processing {uri}...")
|
|
@@ -329,7 +330,7 @@ Learn more in the [**Composition Documentation**](https://gofastmcp.com/patterns
|
|
|
329
330
|
|
|
330
331
|
Automatically generate FastMCP servers from existing OpenAPI specifications (`FastMCP.from_openapi()`) or FastAPI applications (`FastMCP.from_fastapi()`), instantly bringing your web APIs to the MCP ecosystem.
|
|
331
332
|
|
|
332
|
-
Learn more: [**OpenAPI Integration**](https://gofastmcp.com/
|
|
333
|
+
Learn more: [**OpenAPI Integration**](https://gofastmcp.com/servers/openapi#openapi-integration) | [**FastAPI Integration**](https://gofastmcp.com/deployment/asgi#fastapi-integration).
|
|
333
334
|
|
|
334
335
|
### Authentication & Security
|
|
335
336
|
|
|
@@ -351,7 +352,7 @@ from fastmcp import FastMCP
|
|
|
351
352
|
|
|
352
353
|
mcp = FastMCP("Demo 🚀")
|
|
353
354
|
|
|
354
|
-
@mcp.tool
|
|
355
|
+
@mcp.tool
|
|
355
356
|
def hello(name: str) -> str:
|
|
356
357
|
return f"Hello, {name}!"
|
|
357
358
|
|
|
@@ -31,7 +31,7 @@ from fastmcp import FastMCP
|
|
|
31
31
|
|
|
32
32
|
mcp = FastMCP("Demo 🚀")
|
|
33
33
|
|
|
34
|
-
@mcp.tool
|
|
34
|
+
@mcp.tool
|
|
35
35
|
def add(a: int, b: int) -> int:
|
|
36
36
|
"""Add two numbers"""
|
|
37
37
|
return a + b
|
|
@@ -144,7 +144,7 @@ Learn more in the [**FastMCP Server Documentation**](https://gofastmcp.com/serve
|
|
|
144
144
|
Tools allow LLMs to perform actions by executing your Python functions (sync or async). Ideal for computations, API calls, or side effects (like `POST`/`PUT`). FastMCP handles schema generation from type hints and docstrings. Tools can return various types, including text, JSON-serializable objects, and even images using the [`fastmcp.Image`](https://gofastmcp.com/servers/tools#return-values) helper.
|
|
145
145
|
|
|
146
146
|
```python
|
|
147
|
-
@mcp.tool
|
|
147
|
+
@mcp.tool
|
|
148
148
|
def multiply(a: float, b: float) -> float:
|
|
149
149
|
"""Multiplies two numbers."""
|
|
150
150
|
return a * b
|
|
@@ -173,10 +173,10 @@ Learn more in the [**Resources & Templates Documentation**](https://gofastmcp.co
|
|
|
173
173
|
|
|
174
174
|
### Prompts
|
|
175
175
|
|
|
176
|
-
Prompts define reusable message templates to guide LLM interactions. Decorate functions with `@mcp.prompt
|
|
176
|
+
Prompts define reusable message templates to guide LLM interactions. Decorate functions with `@mcp.prompt`. Return strings or `Message` objects.
|
|
177
177
|
|
|
178
178
|
```python
|
|
179
|
-
@mcp.prompt
|
|
179
|
+
@mcp.prompt
|
|
180
180
|
def summarize_request(text: str) -> str:
|
|
181
181
|
"""Generate a prompt asking for a summary."""
|
|
182
182
|
return f"Please summarize the following text:\n\n{text}"
|
|
@@ -201,7 +201,7 @@ from fastmcp import FastMCP, Context
|
|
|
201
201
|
|
|
202
202
|
mcp = FastMCP("My MCP Server")
|
|
203
203
|
|
|
204
|
-
@mcp.tool
|
|
204
|
+
@mcp.tool
|
|
205
205
|
async def process_data(uri: str, ctx: Context):
|
|
206
206
|
# Log a message to the client
|
|
207
207
|
await ctx.info(f"Processing {uri}...")
|
|
@@ -299,7 +299,7 @@ Learn more in the [**Composition Documentation**](https://gofastmcp.com/patterns
|
|
|
299
299
|
|
|
300
300
|
Automatically generate FastMCP servers from existing OpenAPI specifications (`FastMCP.from_openapi()`) or FastAPI applications (`FastMCP.from_fastapi()`), instantly bringing your web APIs to the MCP ecosystem.
|
|
301
301
|
|
|
302
|
-
Learn more: [**OpenAPI Integration**](https://gofastmcp.com/
|
|
302
|
+
Learn more: [**OpenAPI Integration**](https://gofastmcp.com/servers/openapi#openapi-integration) | [**FastAPI Integration**](https://gofastmcp.com/deployment/asgi#fastapi-integration).
|
|
303
303
|
|
|
304
304
|
### Authentication & Security
|
|
305
305
|
|
|
@@ -321,7 +321,7 @@ from fastmcp import FastMCP
|
|
|
321
321
|
|
|
322
322
|
mcp = FastMCP("Demo 🚀")
|
|
323
323
|
|
|
324
|
-
@mcp.tool
|
|
324
|
+
@mcp.tool
|
|
325
325
|
def hello(name: str) -> str:
|
|
326
326
|
return f"Hello, {name}!"
|
|
327
327
|
|
|
@@ -22,7 +22,7 @@ from fastmcp import FastMCP
|
|
|
22
22
|
|
|
23
23
|
mcp = FastMCP(name="MyServer")
|
|
24
24
|
|
|
25
|
-
@mcp.tool
|
|
25
|
+
@mcp.tool
|
|
26
26
|
def hello(name: str) -> str:
|
|
27
27
|
return f"Hello, {name}!"
|
|
28
28
|
|
|
@@ -61,6 +61,17 @@ fastmcp dev server.py
|
|
|
61
61
|
|
|
62
62
|
See the [CLI documentation](/patterns/cli) for detailed information about all available commands and options.
|
|
63
63
|
|
|
64
|
+
### Passing Arguments to Servers
|
|
65
|
+
|
|
66
|
+
When servers accept command line arguments (using argparse, click, or other libraries), you can pass them after `--`:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
fastmcp run config_server.py -- --config config.json
|
|
70
|
+
fastmcp run database_server.py -- --database-path /tmp/db.sqlite --debug
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
This is useful for servers that need configuration files, database paths, API keys, or other runtime options.
|
|
74
|
+
|
|
64
75
|
## Transport Options
|
|
65
76
|
|
|
66
77
|
Below is a comparison of available transport options to help you choose the right one for your needs:
|
|
@@ -233,7 +244,7 @@ import asyncio
|
|
|
233
244
|
|
|
234
245
|
mcp = FastMCP(name="MyServer")
|
|
235
246
|
|
|
236
|
-
@mcp.tool
|
|
247
|
+
@mcp.tool
|
|
237
248
|
def hello(name: str) -> str:
|
|
238
249
|
return f"Hello, {name}!"
|
|
239
250
|
|
|
@@ -270,4 +281,4 @@ async def health_check(request: Request) -> PlainTextResponse:
|
|
|
270
281
|
|
|
271
282
|
if __name__ == "__main__":
|
|
272
283
|
mcp.run()
|
|
273
|
-
```
|
|
284
|
+
```
|
|
@@ -11,11 +11,22 @@
|
|
|
11
11
|
},
|
|
12
12
|
"decoration": "windows"
|
|
13
13
|
},
|
|
14
|
+
"banner": {
|
|
15
|
+
"content": "[FastMCP Cloud](https://fastmcp.link/x0Kyhy2) is coming!"
|
|
16
|
+
},
|
|
14
17
|
"colors": {
|
|
15
18
|
"dark": "#f72585",
|
|
16
19
|
"light": "#4cc9f0",
|
|
17
20
|
"primary": "#2d00f7"
|
|
18
21
|
},
|
|
22
|
+
"contextual": {
|
|
23
|
+
"options": [
|
|
24
|
+
"copy",
|
|
25
|
+
"view",
|
|
26
|
+
"chatgpt",
|
|
27
|
+
"claude"
|
|
28
|
+
]
|
|
29
|
+
},
|
|
19
30
|
"description": "The fast, Pythonic way to build MCP servers and clients.",
|
|
20
31
|
"favicon": {
|
|
21
32
|
"dark": "/assets/favicon.ico",
|
|
@@ -47,7 +58,8 @@
|
|
|
47
58
|
"pages": [
|
|
48
59
|
"getting-started/welcome",
|
|
49
60
|
"getting-started/installation",
|
|
50
|
-
"getting-started/quickstart"
|
|
61
|
+
"getting-started/quickstart",
|
|
62
|
+
"updates"
|
|
51
63
|
]
|
|
52
64
|
},
|
|
53
65
|
{
|
|
@@ -32,7 +32,7 @@ from fastmcp import FastMCP
|
|
|
32
32
|
|
|
33
33
|
mcp = FastMCP("My MCP Server")
|
|
34
34
|
|
|
35
|
-
@mcp.tool
|
|
35
|
+
@mcp.tool
|
|
36
36
|
def greet(name: str) -> str:
|
|
37
37
|
return f"Hello, {name}!"
|
|
38
38
|
```
|
|
@@ -49,7 +49,7 @@ from fastmcp import FastMCP, Client
|
|
|
49
49
|
|
|
50
50
|
mcp = FastMCP("My MCP Server")
|
|
51
51
|
|
|
52
|
-
@mcp.tool
|
|
52
|
+
@mcp.tool
|
|
53
53
|
def greet(name: str) -> str:
|
|
54
54
|
return f"Hello, {name}!"
|
|
55
55
|
|
|
@@ -76,7 +76,7 @@ from fastmcp import FastMCP
|
|
|
76
76
|
|
|
77
77
|
mcp = FastMCP("My MCP Server")
|
|
78
78
|
|
|
79
|
-
@mcp.tool
|
|
79
|
+
@mcp.tool
|
|
80
80
|
def greet(name: str) -> str:
|
|
81
81
|
return f"Hello, {name}!"
|
|
82
82
|
|
|
@@ -3,6 +3,7 @@ title: Anthropic
|
|
|
3
3
|
sidebarTitle: Anthropic
|
|
4
4
|
description: Call FastMCP servers from the Anthropic API
|
|
5
5
|
icon: message-smile
|
|
6
|
+
tag: "New!"
|
|
6
7
|
---
|
|
7
8
|
|
|
8
9
|
import { VersionBadge } from "/snippets/version-badge.mdx"
|
|
@@ -27,7 +28,7 @@ from fastmcp import FastMCP
|
|
|
27
28
|
|
|
28
29
|
mcp = FastMCP(name="Dice Roller")
|
|
29
30
|
|
|
30
|
-
@mcp.tool
|
|
31
|
+
@mcp.tool
|
|
31
32
|
def roll_dice(n_dice: int) -> list[int]:
|
|
32
33
|
"""Roll `n_dice` 6-sided dice and return the results."""
|
|
33
34
|
return [random.randint(1, 6) for _ in range(n_dice)]
|
|
@@ -170,7 +171,7 @@ auth = BearerAuthProvider(
|
|
|
170
171
|
|
|
171
172
|
mcp = FastMCP(name="Dice Roller", auth=auth)
|
|
172
173
|
|
|
173
|
-
@mcp.tool
|
|
174
|
+
@mcp.tool
|
|
174
175
|
def roll_dice(n_dice: int) -> list[int]:
|
|
175
176
|
"""Roll `n_dice` 6-sided dice and return the results."""
|
|
176
177
|
return [random.randint(1, 6) for _ in range(n_dice)]
|
|
@@ -3,6 +3,7 @@ title: Gemini SDK
|
|
|
3
3
|
sidebarTitle: Gemini SDK
|
|
4
4
|
description: Call FastMCP servers from the Google Gemini SDK
|
|
5
5
|
icon: message-smile
|
|
6
|
+
tag: "New!"
|
|
6
7
|
---
|
|
7
8
|
|
|
8
9
|
import { VersionBadge } from "/snippets/version-badge.mdx"
|
|
@@ -31,7 +32,7 @@ from fastmcp import FastMCP
|
|
|
31
32
|
|
|
32
33
|
mcp = FastMCP(name="Dice Roller")
|
|
33
34
|
|
|
34
|
-
@mcp.tool
|
|
35
|
+
@mcp.tool
|
|
35
36
|
def roll_dice(n_dice: int) -> list[int]:
|
|
36
37
|
"""Roll `n_dice` 6-sided dice and return the results."""
|
|
37
38
|
return [random.randint(1, 6) for _ in range(n_dice)]
|
|
@@ -3,6 +3,7 @@ title: OpenAI
|
|
|
3
3
|
sidebarTitle: OpenAI
|
|
4
4
|
description: Call FastMCP servers from the OpenAI API
|
|
5
5
|
icon: message-smile
|
|
6
|
+
tag: "New!"
|
|
6
7
|
---
|
|
7
8
|
|
|
8
9
|
import { VersionBadge } from "/snippets/version-badge.mdx"
|
|
@@ -32,7 +33,7 @@ from fastmcp import FastMCP
|
|
|
32
33
|
|
|
33
34
|
mcp = FastMCP(name="Dice Roller")
|
|
34
35
|
|
|
35
|
-
@mcp.tool
|
|
36
|
+
@mcp.tool
|
|
36
37
|
def roll_dice(n_dice: int) -> list[int]:
|
|
37
38
|
"""Roll `n_dice` 6-sided dice and return the results."""
|
|
38
39
|
return [random.randint(1, 6) for _ in range(n_dice)]
|
|
@@ -165,7 +166,7 @@ auth = BearerAuthProvider(
|
|
|
165
166
|
|
|
166
167
|
mcp = FastMCP(name="Dice Roller", auth=auth)
|
|
167
168
|
|
|
168
|
-
@mcp.tool
|
|
169
|
+
@mcp.tool
|
|
169
170
|
def roll_dice(n_dice: int) -> list[int]:
|
|
170
171
|
"""Roll `n_dice` 6-sided dice and return the results."""
|
|
171
172
|
return [random.randint(1, 6) for _ in range(n_dice)]
|
|
@@ -5,22 +5,47 @@ description: Properly use instance methods, class methods, and static methods wi
|
|
|
5
5
|
icon: at
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
FastMCP's decorator system is designed to work with functions, but you may see unexpected behavior if you try to decorate an instance or class method. This guide explains the correct approach for using methods with all FastMCP decorators (`@tool
|
|
8
|
+
FastMCP's decorator system is designed to work with functions, but you may see unexpected behavior if you try to decorate an instance or class method. This guide explains the correct approach for using methods with all FastMCP decorators (`@tool`, `@resource`, and `.prompt`).
|
|
9
9
|
|
|
10
10
|
## Why Are Methods Hard?
|
|
11
11
|
|
|
12
|
-
When you apply a FastMCP decorator like `@tool
|
|
12
|
+
When you apply a FastMCP decorator like `@tool`, `@resource`, or `@prompt` to a method, the decorator captures the function at decoration time. For instance methods and class methods, this poses a challenge because:
|
|
13
13
|
|
|
14
14
|
1. For instance methods: The decorator gets the unbound method before any instance exists
|
|
15
15
|
2. For class methods: The decorator gets the function before it's bound to the class
|
|
16
16
|
|
|
17
17
|
This means directly decorating these methods doesn't work as expected. In practice, the LLM would see parameters like `self` or `cls` that it cannot provide values for.
|
|
18
18
|
|
|
19
|
+
Additionally, **FastMCP decorators return objects (Tool, Resource, or Prompt instances) rather than the original function**. This means that when you decorate a method directly, the method becomes the returned object and is no longer callable by your code:
|
|
20
|
+
|
|
21
|
+
<Warning>
|
|
22
|
+
**Don't do this!**
|
|
23
|
+
|
|
24
|
+
The method will no longer be callable from Python, and the tool won't be callable by LLMs.
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
|
|
28
|
+
from fastmcp import FastMCP
|
|
29
|
+
mcp = FastMCP()
|
|
30
|
+
|
|
31
|
+
class MyClass:
|
|
32
|
+
@mcp.tool
|
|
33
|
+
def my_method(self, x: int) -> int:
|
|
34
|
+
return x * 2
|
|
35
|
+
|
|
36
|
+
obj = MyClass()
|
|
37
|
+
obj.my_method(5) # Fails - my_method is a Tool, not a function
|
|
38
|
+
```
|
|
39
|
+
</Warning>
|
|
40
|
+
|
|
41
|
+
This is another important reason to register methods functionally after defining the class.
|
|
42
|
+
|
|
19
43
|
## Recommended Patterns
|
|
20
44
|
|
|
21
45
|
### Instance Methods
|
|
22
46
|
|
|
23
|
-
|
|
47
|
+
<Warning>
|
|
48
|
+
**Don't do this!**
|
|
24
49
|
|
|
25
50
|
```python
|
|
26
51
|
from fastmcp import FastMCP
|
|
@@ -28,17 +53,14 @@ from fastmcp import FastMCP
|
|
|
28
53
|
mcp = FastMCP()
|
|
29
54
|
|
|
30
55
|
class MyClass:
|
|
31
|
-
@mcp.tool
|
|
56
|
+
@mcp.tool # This won't work correctly
|
|
32
57
|
def add(self, x, y):
|
|
33
58
|
return x + y
|
|
34
|
-
|
|
35
|
-
@mcp.resource("resource://{param}") # This won't work correctly
|
|
36
|
-
def get_resource(self, param: str):
|
|
37
|
-
return f"Resource data for {param}"
|
|
38
59
|
```
|
|
39
|
-
|
|
60
|
+
</Warning>
|
|
40
61
|
When the decorator is applied this way, it captures the unbound method. When the LLM later tries to use this component, it will see `self` as a required parameter, but it won't know what to provide for it, causing errors or unexpected behavior.
|
|
41
62
|
|
|
63
|
+
<Check>
|
|
42
64
|
**Do this instead**:
|
|
43
65
|
|
|
44
66
|
```python
|
|
@@ -49,21 +71,15 @@ mcp = FastMCP()
|
|
|
49
71
|
class MyClass:
|
|
50
72
|
def add(self, x, y):
|
|
51
73
|
return x + y
|
|
52
|
-
|
|
53
|
-
def get_resource(self, param: str):
|
|
54
|
-
return f"Resource data for {param}"
|
|
55
74
|
|
|
56
|
-
# Create an instance first, then
|
|
75
|
+
# Create an instance first, then register the bound methods
|
|
57
76
|
obj = MyClass()
|
|
58
|
-
mcp.
|
|
59
|
-
mcp.add_resource_fn(obj.get_resource, uri="resource://{param}") # For resources or templates
|
|
60
|
-
|
|
61
|
-
# Note: FastMCP provides add_resource() for adding Resource objects directly and
|
|
62
|
-
# add_resource_fn() for adding functions that generate resources or templates
|
|
77
|
+
mcp.tool(obj.add)
|
|
63
78
|
|
|
64
79
|
# Now you can call it without 'self' showing up as a parameter
|
|
65
|
-
await mcp.
|
|
80
|
+
await mcp._mcp_call_tool('add', {'x': 1, 'y': 2}) # Returns 3
|
|
66
81
|
```
|
|
82
|
+
</Check>
|
|
67
83
|
|
|
68
84
|
This approach works because:
|
|
69
85
|
1. You first create an instance of the class (`obj`)
|
|
@@ -72,9 +88,10 @@ This approach works because:
|
|
|
72
88
|
|
|
73
89
|
### Class Methods
|
|
74
90
|
|
|
75
|
-
|
|
91
|
+
The behavior of decorating class methods depends on the order of decorators:
|
|
76
92
|
|
|
77
|
-
|
|
93
|
+
<Warning>
|
|
94
|
+
**Don't do this** (decorator order matters):
|
|
78
95
|
|
|
79
96
|
```python
|
|
80
97
|
from fastmcp import FastMCP
|
|
@@ -83,13 +100,21 @@ mcp = FastMCP()
|
|
|
83
100
|
|
|
84
101
|
class MyClass:
|
|
85
102
|
@classmethod
|
|
86
|
-
@mcp.tool
|
|
87
|
-
def
|
|
103
|
+
@mcp.tool # This won't work but won't raise an error
|
|
104
|
+
def from_string_v1(cls, s):
|
|
105
|
+
return cls(s)
|
|
106
|
+
|
|
107
|
+
@mcp.tool
|
|
108
|
+
@classmethod # This will raise a helpful ValueError
|
|
109
|
+
def from_string_v2(cls, s):
|
|
88
110
|
return cls(s)
|
|
89
111
|
```
|
|
112
|
+
</Warning>
|
|
90
113
|
|
|
91
|
-
|
|
114
|
+
- If `@classmethod` comes first, then `@mcp.tool`: No error is raised, but it won't work correctly
|
|
115
|
+
- If `@mcp.tool` comes first, then `@classmethod`: FastMCP will detect this and raise a helpful `ValueError` with guidance
|
|
92
116
|
|
|
117
|
+
<Check>
|
|
93
118
|
**Do this instead**:
|
|
94
119
|
|
|
95
120
|
```python
|
|
@@ -102,9 +127,10 @@ class MyClass:
|
|
|
102
127
|
def from_string(cls, s):
|
|
103
128
|
return cls(s)
|
|
104
129
|
|
|
105
|
-
#
|
|
106
|
-
mcp.
|
|
130
|
+
# Register the class method after the class is defined
|
|
131
|
+
mcp.tool(MyClass.from_string)
|
|
107
132
|
```
|
|
133
|
+
</Check>
|
|
108
134
|
|
|
109
135
|
This works because:
|
|
110
136
|
1. The `@classmethod` decorator is applied properly during class definition
|
|
@@ -113,7 +139,10 @@ This works because:
|
|
|
113
139
|
|
|
114
140
|
### Static Methods
|
|
115
141
|
|
|
116
|
-
|
|
142
|
+
Static methods "work" with FastMCP decorators, but this is not recommended because the FastMCP decorator will not return a callable method. Therefore, you should register static methods the same way as other methods.
|
|
143
|
+
|
|
144
|
+
<Warning>
|
|
145
|
+
**This is not recommended, though it will work.**
|
|
117
146
|
|
|
118
147
|
```python
|
|
119
148
|
from fastmcp import FastMCP
|
|
@@ -121,23 +150,17 @@ from fastmcp import FastMCP
|
|
|
121
150
|
mcp = FastMCP()
|
|
122
151
|
|
|
123
152
|
class MyClass:
|
|
153
|
+
@mcp.tool
|
|
124
154
|
@staticmethod
|
|
125
|
-
@mcp.tool() # This works!
|
|
126
155
|
def utility(x, y):
|
|
127
156
|
return x + y
|
|
128
|
-
|
|
129
|
-
@staticmethod
|
|
130
|
-
@mcp.resource("resource://data") # This works too!
|
|
131
|
-
def get_data():
|
|
132
|
-
return "Static resource data"
|
|
133
157
|
```
|
|
158
|
+
</Warning>
|
|
134
159
|
|
|
135
|
-
This
|
|
136
|
-
1. The `@staticmethod` decorator is applied first (executed last), transforming the method into a regular function
|
|
137
|
-
2. When the FastMCP decorator is applied, it's capturing what is effectively just a regular function
|
|
138
|
-
3. A static method doesn't have any binding requirements - it doesn't receive a `self` or `cls` parameter
|
|
160
|
+
This works because `@staticmethod` converts the method to a regular function, which the FastMCP decorator can then properly process. However, this is not recommended because the FastMCP decorator will not return a callable staticmethod. Therefore, you should register static methods the same way as other methods.
|
|
139
161
|
|
|
140
|
-
|
|
162
|
+
<Check>
|
|
163
|
+
**Prefer this pattern:**
|
|
141
164
|
|
|
142
165
|
```python
|
|
143
166
|
from fastmcp import FastMCP
|
|
@@ -150,10 +173,9 @@ class MyClass:
|
|
|
150
173
|
return x + y
|
|
151
174
|
|
|
152
175
|
# This also works
|
|
153
|
-
mcp.
|
|
176
|
+
mcp.tool(MyClass.utility)
|
|
154
177
|
```
|
|
155
|
-
|
|
156
|
-
This works for the same reason - a static method is essentially just a function in a class namespace.
|
|
178
|
+
</Check>
|
|
157
179
|
|
|
158
180
|
## Additional Patterns
|
|
159
181
|
|
|
@@ -169,8 +191,8 @@ mcp = FastMCP()
|
|
|
169
191
|
class ComponentProvider:
|
|
170
192
|
def __init__(self, mcp_instance):
|
|
171
193
|
# Register methods
|
|
172
|
-
mcp_instance.
|
|
173
|
-
mcp_instance.
|
|
194
|
+
mcp_instance.tool(self.tool_method)
|
|
195
|
+
mcp_instance.resource("resource://data")(self.resource_method)
|
|
174
196
|
|
|
175
197
|
def tool_method(self, x):
|
|
176
198
|
return x * 2
|
|
@@ -191,11 +213,13 @@ The class automatically registers its methods during initialization, ensuring th
|
|
|
191
213
|
|
|
192
214
|
## Summary
|
|
193
215
|
|
|
194
|
-
|
|
216
|
+
The current behavior of FastMCP decorators with methods is:
|
|
217
|
+
|
|
218
|
+
- **Static methods**: Can be decorated directly and work perfectly with all FastMCP decorators
|
|
219
|
+
- **Class methods**: Cannot be decorated directly and will raise a helpful `ValueError` with guidance
|
|
220
|
+
- **Instance methods**: Should be registered after creating an instance using the decorator calls
|
|
221
|
+
|
|
222
|
+
For class and instance methods, you should register them after creating the instance or class to ensure proper method binding. This ensures that the methods are properly bound before being registered.
|
|
195
223
|
|
|
196
|
-
These patterns apply to all FastMCP decorators and registration methods:
|
|
197
|
-
- `@tool()` and `add_tool()`
|
|
198
|
-
- `@resource()` and `add_resource_fn()`
|
|
199
|
-
- `@prompt()` and `add_prompt()`
|
|
200
224
|
|
|
201
|
-
Understanding these patterns allows you to effectively organize your components into classes while maintaining proper method binding, giving you the benefits of object-oriented design without sacrificing the simplicity of FastMCP's decorator system.
|
|
225
|
+
Understanding these patterns allows you to effectively organize your components into classes while maintaining proper method binding, giving you the benefits of object-oriented design without sacrificing the simplicity of FastMCP's decorator system.
|
|
@@ -25,7 +25,7 @@ from starlette.requests import Request
|
|
|
25
25
|
|
|
26
26
|
mcp = FastMCP(name="HTTP Request Demo")
|
|
27
27
|
|
|
28
|
-
@mcp.tool
|
|
28
|
+
@mcp.tool
|
|
29
29
|
async def user_agent_info() -> dict:
|
|
30
30
|
"""Return information about the user agent."""
|
|
31
31
|
# Get the HTTP request
|
|
@@ -58,7 +58,7 @@ from fastmcp.server.dependencies import get_http_headers
|
|
|
58
58
|
|
|
59
59
|
mcp = FastMCP(name="Headers Demo")
|
|
60
60
|
|
|
61
|
-
@mcp.tool
|
|
61
|
+
@mcp.tool
|
|
62
62
|
async def safe_header_info() -> dict:
|
|
63
63
|
"""Safely get header information without raising errors."""
|
|
64
64
|
# Get headers (returns empty dict if no request context)
|
|
@@ -3,6 +3,7 @@ title: Bearer Token Authentication
|
|
|
3
3
|
sidebarTitle: Bearer Auth
|
|
4
4
|
description: Secure your FastMCP server's HTTP endpoints by validating JWT Bearer tokens.
|
|
5
5
|
icon: key
|
|
6
|
+
tag: "New!"
|
|
6
7
|
---
|
|
7
8
|
|
|
8
9
|
import { VersionBadge } from "/snippets/version-badge.mdx"
|
|
@@ -159,7 +160,7 @@ Once authenticated, your tools, resources, or prompts can access token informati
|
|
|
159
160
|
from fastmcp import FastMCP, Context, ToolError
|
|
160
161
|
from fastmcp.server.dependencies import get_access_token, AccessToken
|
|
161
162
|
|
|
162
|
-
@mcp.tool
|
|
163
|
+
@mcp.tool
|
|
163
164
|
async def get_my_data(ctx: Context) -> dict:
|
|
164
165
|
access_token: AccessToken = get_access_token()
|
|
165
166
|
|