fastmcp 2.3.3__tar.gz → 2.3.5__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.3.5/.github/labeler.yml +29 -0
- fastmcp-2.3.5/.github/workflows/labeler.yml +12 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/.github/workflows/run-static.yml +3 -6
- {fastmcp-2.3.3 → fastmcp-2.3.5}/.github/workflows/run-tests.yml +5 -17
- fastmcp-2.3.5/AGENTS.md +67 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/PKG-INFO +3 -3
- {fastmcp-2.3.3 → fastmcp-2.3.5}/README.md +1 -1
- {fastmcp-2.3.3 → fastmcp-2.3.5}/docs/clients/client.mdx +127 -8
- fastmcp-2.3.5/docs/clients/transports.mdx +320 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/docs/deployment/asgi.mdx +11 -8
- {fastmcp-2.3.3 → fastmcp-2.3.5}/docs/deployment/cli.mdx +13 -5
- {fastmcp-2.3.3 → fastmcp-2.3.5}/docs/deployment/running-server.mdx +4 -4
- {fastmcp-2.3.3 → fastmcp-2.3.5}/docs/getting-started/quickstart.mdx +2 -1
- {fastmcp-2.3.3 → fastmcp-2.3.5}/docs/patterns/testing.mdx +1 -1
- {fastmcp-2.3.3 → fastmcp-2.3.5}/docs/servers/composition.mdx +2 -2
- {fastmcp-2.3.3 → fastmcp-2.3.5}/docs/servers/fastmcp.mdx +2 -2
- {fastmcp-2.3.3 → fastmcp-2.3.5}/docs/servers/proxy.mdx +18 -22
- {fastmcp-2.3.3 → fastmcp-2.3.5}/docs/servers/resources.mdx +38 -9
- {fastmcp-2.3.3 → fastmcp-2.3.5}/docs/servers/tools.mdx +34 -12
- fastmcp-2.3.5/examples/in_memory_proxy_example.py +82 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/pyproject.toml +2 -1
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/cli/cli.py +30 -138
- fastmcp-2.3.5/src/fastmcp/cli/run.py +179 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/client/__init__.py +2 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/client/client.py +131 -24
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/client/logging.py +8 -0
- fastmcp-2.3.5/src/fastmcp/client/progress.py +38 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/client/transports.py +80 -64
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/exceptions.py +2 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/prompts/prompt.py +12 -6
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/resources/resource_manager.py +22 -1
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/resources/template.py +21 -17
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/resources/types.py +25 -27
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/server/context.py +6 -3
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/server/http.py +47 -14
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/server/openapi.py +14 -1
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/server/proxy.py +4 -4
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/server/server.py +159 -96
- fastmcp-2.3.5/src/fastmcp/settings.py +131 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/tools/tool.py +45 -45
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/tools/tool_manager.py +27 -2
- fastmcp-2.3.5/src/fastmcp/utilities/exceptions.py +49 -0
- fastmcp-2.3.5/src/fastmcp/utilities/json_schema.py +120 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/utilities/logging.py +11 -6
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/utilities/openapi.py +122 -7
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/cli/test_cli.py +23 -90
- fastmcp-2.3.5/tests/cli/test_run.py +262 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/client/test_client.py +245 -9
- fastmcp-2.3.5/tests/client/test_progress.py +70 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/client/test_sse.py +56 -2
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/client/test_streamable_http.py +54 -3
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/contrib/test_bulk_tool_caller.py +1 -2
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/resources/test_file_resources.py +5 -3
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/resources/test_function_resources.py +1 -1
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/resources/test_resource_manager.py +85 -1
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/resources/test_resource_template.py +0 -15
- fastmcp-2.3.5/tests/server/test_app_state.py +26 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/server/test_import_server.py +4 -4
- fastmcp-2.3.5/tests/server/test_logging.py +176 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/server/test_mount.py +7 -7
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/server/test_openapi.py +121 -2
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/server/test_proxy.py +29 -7
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/server/test_server.py +22 -2
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/server/test_server_interactions.py +32 -33
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/test_deprecated.py +19 -1
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/tools/test_tool.py +3 -3
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/tools/test_tool_manager.py +85 -1
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/utilities/openapi/test_openapi_fastapi.py +17 -0
- fastmcp-2.3.5/tests/utilities/test_json_schema.py +304 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/utilities/test_typeadapter.py +2 -2
- {fastmcp-2.3.3 → fastmcp-2.3.5}/uv.lock +4 -4
- fastmcp-2.3.3/docs/clients/transports.mdx +0 -244
- fastmcp-2.3.3/src/fastmcp/low_level/sse_server_transport.py +0 -104
- fastmcp-2.3.3/src/fastmcp/settings.py +0 -105
- fastmcp-2.3.3/src/fastmcp/utilities/json_schema.py +0 -59
- fastmcp-2.3.3/tests/cli/test_run.py +0 -22
- fastmcp-2.3.3/tests/utilities/test_json_schema.py +0 -110
- {fastmcp-2.3.3 → fastmcp-2.3.5}/.cursor/rules/core-mcp-objects.mdc +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/.github/ISSUE_TEMPLATE/bug.yml +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/.github/ISSUE_TEMPLATE/enhancement.yml +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/.github/release.yml +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/.github/workflows/publish.yml +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/.gitignore +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/.pre-commit-config.yaml +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/LICENSE +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/Windows_Notes.md +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/docs/assets/demo-inspector.png +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/docs/deployment/authentication.mdx +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/docs/docs.json +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/docs/getting-started/installation.mdx +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/docs/getting-started/welcome.mdx +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/docs/patterns/contrib.mdx +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/docs/patterns/decorating-methods.mdx +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/docs/patterns/fastapi.mdx +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/docs/patterns/http-requests.mdx +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/docs/patterns/openapi.mdx +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/docs/servers/context.mdx +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/docs/servers/prompts.mdx +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/docs/snippets/version-badge.mdx +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/docs/style.css +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/examples/complex_inputs.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/examples/desktop.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/examples/echo.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/examples/memory.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/examples/mount_example.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/examples/sampling.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/examples/screenshot.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/examples/serializer.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/examples/simple_echo.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/examples/smart_home/README.md +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/examples/smart_home/pyproject.toml +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/examples/smart_home/src/smart_home/__init__.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/examples/smart_home/src/smart_home/__main__.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/examples/smart_home/src/smart_home/hub.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/examples/smart_home/src/smart_home/lights/__init__.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/examples/smart_home/src/smart_home/lights/hue_utils.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/examples/smart_home/src/smart_home/lights/server.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/examples/smart_home/src/smart_home/py.typed +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/examples/smart_home/src/smart_home/settings.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/examples/smart_home/uv.lock +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/examples/text_me.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/justfile +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/__init__.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/cli/__init__.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/cli/claude.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/client/base.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/client/roots.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/client/sampling.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/contrib/README.md +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/contrib/bulk_tool_caller/README.md +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/contrib/bulk_tool_caller/__init__.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/contrib/bulk_tool_caller/bulk_tool_caller.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/contrib/bulk_tool_caller/example.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/contrib/mcp_mixin/README.md +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/contrib/mcp_mixin/__init__.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/contrib/mcp_mixin/example.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/contrib/mcp_mixin/mcp_mixin.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/low_level/README.md +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/low_level/__init__.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/prompts/__init__.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/prompts/prompt_manager.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/py.typed +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/resources/__init__.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/resources/resource.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/server/__init__.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/server/dependencies.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/tools/__init__.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/utilities/__init__.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/utilities/cache.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/utilities/decorators.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/utilities/tests.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/src/fastmcp/utilities/types.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/__init__.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/client/__init__.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/client/test_logs.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/client/test_roots.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/client/test_sampling.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/conftest.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/contrib/__init__.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/contrib/test_mcp_mixin.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/prompts/__init__.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/prompts/test_prompt.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/prompts/test_prompt_manager.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/resources/__init__.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/resources/test_resources.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/server/__init__.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/server/test_auth_integration.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/server/test_context.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/server/test_file_server.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/server/test_http_dependencies.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/server/test_http_middleware.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/server/test_lifespan.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/server/test_run_server.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/server/test_tool_annotations.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/test_examples.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/test_servers/fastmcp_server.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/test_servers/sse.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/test_servers/stdio.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/tools/__init__.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/utilities/__init__.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/utilities/openapi/__init__.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/utilities/openapi/conftest.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/utilities/openapi/test_openapi.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/utilities/openapi/test_openapi_advanced.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/utilities/test_cache.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/utilities/test_decorated_function.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/utilities/test_logging.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/tests/utilities/test_tests.py +0 -0
- {fastmcp-2.3.3 → fastmcp-2.3.5}/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
|
|
|
@@ -45,18 +41,10 @@ jobs:
|
|
|
45
41
|
with:
|
|
46
42
|
enable-cache: true
|
|
47
43
|
cache-dependency-glob: "uv.lock"
|
|
48
|
-
|
|
49
|
-
- name: Set up Python ${{ matrix.python-version }}
|
|
50
|
-
run: uv python install ${{ matrix.python-version }}
|
|
44
|
+
python-version: ${{ matrix.python-version }}
|
|
51
45
|
|
|
52
46
|
- name: Install FastMCP
|
|
53
|
-
run: uv sync --dev
|
|
54
|
-
|
|
55
|
-
- name: Fix pyreadline on Windows
|
|
56
|
-
if: matrix.os == 'windows-latest'
|
|
57
|
-
run: |
|
|
58
|
-
uv pip uninstall -y pyreadline
|
|
59
|
-
uv pip install pyreadline3
|
|
47
|
+
run: uv sync --dev --locked
|
|
60
48
|
|
|
61
49
|
- name: Run tests
|
|
62
|
-
run: uv run
|
|
50
|
+
run: uv run pytest
|
fastmcp-2.3.5/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.
|
|
3
|
+
Version: 2.3.5
|
|
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
|
|
@@ -290,7 +290,7 @@ FastMCP introduces powerful ways to structure and deploy your MCP applications.
|
|
|
290
290
|
|
|
291
291
|
### Proxy Servers
|
|
292
292
|
|
|
293
|
-
Create a FastMCP server that acts as an intermediary for another local or remote MCP server using `FastMCP.
|
|
293
|
+
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
294
|
|
|
295
295
|
Learn more in the [**Proxying Documentation**](https://gofastmcp.com/patterns/proxy).
|
|
296
296
|
|
|
@@ -261,7 +261,7 @@ FastMCP introduces powerful ways to structure and deploy your MCP applications.
|
|
|
261
261
|
|
|
262
262
|
### Proxy Servers
|
|
263
263
|
|
|
264
|
-
Create a FastMCP server that acts as an intermediary for another local or remote MCP server using `FastMCP.
|
|
264
|
+
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
265
|
|
|
266
266
|
Learn more in the [**Proxying Documentation**](https://gofastmcp.com/patterns/proxy).
|
|
267
267
|
|
|
@@ -18,6 +18,17 @@ The FastMCP Client architecture separates the protocol logic (`Client`) from the
|
|
|
18
18
|
- **`Client`**: Handles sending MCP requests (like `tools/call`, `resources/read`), receiving responses, and managing callbacks.
|
|
19
19
|
- **`Transport`**: Responsible for establishing and maintaining the connection to the server (e.g., via WebSockets, SSE, Stdio, or in-memory).
|
|
20
20
|
|
|
21
|
+
```python
|
|
22
|
+
from fastmcp import Client, FastMCP
|
|
23
|
+
from fastmcp.client import (
|
|
24
|
+
RootsHandler,
|
|
25
|
+
RootsList,
|
|
26
|
+
LogHandler,
|
|
27
|
+
MessageHandler,
|
|
28
|
+
SamplingHandler,
|
|
29
|
+
ProgressHandler # For handling progress notifications
|
|
30
|
+
)
|
|
31
|
+
```
|
|
21
32
|
|
|
22
33
|
### Transports
|
|
23
34
|
|
|
@@ -30,9 +41,8 @@ The following inference rules are used to determine the appropriate `ClientTrans
|
|
|
30
41
|
3. **`Path` or `str` pointing to an existing file**:
|
|
31
42
|
* If it ends with `.py`: Creates a `PythonStdioTransport` to run the script using `python`.
|
|
32
43
|
* If it ends with `.js`: Creates a `NodeStdioTransport` to run the script using `node`.
|
|
33
|
-
4. **`AnyUrl` or `str` pointing to a URL
|
|
34
|
-
*
|
|
35
|
-
* If it starts with `ws://` or `wss://`: Creates a `WSTransport`.
|
|
44
|
+
4. **`AnyUrl` or `str` pointing to a URL that begins with `http://` or `https://`**:
|
|
45
|
+
* Creates a `StreamableHttpTransport`
|
|
36
46
|
5. **Other**: Raises a `ValueError` if the type cannot be inferred.
|
|
37
47
|
|
|
38
48
|
```python
|
|
@@ -41,24 +51,24 @@ from fastmcp import Client, FastMCP
|
|
|
41
51
|
|
|
42
52
|
# Example transports (more details in Transports page)
|
|
43
53
|
server_instance = FastMCP(name="TestServer") # In-memory server
|
|
44
|
-
|
|
54
|
+
http_url = "https://example.com/mcp" # HTTP server URL
|
|
45
55
|
ws_url = "ws://localhost:9000" # WebSocket server URL
|
|
46
56
|
server_script = "my_mcp_server.py" # Path to a Python server file
|
|
47
57
|
|
|
48
58
|
# Client automatically infers the transport type
|
|
49
59
|
client_in_memory = Client(server_instance)
|
|
50
|
-
|
|
60
|
+
client_http = Client(http_url)
|
|
51
61
|
client_ws = Client(ws_url)
|
|
52
62
|
client_stdio = Client(server_script)
|
|
53
63
|
|
|
54
64
|
print(client_in_memory.transport)
|
|
55
|
-
print(
|
|
65
|
+
print(client_http.transport)
|
|
56
66
|
print(client_ws.transport)
|
|
57
67
|
print(client_stdio.transport)
|
|
58
68
|
|
|
59
69
|
# Expected Output (types may vary slightly based on environment):
|
|
60
70
|
# <FastMCP(server='TestServer')>
|
|
61
|
-
# <
|
|
71
|
+
# <StreamableHttp(url='https://example.com/mcp')>
|
|
62
72
|
# <WebSocket(url='ws://localhost:9000')>
|
|
63
73
|
# <PythonStdioTransport(command='python', args=['/path/to/your/my_mcp_server.py'])>
|
|
64
74
|
```
|
|
@@ -115,14 +125,26 @@ The standard client methods return user-friendly representations that may change
|
|
|
115
125
|
tools = await client.list_tools()
|
|
116
126
|
# tools -> list[mcp.types.Tool]
|
|
117
127
|
```
|
|
118
|
-
* **`call_tool(name: str, arguments: dict[str, Any] | None = None)`**: Executes a tool on the server.
|
|
128
|
+
* **`call_tool(name: str, arguments: dict[str, Any] | None = None, timeout: float | None = None, progress_handler: ProgressHandler | None = None)`**: Executes a tool on the server.
|
|
119
129
|
```python
|
|
120
130
|
result = await client.call_tool("add", {"a": 5, "b": 3})
|
|
121
131
|
# result -> list[mcp.types.TextContent | mcp.types.ImageContent | ...]
|
|
122
132
|
print(result[0].text) # Assuming TextContent, e.g., '8'
|
|
133
|
+
|
|
134
|
+
# With timeout (aborts if execution takes longer than 2 seconds)
|
|
135
|
+
result = await client.call_tool("long_running_task", {"param": "value"}, timeout=2.0)
|
|
136
|
+
|
|
137
|
+
# With progress handler (to track execution progress)
|
|
138
|
+
result = await client.call_tool(
|
|
139
|
+
"long_running_task",
|
|
140
|
+
{"param": "value"},
|
|
141
|
+
progress_handler=my_progress_handler
|
|
142
|
+
)
|
|
123
143
|
```
|
|
124
144
|
* Arguments are passed as a dictionary. FastMCP servers automatically handle JSON string parsing for complex types if needed.
|
|
125
145
|
* Returns a list of content objects (usually `TextContent` or `ImageContent`).
|
|
146
|
+
* The optional `timeout` parameter limits the maximum execution time (in seconds) for this specific call, overriding any client-level timeout.
|
|
147
|
+
* The optional `progress_handler` parameter receives progress updates during execution, overriding any client-level progress handler.
|
|
126
148
|
|
|
127
149
|
#### Resource Operations
|
|
128
150
|
|
|
@@ -191,6 +213,103 @@ These methods are especially useful for debugging or when you need to access met
|
|
|
191
213
|
|
|
192
214
|
MCP allows servers to interact with clients in order to provide additional capabilities. The `Client` constructor accepts additional configuration to handle these server requests.
|
|
193
215
|
|
|
216
|
+
#### Timeout Control
|
|
217
|
+
|
|
218
|
+
<VersionBadge version="2.3.4" />
|
|
219
|
+
|
|
220
|
+
You can control request timeouts at both the client level and individual request level:
|
|
221
|
+
|
|
222
|
+
```python
|
|
223
|
+
from fastmcp import Client
|
|
224
|
+
from fastmcp.exceptions import McpError
|
|
225
|
+
|
|
226
|
+
# Client with a global 5-second timeout for all requests
|
|
227
|
+
client = Client(
|
|
228
|
+
my_mcp_server,
|
|
229
|
+
timeout=5.0 # Default timeout in seconds
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
async with client:
|
|
233
|
+
# This uses the global 5-second timeout
|
|
234
|
+
result1 = await client.call_tool("quick_task", {"param": "value"})
|
|
235
|
+
|
|
236
|
+
# This specifies a 10-second timeout for this specific call
|
|
237
|
+
result2 = await client.call_tool("slow_task", {"param": "value"}, timeout=10.0)
|
|
238
|
+
|
|
239
|
+
try:
|
|
240
|
+
# This will likely timeout
|
|
241
|
+
result3 = await client.call_tool("medium_task", {"param": "value"}, timeout=0.01)
|
|
242
|
+
except McpError as e:
|
|
243
|
+
# Handle timeout error
|
|
244
|
+
print(f"The task timed out: {e}")
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
<Warning>
|
|
248
|
+
Timeout behavior varies between transport types:
|
|
249
|
+
|
|
250
|
+
- With **SSE** transport, the per-request (tool call) timeout **always** takes precedence, regardless of which is lower.
|
|
251
|
+
- With **HTTP** transport, the **lower** of the two timeouts (client or tool call) takes precedence.
|
|
252
|
+
|
|
253
|
+
For consistent behavior across all transports, we recommend explicitly setting timeouts at the individual tool call level when needed, rather than relying on client-level timeouts.
|
|
254
|
+
</Warning>
|
|
255
|
+
|
|
256
|
+
#### Progress Tracking
|
|
257
|
+
|
|
258
|
+
<VersionBadge version="2.3.5" />
|
|
259
|
+
|
|
260
|
+
MCP servers can report progress during long-running operations. The client can set a progress handler to receive and process these updates.
|
|
261
|
+
|
|
262
|
+
```python
|
|
263
|
+
from fastmcp import Client
|
|
264
|
+
from fastmcp.client.progress import ProgressHandler
|
|
265
|
+
|
|
266
|
+
# A simple progress handler that prints progress updates
|
|
267
|
+
async def my_progress_handler(
|
|
268
|
+
progress: float,
|
|
269
|
+
total: float | None,
|
|
270
|
+
message: str | None
|
|
271
|
+
) -> None:
|
|
272
|
+
"""Handle progress updates from the server."""
|
|
273
|
+
if total is not None:
|
|
274
|
+
percent = (progress / total) * 100
|
|
275
|
+
print(f"Progress: {percent:.1f}% ({progress}/{total})")
|
|
276
|
+
else:
|
|
277
|
+
print(f"Progress: {progress}")
|
|
278
|
+
|
|
279
|
+
if message:
|
|
280
|
+
print(f"Message: {message}")
|
|
281
|
+
|
|
282
|
+
# Set the progress handler at client level
|
|
283
|
+
client = Client(
|
|
284
|
+
my_mcp_server,
|
|
285
|
+
progress_handler=my_progress_handler
|
|
286
|
+
)
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
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.
|
|
290
|
+
|
|
291
|
+
You can override the progress handler for specific tool calls:
|
|
292
|
+
|
|
293
|
+
```python
|
|
294
|
+
# Client uses the default debug logger for progress
|
|
295
|
+
client = Client(my_mcp_server)
|
|
296
|
+
|
|
297
|
+
async with client:
|
|
298
|
+
# Use default progress handler (debug logging)
|
|
299
|
+
result1 = await client.call_tool("long_task", {"param": "value"})
|
|
300
|
+
|
|
301
|
+
# Override with custom progress handler just for this call
|
|
302
|
+
result2 = await client.call_tool(
|
|
303
|
+
"another_task",
|
|
304
|
+
{"param": "value"},
|
|
305
|
+
progress_handler=my_progress_handler
|
|
306
|
+
)
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
A typical progress update includes:
|
|
310
|
+
- Current progress value (e.g., 2 of 5 steps completed)
|
|
311
|
+
- Total expected value (may be None)
|
|
312
|
+
- Status message (may be None)
|
|
194
313
|
|
|
195
314
|
#### LLM Sampling
|
|
196
315
|
|