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