fastmcp 2.3.5__tar.gz → 2.5.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (202) hide show
  1. {fastmcp-2.3.5 → fastmcp-2.5.0}/.github/workflows/run-tests.yml +2 -2
  2. {fastmcp-2.3.5 → fastmcp-2.5.0}/PKG-INFO +27 -4
  3. {fastmcp-2.3.5 → fastmcp-2.5.0}/README.md +26 -3
  4. fastmcp-2.5.0/docs/clients/advanced-features.mdx +152 -0
  5. {fastmcp-2.3.5 → fastmcp-2.5.0}/docs/clients/client.mdx +89 -157
  6. {fastmcp-2.3.5 → fastmcp-2.5.0}/docs/clients/transports.mdx +63 -3
  7. {fastmcp-2.3.5 → fastmcp-2.5.0}/docs/docs.json +3 -3
  8. {fastmcp-2.3.5 → fastmcp-2.5.0}/docs/getting-started/installation.mdx +14 -0
  9. {fastmcp-2.3.5 → fastmcp-2.5.0}/docs/getting-started/welcome.mdx +4 -8
  10. fastmcp-2.5.0/docs/patterns/fastapi.mdx +47 -0
  11. {fastmcp-2.3.5 → fastmcp-2.5.0}/docs/servers/composition.mdx +59 -32
  12. {fastmcp-2.3.5 → fastmcp-2.5.0}/docs/servers/context.mdx +4 -3
  13. fastmcp-2.5.0/docs/servers/openapi.mdx +469 -0
  14. {fastmcp-2.3.5 → fastmcp-2.5.0}/docs/servers/proxy.mdx +60 -2
  15. {fastmcp-2.3.5 → fastmcp-2.5.0}/docs/servers/resources.mdx +15 -6
  16. {fastmcp-2.3.5 → fastmcp-2.5.0}/docs/servers/tools.mdx +20 -8
  17. fastmcp-2.5.0/examples/tags_example.py +141 -0
  18. {fastmcp-2.3.5 → fastmcp-2.5.0}/pyproject.toml +6 -0
  19. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/client/client.py +44 -6
  20. fastmcp-2.5.0/src/fastmcp/client/logging.py +27 -0
  21. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/client/transports.py +202 -57
  22. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/prompts/prompt.py +11 -4
  23. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/prompts/prompt_manager.py +25 -5
  24. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/resources/resource_manager.py +31 -5
  25. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/resources/template.py +10 -5
  26. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/server/context.py +46 -0
  27. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/server/http.py +25 -1
  28. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/server/openapi.py +436 -73
  29. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/server/server.py +412 -127
  30. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/settings.py +46 -1
  31. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/tools/tool.py +5 -1
  32. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/tools/tool_manager.py +9 -2
  33. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/utilities/logging.py +6 -1
  34. fastmcp-2.5.0/src/fastmcp/utilities/mcp_config.py +77 -0
  35. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/utilities/openapi.py +233 -602
  36. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/utilities/tests.py +8 -4
  37. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/client/test_client.py +133 -3
  38. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/client/test_logs.py +2 -2
  39. fastmcp-2.5.0/tests/client/test_openapi.py +192 -0
  40. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/contrib/test_bulk_tool_caller.py +3 -9
  41. {fastmcp-2.3.5/tests → fastmcp-2.5.0/tests/deprecated}/test_deprecated.py +80 -2
  42. fastmcp-2.5.0/tests/deprecated/test_mount_separators.py +85 -0
  43. fastmcp-2.5.0/tests/deprecated/test_resource_prefixes.py +98 -0
  44. fastmcp-2.5.0/tests/deprecated/test_route_type_ignore.py +113 -0
  45. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/prompts/test_prompt.py +24 -0
  46. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/prompts/test_prompt_manager.py +46 -2
  47. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/resources/test_resource_manager.py +38 -35
  48. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/resources/test_resource_template.py +25 -0
  49. fastmcp-2.5.0/tests/server/http/test_custom_routes.py +105 -0
  50. fastmcp-2.5.0/tests/server/http/test_http_dependencies.py +168 -0
  51. {fastmcp-2.3.5/tests/server → fastmcp-2.5.0/tests/server/http}/test_http_middleware.py +0 -6
  52. {fastmcp-2.3.5/tests/server → fastmcp-2.5.0/tests/server/openapi}/test_openapi.py +606 -98
  53. fastmcp-2.5.0/tests/server/openapi/test_openapi_path_parameters.py +457 -0
  54. fastmcp-2.5.0/tests/server/openapi/test_route_map_fn.py +377 -0
  55. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/server/test_auth_integration.py +0 -29
  56. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/server/test_context.py +29 -0
  57. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/server/test_import_server.py +19 -23
  58. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/server/test_lifespan.py +163 -3
  59. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/server/test_mount.py +37 -38
  60. fastmcp-2.5.0/tests/server/test_resource_prefix_formats.py +65 -0
  61. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/server/test_server.py +290 -0
  62. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/server/test_server_interactions.py +46 -0
  63. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/test_examples.py +0 -5
  64. fastmcp-2.5.0/tests/tools/__init__.py +0 -0
  65. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/tools/test_tool.py +31 -0
  66. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/tools/test_tool_manager.py +111 -5
  67. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/utilities/openapi/test_openapi_fastapi.py +9 -9
  68. fastmcp-2.5.0/tests/utilities/test_mcp_config.py +142 -0
  69. fastmcp-2.5.0/tests/utilities/test_tests.py +10 -0
  70. {fastmcp-2.3.5 → fastmcp-2.5.0}/uv.lock +17 -2
  71. fastmcp-2.3.5/docs/patterns/fastapi.mdx +0 -144
  72. fastmcp-2.3.5/docs/patterns/openapi.mdx +0 -226
  73. fastmcp-2.3.5/src/fastmcp/client/logging.py +0 -21
  74. fastmcp-2.3.5/tests/server/test_http_dependencies.py +0 -102
  75. fastmcp-2.3.5/tests/utilities/test_tests.py +0 -9
  76. {fastmcp-2.3.5 → fastmcp-2.5.0}/.cursor/rules/core-mcp-objects.mdc +0 -0
  77. {fastmcp-2.3.5 → fastmcp-2.5.0}/.github/ISSUE_TEMPLATE/bug.yml +0 -0
  78. {fastmcp-2.3.5 → fastmcp-2.5.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  79. {fastmcp-2.3.5 → fastmcp-2.5.0}/.github/ISSUE_TEMPLATE/enhancement.yml +0 -0
  80. {fastmcp-2.3.5 → fastmcp-2.5.0}/.github/labeler.yml +0 -0
  81. {fastmcp-2.3.5 → fastmcp-2.5.0}/.github/release.yml +0 -0
  82. {fastmcp-2.3.5 → fastmcp-2.5.0}/.github/workflows/labeler.yml +0 -0
  83. {fastmcp-2.3.5 → fastmcp-2.5.0}/.github/workflows/publish.yml +0 -0
  84. {fastmcp-2.3.5 → fastmcp-2.5.0}/.github/workflows/run-static.yml +0 -0
  85. {fastmcp-2.3.5 → fastmcp-2.5.0}/.gitignore +0 -0
  86. {fastmcp-2.3.5 → fastmcp-2.5.0}/.pre-commit-config.yaml +0 -0
  87. {fastmcp-2.3.5 → fastmcp-2.5.0}/AGENTS.md +0 -0
  88. {fastmcp-2.3.5 → fastmcp-2.5.0}/LICENSE +0 -0
  89. {fastmcp-2.3.5 → fastmcp-2.5.0}/Windows_Notes.md +0 -0
  90. {fastmcp-2.3.5 → fastmcp-2.5.0}/docs/assets/demo-inspector.png +0 -0
  91. {fastmcp-2.3.5 → fastmcp-2.5.0}/docs/deployment/asgi.mdx +0 -0
  92. {fastmcp-2.3.5 → fastmcp-2.5.0}/docs/deployment/authentication.mdx +0 -0
  93. {fastmcp-2.3.5 → fastmcp-2.5.0}/docs/deployment/cli.mdx +0 -0
  94. {fastmcp-2.3.5 → fastmcp-2.5.0}/docs/deployment/running-server.mdx +0 -0
  95. {fastmcp-2.3.5 → fastmcp-2.5.0}/docs/getting-started/quickstart.mdx +0 -0
  96. {fastmcp-2.3.5 → fastmcp-2.5.0}/docs/patterns/contrib.mdx +0 -0
  97. {fastmcp-2.3.5 → fastmcp-2.5.0}/docs/patterns/decorating-methods.mdx +0 -0
  98. {fastmcp-2.3.5 → fastmcp-2.5.0}/docs/patterns/http-requests.mdx +0 -0
  99. {fastmcp-2.3.5 → fastmcp-2.5.0}/docs/patterns/testing.mdx +0 -0
  100. {fastmcp-2.3.5 → fastmcp-2.5.0}/docs/servers/fastmcp.mdx +0 -0
  101. {fastmcp-2.3.5 → fastmcp-2.5.0}/docs/servers/prompts.mdx +0 -0
  102. {fastmcp-2.3.5 → fastmcp-2.5.0}/docs/snippets/version-badge.mdx +0 -0
  103. {fastmcp-2.3.5 → fastmcp-2.5.0}/docs/style.css +0 -0
  104. {fastmcp-2.3.5 → fastmcp-2.5.0}/examples/complex_inputs.py +0 -0
  105. {fastmcp-2.3.5 → fastmcp-2.5.0}/examples/desktop.py +0 -0
  106. {fastmcp-2.3.5 → fastmcp-2.5.0}/examples/echo.py +0 -0
  107. {fastmcp-2.3.5 → fastmcp-2.5.0}/examples/in_memory_proxy_example.py +0 -0
  108. {fastmcp-2.3.5 → fastmcp-2.5.0}/examples/memory.py +0 -0
  109. {fastmcp-2.3.5 → fastmcp-2.5.0}/examples/mount_example.py +0 -0
  110. {fastmcp-2.3.5 → fastmcp-2.5.0}/examples/sampling.py +0 -0
  111. {fastmcp-2.3.5 → fastmcp-2.5.0}/examples/screenshot.py +0 -0
  112. {fastmcp-2.3.5 → fastmcp-2.5.0}/examples/serializer.py +0 -0
  113. {fastmcp-2.3.5 → fastmcp-2.5.0}/examples/simple_echo.py +0 -0
  114. {fastmcp-2.3.5 → fastmcp-2.5.0}/examples/smart_home/README.md +0 -0
  115. {fastmcp-2.3.5 → fastmcp-2.5.0}/examples/smart_home/pyproject.toml +0 -0
  116. {fastmcp-2.3.5 → fastmcp-2.5.0}/examples/smart_home/src/smart_home/__init__.py +0 -0
  117. {fastmcp-2.3.5 → fastmcp-2.5.0}/examples/smart_home/src/smart_home/__main__.py +0 -0
  118. {fastmcp-2.3.5 → fastmcp-2.5.0}/examples/smart_home/src/smart_home/hub.py +0 -0
  119. {fastmcp-2.3.5 → fastmcp-2.5.0}/examples/smart_home/src/smart_home/lights/__init__.py +0 -0
  120. {fastmcp-2.3.5 → fastmcp-2.5.0}/examples/smart_home/src/smart_home/lights/hue_utils.py +0 -0
  121. {fastmcp-2.3.5 → fastmcp-2.5.0}/examples/smart_home/src/smart_home/lights/server.py +0 -0
  122. {fastmcp-2.3.5 → fastmcp-2.5.0}/examples/smart_home/src/smart_home/py.typed +0 -0
  123. {fastmcp-2.3.5 → fastmcp-2.5.0}/examples/smart_home/src/smart_home/settings.py +0 -0
  124. {fastmcp-2.3.5 → fastmcp-2.5.0}/examples/smart_home/uv.lock +0 -0
  125. {fastmcp-2.3.5 → fastmcp-2.5.0}/examples/text_me.py +0 -0
  126. {fastmcp-2.3.5 → fastmcp-2.5.0}/justfile +0 -0
  127. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/__init__.py +0 -0
  128. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/cli/__init__.py +0 -0
  129. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/cli/claude.py +0 -0
  130. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/cli/cli.py +0 -0
  131. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/cli/run.py +0 -0
  132. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/client/__init__.py +0 -0
  133. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/client/base.py +0 -0
  134. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/client/progress.py +0 -0
  135. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/client/roots.py +0 -0
  136. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/client/sampling.py +0 -0
  137. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/contrib/README.md +0 -0
  138. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/contrib/bulk_tool_caller/README.md +0 -0
  139. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/contrib/bulk_tool_caller/__init__.py +0 -0
  140. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/contrib/bulk_tool_caller/bulk_tool_caller.py +0 -0
  141. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/contrib/bulk_tool_caller/example.py +0 -0
  142. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/contrib/mcp_mixin/README.md +0 -0
  143. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/contrib/mcp_mixin/__init__.py +0 -0
  144. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/contrib/mcp_mixin/example.py +0 -0
  145. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/contrib/mcp_mixin/mcp_mixin.py +0 -0
  146. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/exceptions.py +0 -0
  147. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/low_level/README.md +0 -0
  148. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/low_level/__init__.py +0 -0
  149. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/prompts/__init__.py +0 -0
  150. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/py.typed +0 -0
  151. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/resources/__init__.py +0 -0
  152. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/resources/resource.py +0 -0
  153. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/resources/types.py +0 -0
  154. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/server/__init__.py +0 -0
  155. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/server/dependencies.py +0 -0
  156. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/server/proxy.py +0 -0
  157. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/tools/__init__.py +0 -0
  158. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/utilities/__init__.py +0 -0
  159. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/utilities/cache.py +0 -0
  160. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/utilities/decorators.py +0 -0
  161. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/utilities/exceptions.py +0 -0
  162. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/utilities/json_schema.py +0 -0
  163. {fastmcp-2.3.5 → fastmcp-2.5.0}/src/fastmcp/utilities/types.py +0 -0
  164. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/__init__.py +0 -0
  165. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/cli/test_cli.py +0 -0
  166. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/cli/test_run.py +0 -0
  167. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/client/__init__.py +0 -0
  168. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/client/test_progress.py +0 -0
  169. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/client/test_roots.py +0 -0
  170. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/client/test_sampling.py +0 -0
  171. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/client/test_sse.py +0 -0
  172. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/client/test_streamable_http.py +0 -0
  173. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/conftest.py +0 -0
  174. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/contrib/__init__.py +0 -0
  175. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/contrib/test_mcp_mixin.py +0 -0
  176. {fastmcp-2.3.5/tests/prompts → fastmcp-2.5.0/tests/deprecated}/__init__.py +0 -0
  177. {fastmcp-2.3.5/tests/resources → fastmcp-2.5.0/tests/prompts}/__init__.py +0 -0
  178. {fastmcp-2.3.5/tests/server → fastmcp-2.5.0/tests/resources}/__init__.py +0 -0
  179. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/resources/test_file_resources.py +0 -0
  180. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/resources/test_function_resources.py +0 -0
  181. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/resources/test_resources.py +0 -0
  182. {fastmcp-2.3.5/tests/tools → fastmcp-2.5.0/tests/server}/__init__.py +0 -0
  183. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/server/test_app_state.py +0 -0
  184. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/server/test_file_server.py +0 -0
  185. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/server/test_logging.py +0 -0
  186. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/server/test_proxy.py +0 -0
  187. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/server/test_run_server.py +0 -0
  188. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/server/test_tool_annotations.py +0 -0
  189. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/test_servers/fastmcp_server.py +0 -0
  190. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/test_servers/sse.py +0 -0
  191. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/test_servers/stdio.py +0 -0
  192. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/utilities/__init__.py +0 -0
  193. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/utilities/openapi/__init__.py +0 -0
  194. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/utilities/openapi/conftest.py +0 -0
  195. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/utilities/openapi/test_openapi.py +0 -0
  196. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/utilities/openapi/test_openapi_advanced.py +0 -0
  197. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/utilities/test_cache.py +0 -0
  198. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/utilities/test_decorated_function.py +0 -0
  199. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/utilities/test_json_schema.py +0 -0
  200. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/utilities/test_logging.py +0 -0
  201. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/utilities/test_typeadapter.py +0 -0
  202. {fastmcp-2.3.5 → fastmcp-2.5.0}/tests/utilities/test_types.py +0 -0
@@ -44,7 +44,7 @@ jobs:
44
44
  python-version: ${{ matrix.python-version }}
45
45
 
46
46
  - name: Install FastMCP
47
- run: uv sync --dev --locked
47
+ run: uv sync --locked
48
48
 
49
49
  - name: Run tests
50
- run: uv run pytest
50
+ run: uv run pytest tests
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastmcp
3
- Version: 2.3.5
3
+ Version: 2.5.0
4
4
  Summary: The fast, Pythonic way to build MCP servers.
5
5
  Project-URL: Homepage, https://gofastmcp.com
6
6
  Project-URL: Repository, https://github.com/jlowin/fastmcp
@@ -44,11 +44,11 @@ Description-Content-Type: text/markdown
44
44
  > [!NOTE]
45
45
  > #### FastMCP 2.0 & The Official MCP SDK
46
46
  >
47
- > Recognize the `FastMCP` name? You might have seen the version that was contributed to the [official MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk), which was based on **FastMCP 1.0**.
47
+ > FastMCP is the standard framework for building MCP servers and clients. FastMCP 1.0 was incorporated into the [official MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk).
48
48
  >
49
- > **Welcome to FastMCP 2.0!** This is the actively developed successor, and it significantly expands on 1.0 by introducing powerful client capabilities, server proxying & composition, OpenAPI/FastAPI integration, and more advanced features.
49
+ > **This is FastMCP 2.0,** the actively maintained version that significantly expands on 1.0's basic server-building capabilities by introducing full client support, server composition, OpenAPI/FastAPI integration, remote server proxying, built-in testing tools, and more.
50
50
  >
51
- > FastMCP 2.0 is the recommended path for building modern, powerful MCP applications. Ready to upgrade or get started? Follow the [installation instructions](https://gofastmcp.com/getting-started/installation), which include specific steps for upgrading from the official MCP SDK.
51
+ > FastMCP 2.0 is the complete toolkit for modern AI applications. Ready to upgrade or get started? Follow the [installation instructions](https://gofastmcp.com/getting-started/installation), which include specific steps for upgrading from the official MCP SDK.
52
52
 
53
53
  ---
54
54
 
@@ -282,6 +282,29 @@ async def main():
282
282
  # ... use the client
283
283
  ```
284
284
 
285
+ FastMCP also supports connecting to multiple servers through a single unified client using the standard MCP configuration format:
286
+
287
+ ```python
288
+ from fastmcp import Client
289
+
290
+ # Standard MCP configuration with multiple servers
291
+ config = {
292
+ "mcpServers": {
293
+ "weather": {"url": "https://weather-api.example.com/mcp"},
294
+ "assistant": {"command": "python", "args": ["./assistant_server.py"]}
295
+ }
296
+ }
297
+
298
+ # Create a client that connects to all servers
299
+ client = Client(config)
300
+
301
+ async def main():
302
+ async with client:
303
+ # Access tools and resources with server prefixes
304
+ forecast = await client.call_tool("weather_get_forecast", {"city": "London"})
305
+ answer = await client.call_tool("assistant_answer_question", {"query": "What is MCP?"})
306
+ ```
307
+
285
308
  Learn more in the [**Client Documentation**](https://gofastmcp.com/clients/client) and [**Transports Documentation**](https://gofastmcp.com/clients/transports).
286
309
 
287
310
  ## Advanced Features
@@ -15,11 +15,11 @@
15
15
  > [!NOTE]
16
16
  > #### FastMCP 2.0 & The Official MCP SDK
17
17
  >
18
- > Recognize the `FastMCP` name? You might have seen the version that was contributed to the [official MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk), which was based on **FastMCP 1.0**.
18
+ > FastMCP is the standard framework for building MCP servers and clients. FastMCP 1.0 was incorporated into the [official MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk).
19
19
  >
20
- > **Welcome to FastMCP 2.0!** This is the actively developed successor, and it significantly expands on 1.0 by introducing powerful client capabilities, server proxying & composition, OpenAPI/FastAPI integration, and more advanced features.
20
+ > **This is FastMCP 2.0,** the actively maintained version that significantly expands on 1.0's basic server-building capabilities by introducing full client support, server composition, OpenAPI/FastAPI integration, remote server proxying, built-in testing tools, and more.
21
21
  >
22
- > FastMCP 2.0 is the recommended path for building modern, powerful MCP applications. Ready to upgrade or get started? Follow the [installation instructions](https://gofastmcp.com/getting-started/installation), which include specific steps for upgrading from the official MCP SDK.
22
+ > FastMCP 2.0 is the complete toolkit for modern AI applications. Ready to upgrade or get started? Follow the [installation instructions](https://gofastmcp.com/getting-started/installation), which include specific steps for upgrading from the official MCP SDK.
23
23
 
24
24
  ---
25
25
 
@@ -253,6 +253,29 @@ async def main():
253
253
  # ... use the client
254
254
  ```
255
255
 
256
+ FastMCP also supports connecting to multiple servers through a single unified client using the standard MCP configuration format:
257
+
258
+ ```python
259
+ from fastmcp import Client
260
+
261
+ # Standard MCP configuration with multiple servers
262
+ config = {
263
+ "mcpServers": {
264
+ "weather": {"url": "https://weather-api.example.com/mcp"},
265
+ "assistant": {"command": "python", "args": ["./assistant_server.py"]}
266
+ }
267
+ }
268
+
269
+ # Create a client that connects to all servers
270
+ client = Client(config)
271
+
272
+ async def main():
273
+ async with client:
274
+ # Access tools and resources with server prefixes
275
+ forecast = await client.call_tool("weather_get_forecast", {"city": "London"})
276
+ answer = await client.call_tool("assistant_answer_question", {"query": "What is MCP?"})
277
+ ```
278
+
256
279
  Learn more in the [**Client Documentation**](https://gofastmcp.com/clients/client) and [**Transports Documentation**](https://gofastmcp.com/clients/transports).
257
280
 
258
281
  ## Advanced Features
@@ -0,0 +1,152 @@
1
+ ---
2
+ title: Advanced Features
3
+ sidebarTitle: Advanced Features
4
+ description: Learn about the advanced features of the FastMCP Client.
5
+ icon: stars
6
+ ---
7
+
8
+ import { VersionBadge } from '/snippets/version-badge.mdx'
9
+
10
+ In addition to basic server interaction, FastMCP clients can also handle more advanced features and server interaction patterns. The `Client` constructor accepts additional configuration to handle these server requests.
11
+
12
+ <Tip>
13
+ To enable many of these features, you must provide an appropriate handler or callback function. For example. In most cases, if you do not provide a handler, FastMCP's default handler will emit a `DEBUG` level log.
14
+ </Tip>
15
+
16
+ ## Logging and Notifications
17
+
18
+ <VersionBadge version="2.0.0" />
19
+ MCP servers can emit logs to clients. To process these logs, you can provide a `log_handler` to the client.
20
+
21
+ The `log_handler` must be an async function that accepts a single argument, which is an instance of `fastmcp.client.logging.LogMessage`. This has attributes like `level`, `logger`, and `data`.
22
+
23
+ ```python {2, 12}
24
+ from fastmcp import Client
25
+ from fastmcp.client.logging import LogMessage
26
+
27
+ async def log_handler(message: LogMessage):
28
+ level = message.level.upper()
29
+ logger = message.logger or 'default'
30
+ data = message.data
31
+ print(f"[Server Log - {level}] {logger}: {data}")
32
+
33
+ client_with_logging = Client(
34
+ ...,
35
+ log_handler=log_handler,
36
+ )
37
+ ```
38
+ ## Progress Monitoring
39
+
40
+ <VersionBadge version="2.3.5" />
41
+
42
+ MCP servers can report progress during long-running operations. The client can set a progress handler to receive and process these updates.
43
+
44
+ ```python {2, 13}
45
+ from fastmcp import Client
46
+ from fastmcp.client.progress import ProgressHandler
47
+
48
+ async def my_progress_handler(
49
+ progress: float,
50
+ total: float | None,
51
+ message: str | None
52
+ ) -> None:
53
+ print(f"Progress: {progress} / {total} ({message})")
54
+
55
+ client = Client(
56
+ ...,
57
+ progress_handler=my_progress_handler
58
+ )
59
+ ```
60
+
61
+ By default, FastMCP uses a handler that logs progress updates at the debug level. This default handler properly handles cases where `total` or `message` might be None.
62
+
63
+ You can override the progress handler for specific tool calls:
64
+
65
+ ```python
66
+ # Client uses the default debug logger for progress
67
+ client = Client(...)
68
+
69
+ async with client:
70
+ # Use default progress handler (debug logging)
71
+ result1 = await client.call_tool("long_task", {"param": "value"})
72
+
73
+ # Override with custom progress handler just for this call
74
+ result2 = await client.call_tool(
75
+ "another_task",
76
+ {"param": "value"},
77
+ progress_handler=my_progress_handler
78
+ )
79
+ ```
80
+
81
+ A typical progress update includes:
82
+ - Current progress value (e.g., 2 of 5 steps completed)
83
+ - Total expected value (may be None)
84
+ - Status message (may be None)
85
+
86
+ ## LLM Sampling
87
+
88
+ <VersionBadge version="2.0.0" />
89
+
90
+ MCP Servers can request LLM completions from clients. The client can provide a `sampling_handler` to handle these requests. The sampling handler receives a list of messages and other parameters from the server, and should return a string completion.
91
+
92
+ The following example uses the `marvin` library to generate a completion:
93
+
94
+ ```python {8-17, 21}
95
+ import marvin
96
+ from fastmcp import Client
97
+ from fastmcp.client.sampling import (
98
+ SamplingMessage,
99
+ SamplingParams,
100
+ RequestContext,
101
+ )
102
+
103
+ async def sampling_handler(
104
+ messages: list[SamplingMessage],
105
+ params: SamplingParams,
106
+ context: RequestContext
107
+ ) -> str:
108
+ return await marvin.say_async(
109
+ message=[m.content.text for m in messages],
110
+ instructions=params.systemPrompt,
111
+ )
112
+
113
+ client = Client(
114
+ ...,
115
+ sampling_handler=sampling_handler,
116
+ )
117
+ ```
118
+
119
+
120
+ ## Roots
121
+
122
+ <VersionBadge version="2.0.0" />
123
+
124
+ Roots are a way for clients to inform servers about the resources they have access to or certain boundaries on their access. The server can use this information to adjust behavior or provide more accurate responses.
125
+
126
+ Servers can request roots from clients, and clients can notify servers when their roots change.
127
+
128
+ To set the roots when creating a client, users can either provide a list of roots (which can be a list of strings) or an async function that returns a list of roots.
129
+
130
+ <CodeGroup>
131
+ ```python Static Roots {5}
132
+ from fastmcp import Client
133
+
134
+ client = Client(
135
+ ...,
136
+ roots=["/path/to/root1", "/path/to/root2"],
137
+ )
138
+ ```
139
+ ```python Dynamic Roots Callback {4-6, 10}
140
+ from fastmcp import Client
141
+ from fastmcp.client.roots import RequestContext
142
+
143
+ async def roots_callback(context: RequestContext) -> list[str]:
144
+ print(f"Server requested roots (Request ID: {context.request_id})")
145
+ return ["/path/to/root1", "/path/to/root2"]
146
+
147
+ client = Client(
148
+ ...,
149
+ roots=roots_callback,
150
+ )
151
+ ```
152
+ </CodeGroup>
@@ -37,13 +37,14 @@ Clients must be initialized with a `transport`. You can either provide an alread
37
37
  The following inference rules are used to determine the appropriate `ClientTransport` based on the input type:
38
38
 
39
39
  1. **`ClientTransport` Instance**: If you provide an already instantiated transport object, it's used directly.
40
- 2. **`FastMCP` Instance**: Creates a `FastMCPTransport` for efficient in-memory communication (ideal for testing).
40
+ 2. **`FastMCP` Instance**: Creates a `FastMCPTransport` for efficient in-memory communication (ideal for testing). This also works with a **FastMCP 1.0 server** created via `mcp.server.fastmcp.FastMCP`.
41
41
  3. **`Path` or `str` pointing to an existing file**:
42
42
  * If it ends with `.py`: Creates a `PythonStdioTransport` to run the script using `python`.
43
43
  * If it ends with `.js`: Creates a `NodeStdioTransport` to run the script using `node`.
44
44
  4. **`AnyUrl` or `str` pointing to a URL that begins with `http://` or `https://`**:
45
45
  * Creates a `StreamableHttpTransport`
46
- 5. **Other**: Raises a `ValueError` if the type cannot be inferred.
46
+ 5. **`MCPConfig` or dictionary matching MCPConfig schema**: Creates a client that connects to one or more MCP servers specified in the config.
47
+ 6. **Other**: Raises a `ValueError` if the type cannot be inferred.
47
48
 
48
49
  ```python
49
50
  import asyncio
@@ -52,30 +53,100 @@ from fastmcp import Client, FastMCP
52
53
  # Example transports (more details in Transports page)
53
54
  server_instance = FastMCP(name="TestServer") # In-memory server
54
55
  http_url = "https://example.com/mcp" # HTTP server URL
55
- ws_url = "ws://localhost:9000" # WebSocket server URL
56
56
  server_script = "my_mcp_server.py" # Path to a Python server file
57
57
 
58
58
  # Client automatically infers the transport type
59
59
  client_in_memory = Client(server_instance)
60
60
  client_http = Client(http_url)
61
- client_ws = Client(ws_url)
61
+
62
62
  client_stdio = Client(server_script)
63
63
 
64
64
  print(client_in_memory.transport)
65
65
  print(client_http.transport)
66
- print(client_ws.transport)
67
66
  print(client_stdio.transport)
68
67
 
69
68
  # Expected Output (types may vary slightly based on environment):
70
69
  # <FastMCP(server='TestServer')>
71
70
  # <StreamableHttp(url='https://example.com/mcp')>
72
- # <WebSocket(url='ws://localhost:9000')>
73
71
  # <PythonStdioTransport(command='python', args=['/path/to/your/my_mcp_server.py'])>
74
72
  ```
73
+
74
+ You can also initialize a client from an MCP configuration dictionary or `MCPConfig` file:
75
+
76
+ ```python
77
+ from fastmcp import Client
78
+
79
+ config = {
80
+ "mcpServers": {
81
+ "local": {"command": "python", "args": ["local_server.py"]},
82
+ "remote": {"url": "https://example.com/mcp"},
83
+ }
84
+ }
85
+
86
+ client_config = Client(config)
87
+ ```
75
88
  <Tip>
76
89
  For more control over connection details (like headers for SSE, environment variables for Stdio), you can instantiate the specific `ClientTransport` class yourself and pass it to the `Client`. See the [Transports](/clients/transports) page for details.
77
90
  </Tip>
78
91
 
92
+ ### Multi-Server Clients
93
+
94
+ <VersionBadge version="2.4.0" />
95
+
96
+ FastMCP supports creating clients that connect to multiple MCP servers through a single client interface using a standard MCP configuration format (`MCPConfig`). This configuration approach makes it easy to connect to multiple specialized servers or create composable systems with a simple, declarative syntax.
97
+
98
+ <Note>
99
+ The MCP configuration format follows an emerging standard and may evolve as the specification matures. FastMCP will strive to maintain compatibility with future versions, but be aware that field names or structure might change.
100
+ </Note>
101
+
102
+ When you create a client with an `MCPConfig` containing multiple servers:
103
+
104
+ 1. FastMCP creates a composite client that internally mounts all servers using their config names as prefixes
105
+ 2. Tools and resources from each server are accessible with appropriate prefixes in the format `servername_toolname` and `protocol://servername/resource/path`
106
+ 3. You interact with this as a single unified client, with requests automatically routed to the appropriate server
107
+
108
+ ```python
109
+ from fastmcp import Client
110
+
111
+ # Create a standard MCP configuration with multiple servers
112
+ config = {
113
+ "mcpServers": {
114
+ # A remote HTTP server
115
+ "weather": {
116
+ "url": "https://weather-api.example.com/mcp",
117
+ "transport": "streamable-http"
118
+ },
119
+ # A local server running via stdio
120
+ "assistant": {
121
+ "command": "python",
122
+ "args": ["./my_assistant_server.py"],
123
+ "env": {"DEBUG": "true"}
124
+ }
125
+ }
126
+ }
127
+
128
+ # Create a client that connects to both servers
129
+ client = Client(config)
130
+
131
+ async def main():
132
+ async with client:
133
+ # Access tools from different servers with prefixes
134
+ weather_data = await client.call_tool("weather_get_forecast", {"city": "London"})
135
+ response = await client.call_tool("assistant_answer_question", {"question": "What's the capital of France?"})
136
+
137
+ # Access resources with prefixed URIs
138
+ weather_icons = await client.read_resource("weather://weather/icons/sunny")
139
+ templates = await client.read_resource("resource://assistant/templates/list")
140
+
141
+ print(f"Weather: {weather_data}")
142
+ print(f"Assistant: {response}")
143
+
144
+ if __name__ == "__main__":
145
+ asyncio.run(main())
146
+ ```
147
+
148
+ If your configuration has only a single server, FastMCP will create a direct client to that server without any prefixing.
149
+
79
150
  ## Client Usage
80
151
 
81
152
  ### Connection Lifecycle
@@ -209,11 +280,19 @@ Available raw MCP methods:
209
280
 
210
281
  These methods are especially useful for debugging or when you need to access metadata or fields that aren't exposed by the simplified methods.
211
282
 
212
- ### Advanced Features
283
+ ### Additional Features
284
+
285
+ #### Pinging the server
213
286
 
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.
287
+ The client can be used to ping the server to verify connectivity.
288
+
289
+ ```python
290
+ async with client:
291
+ await client.ping()
292
+ print("Server is reachable")
293
+ ```
215
294
 
216
- #### Timeout Control
295
+ #### Timeouts
217
296
 
218
297
  <VersionBadge version="2.3.4" />
219
298
 
@@ -253,154 +332,7 @@ Timeout behavior varies between transport types:
253
332
  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
333
  </Warning>
255
334
 
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
-
314
- #### LLM Sampling
315
-
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.
317
-
318
- The following example uses the `marvin` library to generate a completion:
319
-
320
- ```python {8-17, 21}
321
- import marvin
322
- from fastmcp import Client
323
- from fastmcp.client.sampling import (
324
- SamplingMessage,
325
- SamplingParams,
326
- RequestContext,
327
- )
328
-
329
- async def sampling_handler(
330
- messages: list[SamplingMessage],
331
- params: SamplingParams,
332
- context: RequestContext
333
- ) -> str:
334
- return await marvin.say_async(
335
- message=[m.content.text for m in messages],
336
- instructions=params.systemPrompt,
337
- )
338
-
339
- client = Client(
340
- ...,
341
- sampling_handler=sampling_handler,
342
- )
343
- ```
344
-
345
- #### Logging
346
-
347
- MCP servers can emit logs to clients. The client can set a logging callback to receive these logs.
348
-
349
- ```python {4-5, 9}
350
- from fastmcp import Client
351
- from fastmcp.client.logging import LogHandler, LogMessage
352
-
353
- async def my_log_handler(params: LogMessage):
354
- print(f"[Server Log - {params.level.upper()}] {params.logger or 'default'}: {params.data}")
355
-
356
- client_with_logging = Client(
357
- ...,
358
- log_handler=my_log_handler,
359
- )
360
- ```
361
-
362
- #### Roots
363
-
364
- Roots are a way for clients to inform servers about the resources they have access to or certain boundaries on their access. The server can use this information to adjust behavior or provide more accurate responses.
365
-
366
- Servers can request roots from clients, and clients can notify servers when their roots change.
367
-
368
- To set the roots when creating a client, users can either provide a list of roots (which can be a list of strings) or an async function that returns a list of roots.
369
-
370
- <CodeGroup>
371
- ```python Static Roots {5}
372
- from fastmcp import Client
373
-
374
- client = Client(
375
- ...,
376
- roots=["/path/to/root1", "/path/to/root2"],
377
- )
378
- ```
379
- ```python Dynamic Roots Callback {4-6, 10}
380
- from fastmcp import Client
381
- from fastmcp.client.roots import RequestContext
382
-
383
- async def roots_callback(context: RequestContext) -> list[str]:
384
- print(f"Server requested roots (Request ID: {context.request_id})")
385
- return ["/path/to/root1", "/path/to/root2"]
386
-
387
- client = Client(
388
- ...,
389
- roots=roots_callback,
390
- )
391
- ```
392
- </CodeGroup>
393
- ### Utility Methods
394
-
395
- * **`ping()`**: Sends a ping request to the server to verify connectivity.
396
- ```python
397
- async def check_connection():
398
- async with client:
399
- await client.ping()
400
- print("Server is reachable")
401
- ```
402
-
403
- ### Error Handling
335
+ #### Error Handling
404
336
 
405
337
  When a `call_tool` request results in an error on the server (e.g., the tool function raised an exception), the `client.call_tool()` method will raise a `fastmcp.client.ClientError`.
406
338
 
@@ -290,8 +290,8 @@ asyncio.run(main())
290
290
  ### FastMCP Transport
291
291
 
292
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
293
+ - **Inferred From:** An instance of `fastmcp.server.FastMCP` or a **FastMCP 1.0 server** (`mcp.server.fastmcp.FastMCP`)
294
+ - **Use Case:** Connecting directly to a FastMCP server instance in the same Python process
295
295
 
296
296
  This is extremely useful for testing your FastMCP servers.
297
297
 
@@ -317,4 +317,64 @@ async def main():
317
317
  asyncio.run(main())
318
318
  ```
319
319
 
320
- Communication happens through efficient in-memory queues, making it very fast and ideal for unit testing.
320
+ Communication happens through efficient in-memory queues, making it very fast and ideal for unit testing.
321
+
322
+ ## Configuration-Based Transports
323
+
324
+ ### MCPConfig Transport
325
+
326
+ <VersionBadge version="2.4.0" />
327
+
328
+ - **Class:** `fastmcp.client.transports.MCPConfigTransport`
329
+ - **Inferred From:** An instance of `MCPConfig` or a dictionary matching the MCPConfig schema
330
+ - **Use Case:** Connecting to one or more MCP servers defined in a configuration object
331
+
332
+ MCPConfig follows an emerging standard for MCP server configuration but is subject to change as the specification evolves. The standard supports both local servers (running via stdio) and remote servers (accessed via HTTP).
333
+
334
+ ```python
335
+ from fastmcp import Client
336
+
337
+ # Configuration for multiple MCP servers (both local and remote)
338
+ config = {
339
+ "mcpServers": {
340
+ # Remote HTTP server
341
+ "weather": {
342
+ "url": "https://weather-api.example.com/mcp",
343
+ "transport": "streamable-http"
344
+ },
345
+ # Local stdio server
346
+ "assistant": {
347
+ "command": "python",
348
+ "args": ["./assistant_server.py"],
349
+ "env": {"DEBUG": "true"}
350
+ },
351
+ # Another remote server
352
+ "calendar": {
353
+ "url": "https://calendar-api.example.com/mcp",
354
+ "transport": "streamable-http"
355
+ }
356
+ }
357
+ }
358
+
359
+ # Create a transport from the config (happens automatically with Client)
360
+ client = Client(config)
361
+
362
+ async def main():
363
+ async with client:
364
+ # Tools are accessible with server name prefixes
365
+ weather = await client.call_tool("weather_get_forecast", {"city": "London"})
366
+ answer = await client.call_tool("assistant_answer_question", {"query": "What is MCP?"})
367
+ events = await client.call_tool("calendar_list_events", {"date": "2023-06-01"})
368
+
369
+ # Resources use prefixed URI paths
370
+ icons = await client.read_resource("weather://weather/icons/sunny")
371
+ docs = await client.read_resource("resource://assistant/docs/mcp")
372
+
373
+ asyncio.run(main())
374
+ ```
375
+
376
+ If your configuration has only a single server, the client will connect directly to that server without any prefixing. This makes it convenient to switch between single and multi-server configurations without changing your client code.
377
+
378
+ <Note>
379
+ The MCPConfig format is an emerging standard for MCP server configuration and may change as the MCP ecosystem evolves. While FastMCP aims to maintain compatibility with future versions, be aware that field names or structure might change.
380
+ </Note>
@@ -50,6 +50,7 @@
50
50
  "servers/resources",
51
51
  "servers/prompts",
52
52
  "servers/context",
53
+ "servers/openapi",
53
54
  "servers/proxy",
54
55
  "servers/composition"
55
56
  ]
@@ -67,7 +68,8 @@
67
68
  "group": "Clients",
68
69
  "pages": [
69
70
  "clients/client",
70
- "clients/transports"
71
+ "clients/transports",
72
+ "clients/advanced-features"
71
73
  ]
72
74
  },
73
75
  {
@@ -75,8 +77,6 @@
75
77
  "pages": [
76
78
  "patterns/decorating-methods",
77
79
  "patterns/http-requests",
78
- "patterns/openapi",
79
- "patterns/fastapi",
80
80
  "patterns/contrib",
81
81
  "patterns/testing"
82
82
  ]