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.
Files changed (187) hide show
  1. fastmcp-2.3.5/.github/labeler.yml +29 -0
  2. fastmcp-2.3.5/.github/workflows/labeler.yml +12 -0
  3. {fastmcp-2.3.4 → fastmcp-2.3.5}/.github/workflows/run-static.yml +3 -6
  4. {fastmcp-2.3.4 → fastmcp-2.3.5}/.github/workflows/run-tests.yml +2 -6
  5. fastmcp-2.3.5/AGENTS.md +67 -0
  6. {fastmcp-2.3.4 → fastmcp-2.3.5}/PKG-INFO +3 -3
  7. {fastmcp-2.3.4 → fastmcp-2.3.5}/README.md +1 -1
  8. {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/clients/client.mdx +84 -8
  9. fastmcp-2.3.5/docs/clients/transports.mdx +320 -0
  10. {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/deployment/asgi.mdx +11 -8
  11. {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/deployment/cli.mdx +13 -5
  12. {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/deployment/running-server.mdx +4 -4
  13. {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/getting-started/quickstart.mdx +2 -1
  14. {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/patterns/testing.mdx +1 -1
  15. {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/servers/composition.mdx +2 -2
  16. {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/servers/fastmcp.mdx +2 -2
  17. {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/servers/proxy.mdx +18 -22
  18. fastmcp-2.3.5/examples/in_memory_proxy_example.py +82 -0
  19. {fastmcp-2.3.4 → fastmcp-2.3.5}/pyproject.toml +2 -1
  20. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/cli/cli.py +30 -138
  21. fastmcp-2.3.5/src/fastmcp/cli/run.py +179 -0
  22. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/client/client.py +62 -18
  23. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/client/logging.py +8 -0
  24. fastmcp-2.3.5/src/fastmcp/client/progress.py +38 -0
  25. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/client/transports.py +27 -36
  26. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/server/context.py +6 -3
  27. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/server/http.py +47 -14
  28. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/server/server.py +86 -43
  29. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/cli/test_cli.py +23 -90
  30. fastmcp-2.3.5/tests/cli/test_run.py +262 -0
  31. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/client/test_client.py +104 -7
  32. fastmcp-2.3.5/tests/client/test_progress.py +70 -0
  33. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/client/test_sse.py +4 -4
  34. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/client/test_streamable_http.py +5 -1
  35. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/resources/test_file_resources.py +2 -1
  36. fastmcp-2.3.5/tests/server/test_app_state.py +26 -0
  37. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/server/test_import_server.py +4 -4
  38. fastmcp-2.3.5/tests/server/test_logging.py +176 -0
  39. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/server/test_mount.py +7 -7
  40. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/server/test_proxy.py +25 -2
  41. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/server/test_server_interactions.py +3 -5
  42. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/test_deprecated.py +8 -1
  43. {fastmcp-2.3.4 → fastmcp-2.3.5}/uv.lock +4 -4
  44. fastmcp-2.3.4/docs/clients/transports.mdx +0 -244
  45. fastmcp-2.3.4/src/fastmcp/low_level/sse_server_transport.py +0 -104
  46. fastmcp-2.3.4/tests/cli/test_run.py +0 -22
  47. {fastmcp-2.3.4 → fastmcp-2.3.5}/.cursor/rules/core-mcp-objects.mdc +0 -0
  48. {fastmcp-2.3.4 → fastmcp-2.3.5}/.github/ISSUE_TEMPLATE/bug.yml +0 -0
  49. {fastmcp-2.3.4 → fastmcp-2.3.5}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  50. {fastmcp-2.3.4 → fastmcp-2.3.5}/.github/ISSUE_TEMPLATE/enhancement.yml +0 -0
  51. {fastmcp-2.3.4 → fastmcp-2.3.5}/.github/release.yml +0 -0
  52. {fastmcp-2.3.4 → fastmcp-2.3.5}/.github/workflows/publish.yml +0 -0
  53. {fastmcp-2.3.4 → fastmcp-2.3.5}/.gitignore +0 -0
  54. {fastmcp-2.3.4 → fastmcp-2.3.5}/.pre-commit-config.yaml +0 -0
  55. {fastmcp-2.3.4 → fastmcp-2.3.5}/LICENSE +0 -0
  56. {fastmcp-2.3.4 → fastmcp-2.3.5}/Windows_Notes.md +0 -0
  57. {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/assets/demo-inspector.png +0 -0
  58. {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/deployment/authentication.mdx +0 -0
  59. {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/docs.json +0 -0
  60. {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/getting-started/installation.mdx +0 -0
  61. {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/getting-started/welcome.mdx +0 -0
  62. {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/patterns/contrib.mdx +0 -0
  63. {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/patterns/decorating-methods.mdx +0 -0
  64. {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/patterns/fastapi.mdx +0 -0
  65. {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/patterns/http-requests.mdx +0 -0
  66. {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/patterns/openapi.mdx +0 -0
  67. {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/servers/context.mdx +0 -0
  68. {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/servers/prompts.mdx +0 -0
  69. {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/servers/resources.mdx +0 -0
  70. {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/servers/tools.mdx +0 -0
  71. {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/snippets/version-badge.mdx +0 -0
  72. {fastmcp-2.3.4 → fastmcp-2.3.5}/docs/style.css +0 -0
  73. {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/complex_inputs.py +0 -0
  74. {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/desktop.py +0 -0
  75. {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/echo.py +0 -0
  76. {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/memory.py +0 -0
  77. {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/mount_example.py +0 -0
  78. {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/sampling.py +0 -0
  79. {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/screenshot.py +0 -0
  80. {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/serializer.py +0 -0
  81. {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/simple_echo.py +0 -0
  82. {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/smart_home/README.md +0 -0
  83. {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/smart_home/pyproject.toml +0 -0
  84. {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/smart_home/src/smart_home/__init__.py +0 -0
  85. {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/smart_home/src/smart_home/__main__.py +0 -0
  86. {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/smart_home/src/smart_home/hub.py +0 -0
  87. {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/smart_home/src/smart_home/lights/__init__.py +0 -0
  88. {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/smart_home/src/smart_home/lights/hue_utils.py +0 -0
  89. {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/smart_home/src/smart_home/lights/server.py +0 -0
  90. {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/smart_home/src/smart_home/py.typed +0 -0
  91. {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/smart_home/src/smart_home/settings.py +0 -0
  92. {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/smart_home/uv.lock +0 -0
  93. {fastmcp-2.3.4 → fastmcp-2.3.5}/examples/text_me.py +0 -0
  94. {fastmcp-2.3.4 → fastmcp-2.3.5}/justfile +0 -0
  95. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/__init__.py +0 -0
  96. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/cli/__init__.py +0 -0
  97. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/cli/claude.py +0 -0
  98. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/client/__init__.py +0 -0
  99. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/client/base.py +0 -0
  100. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/client/roots.py +0 -0
  101. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/client/sampling.py +0 -0
  102. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/contrib/README.md +0 -0
  103. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/contrib/bulk_tool_caller/README.md +0 -0
  104. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/contrib/bulk_tool_caller/__init__.py +0 -0
  105. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/contrib/bulk_tool_caller/bulk_tool_caller.py +0 -0
  106. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/contrib/bulk_tool_caller/example.py +0 -0
  107. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/contrib/mcp_mixin/README.md +0 -0
  108. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/contrib/mcp_mixin/__init__.py +0 -0
  109. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/contrib/mcp_mixin/example.py +0 -0
  110. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/contrib/mcp_mixin/mcp_mixin.py +0 -0
  111. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/exceptions.py +0 -0
  112. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/low_level/README.md +0 -0
  113. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/low_level/__init__.py +0 -0
  114. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/prompts/__init__.py +0 -0
  115. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/prompts/prompt.py +0 -0
  116. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/prompts/prompt_manager.py +0 -0
  117. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/py.typed +0 -0
  118. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/resources/__init__.py +0 -0
  119. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/resources/resource.py +0 -0
  120. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/resources/resource_manager.py +0 -0
  121. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/resources/template.py +0 -0
  122. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/resources/types.py +0 -0
  123. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/server/__init__.py +0 -0
  124. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/server/dependencies.py +0 -0
  125. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/server/openapi.py +0 -0
  126. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/server/proxy.py +0 -0
  127. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/settings.py +0 -0
  128. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/tools/__init__.py +0 -0
  129. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/tools/tool.py +0 -0
  130. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/tools/tool_manager.py +0 -0
  131. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/utilities/__init__.py +0 -0
  132. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/utilities/cache.py +0 -0
  133. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/utilities/decorators.py +0 -0
  134. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/utilities/exceptions.py +0 -0
  135. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/utilities/json_schema.py +0 -0
  136. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/utilities/logging.py +0 -0
  137. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/utilities/openapi.py +0 -0
  138. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/utilities/tests.py +0 -0
  139. {fastmcp-2.3.4 → fastmcp-2.3.5}/src/fastmcp/utilities/types.py +0 -0
  140. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/__init__.py +0 -0
  141. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/client/__init__.py +0 -0
  142. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/client/test_logs.py +0 -0
  143. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/client/test_roots.py +0 -0
  144. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/client/test_sampling.py +0 -0
  145. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/conftest.py +0 -0
  146. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/contrib/__init__.py +0 -0
  147. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/contrib/test_bulk_tool_caller.py +0 -0
  148. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/contrib/test_mcp_mixin.py +0 -0
  149. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/prompts/__init__.py +0 -0
  150. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/prompts/test_prompt.py +0 -0
  151. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/prompts/test_prompt_manager.py +0 -0
  152. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/resources/__init__.py +0 -0
  153. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/resources/test_function_resources.py +0 -0
  154. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/resources/test_resource_manager.py +0 -0
  155. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/resources/test_resource_template.py +0 -0
  156. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/resources/test_resources.py +0 -0
  157. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/server/__init__.py +0 -0
  158. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/server/test_auth_integration.py +0 -0
  159. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/server/test_context.py +0 -0
  160. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/server/test_file_server.py +0 -0
  161. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/server/test_http_dependencies.py +0 -0
  162. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/server/test_http_middleware.py +0 -0
  163. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/server/test_lifespan.py +0 -0
  164. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/server/test_openapi.py +0 -0
  165. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/server/test_run_server.py +0 -0
  166. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/server/test_server.py +0 -0
  167. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/server/test_tool_annotations.py +0 -0
  168. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/test_examples.py +0 -0
  169. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/test_servers/fastmcp_server.py +0 -0
  170. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/test_servers/sse.py +0 -0
  171. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/test_servers/stdio.py +0 -0
  172. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/tools/__init__.py +0 -0
  173. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/tools/test_tool.py +0 -0
  174. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/tools/test_tool_manager.py +0 -0
  175. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/utilities/__init__.py +0 -0
  176. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/utilities/openapi/__init__.py +0 -0
  177. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/utilities/openapi/conftest.py +0 -0
  178. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/utilities/openapi/test_openapi.py +0 -0
  179. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/utilities/openapi/test_openapi_advanced.py +0 -0
  180. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/utilities/openapi/test_openapi_fastapi.py +0 -0
  181. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/utilities/test_cache.py +0 -0
  182. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/utilities/test_decorated_function.py +0 -0
  183. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/utilities/test_json_schema.py +0 -0
  184. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/utilities/test_logging.py +0 -0
  185. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/utilities/test_tests.py +0 -0
  186. {fastmcp-2.3.4 → fastmcp-2.3.5}/tests/utilities/test_typeadapter.py +0 -0
  187. {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"
@@ -0,0 +1,12 @@
1
+ name: "Pull Request Labeler"
2
+ on:
3
+ - pull_request_target
4
+
5
+ jobs:
6
+ labeler:
7
+ permissions:
8
+ contents: read
9
+ pull-requests: write
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/labeler@v5
@@ -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
- paths:
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
 
@@ -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.4
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.8.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.from_client()`. 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.
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.from_client()`. 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.
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
- * If it starts with `http://` or `https://`: Creates an `SSETransport`.
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
- sse_url = "http://localhost:8000/sse" # SSE server URL
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
- client_sse = Client(sse_url)
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(client_sse.transport)
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
- # <SSE(url='http://localhost:8000/sse')>
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.