fastmcp 2.3.4__tar.gz → 2.4.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.4.0/.github/labeler.yml +29 -0
- fastmcp-2.4.0/.github/workflows/labeler.yml +12 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/.github/workflows/run-static.yml +3 -6
- {fastmcp-2.3.4 → fastmcp-2.4.0}/.github/workflows/run-tests.yml +4 -8
- fastmcp-2.4.0/AGENTS.md +67 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/PKG-INFO +26 -3
- {fastmcp-2.3.4 → fastmcp-2.4.0}/README.md +24 -1
- fastmcp-2.4.0/docs/clients/advanced-features.mdx +152 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/docs/clients/client.mdx +114 -106
- fastmcp-2.4.0/docs/clients/transports.mdx +380 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/docs/deployment/asgi.mdx +11 -8
- {fastmcp-2.3.4 → fastmcp-2.4.0}/docs/deployment/cli.mdx +13 -5
- {fastmcp-2.3.4 → fastmcp-2.4.0}/docs/deployment/running-server.mdx +4 -4
- {fastmcp-2.3.4 → fastmcp-2.4.0}/docs/docs.json +2 -1
- {fastmcp-2.3.4 → fastmcp-2.4.0}/docs/getting-started/quickstart.mdx +2 -1
- {fastmcp-2.3.4 → fastmcp-2.4.0}/docs/patterns/openapi.mdx +44 -7
- {fastmcp-2.3.4 → fastmcp-2.4.0}/docs/patterns/testing.mdx +1 -1
- {fastmcp-2.3.4 → fastmcp-2.4.0}/docs/servers/composition.mdx +59 -34
- {fastmcp-2.3.4 → fastmcp-2.4.0}/docs/servers/fastmcp.mdx +2 -2
- {fastmcp-2.3.4 → fastmcp-2.4.0}/docs/servers/proxy.mdx +76 -22
- fastmcp-2.4.0/examples/in_memory_proxy_example.py +82 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/pyproject.toml +2 -1
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/cli/cli.py +30 -138
- fastmcp-2.4.0/src/fastmcp/cli/run.py +179 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/client/client.py +80 -20
- fastmcp-2.4.0/src/fastmcp/client/logging.py +27 -0
- fastmcp-2.4.0/src/fastmcp/client/progress.py +38 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/client/transports.py +153 -67
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/server/context.py +6 -3
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/server/http.py +70 -15
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/server/openapi.py +113 -10
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/server/server.py +414 -138
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/settings.py +16 -0
- fastmcp-2.4.0/src/fastmcp/utilities/mcp_config.py +76 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/utilities/openapi.py +233 -602
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/utilities/tests.py +8 -4
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/cli/test_cli.py +23 -90
- fastmcp-2.4.0/tests/cli/test_run.py +262 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/client/test_client.py +154 -7
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/client/test_logs.py +2 -2
- fastmcp-2.4.0/tests/client/test_progress.py +70 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/client/test_sse.py +4 -4
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/client/test_streamable_http.py +5 -1
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/contrib/test_bulk_tool_caller.py +0 -8
- {fastmcp-2.3.4/tests → fastmcp-2.4.0/tests/deprecated}/test_deprecated.py +88 -3
- fastmcp-2.4.0/tests/deprecated/test_mount_separators.py +85 -0
- fastmcp-2.4.0/tests/deprecated/test_resource_prefixes.py +98 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/resources/test_file_resources.py +2 -1
- fastmcp-2.4.0/tests/server/test_app_state.py +26 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/server/test_auth_integration.py +0 -29
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/server/test_http_middleware.py +0 -6
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/server/test_import_server.py +23 -27
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/server/test_lifespan.py +163 -3
- fastmcp-2.4.0/tests/server/test_logging.py +176 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/server/test_mount.py +44 -45
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/server/test_openapi.py +285 -23
- fastmcp-2.4.0/tests/server/test_openapi_path_parameters.py +459 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/server/test_proxy.py +25 -2
- fastmcp-2.4.0/tests/server/test_resource_prefix_formats.py +65 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/server/test_server.py +290 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/server/test_server_interactions.py +3 -5
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/test_examples.py +0 -5
- fastmcp-2.4.0/tests/tools/__init__.py +0 -0
- fastmcp-2.4.0/tests/utilities/test_mcp_config.py +142 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/uv.lock +4 -4
- fastmcp-2.3.4/docs/clients/transports.mdx +0 -244
- fastmcp-2.3.4/src/fastmcp/client/logging.py +0 -13
- fastmcp-2.3.4/src/fastmcp/low_level/sse_server_transport.py +0 -104
- fastmcp-2.3.4/tests/cli/test_run.py +0 -22
- {fastmcp-2.3.4 → fastmcp-2.4.0}/.cursor/rules/core-mcp-objects.mdc +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/.github/ISSUE_TEMPLATE/bug.yml +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/.github/ISSUE_TEMPLATE/enhancement.yml +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/.github/release.yml +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/.github/workflows/publish.yml +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/.gitignore +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/.pre-commit-config.yaml +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/LICENSE +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/Windows_Notes.md +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/docs/assets/demo-inspector.png +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/docs/deployment/authentication.mdx +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/docs/getting-started/installation.mdx +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/docs/getting-started/welcome.mdx +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/docs/patterns/contrib.mdx +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/docs/patterns/decorating-methods.mdx +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/docs/patterns/fastapi.mdx +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/docs/patterns/http-requests.mdx +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/docs/servers/context.mdx +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/docs/servers/prompts.mdx +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/docs/servers/resources.mdx +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/docs/servers/tools.mdx +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/docs/snippets/version-badge.mdx +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/docs/style.css +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/examples/complex_inputs.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/examples/desktop.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/examples/echo.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/examples/memory.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/examples/mount_example.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/examples/sampling.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/examples/screenshot.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/examples/serializer.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/examples/simple_echo.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/examples/smart_home/README.md +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/examples/smart_home/pyproject.toml +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/examples/smart_home/src/smart_home/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/examples/smart_home/src/smart_home/__main__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/examples/smart_home/src/smart_home/hub.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/examples/smart_home/src/smart_home/lights/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/examples/smart_home/src/smart_home/lights/hue_utils.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/examples/smart_home/src/smart_home/lights/server.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/examples/smart_home/src/smart_home/py.typed +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/examples/smart_home/src/smart_home/settings.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/examples/smart_home/uv.lock +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/examples/text_me.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/justfile +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/cli/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/cli/claude.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/client/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/client/base.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/client/roots.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/client/sampling.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/contrib/README.md +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/contrib/bulk_tool_caller/README.md +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/contrib/bulk_tool_caller/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/contrib/bulk_tool_caller/bulk_tool_caller.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/contrib/bulk_tool_caller/example.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/contrib/mcp_mixin/README.md +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/contrib/mcp_mixin/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/contrib/mcp_mixin/example.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/contrib/mcp_mixin/mcp_mixin.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/exceptions.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/low_level/README.md +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/low_level/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/prompts/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/prompts/prompt.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/prompts/prompt_manager.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/py.typed +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/resources/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/resources/resource.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/resources/resource_manager.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/resources/template.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/resources/types.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/server/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/server/dependencies.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/server/proxy.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/tools/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/tools/tool.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/tools/tool_manager.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/utilities/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/utilities/cache.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/utilities/decorators.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/utilities/exceptions.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/utilities/json_schema.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/utilities/logging.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/src/fastmcp/utilities/types.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/client/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/client/test_roots.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/client/test_sampling.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/conftest.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/contrib/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/contrib/test_mcp_mixin.py +0 -0
- {fastmcp-2.3.4/tests/prompts → fastmcp-2.4.0/tests/deprecated}/__init__.py +0 -0
- {fastmcp-2.3.4/tests/resources → fastmcp-2.4.0/tests/prompts}/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/prompts/test_prompt.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/prompts/test_prompt_manager.py +0 -0
- {fastmcp-2.3.4/tests/server → fastmcp-2.4.0/tests/resources}/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/resources/test_function_resources.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/resources/test_resource_manager.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/resources/test_resource_template.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/resources/test_resources.py +0 -0
- {fastmcp-2.3.4/tests/tools → fastmcp-2.4.0/tests/server}/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/server/test_context.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/server/test_file_server.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/server/test_http_dependencies.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/server/test_run_server.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/server/test_tool_annotations.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/test_servers/fastmcp_server.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/test_servers/sse.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/test_servers/stdio.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/tools/test_tool.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/tools/test_tool_manager.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/utilities/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/utilities/openapi/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/utilities/openapi/conftest.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/utilities/openapi/test_openapi.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/utilities/openapi/test_openapi_advanced.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/utilities/openapi/test_openapi_fastapi.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/utilities/test_cache.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/utilities/test_decorated_function.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/utilities/test_json_schema.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/utilities/test_logging.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/utilities/test_tests.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/utilities/test_typeadapter.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.4.0}/tests/utilities/test_types.py +0 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
documentation:
|
|
2
|
+
- changed-files:
|
|
3
|
+
- any-glob-to-any-file: "docs/**"
|
|
4
|
+
|
|
5
|
+
example:
|
|
6
|
+
- changed-files:
|
|
7
|
+
- any-glob-to-any-file:
|
|
8
|
+
- "examples/**"
|
|
9
|
+
|
|
10
|
+
tests:
|
|
11
|
+
- changed-files:
|
|
12
|
+
- any-glob-to-any-file: "tests/**"
|
|
13
|
+
|
|
14
|
+
"component: HTTP":
|
|
15
|
+
- changed-files:
|
|
16
|
+
- any-glob-to-any-file: "src/fastmcp/server/http.py"
|
|
17
|
+
|
|
18
|
+
"component: client":
|
|
19
|
+
- changed-files:
|
|
20
|
+
- any-glob-to-any-file: "src/fastmcp/client/**"
|
|
21
|
+
|
|
22
|
+
"contrib":
|
|
23
|
+
- changed-files:
|
|
24
|
+
- any-glob-to-any-file: "src/fastmcp/contrib/**"
|
|
25
|
+
|
|
26
|
+
"component: openapi":
|
|
27
|
+
- changed-files:
|
|
28
|
+
- any-glob-to-any-file:
|
|
29
|
+
- "src/**/*openapi*.py"
|
|
@@ -14,13 +14,10 @@ on:
|
|
|
14
14
|
- "uv.lock"
|
|
15
15
|
- "pyproject.toml"
|
|
16
16
|
- ".github/workflows/**"
|
|
17
|
+
|
|
18
|
+
# run on all pull requests because these checks are required and will block merges otherwise
|
|
17
19
|
pull_request:
|
|
18
|
-
|
|
19
|
-
- "src/**"
|
|
20
|
-
- "tests/**"
|
|
21
|
-
- "uv.lock"
|
|
22
|
-
- "pyproject.toml"
|
|
23
|
-
- ".github/workflows/**"
|
|
20
|
+
|
|
24
21
|
workflow_dispatch:
|
|
25
22
|
|
|
26
23
|
permissions:
|
|
@@ -13,13 +13,9 @@ on:
|
|
|
13
13
|
- "uv.lock"
|
|
14
14
|
- "pyproject.toml"
|
|
15
15
|
- ".github/workflows/**"
|
|
16
|
+
|
|
17
|
+
# run on all pull requests because these checks are required and will block merges otherwise
|
|
16
18
|
pull_request:
|
|
17
|
-
paths:
|
|
18
|
-
- "src/**"
|
|
19
|
-
- "tests/**"
|
|
20
|
-
- "uv.lock"
|
|
21
|
-
- "pyproject.toml"
|
|
22
|
-
- ".github/workflows/**"
|
|
23
19
|
|
|
24
20
|
workflow_dispatch:
|
|
25
21
|
|
|
@@ -48,7 +44,7 @@ jobs:
|
|
|
48
44
|
python-version: ${{ matrix.python-version }}
|
|
49
45
|
|
|
50
46
|
- name: Install FastMCP
|
|
51
|
-
run: uv sync --
|
|
47
|
+
run: uv sync --locked
|
|
52
48
|
|
|
53
49
|
- name: Run tests
|
|
54
|
-
run: uv run pytest
|
|
50
|
+
run: uv run pytest tests
|
fastmcp-2.4.0/AGENTS.md
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# AGENTS
|
|
2
|
+
|
|
3
|
+
> **Audience**: LLM-driven engineering agents
|
|
4
|
+
|
|
5
|
+
This file provides guidance for autonomous coding agents working inside the **FastMCP** repository.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Repository map
|
|
10
|
+
|
|
11
|
+
| Path | Purpose |
|
|
12
|
+
| ---------------- | ---------------------------------------------------------------------------------------- |
|
|
13
|
+
| `src/fastmcp/` | Library source code (Python ≥ 3.10) |
|
|
14
|
+
| ` └─server/` | Server implementation, `FastMCP`, auth, networking |
|
|
15
|
+
| ` └─client/` | High‑level client SDK + helpers |
|
|
16
|
+
| ` └─resources/` | MCP resources and resource templates |
|
|
17
|
+
| ` └─prompts/` | Prompt templates |
|
|
18
|
+
| ` └─tools/` | Tool implementations |
|
|
19
|
+
| `tests/` | Pytest test‑suite |
|
|
20
|
+
| `docs/` | Mintlify‑flavoured Markdown, published to [https://gofastmcp.com](https://gofastmcp.com) |
|
|
21
|
+
| `examples/` | Minimal runnable demos |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Mandatory dev workflow
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
uv sync # install dependencies
|
|
29
|
+
uv run pre-commit run --all-files # Ruff + Prettier + Pyright
|
|
30
|
+
uv run pytest # run full test suite
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
*Tests must pass* and *lint/typing must be clean* before committing.
|
|
34
|
+
|
|
35
|
+
### Core MCP objects
|
|
36
|
+
|
|
37
|
+
There are four major MCP object types:
|
|
38
|
+
|
|
39
|
+
- Tools (`src/tools/`)
|
|
40
|
+
- Resources (`src/resources/`)
|
|
41
|
+
- Resource Templates (`src/resources/`)
|
|
42
|
+
- Prompts (`src/prompts`)
|
|
43
|
+
|
|
44
|
+
While these have slightly different semantics and implementations, in general changes that affect interactions with any one (like adding tags, importing, etc.) will need to be adopted, applied, and tested on all others. Be sure to look at not only the object definition but also the related `Manager` (e.g. `ToolManager`, `ResourceManager`, and `PromptManager`). Also note that while resources and resource templates are different objects, they both are handled by the `ResourceManager`.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Code conventions
|
|
49
|
+
|
|
50
|
+
* **Language:** Python ≥ 3.10
|
|
51
|
+
* **Style:** Enforced through pre-commit hooks
|
|
52
|
+
* **Type-checking:** Fully typed codebase
|
|
53
|
+
* **Tests:** Each feature should have corresponding tests
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Development guidelines
|
|
58
|
+
|
|
59
|
+
1. **Set up** the environment:
|
|
60
|
+
```bash
|
|
61
|
+
uv sync && uv run pre-commit run --all-files
|
|
62
|
+
```
|
|
63
|
+
2. **Run tests**: `uv run pytest` until they pass.
|
|
64
|
+
3. **Iterate**: if a command fails, read the output, fix the code, retry.
|
|
65
|
+
4. Make the smallest set of changes that achieve the desired outcome.
|
|
66
|
+
5. Always read code before modifying it blindly.
|
|
67
|
+
6. Follow established patterns and maintain consistency.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: fastmcp
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.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
|
|
@@ -19,7 +19,7 @@ Classifier: Typing :: Typed
|
|
|
19
19
|
Requires-Python: >=3.10
|
|
20
20
|
Requires-Dist: exceptiongroup>=1.2.2
|
|
21
21
|
Requires-Dist: httpx>=0.28.1
|
|
22
|
-
Requires-Dist: mcp<2.0.0,>=1.
|
|
22
|
+
Requires-Dist: mcp<2.0.0,>=1.9.0
|
|
23
23
|
Requires-Dist: openapi-pydantic>=0.5.1
|
|
24
24
|
Requires-Dist: python-dotenv>=1.1.0
|
|
25
25
|
Requires-Dist: rich>=13.9.4
|
|
@@ -282,6 +282,29 @@ async def main():
|
|
|
282
282
|
# ... use the client
|
|
283
283
|
```
|
|
284
284
|
|
|
285
|
+
FastMCP also supports connecting to multiple servers through a single unified client using the standard MCP configuration format:
|
|
286
|
+
|
|
287
|
+
```python
|
|
288
|
+
from fastmcp import Client
|
|
289
|
+
|
|
290
|
+
# Standard MCP configuration with multiple servers
|
|
291
|
+
config = {
|
|
292
|
+
"mcpServers": {
|
|
293
|
+
"weather": {"url": "https://weather-api.example.com/mcp"},
|
|
294
|
+
"assistant": {"command": "python", "args": ["./assistant_server.py"]}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
# Create a client that connects to all servers
|
|
299
|
+
client = Client(config)
|
|
300
|
+
|
|
301
|
+
async def main():
|
|
302
|
+
async with client:
|
|
303
|
+
# Access tools and resources with server prefixes
|
|
304
|
+
forecast = await client.call_tool("weather_get_forecast", {"city": "London"})
|
|
305
|
+
answer = await client.call_tool("assistant_answer_question", {"query": "What is MCP?"})
|
|
306
|
+
```
|
|
307
|
+
|
|
285
308
|
Learn more in the [**Client Documentation**](https://gofastmcp.com/clients/client) and [**Transports Documentation**](https://gofastmcp.com/clients/transports).
|
|
286
309
|
|
|
287
310
|
## Advanced Features
|
|
@@ -290,7 +313,7 @@ FastMCP introduces powerful ways to structure and deploy your MCP applications.
|
|
|
290
313
|
|
|
291
314
|
### Proxy Servers
|
|
292
315
|
|
|
293
|
-
Create a FastMCP server that acts as an intermediary for another local or remote MCP server using `FastMCP.
|
|
316
|
+
Create a FastMCP server that acts as an intermediary for another local or remote MCP server using `FastMCP.as_proxy()`. This is especially useful for bridging transports (e.g., remote SSE to local Stdio) or adding a layer of logic to a server you don't control.
|
|
294
317
|
|
|
295
318
|
Learn more in the [**Proxying Documentation**](https://gofastmcp.com/patterns/proxy).
|
|
296
319
|
|
|
@@ -253,6 +253,29 @@ async def main():
|
|
|
253
253
|
# ... use the client
|
|
254
254
|
```
|
|
255
255
|
|
|
256
|
+
FastMCP also supports connecting to multiple servers through a single unified client using the standard MCP configuration format:
|
|
257
|
+
|
|
258
|
+
```python
|
|
259
|
+
from fastmcp import Client
|
|
260
|
+
|
|
261
|
+
# Standard MCP configuration with multiple servers
|
|
262
|
+
config = {
|
|
263
|
+
"mcpServers": {
|
|
264
|
+
"weather": {"url": "https://weather-api.example.com/mcp"},
|
|
265
|
+
"assistant": {"command": "python", "args": ["./assistant_server.py"]}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
# Create a client that connects to all servers
|
|
270
|
+
client = Client(config)
|
|
271
|
+
|
|
272
|
+
async def main():
|
|
273
|
+
async with client:
|
|
274
|
+
# Access tools and resources with server prefixes
|
|
275
|
+
forecast = await client.call_tool("weather_get_forecast", {"city": "London"})
|
|
276
|
+
answer = await client.call_tool("assistant_answer_question", {"query": "What is MCP?"})
|
|
277
|
+
```
|
|
278
|
+
|
|
256
279
|
Learn more in the [**Client Documentation**](https://gofastmcp.com/clients/client) and [**Transports Documentation**](https://gofastmcp.com/clients/transports).
|
|
257
280
|
|
|
258
281
|
## Advanced Features
|
|
@@ -261,7 +284,7 @@ FastMCP introduces powerful ways to structure and deploy your MCP applications.
|
|
|
261
284
|
|
|
262
285
|
### Proxy Servers
|
|
263
286
|
|
|
264
|
-
Create a FastMCP server that acts as an intermediary for another local or remote MCP server using `FastMCP.
|
|
287
|
+
Create a FastMCP server that acts as an intermediary for another local or remote MCP server using `FastMCP.as_proxy()`. This is especially useful for bridging transports (e.g., remote SSE to local Stdio) or adding a layer of logic to a server you don't control.
|
|
265
288
|
|
|
266
289
|
Learn more in the [**Proxying Documentation**](https://gofastmcp.com/patterns/proxy).
|
|
267
290
|
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Advanced Features
|
|
3
|
+
sidebarTitle: Advanced Features
|
|
4
|
+
description: Learn about the advanced features of the FastMCP Client.
|
|
5
|
+
icon: stars
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
import { VersionBadge } from '/snippets/version-badge.mdx'
|
|
9
|
+
|
|
10
|
+
In addition to basic server interaction, FastMCP clients can also handle more advanced features and server interaction patterns. The `Client` constructor accepts additional configuration to handle these server requests.
|
|
11
|
+
|
|
12
|
+
<Tip>
|
|
13
|
+
To enable many of these features, you must provide an appropriate handler or callback function. For example. In most cases, if you do not provide a handler, FastMCP's default handler will emit a `DEBUG` level log.
|
|
14
|
+
</Tip>
|
|
15
|
+
|
|
16
|
+
## Logging and Notifications
|
|
17
|
+
|
|
18
|
+
<VersionBadge version="2.0.0" />
|
|
19
|
+
MCP servers can emit logs to clients. To process these logs, you can provide a `log_handler` to the client.
|
|
20
|
+
|
|
21
|
+
The `log_handler` must be an async function that accepts a single argument, which is an instance of `fastmcp.client.logging.LogMessage`. This has attributes like `level`, `logger`, and `data`.
|
|
22
|
+
|
|
23
|
+
```python {2, 12}
|
|
24
|
+
from fastmcp import Client
|
|
25
|
+
from fastmcp.client.logging import LogMessage
|
|
26
|
+
|
|
27
|
+
async def log_handler(message: LogMessage):
|
|
28
|
+
level = message.level.upper()
|
|
29
|
+
logger = message.logger or 'default'
|
|
30
|
+
data = message.data
|
|
31
|
+
print(f"[Server Log - {level}] {logger}: {data}")
|
|
32
|
+
|
|
33
|
+
client_with_logging = Client(
|
|
34
|
+
...,
|
|
35
|
+
log_handler=log_handler,
|
|
36
|
+
)
|
|
37
|
+
```
|
|
38
|
+
## Progress Monitoring
|
|
39
|
+
|
|
40
|
+
<VersionBadge version="2.3.5" />
|
|
41
|
+
|
|
42
|
+
MCP servers can report progress during long-running operations. The client can set a progress handler to receive and process these updates.
|
|
43
|
+
|
|
44
|
+
```python {2, 13}
|
|
45
|
+
from fastmcp import Client
|
|
46
|
+
from fastmcp.client.progress import ProgressHandler
|
|
47
|
+
|
|
48
|
+
async def my_progress_handler(
|
|
49
|
+
progress: float,
|
|
50
|
+
total: float | None,
|
|
51
|
+
message: str | None
|
|
52
|
+
) -> None:
|
|
53
|
+
print(f"Progress: {progress} / {total} ({message})")
|
|
54
|
+
|
|
55
|
+
client = Client(
|
|
56
|
+
...,
|
|
57
|
+
progress_handler=my_progress_handler
|
|
58
|
+
)
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
By default, FastMCP uses a handler that logs progress updates at the debug level. This default handler properly handles cases where `total` or `message` might be None.
|
|
62
|
+
|
|
63
|
+
You can override the progress handler for specific tool calls:
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
# Client uses the default debug logger for progress
|
|
67
|
+
client = Client(...)
|
|
68
|
+
|
|
69
|
+
async with client:
|
|
70
|
+
# Use default progress handler (debug logging)
|
|
71
|
+
result1 = await client.call_tool("long_task", {"param": "value"})
|
|
72
|
+
|
|
73
|
+
# Override with custom progress handler just for this call
|
|
74
|
+
result2 = await client.call_tool(
|
|
75
|
+
"another_task",
|
|
76
|
+
{"param": "value"},
|
|
77
|
+
progress_handler=my_progress_handler
|
|
78
|
+
)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
A typical progress update includes:
|
|
82
|
+
- Current progress value (e.g., 2 of 5 steps completed)
|
|
83
|
+
- Total expected value (may be None)
|
|
84
|
+
- Status message (may be None)
|
|
85
|
+
|
|
86
|
+
## LLM Sampling
|
|
87
|
+
|
|
88
|
+
<VersionBadge version="2.0.0" />
|
|
89
|
+
|
|
90
|
+
MCP Servers can request LLM completions from clients. The client can provide a `sampling_handler` to handle these requests. The sampling handler receives a list of messages and other parameters from the server, and should return a string completion.
|
|
91
|
+
|
|
92
|
+
The following example uses the `marvin` library to generate a completion:
|
|
93
|
+
|
|
94
|
+
```python {8-17, 21}
|
|
95
|
+
import marvin
|
|
96
|
+
from fastmcp import Client
|
|
97
|
+
from fastmcp.client.sampling import (
|
|
98
|
+
SamplingMessage,
|
|
99
|
+
SamplingParams,
|
|
100
|
+
RequestContext,
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
async def sampling_handler(
|
|
104
|
+
messages: list[SamplingMessage],
|
|
105
|
+
params: SamplingParams,
|
|
106
|
+
context: RequestContext
|
|
107
|
+
) -> str:
|
|
108
|
+
return await marvin.say_async(
|
|
109
|
+
message=[m.content.text for m in messages],
|
|
110
|
+
instructions=params.systemPrompt,
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
client = Client(
|
|
114
|
+
...,
|
|
115
|
+
sampling_handler=sampling_handler,
|
|
116
|
+
)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
## Roots
|
|
121
|
+
|
|
122
|
+
<VersionBadge version="2.0.0" />
|
|
123
|
+
|
|
124
|
+
Roots are a way for clients to inform servers about the resources they have access to or certain boundaries on their access. The server can use this information to adjust behavior or provide more accurate responses.
|
|
125
|
+
|
|
126
|
+
Servers can request roots from clients, and clients can notify servers when their roots change.
|
|
127
|
+
|
|
128
|
+
To set the roots when creating a client, users can either provide a list of roots (which can be a list of strings) or an async function that returns a list of roots.
|
|
129
|
+
|
|
130
|
+
<CodeGroup>
|
|
131
|
+
```python Static Roots {5}
|
|
132
|
+
from fastmcp import Client
|
|
133
|
+
|
|
134
|
+
client = Client(
|
|
135
|
+
...,
|
|
136
|
+
roots=["/path/to/root1", "/path/to/root2"],
|
|
137
|
+
)
|
|
138
|
+
```
|
|
139
|
+
```python Dynamic Roots Callback {4-6, 10}
|
|
140
|
+
from fastmcp import Client
|
|
141
|
+
from fastmcp.client.roots import RequestContext
|
|
142
|
+
|
|
143
|
+
async def roots_callback(context: RequestContext) -> list[str]:
|
|
144
|
+
print(f"Server requested roots (Request ID: {context.request_id})")
|
|
145
|
+
return ["/path/to/root1", "/path/to/root2"]
|
|
146
|
+
|
|
147
|
+
client = Client(
|
|
148
|
+
...,
|
|
149
|
+
roots=roots_callback,
|
|
150
|
+
)
|
|
151
|
+
```
|
|
152
|
+
</CodeGroup>
|