fastmcp 2.9.2__tar.gz → 2.10.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.10.0/.ccignore +7 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/CLAUDE.md +10 -1
- {fastmcp-2.9.2 → fastmcp-2.10.0}/PKG-INFO +3 -2
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/clients/client.mdx +1 -1
- fastmcp-2.10.0/docs/clients/elicitation.mdx +126 -0
- fastmcp-2.10.0/docs/clients/tools.mdx +241 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/docs.json +15 -3
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/integrations/chatgpt.mdx +2 -2
- fastmcp-2.10.0/docs/integrations/eunomia-authorization.mdx +108 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/patterns/cli.mdx +1 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/patterns/tool-transformation.mdx +39 -1
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/servers/auth/bearer.mdx +5 -0
- fastmcp-2.10.0/docs/servers/context.mdx +242 -0
- fastmcp-2.10.0/docs/servers/elicitation.mdx +320 -0
- fastmcp-2.10.0/docs/servers/logging.mdx +194 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/servers/middleware.mdx +8 -5
- fastmcp-2.10.0/docs/servers/progress.mdx +189 -0
- fastmcp-2.10.0/docs/servers/sampling.mdx +190 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/servers/tools.mdx +209 -45
- {fastmcp-2.9.2 → fastmcp-2.10.0}/pyproject.toml +5 -1
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/cli/cli.py +16 -1
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/cli/run.py +4 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/client/auth/oauth.py +5 -82
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/client/client.py +114 -24
- fastmcp-2.10.0/src/fastmcp/client/elicitation.py +63 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/client/transports.py +50 -36
- fastmcp-2.10.0/src/fastmcp/contrib/component_manager/README.md +170 -0
- fastmcp-2.10.0/src/fastmcp/contrib/component_manager/__init__.py +4 -0
- fastmcp-2.10.0/src/fastmcp/contrib/component_manager/component_manager.py +186 -0
- fastmcp-2.10.0/src/fastmcp/contrib/component_manager/component_service.py +225 -0
- fastmcp-2.10.0/src/fastmcp/contrib/component_manager/example.py +59 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/prompts/prompt.py +12 -4
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/resources/resource.py +8 -3
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/resources/template.py +5 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/server/auth/auth.py +15 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/server/auth/providers/bearer.py +41 -3
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/server/auth/providers/bearer_env.py +4 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/server/auth/providers/in_memory.py +15 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/server/context.py +144 -4
- fastmcp-2.10.0/src/fastmcp/server/elicitation.py +160 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/server/http.py +1 -9
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/server/low_level.py +4 -2
- fastmcp-2.10.0/src/fastmcp/server/middleware/__init__.py +19 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/server/middleware/logging.py +11 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/server/middleware/middleware.py +10 -6
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/server/openapi.py +19 -77
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/server/proxy.py +13 -6
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/server/server.py +76 -11
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/settings.py +0 -17
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/tools/tool.py +209 -57
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/tools/tool_manager.py +2 -3
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/tools/tool_transform.py +125 -26
- fastmcp-2.10.0/src/fastmcp/utilities/cli.py +106 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/utilities/components.py +5 -1
- fastmcp-2.10.0/src/fastmcp/utilities/json_schema_type.py +648 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/utilities/openapi.py +69 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/utilities/types.py +50 -19
- fastmcp-2.10.0/tests/auth/providers/test_token_verifier.py +179 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/auth/test_oauth_client.py +3 -1
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/cli/test_cli.py +3 -2
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/client/test_client.py +4 -3
- fastmcp-2.10.0/tests/client/test_elicitation.py +602 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/client/test_notifications.py +6 -6
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/client/test_openapi.py +2 -2
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/client/test_roots.py +1 -3
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/client/test_sampling.py +3 -6
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/client/test_stdio.py +20 -9
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/client/test_streamable_http.py +25 -5
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/contrib/test_bulk_tool_caller.py +4 -1
- fastmcp-2.10.0/tests/contrib/test_component_manager.py +743 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/deprecated/test_mount_import_arg_order.py +2 -2
- fastmcp-2.10.0/tests/server/http/test_auth_setup.py +187 -0
- fastmcp-2.10.0/tests/server/http/test_bearer_auth_backend.py +178 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/http/test_http_dependencies.py +4 -6
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/middleware/test_logging.py +24 -8
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/middleware/test_middleware.py +160 -143
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/middleware/test_rate_limiting.py +21 -14
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/middleware/test_timing.py +8 -4
- fastmcp-2.10.0/tests/server/openapi/test_explode_integration.py +324 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/openapi/test_openapi.py +41 -13
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/openapi/test_openapi_path_parameters.py +4 -13
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/test_import_server.py +6 -6
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/test_mount.py +50 -37
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/test_proxy.py +8 -6
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/test_server.py +51 -29
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/test_server_interactions.py +409 -93
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/test_tool_annotations.py +1 -5
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/test_tool_exclude_args.py +1 -7
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/test_examples.py +12 -12
- fastmcp-2.10.0/tests/tools/test_tool.py +1361 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/tools/test_tool_manager.py +42 -50
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/tools/test_tool_transform.py +325 -44
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/utilities/openapi/test_openapi.py +23 -0
- fastmcp-2.10.0/tests/utilities/test_json_schema_type.py +1525 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/utilities/test_mcp_config.py +4 -4
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/utilities/test_types.py +27 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/uv.lock +232 -52
- fastmcp-2.9.2/docs/clients/tools.mdx +0 -143
- fastmcp-2.9.2/docs/servers/context.mdx +0 -373
- fastmcp-2.9.2/src/fastmcp/server/middleware/__init__.py +0 -6
- fastmcp-2.9.2/tests/tools/test_tool.py +0 -720
- {fastmcp-2.9.2 → fastmcp-2.10.0}/.cursor/rules/core-mcp-objects.mdc +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/.github/ISSUE_TEMPLATE/bug.yml +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/.github/ISSUE_TEMPLATE/enhancement.yml +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/.github/dependabot.yml +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/.github/labeler.yml +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/.github/release.yml +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/.github/workflows/labeler.yml +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/.github/workflows/publish.yml +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/.github/workflows/run-static.yml +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/.github/workflows/run-tests.yml +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/.gitignore +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/.pre-commit-config.yaml +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/AGENTS.md +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/LICENSE +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/README.md +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/Windows_Notes.md +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/.cursor/rules/mintlify.mdc +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/assets/demo-inspector.png +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/assets/favicon.ico +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/assets/images/tutorial-rest-api-result.png +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/assets/logo.png +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/assets/updates/release-2-7.png +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/changelog.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/clients/auth/bearer.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/clients/auth/oauth.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/clients/logging.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/clients/messages.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/clients/progress.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/clients/prompts.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/clients/resources.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/clients/roots.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/clients/sampling.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/clients/transports.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/community/README.md +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/community/showcase.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/css/banner.css +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/css/python-sdk.css +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/css/style.css +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/css/version-badge.css +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/deployment/asgi.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/deployment/running-server.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/getting-started/installation.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/getting-started/quickstart.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/getting-started/welcome.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/integrations/anthropic.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/integrations/claude-code.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/integrations/claude-desktop.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/integrations/contrib.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/integrations/gemini.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/integrations/openai.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/patterns/decorating-methods.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/patterns/http-requests.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/patterns/testing.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-cli-__init__.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-cli-claude.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-cli-cli.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-cli-run.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-client-__init__.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-client-auth-__init__.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-client-auth-bearer.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-client-auth-oauth.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-client-client.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-client-logging.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-client-oauth_callback.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-client-progress.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-client-roots.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-client-sampling.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-client-transports.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-exceptions.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-prompts-__init__.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-prompts-prompt.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-prompts-prompt_manager.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-resources-__init__.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-resources-resource.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-resources-resource_manager.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-resources-template.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-resources-types.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-__init__.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-auth-__init__.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-auth-auth.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-auth-providers-__init__.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-auth-providers-bearer.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-auth-providers-bearer_env.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-auth-providers-in_memory.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-context.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-dependencies.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-http.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-middleware-__init__.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-middleware-error_handling.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-middleware-logging.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-middleware-middleware.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-middleware-rate_limiting.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-middleware-timing.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-middleware.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-openapi.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-proxy.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-server.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-settings.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-tools-__init__.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-tools-tool.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-tools-tool_manager.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-tools-tool_transform.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-utilities-__init__.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-utilities-cache.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-utilities-components.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-utilities-exceptions.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-utilities-http.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-utilities-inspect.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-utilities-json_schema.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-utilities-logging.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-utilities-mcp_config.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-utilities-openapi.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-utilities-tests.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-utilities-types.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/servers/composition.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/servers/openapi.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/servers/prompts.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/servers/proxy.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/servers/resources.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/servers/server.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/snippets/version-badge.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/snippets/youtube-embed.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/tutorials/create-mcp-server.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/tutorials/mcp.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/tutorials/rest-api.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/docs/updates.mdx +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/atproto_mcp/README.md +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/atproto_mcp/demo.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/atproto_mcp/pyproject.toml +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/atproto_mcp/src/atproto_mcp/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/atproto_mcp/src/atproto_mcp/__main__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/atproto_mcp/src/atproto_mcp/_atproto/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/atproto_mcp/src/atproto_mcp/_atproto/_client.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/atproto_mcp/src/atproto_mcp/_atproto/_posts.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/atproto_mcp/src/atproto_mcp/_atproto/_profile.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/atproto_mcp/src/atproto_mcp/_atproto/_read.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/atproto_mcp/src/atproto_mcp/_atproto/_social.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/atproto_mcp/src/atproto_mcp/py.typed +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/atproto_mcp/src/atproto_mcp/server.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/atproto_mcp/src/atproto_mcp/settings.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/atproto_mcp/src/atproto_mcp/types.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/complex_inputs.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/config_server.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/desktop.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/echo.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/get_file.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/in_memory_proxy_example.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/memory.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/mount_example.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/sampling.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/screenshot.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/serializer.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/simple_echo.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/smart_home/README.md +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/smart_home/pyproject.toml +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/smart_home/src/smart_home/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/smart_home/src/smart_home/__main__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/smart_home/src/smart_home/hub.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/smart_home/src/smart_home/lights/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/smart_home/src/smart_home/lights/hue_utils.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/smart_home/src/smart_home/lights/server.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/smart_home/src/smart_home/py.typed +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/smart_home/src/smart_home/settings.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/smart_home/uv.lock +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/tags_example.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/examples/text_me.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/justfile +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/cli/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/cli/claude.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/client/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/client/auth/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/client/auth/bearer.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/client/logging.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/client/messages.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/client/oauth_callback.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/client/progress.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/client/roots.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/client/sampling.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/contrib/README.md +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/contrib/bulk_tool_caller/README.md +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/contrib/bulk_tool_caller/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/contrib/bulk_tool_caller/bulk_tool_caller.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/contrib/bulk_tool_caller/example.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/contrib/mcp_mixin/README.md +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/contrib/mcp_mixin/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/contrib/mcp_mixin/example.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/contrib/mcp_mixin/mcp_mixin.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/exceptions.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/prompts/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/prompts/prompt_manager.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/py.typed +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/resources/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/resources/resource_manager.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/resources/types.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/server/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/server/auth/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/server/auth/providers/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/server/dependencies.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/server/middleware/error_handling.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/server/middleware/rate_limiting.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/server/middleware/timing.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/tools/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/utilities/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/utilities/cache.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/utilities/exceptions.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/utilities/http.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/utilities/inspect.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/utilities/json_schema.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/utilities/logging.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/utilities/mcp_config.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/src/fastmcp/utilities/tests.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/auth/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/auth/providers/test_bearer.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/auth/providers/test_bearer_env.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/cli/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/cli/test_run.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/client/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/client/test_logs.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/client/test_progress.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/client/test_sse.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/conftest.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/contrib/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/contrib/test_mcp_mixin.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/deprecated/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/deprecated/test_deprecated.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/deprecated/test_mount_separators.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/deprecated/test_resource_prefixes.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/deprecated/test_route_type_ignore.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/deprecated/test_settings.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/prompts/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/prompts/test_prompt.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/prompts/test_prompt_manager.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/resources/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/resources/test_file_resources.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/resources/test_function_resources.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/resources/test_resource_manager.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/resources/test_resource_template.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/resources/test_resources.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/http/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/http/test_custom_routes.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/http/test_http_middleware.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/middleware/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/middleware/test_error_handling.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/openapi/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/openapi/test_route_map_fn.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/test_app_state.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/test_auth_integration.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/test_context.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/test_file_server.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/test_logging.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/test_resource_prefix_formats.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/server/test_run_server.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/test_servers/fastmcp_server.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/test_servers/sse.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/test_servers/stdio.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/tools/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/utilities/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/utilities/openapi/__init__.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/utilities/openapi/conftest.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/utilities/openapi/test_openapi_advanced.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/utilities/openapi/test_openapi_fastapi.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/utilities/test_cache.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/utilities/test_inspect.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/utilities/test_json_schema.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/utilities/test_logging.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/utilities/test_tests.py +0 -0
- {fastmcp-2.9.2 → fastmcp-2.10.0}/tests/utilities/test_typeadapter.py +0 -0
fastmcp-2.10.0/.ccignore
ADDED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# FastMCP Development Guidelines
|
|
2
2
|
|
|
3
|
+
## Git
|
|
4
|
+
|
|
5
|
+
This project uses `pre-commit` to run checks on all commits. If your commit doesn't pass the checks, it will not be created. Do not attempt to amend commits to pass checks.
|
|
6
|
+
|
|
7
|
+
## Documentation
|
|
8
|
+
|
|
9
|
+
- Documentation uses the Mintlify framework
|
|
10
|
+
- Files must be present in docs.json to be included in the documentation
|
|
11
|
+
|
|
3
12
|
## Testing and Investigation
|
|
4
13
|
|
|
5
14
|
### In-Memory Transport - Always Preferred
|
|
@@ -34,4 +43,4 @@ async with Client(transport=StreamableHttpTransport(server_url)) as client:
|
|
|
34
43
|
- You must always run pre-commit if you open a PR, because it is run as part of a required check.
|
|
35
44
|
- When opening PRs, apply labels appropriately for bugs/breaking changes/enhancements/features. Generally, improvements are enhancements (not features) unless told otherwise.
|
|
36
45
|
- NEVER modify files in docs/python-sdk/**, as they are auto-generated.
|
|
37
|
-
- Use # type: ignore[attr-defined] in unit tests when accessing an MCP result of indeterminate type instead of asserting its type
|
|
46
|
+
- Use # type: ignore[attr-defined] in unit tests when accessing an MCP result of indeterminate type instead of asserting its type
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastmcp
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.10.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
|
|
@@ -20,8 +20,9 @@ Requires-Python: >=3.10
|
|
|
20
20
|
Requires-Dist: authlib>=1.5.2
|
|
21
21
|
Requires-Dist: exceptiongroup>=1.2.2
|
|
22
22
|
Requires-Dist: httpx>=0.28.1
|
|
23
|
-
Requires-Dist: mcp
|
|
23
|
+
Requires-Dist: mcp>=1.10.0
|
|
24
24
|
Requires-Dist: openapi-pydantic>=0.5.1
|
|
25
|
+
Requires-Dist: pydantic[email]>=2.11.7
|
|
25
26
|
Requires-Dist: python-dotenv>=1.1.0
|
|
26
27
|
Requires-Dist: rich>=13.9.4
|
|
27
28
|
Requires-Dist: typer>=0.15.2
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: User Elicitation
|
|
3
|
+
sidebarTitle: Elicitation
|
|
4
|
+
description: Handle server-initiated user input requests with structured schemas.
|
|
5
|
+
icon: message-question
|
|
6
|
+
tag: NEW
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
import { VersionBadge } from "/snippets/version-badge.mdx";
|
|
10
|
+
|
|
11
|
+
<VersionBadge version="2.10.0" />
|
|
12
|
+
|
|
13
|
+
## What is Elicitation?
|
|
14
|
+
|
|
15
|
+
Elicitation allows MCP servers to request structured input from users during tool execution. Instead of requiring all inputs upfront, servers can interactively ask users for information as needed - like prompting for missing parameters, requesting clarification, or gathering additional context.
|
|
16
|
+
|
|
17
|
+
For example, a file management tool might ask "Which directory should I create?" or a data analysis tool might request "What date range should I analyze?"
|
|
18
|
+
|
|
19
|
+
## How FastMCP Makes Elicitation Easy
|
|
20
|
+
|
|
21
|
+
FastMCP's client provides a helpful abstraction layer that:
|
|
22
|
+
|
|
23
|
+
- **Converts JSON schemas to Python types**: The raw MCP protocol uses JSON schemas, but FastMCP automatically converts these to Python dataclasses
|
|
24
|
+
- **Provides structured constructors**: Instead of manually building dictionaries that match the schema, you get dataclass constructors that ensure correct structure
|
|
25
|
+
- **Handles type conversion**: FastMCP takes care of converting between JSON representations and Python objects
|
|
26
|
+
- **Runtime introspection**: You can inspect the generated dataclass fields to understand the expected structure
|
|
27
|
+
|
|
28
|
+
When you implement an elicitation handler, FastMCP gives you a dataclass type that matches the server's schema, making it easy to create properly structured responses without having to manually parse JSON schemas.
|
|
29
|
+
|
|
30
|
+
## Elicitation Handler
|
|
31
|
+
|
|
32
|
+
Provide an `elicitation_handler` function when creating the client. FastMCP automatically converts the server's JSON schema into a Python dataclass type, making it easy to construct the response:
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
from fastmcp import Client
|
|
36
|
+
from fastmcp.client.elicitation import ElicitResult
|
|
37
|
+
|
|
38
|
+
async def elicitation_handler(message: str, response_type: type, params, context):
|
|
39
|
+
# Present the message to the user and collect input
|
|
40
|
+
user_input = input(f"{message}: ")
|
|
41
|
+
|
|
42
|
+
# Create response using the provided dataclass type
|
|
43
|
+
# FastMCP converted the JSON schema to this Python type for you
|
|
44
|
+
response_data = response_type(value=user_input)
|
|
45
|
+
|
|
46
|
+
# You can return data directly - FastMCP will implicitly accept the elicitation
|
|
47
|
+
return response_data
|
|
48
|
+
|
|
49
|
+
# Or explicitly return an ElicitResult for more control
|
|
50
|
+
# return ElicitResult(action="accept", content=response_data)
|
|
51
|
+
|
|
52
|
+
client = Client(
|
|
53
|
+
"my_mcp_server.py",
|
|
54
|
+
elicitation_handler=elicitation_handler,
|
|
55
|
+
)
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Handler Parameters
|
|
59
|
+
|
|
60
|
+
The elicitation handler receives four parameters:
|
|
61
|
+
|
|
62
|
+
<Card icon="code" title="Elicitation Handler Parameters">
|
|
63
|
+
<ResponseField name="message" type="str">
|
|
64
|
+
The prompt message to display to the user
|
|
65
|
+
</ResponseField>
|
|
66
|
+
|
|
67
|
+
<ResponseField name="response_type" type="type">
|
|
68
|
+
A Python dataclass type that FastMCP created from the server's JSON schema. Use this to construct your response with proper typing and IDE support. If the server requests an empty object (indicating no response), this will be `None`.
|
|
69
|
+
</ResponseField>
|
|
70
|
+
|
|
71
|
+
<ResponseField name="params" type="ElicitRequestParams">
|
|
72
|
+
The original MCP elicitation request parameters, including the raw JSON schema in `params.requestedSchema` if you need it
|
|
73
|
+
</ResponseField>
|
|
74
|
+
|
|
75
|
+
<ResponseField name="context" type="RequestContext">
|
|
76
|
+
Request context containing metadata about the elicitation request
|
|
77
|
+
</ResponseField>
|
|
78
|
+
</Card>
|
|
79
|
+
|
|
80
|
+
### Response Actions
|
|
81
|
+
|
|
82
|
+
The handler can return data directly (which implicitly accepts the elicitation) or an `ElicitResult` object for more control over the response action:
|
|
83
|
+
|
|
84
|
+
<Card icon="code" title="ElicitResult Structure">
|
|
85
|
+
<ResponseField name="action" type="Literal['accept', 'decline', 'cancel']">
|
|
86
|
+
How the user responded to the elicitation request
|
|
87
|
+
</ResponseField>
|
|
88
|
+
|
|
89
|
+
<ResponseField name="content" type="dataclass instance | dict | None">
|
|
90
|
+
The user's input data (required for "accept", omitted for "decline"/"cancel")
|
|
91
|
+
</ResponseField>
|
|
92
|
+
</Card>
|
|
93
|
+
|
|
94
|
+
**Action Types:**
|
|
95
|
+
- **`accept`**: User provided valid input - include their data in the `content` field
|
|
96
|
+
- **`decline`**: User chose not to provide the requested information - omit `content`
|
|
97
|
+
- **`cancel`**: User cancelled the entire operation - omit `content`
|
|
98
|
+
|
|
99
|
+
## Basic Example
|
|
100
|
+
|
|
101
|
+
```python
|
|
102
|
+
from fastmcp import Client
|
|
103
|
+
from fastmcp.client.elicitation import ElicitResult
|
|
104
|
+
|
|
105
|
+
async def basic_elicitation_handler(message: str, response_type: type, params, context):
|
|
106
|
+
print(f"Server asks: {message}")
|
|
107
|
+
|
|
108
|
+
# Simple text input for demonstration
|
|
109
|
+
user_response = input("Your response: ")
|
|
110
|
+
|
|
111
|
+
if not user_response:
|
|
112
|
+
# For non-acceptance, use ElicitResult explicitly
|
|
113
|
+
return ElicitResult(action="decline")
|
|
114
|
+
|
|
115
|
+
# Use the response_type dataclass to create a properly structured response
|
|
116
|
+
# FastMCP handles the conversion from JSON schema to Python type
|
|
117
|
+
# Return data directly - FastMCP will implicitly accept the elicitation
|
|
118
|
+
return response_type(value=user_response)
|
|
119
|
+
|
|
120
|
+
client = Client(
|
|
121
|
+
"my_mcp_server.py",
|
|
122
|
+
elicitation_handler=basic_elicitation_handler
|
|
123
|
+
)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Tool Operations
|
|
3
|
+
sidebarTitle: Tools
|
|
4
|
+
description: Discover and execute server-side tools with the FastMCP client.
|
|
5
|
+
icon: wrench
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
import { VersionBadge } from '/snippets/version-badge.mdx'
|
|
9
|
+
|
|
10
|
+
<VersionBadge version="2.0.0" />
|
|
11
|
+
|
|
12
|
+
Tools are executable functions exposed by MCP servers. The FastMCP client provides methods to discover available tools and execute them with arguments.
|
|
13
|
+
|
|
14
|
+
## Discovering Tools
|
|
15
|
+
|
|
16
|
+
Use `list_tools()` to retrieve all tools available on the server:
|
|
17
|
+
|
|
18
|
+
```python
|
|
19
|
+
async with client:
|
|
20
|
+
tools = await client.list_tools()
|
|
21
|
+
# tools -> list[mcp.types.Tool]
|
|
22
|
+
|
|
23
|
+
for tool in tools:
|
|
24
|
+
print(f"Tool: {tool.name}")
|
|
25
|
+
print(f"Description: {tool.description}")
|
|
26
|
+
if tool.inputSchema:
|
|
27
|
+
print(f"Parameters: {tool.inputSchema}")
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Executing Tools
|
|
31
|
+
|
|
32
|
+
### Basic Execution
|
|
33
|
+
|
|
34
|
+
Execute a tool using `call_tool()` with the tool name and arguments:
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
async with client:
|
|
38
|
+
# Simple tool call
|
|
39
|
+
result = await client.call_tool("add", {"a": 5, "b": 3})
|
|
40
|
+
# result -> CallToolResult with structured and unstructured data
|
|
41
|
+
|
|
42
|
+
# Access structured data (automatically deserialized)
|
|
43
|
+
print(result.data) # 8 (int) or {"result": 8} for primitive types
|
|
44
|
+
|
|
45
|
+
# Access traditional content blocks
|
|
46
|
+
print(result.content[0].text) # "8" (TextContent)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Advanced Execution Options
|
|
50
|
+
|
|
51
|
+
The `call_tool()` method supports additional parameters for timeout control and progress monitoring:
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
async with client:
|
|
55
|
+
# With timeout (aborts if execution takes longer than 2 seconds)
|
|
56
|
+
result = await client.call_tool(
|
|
57
|
+
"long_running_task",
|
|
58
|
+
{"param": "value"},
|
|
59
|
+
timeout=2.0
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
# With progress handler (to track execution progress)
|
|
63
|
+
result = await client.call_tool(
|
|
64
|
+
"long_running_task",
|
|
65
|
+
{"param": "value"},
|
|
66
|
+
progress_handler=my_progress_handler
|
|
67
|
+
)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**Parameters:**
|
|
71
|
+
- `name`: The tool name (string)
|
|
72
|
+
- `arguments`: Dictionary of arguments to pass to the tool (optional)
|
|
73
|
+
- `timeout`: Maximum execution time in seconds (optional, overrides client-level timeout)
|
|
74
|
+
- `progress_handler`: Progress callback function (optional, overrides client-level handler)
|
|
75
|
+
|
|
76
|
+
## Handling Results
|
|
77
|
+
|
|
78
|
+
<VersionBadge version="2.10.0" />
|
|
79
|
+
|
|
80
|
+
Tool execution returns a `CallToolResult` object with both structured and traditional content. FastMCP's standout feature is the `.data` property, which doesn't just provide raw JSON but actually hydrates complete Python objects including complex types like datetimes, UUIDs, and custom classes.
|
|
81
|
+
|
|
82
|
+
### CallToolResult Properties
|
|
83
|
+
|
|
84
|
+
<Card icon="code" title="CallToolResult Properties">
|
|
85
|
+
<ResponseField name=".data" type="Any">
|
|
86
|
+
**FastMCP exclusive**: Fully hydrated Python objects with complex type support (datetimes, UUIDs, custom classes). Goes beyond JSON to provide complete object reconstruction from output schemas.
|
|
87
|
+
</ResponseField>
|
|
88
|
+
|
|
89
|
+
<ResponseField name=".content" type="list[mcp.types.ContentBlock]">
|
|
90
|
+
Standard MCP content blocks (`TextContent`, `ImageContent`, `AudioContent`, etc.) available from all MCP servers.
|
|
91
|
+
</ResponseField>
|
|
92
|
+
|
|
93
|
+
<ResponseField name=".structured_content" type="dict[str, Any] | None">
|
|
94
|
+
Standard MCP structured JSON data as sent by the server, available from all MCP servers that support structured outputs.
|
|
95
|
+
</ResponseField>
|
|
96
|
+
|
|
97
|
+
<ResponseField name=".is_error" type="bool">
|
|
98
|
+
Boolean indicating if the tool execution failed.
|
|
99
|
+
</ResponseField>
|
|
100
|
+
</Card>
|
|
101
|
+
|
|
102
|
+
### Structured Data Access
|
|
103
|
+
|
|
104
|
+
FastMCP's `.data` property provides fully hydrated Python objects, not just JSON dictionaries. This includes complex type reconstruction:
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
from datetime import datetime
|
|
108
|
+
from uuid import UUID
|
|
109
|
+
|
|
110
|
+
async with client:
|
|
111
|
+
result = await client.call_tool("get_weather", {"city": "London"})
|
|
112
|
+
|
|
113
|
+
# FastMCP reconstructs complete Python objects from the server's output schema
|
|
114
|
+
weather = result.data # Server-defined WeatherReport object
|
|
115
|
+
print(f"Temperature: {weather.temperature}°C at {weather.timestamp}")
|
|
116
|
+
print(f"Station: {weather.station_id}")
|
|
117
|
+
print(f"Humidity: {weather.humidity}%")
|
|
118
|
+
|
|
119
|
+
# The timestamp is a real datetime object, not a string!
|
|
120
|
+
assert isinstance(weather.timestamp, datetime)
|
|
121
|
+
assert isinstance(weather.station_id, UUID)
|
|
122
|
+
|
|
123
|
+
# Compare with raw structured JSON (standard MCP)
|
|
124
|
+
print(f"Raw JSON: {result.structured_content}")
|
|
125
|
+
# {"temperature": 20, "timestamp": "2024-01-15T14:30:00Z", "station_id": "123e4567-..."}
|
|
126
|
+
|
|
127
|
+
# Traditional content blocks (standard MCP)
|
|
128
|
+
print(f"Text content: {result.content[0].text}")
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Fallback Behavior
|
|
132
|
+
|
|
133
|
+
For tools without output schemas or when deserialization fails, `.data` will be `None`:
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
async with client:
|
|
137
|
+
result = await client.call_tool("legacy_tool", {"param": "value"})
|
|
138
|
+
|
|
139
|
+
if result.data is not None:
|
|
140
|
+
# Structured output available and successfully deserialized
|
|
141
|
+
print(f"Structured: {result.data}")
|
|
142
|
+
else:
|
|
143
|
+
# No structured output or deserialization failed - use content blocks
|
|
144
|
+
for content in result.content:
|
|
145
|
+
if hasattr(content, 'text'):
|
|
146
|
+
print(f"Text result: {content.text}")
|
|
147
|
+
elif hasattr(content, 'data'):
|
|
148
|
+
print(f"Binary data: {len(content.data)} bytes")
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Primitive Type Unwrapping
|
|
152
|
+
|
|
153
|
+
<Tip>
|
|
154
|
+
FastMCP servers automatically wrap non-object results (like `int`, `str`, `bool`) in a `{"result": value}` structure to create valid structured outputs. FastMCP clients understand this convention and automatically unwrap the value in `.data` for convenience, so you get the original primitive value instead of a wrapper object.
|
|
155
|
+
</Tip>
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
async with client:
|
|
159
|
+
result = await client.call_tool("calculate_sum", {"a": 5, "b": 3})
|
|
160
|
+
|
|
161
|
+
# FastMCP client automatically unwraps for convenience
|
|
162
|
+
print(result.data) # 8 (int) - the original value
|
|
163
|
+
|
|
164
|
+
# Raw structured content shows the server-side wrapping
|
|
165
|
+
print(result.structured_content) # {"result": 8}
|
|
166
|
+
|
|
167
|
+
# Other MCP clients would need to manually access ["result"]
|
|
168
|
+
# value = result.structured_content["result"] # Not needed with FastMCP!
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Error Handling
|
|
172
|
+
|
|
173
|
+
### Exception-Based Error Handling
|
|
174
|
+
|
|
175
|
+
By default, `call_tool()` raises a `ToolError` if the tool execution fails:
|
|
176
|
+
|
|
177
|
+
```python
|
|
178
|
+
from fastmcp.exceptions import ToolError
|
|
179
|
+
|
|
180
|
+
async with client:
|
|
181
|
+
try:
|
|
182
|
+
result = await client.call_tool("potentially_failing_tool", {"param": "value"})
|
|
183
|
+
print("Tool succeeded:", result.data)
|
|
184
|
+
except ToolError as e:
|
|
185
|
+
print(f"Tool failed: {e}")
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Manual Error Checking
|
|
189
|
+
|
|
190
|
+
You can disable automatic error raising and manually check the result:
|
|
191
|
+
|
|
192
|
+
```python
|
|
193
|
+
async with client:
|
|
194
|
+
result = await client.call_tool(
|
|
195
|
+
"potentially_failing_tool",
|
|
196
|
+
{"param": "value"},
|
|
197
|
+
raise_on_error=False
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
if result.is_error:
|
|
201
|
+
print(f"Tool failed: {result.content[0].text}")
|
|
202
|
+
else:
|
|
203
|
+
print(f"Tool succeeded: {result.data}")
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Raw MCP Protocol Access
|
|
207
|
+
|
|
208
|
+
For complete control, use `call_tool_mcp()` which returns the raw MCP protocol object:
|
|
209
|
+
|
|
210
|
+
```python
|
|
211
|
+
async with client:
|
|
212
|
+
result = await client.call_tool_mcp("potentially_failing_tool", {"param": "value"})
|
|
213
|
+
# result -> mcp.types.CallToolResult
|
|
214
|
+
|
|
215
|
+
if result.isError:
|
|
216
|
+
print(f"Tool failed: {result.content}")
|
|
217
|
+
else:
|
|
218
|
+
print(f"Tool succeeded: {result.content}")
|
|
219
|
+
# Note: No automatic deserialization with call_tool_mcp()
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## Argument Handling
|
|
223
|
+
|
|
224
|
+
Arguments are passed as a dictionary to the tool:
|
|
225
|
+
|
|
226
|
+
```python
|
|
227
|
+
async with client:
|
|
228
|
+
# Simple arguments
|
|
229
|
+
result = await client.call_tool("greet", {"name": "World"})
|
|
230
|
+
|
|
231
|
+
# Complex arguments
|
|
232
|
+
result = await client.call_tool("process_data", {
|
|
233
|
+
"config": {"format": "json", "validate": True},
|
|
234
|
+
"items": [1, 2, 3, 4, 5],
|
|
235
|
+
"metadata": {"source": "api", "version": "1.0"}
|
|
236
|
+
})
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
<Tip>
|
|
240
|
+
For multi-server clients, tool names are automatically prefixed with the server name (e.g., `weather_get_forecast` for a tool named `get_forecast` on the `weather` server).
|
|
241
|
+
</Tip>
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"decoration": "windows"
|
|
13
13
|
},
|
|
14
14
|
"banner": {
|
|
15
|
-
"content": "
|
|
15
|
+
"content": "FastMCP Cloud is here! [Join the beta](https://fastmcp.link/x0Kyhy2)."
|
|
16
16
|
},
|
|
17
17
|
"colors": {
|
|
18
18
|
"dark": "#f72585",
|
|
@@ -69,8 +69,18 @@
|
|
|
69
69
|
"pages": [
|
|
70
70
|
"servers/tools",
|
|
71
71
|
"servers/resources",
|
|
72
|
-
"servers/prompts"
|
|
73
|
-
|
|
72
|
+
"servers/prompts"
|
|
73
|
+
]
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"group": "Advanced Features",
|
|
77
|
+
"icon": "stars",
|
|
78
|
+
"pages": [
|
|
79
|
+
"servers/context",
|
|
80
|
+
"servers/elicitation",
|
|
81
|
+
"servers/logging",
|
|
82
|
+
"servers/progress",
|
|
83
|
+
"servers/sampling"
|
|
74
84
|
]
|
|
75
85
|
},
|
|
76
86
|
{
|
|
@@ -106,6 +116,7 @@
|
|
|
106
116
|
"group": "Advanced Features",
|
|
107
117
|
"icon": "stars",
|
|
108
118
|
"pages": [
|
|
119
|
+
"clients/elicitation",
|
|
109
120
|
"clients/logging",
|
|
110
121
|
"clients/progress",
|
|
111
122
|
"clients/sampling",
|
|
@@ -130,6 +141,7 @@
|
|
|
130
141
|
"integrations/claude-desktop",
|
|
131
142
|
"integrations/gemini",
|
|
132
143
|
"integrations/openai",
|
|
144
|
+
"integrations/eunomia-authorization",
|
|
133
145
|
"integrations/contrib"
|
|
134
146
|
]
|
|
135
147
|
},
|
|
@@ -13,7 +13,7 @@ MCP integration with ChatGPT is currently limited to **Deep Research** functiona
|
|
|
13
13
|
</Note>
|
|
14
14
|
|
|
15
15
|
<Tip>
|
|
16
|
-
OpenAI's official MCP documentation and examples are built with **FastMCP v2**! Check out their [
|
|
16
|
+
OpenAI's official MCP documentation and examples are built with **FastMCP v2**! Check out their [simple Deep Research-style MCP server example](https://github.com/openai/sample-deep-research-mcp) for a quick reference similar to the one in this document, or their [more complete Deep Research example](https://github.com/openai/openai-cookbook/tree/main/examples/deep_research_api/how_to_build_a_deep_research_mcp_server) from the OpenAI Cookbook, which includes vector search and more.
|
|
17
17
|
</Tip>
|
|
18
18
|
|
|
19
19
|
## Deep Research
|
|
@@ -42,7 +42,7 @@ A Deep Research-compatible server must implement these two required tools:
|
|
|
42
42
|
|
|
43
43
|
The `search` tool should take a query (of any kind!) and return IDs. The `fetch` tool should take an ID and return the record.
|
|
44
44
|
|
|
45
|
-
Here's a reference server implementation you can adapt (see also [OpenAI's sample server](https://github.com/openai/
|
|
45
|
+
Here's a reference server implementation you can adapt (see also [OpenAI's sample server](https://github.com/openai/sample-deep-research-mcp) for comparison):
|
|
46
46
|
|
|
47
47
|
```python server.py [expandable]
|
|
48
48
|
import json
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Eunomia Authorization + FastMCP
|
|
3
|
+
sidebarTitle: Eunomia Authorization
|
|
4
|
+
description: Add policy-based authorization to your FastMCP servers
|
|
5
|
+
icon: layer-group
|
|
6
|
+
tag: NEW
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
Add **policy-based authorization** to your FastMCP servers with minimal code changes using Eunomia authorization middleware.
|
|
10
|
+
|
|
11
|
+
Control which actions MCP clients can perform on your server by restricting how the agent can access resources, tools and prompts by using JSON-based policies, while obtaining a comprehensive audit log of all access attempts and violations.
|
|
12
|
+
|
|
13
|
+
## Eunomia Authorization Middleware
|
|
14
|
+
|
|
15
|
+
The middleware intercepts all MCP requests to your server and automatically maps MCP methods to authorization checks.
|
|
16
|
+
|
|
17
|
+
```mermaid
|
|
18
|
+
sequenceDiagram
|
|
19
|
+
participant MCPClient as MCP Client
|
|
20
|
+
participant EunomiaMiddleware as Eunomia Middleware
|
|
21
|
+
participant MCPServer as FastMCP Server
|
|
22
|
+
participant EunomiaServer as Eunomia Server
|
|
23
|
+
|
|
24
|
+
MCPClient->>EunomiaMiddleware: MCP Request
|
|
25
|
+
Note over MCPClient, EunomiaMiddleware: Middleware intercepts request to server
|
|
26
|
+
EunomiaMiddleware->>EunomiaServer: Authorization Check
|
|
27
|
+
EunomiaServer->>EunomiaMiddleware: Authorization Decision (allow/deny)
|
|
28
|
+
EunomiaMiddleware-->>MCPClient: MCP Unauthorized Error (if denied)
|
|
29
|
+
EunomiaMiddleware->>MCPServer: MCP Request (if allowed)
|
|
30
|
+
MCPServer-->>MCPClient: MCP Response (if allowed)
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
<Note>
|
|
34
|
+
Eunomia is an AI-specific standalone authorization server that handles policy decisions. You must have an Eunomia server running alongside your FastMCP server for the middleware to function.
|
|
35
|
+
|
|
36
|
+
Run it in the background with Docker:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
docker run -d -p 8000:8000 ttommitt/eunomia-server:latest
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
</Note>
|
|
43
|
+
|
|
44
|
+
### Create a Server with Authorization
|
|
45
|
+
|
|
46
|
+
First, install the `eunomia-mcp` package:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install eunomia-mcp
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Then create a FastMCP server and add the Eunomia middleware with a few lines of code:
|
|
53
|
+
|
|
54
|
+
```python server.py
|
|
55
|
+
from fastmcp import FastMCP
|
|
56
|
+
from eunomia_mcp import create_eunomia_middleware
|
|
57
|
+
|
|
58
|
+
mcp = FastMCP("Secure FastMCP Server 🔒")
|
|
59
|
+
|
|
60
|
+
@mcp.tool()
|
|
61
|
+
def add(a: int, b: int) -> int:
|
|
62
|
+
"""Add two numbers"""
|
|
63
|
+
return a + b
|
|
64
|
+
|
|
65
|
+
middleware = [create_eunomia_middleware()]
|
|
66
|
+
app = mcp.http_app(middleware=middleware)
|
|
67
|
+
|
|
68
|
+
if __name__ == "__main__":
|
|
69
|
+
import uvicorn
|
|
70
|
+
uvicorn.run(app, host="0.0.0.0", port=8080)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Configure Access Policies
|
|
74
|
+
|
|
75
|
+
Use the `eunomia-mcp` CLI in your terminal to manage your authorization policies:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# Create a default policy configuration file
|
|
79
|
+
eunomia-mcp init
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
This creates a policy file you can customize to control access to your MCP tools and resources.
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# Once ready, validate your policy
|
|
86
|
+
eunomia-mcp validate mcp_policies.json
|
|
87
|
+
|
|
88
|
+
# And push it to the Eunomia server
|
|
89
|
+
eunomia-mcp push mcp_policies.json
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Run the Server
|
|
93
|
+
|
|
94
|
+
Start your FastMCP server normally:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
python server.py
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The middleware will now intercept all MCP requests and check them against your policies. Requests include agent identification through headers like `X-Agent-ID`, `X-User-ID`, or `Authorization` and an automatic mapping of MCP methods to authorization resources and actions.
|
|
101
|
+
|
|
102
|
+
<Tip>
|
|
103
|
+
For detailed policy configuration, custom authentication, and advanced
|
|
104
|
+
deployment patterns, visit the [Eunomia MCP Middleware
|
|
105
|
+
repository][eunomia-github].
|
|
106
|
+
</Tip>
|
|
107
|
+
|
|
108
|
+
[eunomia-github]: https://github.com/whataboutyou-ai/eunomia/tree/main/pkgs/extensions/mcp
|
|
@@ -46,6 +46,7 @@ This command runs the server directly in your current Python environment. You ar
|
|
|
46
46
|
| Host | `--host` | Host to bind to when using http transport (default: 127.0.0.1) |
|
|
47
47
|
| Port | `--port`, `-p` | Port to bind to when using http transport (default: 8000) |
|
|
48
48
|
| Log Level | `--log-level`, `-l` | Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL) |
|
|
49
|
+
| No Banner | `--no-banner` | Disable the startup banner display |
|
|
49
50
|
|
|
50
51
|
|
|
51
52
|
#### Server Specification
|
|
@@ -89,6 +89,7 @@ The `Tool.from_tool()` class method is the primary way to create a transformed t
|
|
|
89
89
|
- `description`: An optional description for the new tool.
|
|
90
90
|
- `transform_args`: A dictionary of `ArgTransform` objects, one for each argument you want to modify.
|
|
91
91
|
- `transform_fn`: An optional function that will be called instead of the parent tool's logic.
|
|
92
|
+
- `output_schema`: Control output schema and structured outputs (see [Output Schema Control](#output-schema-control)).
|
|
92
93
|
- `tags`: An optional set of tags for the new tool.
|
|
93
94
|
- `annotations`: An optional set of `ToolAnnotations` for the new tool.
|
|
94
95
|
- `serializer`: An optional function that will be called to serialize the result of the new tool.
|
|
@@ -439,7 +440,44 @@ mcp.add_tool(new_tool)
|
|
|
439
440
|
|
|
440
441
|
<Tip>
|
|
441
442
|
In the above example, `**kwargs` receives the renamed argument `b`, not the original argument `y`. It is therefore recommended to use with `forward()`, not `forward_raw()`.
|
|
442
|
-
</Tip>
|
|
443
|
+
</Tip>
|
|
444
|
+
|
|
445
|
+
## Output Schema Control
|
|
446
|
+
|
|
447
|
+
<VersionBadge version="2.10.0" />
|
|
448
|
+
|
|
449
|
+
Transformed tools inherit output schemas from their parent by default, but you can control this behavior:
|
|
450
|
+
|
|
451
|
+
**Inherit from Parent (Default)**
|
|
452
|
+
```python
|
|
453
|
+
Tool.from_tool(parent_tool, name="renamed_tool")
|
|
454
|
+
```
|
|
455
|
+
The transformed tool automatically uses the parent tool's output schema and structured output behavior.
|
|
456
|
+
|
|
457
|
+
**Custom Output Schema**
|
|
458
|
+
```python
|
|
459
|
+
Tool.from_tool(parent_tool, output_schema={
|
|
460
|
+
"type": "object",
|
|
461
|
+
"properties": {"status": {"type": "string"}}
|
|
462
|
+
})
|
|
463
|
+
```
|
|
464
|
+
Provide your own schema that differs from the parent. The tool must return data matching this schema.
|
|
465
|
+
|
|
466
|
+
**Remove Output Schema**
|
|
467
|
+
```python
|
|
468
|
+
Tool.from_tool(parent_tool, output_schema=False)
|
|
469
|
+
```
|
|
470
|
+
Removes the output schema declaration. Automatic structured content still works for object-like returns (dict, dataclass, Pydantic models) but primitive types won't be structured.
|
|
471
|
+
|
|
472
|
+
**Full Control with Transform Functions**
|
|
473
|
+
```python
|
|
474
|
+
async def custom_output(**kwargs) -> ToolResult:
|
|
475
|
+
result = await forward(**kwargs)
|
|
476
|
+
return ToolResult(content=[...], structured_content={...})
|
|
477
|
+
|
|
478
|
+
Tool.from_tool(parent_tool, transform_fn=custom_output)
|
|
479
|
+
```
|
|
480
|
+
Use a transform function returning `ToolResult` for complete control over both content blocks and structured outputs.
|
|
443
481
|
|
|
444
482
|
## Common Patterns
|
|
445
483
|
|
|
@@ -53,6 +53,7 @@ from fastmcp.server.auth import BearerAuthProvider
|
|
|
53
53
|
auth = BearerAuthProvider(
|
|
54
54
|
jwks_uri="https://my-identity-provider.com/.well-known/jwks.json",
|
|
55
55
|
issuer="https://my-identity-provider.com/",
|
|
56
|
+
algorithm="RS512",
|
|
56
57
|
audience="my-mcp-server"
|
|
57
58
|
)
|
|
58
59
|
|
|
@@ -74,6 +75,10 @@ mcp = FastMCP(name="My MCP Server", auth=auth)
|
|
|
74
75
|
Expected JWT `iss` claim value
|
|
75
76
|
</ParamField>
|
|
76
77
|
|
|
78
|
+
<ParamField body="algorithm" type="str | None">
|
|
79
|
+
Algorithm for decoding JWT token. Defaults to 'RS256'
|
|
80
|
+
</ParamField>
|
|
81
|
+
|
|
77
82
|
<ParamField body="audience" type="str | None">
|
|
78
83
|
Expected JWT `aud` claim value
|
|
79
84
|
</ParamField>
|