fastmcp 2.3.4__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.4 → fastmcp-2.3.5}/.github/workflows/run-static.yml +3 -6
- {fastmcp-2.3.4 → fastmcp-2.3.5}/.github/workflows/run-tests.yml +2 -6
- fastmcp-2.3.5/AGENTS.md +67 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/PKG-INFO +3 -3
- {fastmcp-2.3.4 → fastmcp-2.3.5}/README.md +1 -1
- {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/clients/client.mdx +84 -8
- fastmcp-2.3.5/docs/clients/transports.mdx +320 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/deployment/asgi.mdx +11 -8
- {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/deployment/cli.mdx +13 -5
- {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/deployment/running-server.mdx +4 -4
- {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/getting-started/quickstart.mdx +2 -1
- {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/patterns/testing.mdx +1 -1
- {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/servers/composition.mdx +2 -2
- {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/servers/fastmcp.mdx +2 -2
- {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/servers/proxy.mdx +18 -22
- fastmcp-2.3.5/examples/in_memory_proxy_example.py +82 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/pyproject.toml +2 -1
- {fastmcp-2.3.4 → 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.4 → fastmcp-2.3.5}/src/fastmcp/client/client.py +62 -18
- {fastmcp-2.3.4 → 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.4 → fastmcp-2.3.5}/src/fastmcp/client/transports.py +27 -36
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/server/context.py +6 -3
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/server/http.py +47 -14
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/server/server.py +86 -43
- {fastmcp-2.3.4 → 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.4 → fastmcp-2.3.5}/tests/client/test_client.py +104 -7
- fastmcp-2.3.5/tests/client/test_progress.py +70 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/client/test_sse.py +4 -4
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/client/test_streamable_http.py +5 -1
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/resources/test_file_resources.py +2 -1
- fastmcp-2.3.5/tests/server/test_app_state.py +26 -0
- {fastmcp-2.3.4 → 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.4 → fastmcp-2.3.5}/tests/server/test_mount.py +7 -7
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/server/test_proxy.py +25 -2
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/server/test_server_interactions.py +3 -5
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/test_deprecated.py +8 -1
- {fastmcp-2.3.4 → fastmcp-2.3.5}/uv.lock +4 -4
- fastmcp-2.3.4/docs/clients/transports.mdx +0 -244
- 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.3.5}/.cursor/rules/core-mcp-objects.mdc +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/.github/ISSUE_TEMPLATE/bug.yml +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/.github/ISSUE_TEMPLATE/enhancement.yml +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/.github/release.yml +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/.github/workflows/publish.yml +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/.gitignore +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/.pre-commit-config.yaml +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/LICENSE +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/Windows_Notes.md +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/assets/demo-inspector.png +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/deployment/authentication.mdx +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/docs.json +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/getting-started/installation.mdx +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/getting-started/welcome.mdx +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/patterns/contrib.mdx +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/patterns/decorating-methods.mdx +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/patterns/fastapi.mdx +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/patterns/http-requests.mdx +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/patterns/openapi.mdx +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/servers/context.mdx +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/servers/prompts.mdx +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/servers/resources.mdx +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/servers/tools.mdx +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/snippets/version-badge.mdx +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/style.css +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/complex_inputs.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/desktop.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/echo.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/memory.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/mount_example.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/sampling.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/screenshot.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/serializer.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/simple_echo.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/smart_home/README.md +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/smart_home/pyproject.toml +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/smart_home/src/smart_home/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/smart_home/src/smart_home/__main__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/smart_home/src/smart_home/hub.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/smart_home/src/smart_home/lights/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/smart_home/src/smart_home/lights/hue_utils.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/smart_home/src/smart_home/lights/server.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/smart_home/src/smart_home/py.typed +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/smart_home/src/smart_home/settings.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/smart_home/uv.lock +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/text_me.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/justfile +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/cli/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/cli/claude.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/client/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/client/base.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/client/roots.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/client/sampling.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/contrib/README.md +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/contrib/bulk_tool_caller/README.md +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/contrib/bulk_tool_caller/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/contrib/bulk_tool_caller/bulk_tool_caller.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/contrib/bulk_tool_caller/example.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/contrib/mcp_mixin/README.md +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/contrib/mcp_mixin/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/contrib/mcp_mixin/example.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/contrib/mcp_mixin/mcp_mixin.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/exceptions.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/low_level/README.md +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/low_level/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/prompts/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/prompts/prompt.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/prompts/prompt_manager.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/py.typed +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/resources/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/resources/resource.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/resources/resource_manager.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/resources/template.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/resources/types.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/server/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/server/dependencies.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/server/openapi.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/server/proxy.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/settings.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/tools/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/tools/tool.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/tools/tool_manager.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/utilities/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/utilities/cache.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/utilities/decorators.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/utilities/exceptions.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/utilities/json_schema.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/utilities/logging.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/utilities/openapi.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/utilities/tests.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/utilities/types.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/client/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/client/test_logs.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/client/test_roots.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/client/test_sampling.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/conftest.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/contrib/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/contrib/test_bulk_tool_caller.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/contrib/test_mcp_mixin.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/prompts/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/prompts/test_prompt.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/prompts/test_prompt_manager.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/resources/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/resources/test_function_resources.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/resources/test_resource_manager.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/resources/test_resource_template.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/resources/test_resources.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/server/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/server/test_auth_integration.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/server/test_context.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/server/test_file_server.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/server/test_http_dependencies.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/server/test_http_middleware.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/server/test_lifespan.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/server/test_openapi.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/server/test_run_server.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/server/test_server.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/server/test_tool_annotations.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/test_examples.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/test_servers/fastmcp_server.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/test_servers/sse.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/test_servers/stdio.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/tools/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/tools/test_tool.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/tools/test_tool_manager.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/utilities/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/utilities/openapi/__init__.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/utilities/openapi/conftest.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/utilities/openapi/test_openapi.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/utilities/openapi/test_openapi_advanced.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/utilities/openapi/test_openapi_fastapi.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/utilities/test_cache.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/utilities/test_decorated_function.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/utilities/test_json_schema.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/utilities/test_logging.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/utilities/test_tests.py +0 -0
- {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/utilities/test_typeadapter.py +0 -0
- {fastmcp-2.3.4 → 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
|
|
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,7 +125,7 @@ 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, timeout: float | 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 | ...]
|
|
@@ -123,10 +133,18 @@ The standard client methods return user-friendly representations that may change
|
|
|
123
133
|
|
|
124
134
|
# With timeout (aborts if execution takes longer than 2 seconds)
|
|
125
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
|
+
)
|
|
126
143
|
```
|
|
127
144
|
* Arguments are passed as a dictionary. FastMCP servers automatically handle JSON string parsing for complex types if needed.
|
|
128
145
|
* Returns a list of content objects (usually `TextContent` or `ImageContent`).
|
|
129
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.
|
|
130
148
|
|
|
131
149
|
#### Resource Operations
|
|
132
150
|
|
|
@@ -235,6 +253,64 @@ Timeout behavior varies between transport types:
|
|
|
235
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.
|
|
236
254
|
</Warning>
|
|
237
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)
|
|
313
|
+
|
|
238
314
|
#### LLM Sampling
|
|
239
315
|
|
|
240
316
|
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.
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Client Transports
|
|
3
|
+
sidebarTitle: Transports
|
|
4
|
+
description: Understand the different ways FastMCP Clients can connect to servers.
|
|
5
|
+
icon: link
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
import { VersionBadge } from "/snippets/version-badge.mdx"
|
|
9
|
+
|
|
10
|
+
<VersionBadge version="2.0.0" />
|
|
11
|
+
|
|
12
|
+
The FastMCP `Client` relies on a `ClientTransport` object to handle the specifics of connecting to and communicating with an MCP server. FastMCP provides several built-in transport implementations for common connection methods.
|
|
13
|
+
|
|
14
|
+
While the `Client` often infers the correct transport automatically (see [Client Overview](/clients/client#transport-inference)), you can also instantiate transports explicitly for more control.
|
|
15
|
+
|
|
16
|
+
<Tip>
|
|
17
|
+
Clients are lightweight objects, so don't hesitate to create new ones as needed. However, be mindful of the context management - each time you open a client context (`async with client:`), a new connection or process starts. For best performance, keep client contexts open while performing multiple operations rather than repeatedly opening and closing them.
|
|
18
|
+
</Tip>
|
|
19
|
+
|
|
20
|
+
## Choosing a Transport
|
|
21
|
+
|
|
22
|
+
Choose the transport that best fits your use case:
|
|
23
|
+
|
|
24
|
+
- **Connecting to Remote/Persistent Servers:** Use `StreamableHttpTransport` (recommended, default for HTTP URLs) or `SSETransport` (legacy option) for web-based deployments.
|
|
25
|
+
|
|
26
|
+
- **Local Development/Testing:** Use `FastMCPTransport` for in-memory, same-process testing of your FastMCP servers.
|
|
27
|
+
|
|
28
|
+
- **Running Local Servers:** Use `UvxStdioTransport` (Python/uv) or `NpxStdioTransport` (Node/npm) if you need to run MCP servers as packaged tools.
|
|
29
|
+
|
|
30
|
+
## Network Transports
|
|
31
|
+
|
|
32
|
+
These transports connect to servers running over a network, typically long-running services accessible via URLs.
|
|
33
|
+
|
|
34
|
+
### Streamable HTTP
|
|
35
|
+
|
|
36
|
+
<VersionBadge version="2.3.0" />
|
|
37
|
+
|
|
38
|
+
Streamable HTTP is the recommended transport for web-based deployments, providing efficient bidirectional communication over HTTP.
|
|
39
|
+
|
|
40
|
+
#### Overview
|
|
41
|
+
|
|
42
|
+
- **Class:** `fastmcp.client.transports.StreamableHttpTransport`
|
|
43
|
+
- **Inferred From:** URLs starting with `http://` or `https://` (default for HTTP URLs since v2.3.0) that do not contain `/sse/` in the path
|
|
44
|
+
- **Server Compatibility:** Works with FastMCP servers running in `streamable-http` mode
|
|
45
|
+
|
|
46
|
+
#### Basic Usage
|
|
47
|
+
|
|
48
|
+
The simplest way to use Streamable HTTP is to let the transport be inferred from a URL:
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
from fastmcp import Client
|
|
52
|
+
import asyncio
|
|
53
|
+
|
|
54
|
+
# The Client automatically uses StreamableHttpTransport for HTTP URLs
|
|
55
|
+
client = Client("https://example.com/mcp")
|
|
56
|
+
|
|
57
|
+
async def main():
|
|
58
|
+
async with client:
|
|
59
|
+
tools = await client.list_tools()
|
|
60
|
+
print(f"Available tools: {tools}")
|
|
61
|
+
|
|
62
|
+
asyncio.run(main())
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
You can also explicitly instantiate the transport:
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from fastmcp.client.transports import StreamableHttpTransport
|
|
69
|
+
|
|
70
|
+
transport = StreamableHttpTransport(url="https://example.com/mcp")
|
|
71
|
+
client = Client(transport)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
#### Authentication with Headers
|
|
75
|
+
|
|
76
|
+
For servers requiring authentication:
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
from fastmcp import Client
|
|
80
|
+
from fastmcp.client.transports import StreamableHttpTransport
|
|
81
|
+
|
|
82
|
+
# Create transport with authentication headers
|
|
83
|
+
transport = StreamableHttpTransport(
|
|
84
|
+
url="https://example.com/mcp",
|
|
85
|
+
headers={"Authorization": "Bearer your-token-here"}
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
client = Client(transport)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### SSE (Server-Sent Events)
|
|
92
|
+
|
|
93
|
+
<VersionBadge version="2.0.0" />
|
|
94
|
+
|
|
95
|
+
Server-Sent Events (SSE) is a transport that allows servers to push data to clients over HTTP connections. While still supported, Streamable HTTP is now the recommended transport for new web-based deployments.
|
|
96
|
+
|
|
97
|
+
#### Overview
|
|
98
|
+
|
|
99
|
+
- **Class:** `fastmcp.client.transports.SSETransport`
|
|
100
|
+
- **Inferred From:** HTTP URLs containing `/sse/` in the path
|
|
101
|
+
- **Server Compatibility:** Works with FastMCP servers running in `sse` mode
|
|
102
|
+
|
|
103
|
+
#### Basic Usage
|
|
104
|
+
|
|
105
|
+
The simplest way to use SSE is to let the transport be inferred from a URL with `/sse/` in the path:
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
from fastmcp import Client
|
|
109
|
+
import asyncio
|
|
110
|
+
|
|
111
|
+
# The Client automatically uses SSETransport for URLs containing /sse/ in the path
|
|
112
|
+
client = Client("https://example.com/sse")
|
|
113
|
+
|
|
114
|
+
async def main():
|
|
115
|
+
async with client:
|
|
116
|
+
tools = await client.list_tools()
|
|
117
|
+
print(f"Available tools: {tools}")
|
|
118
|
+
|
|
119
|
+
asyncio.run(main())
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
You can also explicitly instantiate the transport for URLs that do not contain `/sse/` in the path or for more control:
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
from fastmcp.client.transports import SSETransport
|
|
126
|
+
|
|
127
|
+
transport = SSETransport(url="https://example.com/sse")
|
|
128
|
+
client = Client(transport)
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
#### Authentication with Headers
|
|
132
|
+
|
|
133
|
+
SSE transport also supports custom headers for authentication:
|
|
134
|
+
|
|
135
|
+
```python
|
|
136
|
+
from fastmcp import Client
|
|
137
|
+
from fastmcp.client.transports import SSETransport
|
|
138
|
+
|
|
139
|
+
# Create SSE transport with authentication headers
|
|
140
|
+
transport = SSETransport(
|
|
141
|
+
url="https://example.com/sse",
|
|
142
|
+
headers={"Authorization": "Bearer your-token-here"}
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
client = Client(transport)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
#### When to Use SSE vs. Streamable HTTP
|
|
149
|
+
|
|
150
|
+
- **Use Streamable HTTP when:**
|
|
151
|
+
- Setting up new deployments (recommended default)
|
|
152
|
+
- You need bidirectional streaming
|
|
153
|
+
- You're connecting to FastMCP servers running in `streamable-http` mode
|
|
154
|
+
|
|
155
|
+
- **Use SSE when:**
|
|
156
|
+
- Connecting to legacy FastMCP servers running in `sse` mode
|
|
157
|
+
- Working with infrastructure optimized for Server-Sent Events
|
|
158
|
+
|
|
159
|
+
## Local Transports
|
|
160
|
+
|
|
161
|
+
These transports manage an MCP server running as a subprocess, communicating with it via standard input (stdin) and standard output (stdout). This is the standard mechanism used by clients like Claude Desktop.
|
|
162
|
+
|
|
163
|
+
### Python Stdio
|
|
164
|
+
|
|
165
|
+
- **Class:** `fastmcp.client.transports.PythonStdioTransport`
|
|
166
|
+
- **Inferred From:** Paths to `.py` files
|
|
167
|
+
- **Use Case:** Running a Python-based MCP server script in a subprocess
|
|
168
|
+
|
|
169
|
+
This is the most common way to interact with local FastMCP servers during development or when integrating with tools that expect to launch a server script.
|
|
170
|
+
|
|
171
|
+
```python
|
|
172
|
+
from fastmcp import Client
|
|
173
|
+
from fastmcp.client.transports import PythonStdioTransport
|
|
174
|
+
|
|
175
|
+
server_script = "my_mcp_server.py" # Path to your server script
|
|
176
|
+
|
|
177
|
+
# Option 1: Inferred transport
|
|
178
|
+
client = Client(server_script)
|
|
179
|
+
|
|
180
|
+
# Option 2: Explicit transport with custom configuration
|
|
181
|
+
transport = PythonStdioTransport(
|
|
182
|
+
script_path=server_script,
|
|
183
|
+
python_cmd="/usr/bin/python3.11", # Optional: specify Python interpreter
|
|
184
|
+
# args=["--some-server-arg"], # Optional: pass arguments to the script
|
|
185
|
+
# env={"MY_VAR": "value"}, # Optional: set environment variables
|
|
186
|
+
)
|
|
187
|
+
client = Client(transport)
|
|
188
|
+
|
|
189
|
+
async def main():
|
|
190
|
+
async with client:
|
|
191
|
+
tools = await client.list_tools()
|
|
192
|
+
print(f"Connected via Python Stdio, found tools: {tools}")
|
|
193
|
+
|
|
194
|
+
asyncio.run(main())
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
<Warning>
|
|
198
|
+
The server script must include logic to start the MCP server and listen on stdio, typically via `mcp.run()` or `fastmcp.server.run()`. The Client only launches the script; it doesn't inject the server logic.
|
|
199
|
+
</Warning>
|
|
200
|
+
|
|
201
|
+
### Node.js Stdio
|
|
202
|
+
|
|
203
|
+
- **Class:** `fastmcp.client.transports.NodeStdioTransport`
|
|
204
|
+
- **Inferred From:** Paths to `.js` files
|
|
205
|
+
- **Use Case:** Running a Node.js-based MCP server script in a subprocess
|
|
206
|
+
|
|
207
|
+
Similar to the Python transport, but for JavaScript servers.
|
|
208
|
+
|
|
209
|
+
```python
|
|
210
|
+
from fastmcp import Client
|
|
211
|
+
from fastmcp.client.transports import NodeStdioTransport
|
|
212
|
+
|
|
213
|
+
node_server_script = "my_mcp_server.js" # Path to your Node.js server script
|
|
214
|
+
|
|
215
|
+
# Option 1: Inferred transport
|
|
216
|
+
client = Client(node_server_script)
|
|
217
|
+
|
|
218
|
+
# Option 2: Explicit transport
|
|
219
|
+
transport = NodeStdioTransport(
|
|
220
|
+
script_path=node_server_script,
|
|
221
|
+
node_cmd="node" # Optional: specify path to Node executable
|
|
222
|
+
)
|
|
223
|
+
client = Client(transport)
|
|
224
|
+
|
|
225
|
+
async def main():
|
|
226
|
+
async with client:
|
|
227
|
+
tools = await client.list_tools()
|
|
228
|
+
print(f"Connected via Node.js Stdio, found tools: {tools}")
|
|
229
|
+
|
|
230
|
+
asyncio.run(main())
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### UVX Stdio (Experimental)
|
|
234
|
+
|
|
235
|
+
- **Class:** `fastmcp.client.transports.UvxStdioTransport`
|
|
236
|
+
- **Inferred From:** Not automatically inferred
|
|
237
|
+
- **Use Case:** Running an MCP server packaged as a Python tool using [`uvx`](https://docs.astral.sh/uv/reference/cli/#uvx)
|
|
238
|
+
|
|
239
|
+
This is useful for executing MCP servers distributed as command-line tools or packages without installing them into your environment.
|
|
240
|
+
|
|
241
|
+
```python
|
|
242
|
+
from fastmcp import Client
|
|
243
|
+
from fastmcp.client.transports import UvxStdioTransport
|
|
244
|
+
|
|
245
|
+
# Run a hypothetical 'cloud-analyzer-mcp' tool via uvx
|
|
246
|
+
transport = UvxStdioTransport(
|
|
247
|
+
tool_name="cloud-analyzer-mcp",
|
|
248
|
+
# from_package="cloud-analyzer-cli", # Optional: specify package if tool name differs
|
|
249
|
+
# with_packages=["boto3", "requests"] # Optional: add dependencies
|
|
250
|
+
)
|
|
251
|
+
client = Client(transport)
|
|
252
|
+
|
|
253
|
+
async def main():
|
|
254
|
+
async with client:
|
|
255
|
+
result = await client.call_tool("analyze_bucket", {"name": "my-data"})
|
|
256
|
+
print(f"Analysis result: {result}")
|
|
257
|
+
|
|
258
|
+
asyncio.run(main())
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### NPX Stdio (Experimental)
|
|
262
|
+
|
|
263
|
+
- **Class:** `fastmcp.client.transports.NpxStdioTransport`
|
|
264
|
+
- **Inferred From:** Not automatically inferred
|
|
265
|
+
- **Use Case:** Running an MCP server packaged as an NPM package using `npx`
|
|
266
|
+
|
|
267
|
+
Similar to `UvxStdioTransport`, but for the Node.js ecosystem.
|
|
268
|
+
|
|
269
|
+
```python
|
|
270
|
+
from fastmcp import Client
|
|
271
|
+
from fastmcp.client.transports import NpxStdioTransport
|
|
272
|
+
|
|
273
|
+
# Run an MCP server from an NPM package
|
|
274
|
+
transport = NpxStdioTransport(
|
|
275
|
+
package="mcp-server-package",
|
|
276
|
+
# args=["--port", "stdio"] # Optional: pass arguments to the package
|
|
277
|
+
)
|
|
278
|
+
client = Client(transport)
|
|
279
|
+
|
|
280
|
+
async def main():
|
|
281
|
+
async with client:
|
|
282
|
+
result = await client.call_tool("get_npm_data", {})
|
|
283
|
+
print(f"Result: {result}")
|
|
284
|
+
|
|
285
|
+
asyncio.run(main())
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## In-Memory Transports
|
|
289
|
+
|
|
290
|
+
### FastMCP Transport
|
|
291
|
+
|
|
292
|
+
- **Class:** `fastmcp.client.transports.FastMCPTransport`
|
|
293
|
+
- **Inferred From:** An instance of `fastmcp.server.FastMCP`
|
|
294
|
+
- **Use Case:** Connecting directly to a `FastMCP` server instance in the same Python process
|
|
295
|
+
|
|
296
|
+
This is extremely useful for testing your FastMCP servers.
|
|
297
|
+
|
|
298
|
+
```python
|
|
299
|
+
from fastmcp import FastMCP, Client
|
|
300
|
+
import asyncio
|
|
301
|
+
|
|
302
|
+
# 1. Create your FastMCP server instance
|
|
303
|
+
server = FastMCP(name="InMemoryServer")
|
|
304
|
+
|
|
305
|
+
@server.tool()
|
|
306
|
+
def ping():
|
|
307
|
+
return "pong"
|
|
308
|
+
|
|
309
|
+
# 2. Create a client pointing directly to the server instance
|
|
310
|
+
client = Client(server) # Transport is automatically inferred
|
|
311
|
+
|
|
312
|
+
async def main():
|
|
313
|
+
async with client:
|
|
314
|
+
result = await client.call_tool("ping")
|
|
315
|
+
print(f"In-memory call result: {result}")
|
|
316
|
+
|
|
317
|
+
asyncio.run(main())
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
Communication happens through efficient in-memory queues, making it very fast and ideal for unit testing.
|