fastmcp 2.9.1__tar.gz → 2.10.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 (372) hide show
  1. fastmcp-2.10.0/.ccignore +7 -0
  2. {fastmcp-2.9.1 → fastmcp-2.10.0}/CLAUDE.md +10 -1
  3. {fastmcp-2.9.1 → fastmcp-2.10.0}/PKG-INFO +3 -2
  4. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/clients/client.mdx +1 -1
  5. fastmcp-2.10.0/docs/clients/elicitation.mdx +126 -0
  6. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/clients/messages.mdx +1 -1
  7. fastmcp-2.10.0/docs/clients/tools.mdx +241 -0
  8. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/docs.json +15 -3
  9. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/integrations/chatgpt.mdx +2 -2
  10. fastmcp-2.10.0/docs/integrations/eunomia-authorization.mdx +108 -0
  11. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/patterns/cli.mdx +1 -0
  12. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/patterns/tool-transformation.mdx +39 -1
  13. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/servers/auth/bearer.mdx +5 -0
  14. fastmcp-2.10.0/docs/servers/context.mdx +242 -0
  15. fastmcp-2.10.0/docs/servers/elicitation.mdx +320 -0
  16. fastmcp-2.10.0/docs/servers/logging.mdx +194 -0
  17. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/servers/middleware.mdx +8 -5
  18. fastmcp-2.10.0/docs/servers/progress.mdx +189 -0
  19. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/servers/prompts.mdx +1 -0
  20. fastmcp-2.10.0/docs/servers/sampling.mdx +190 -0
  21. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/servers/tools.mdx +209 -45
  22. {fastmcp-2.9.1 → fastmcp-2.10.0}/pyproject.toml +5 -1
  23. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/cli/cli.py +16 -1
  24. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/cli/run.py +4 -0
  25. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/client/auth/oauth.py +5 -82
  26. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/client/client.py +114 -24
  27. fastmcp-2.10.0/src/fastmcp/client/elicitation.py +63 -0
  28. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/client/transports.py +50 -36
  29. fastmcp-2.10.0/src/fastmcp/contrib/component_manager/README.md +170 -0
  30. fastmcp-2.10.0/src/fastmcp/contrib/component_manager/__init__.py +4 -0
  31. fastmcp-2.10.0/src/fastmcp/contrib/component_manager/component_manager.py +186 -0
  32. fastmcp-2.10.0/src/fastmcp/contrib/component_manager/component_service.py +225 -0
  33. fastmcp-2.10.0/src/fastmcp/contrib/component_manager/example.py +59 -0
  34. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/prompts/prompt.py +12 -4
  35. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/resources/resource.py +8 -3
  36. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/resources/template.py +5 -0
  37. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/server/auth/auth.py +15 -0
  38. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/server/auth/providers/bearer.py +41 -3
  39. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/server/auth/providers/bearer_env.py +4 -0
  40. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/server/auth/providers/in_memory.py +15 -0
  41. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/server/context.py +144 -4
  42. fastmcp-2.10.0/src/fastmcp/server/elicitation.py +160 -0
  43. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/server/http.py +1 -9
  44. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/server/low_level.py +4 -2
  45. fastmcp-2.10.0/src/fastmcp/server/middleware/__init__.py +19 -0
  46. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/server/middleware/logging.py +11 -0
  47. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/server/middleware/middleware.py +10 -6
  48. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/server/openapi.py +19 -77
  49. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/server/proxy.py +13 -6
  50. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/server/server.py +76 -11
  51. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/settings.py +0 -17
  52. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/tools/tool.py +209 -57
  53. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/tools/tool_manager.py +2 -3
  54. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/tools/tool_transform.py +125 -26
  55. fastmcp-2.10.0/src/fastmcp/utilities/cli.py +106 -0
  56. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/utilities/components.py +5 -1
  57. fastmcp-2.10.0/src/fastmcp/utilities/json_schema_type.py +648 -0
  58. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/utilities/openapi.py +69 -0
  59. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/utilities/types.py +50 -19
  60. fastmcp-2.10.0/tests/auth/providers/test_token_verifier.py +179 -0
  61. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/auth/test_oauth_client.py +3 -1
  62. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/cli/test_cli.py +3 -2
  63. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/client/test_client.py +4 -3
  64. fastmcp-2.10.0/tests/client/test_elicitation.py +602 -0
  65. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/client/test_notifications.py +6 -6
  66. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/client/test_openapi.py +2 -2
  67. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/client/test_roots.py +1 -3
  68. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/client/test_sampling.py +3 -6
  69. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/client/test_stdio.py +20 -9
  70. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/client/test_streamable_http.py +25 -5
  71. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/contrib/test_bulk_tool_caller.py +4 -1
  72. fastmcp-2.10.0/tests/contrib/test_component_manager.py +743 -0
  73. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/deprecated/test_mount_import_arg_order.py +2 -2
  74. fastmcp-2.10.0/tests/server/http/test_auth_setup.py +187 -0
  75. fastmcp-2.10.0/tests/server/http/test_bearer_auth_backend.py +178 -0
  76. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/http/test_http_dependencies.py +4 -6
  77. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/middleware/test_logging.py +24 -8
  78. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/middleware/test_middleware.py +160 -143
  79. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/middleware/test_rate_limiting.py +21 -14
  80. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/middleware/test_timing.py +8 -4
  81. fastmcp-2.10.0/tests/server/openapi/test_explode_integration.py +324 -0
  82. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/openapi/test_openapi.py +41 -13
  83. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/openapi/test_openapi_path_parameters.py +4 -13
  84. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/test_import_server.py +6 -6
  85. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/test_mount.py +50 -37
  86. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/test_proxy.py +8 -6
  87. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/test_server.py +51 -29
  88. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/test_server_interactions.py +409 -93
  89. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/test_tool_annotations.py +1 -5
  90. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/test_tool_exclude_args.py +1 -7
  91. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/test_examples.py +12 -12
  92. fastmcp-2.10.0/tests/tools/test_tool.py +1361 -0
  93. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/tools/test_tool_manager.py +42 -50
  94. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/tools/test_tool_transform.py +325 -44
  95. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/utilities/openapi/test_openapi.py +23 -0
  96. fastmcp-2.10.0/tests/utilities/test_json_schema_type.py +1525 -0
  97. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/utilities/test_mcp_config.py +4 -4
  98. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/utilities/test_types.py +27 -0
  99. {fastmcp-2.9.1 → fastmcp-2.10.0}/uv.lock +232 -52
  100. fastmcp-2.9.1/docs/clients/tools.mdx +0 -143
  101. fastmcp-2.9.1/docs/servers/context.mdx +0 -373
  102. fastmcp-2.9.1/src/fastmcp/server/middleware/__init__.py +0 -6
  103. fastmcp-2.9.1/tests/tools/test_tool.py +0 -720
  104. {fastmcp-2.9.1 → fastmcp-2.10.0}/.cursor/rules/core-mcp-objects.mdc +0 -0
  105. {fastmcp-2.9.1 → fastmcp-2.10.0}/.github/ISSUE_TEMPLATE/bug.yml +0 -0
  106. {fastmcp-2.9.1 → fastmcp-2.10.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  107. {fastmcp-2.9.1 → fastmcp-2.10.0}/.github/ISSUE_TEMPLATE/enhancement.yml +0 -0
  108. {fastmcp-2.9.1 → fastmcp-2.10.0}/.github/dependabot.yml +0 -0
  109. {fastmcp-2.9.1 → fastmcp-2.10.0}/.github/labeler.yml +0 -0
  110. {fastmcp-2.9.1 → fastmcp-2.10.0}/.github/release.yml +0 -0
  111. {fastmcp-2.9.1 → fastmcp-2.10.0}/.github/workflows/labeler.yml +0 -0
  112. {fastmcp-2.9.1 → fastmcp-2.10.0}/.github/workflows/publish.yml +0 -0
  113. {fastmcp-2.9.1 → fastmcp-2.10.0}/.github/workflows/run-static.yml +0 -0
  114. {fastmcp-2.9.1 → fastmcp-2.10.0}/.github/workflows/run-tests.yml +0 -0
  115. {fastmcp-2.9.1 → fastmcp-2.10.0}/.gitignore +0 -0
  116. {fastmcp-2.9.1 → fastmcp-2.10.0}/.pre-commit-config.yaml +0 -0
  117. {fastmcp-2.9.1 → fastmcp-2.10.0}/AGENTS.md +0 -0
  118. {fastmcp-2.9.1 → fastmcp-2.10.0}/LICENSE +0 -0
  119. {fastmcp-2.9.1 → fastmcp-2.10.0}/README.md +0 -0
  120. {fastmcp-2.9.1 → fastmcp-2.10.0}/Windows_Notes.md +0 -0
  121. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/.cursor/rules/mintlify.mdc +0 -0
  122. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/assets/demo-inspector.png +0 -0
  123. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/assets/favicon.ico +0 -0
  124. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/assets/images/tutorial-rest-api-result.png +0 -0
  125. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/assets/logo.png +0 -0
  126. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/assets/updates/release-2-7.png +0 -0
  127. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/changelog.mdx +0 -0
  128. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/clients/auth/bearer.mdx +0 -0
  129. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/clients/auth/oauth.mdx +0 -0
  130. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/clients/logging.mdx +0 -0
  131. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/clients/progress.mdx +0 -0
  132. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/clients/prompts.mdx +0 -0
  133. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/clients/resources.mdx +0 -0
  134. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/clients/roots.mdx +0 -0
  135. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/clients/sampling.mdx +0 -0
  136. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/clients/transports.mdx +0 -0
  137. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/community/README.md +0 -0
  138. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/community/showcase.mdx +0 -0
  139. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/css/banner.css +0 -0
  140. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/css/python-sdk.css +0 -0
  141. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/css/style.css +0 -0
  142. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/css/version-badge.css +0 -0
  143. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/deployment/asgi.mdx +0 -0
  144. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/deployment/running-server.mdx +0 -0
  145. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/getting-started/installation.mdx +0 -0
  146. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/getting-started/quickstart.mdx +0 -0
  147. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/getting-started/welcome.mdx +0 -0
  148. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/integrations/anthropic.mdx +0 -0
  149. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/integrations/claude-code.mdx +0 -0
  150. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/integrations/claude-desktop.mdx +0 -0
  151. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/integrations/contrib.mdx +0 -0
  152. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/integrations/gemini.mdx +0 -0
  153. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/integrations/openai.mdx +0 -0
  154. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/patterns/decorating-methods.mdx +0 -0
  155. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/patterns/http-requests.mdx +0 -0
  156. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/patterns/testing.mdx +0 -0
  157. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-cli-__init__.mdx +0 -0
  158. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-cli-claude.mdx +0 -0
  159. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-cli-cli.mdx +0 -0
  160. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-cli-run.mdx +0 -0
  161. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-client-__init__.mdx +0 -0
  162. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-client-auth-__init__.mdx +0 -0
  163. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-client-auth-bearer.mdx +0 -0
  164. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-client-auth-oauth.mdx +0 -0
  165. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-client-client.mdx +0 -0
  166. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-client-logging.mdx +0 -0
  167. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-client-oauth_callback.mdx +0 -0
  168. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-client-progress.mdx +0 -0
  169. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-client-roots.mdx +0 -0
  170. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-client-sampling.mdx +0 -0
  171. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-client-transports.mdx +0 -0
  172. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-exceptions.mdx +0 -0
  173. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-prompts-__init__.mdx +0 -0
  174. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-prompts-prompt.mdx +0 -0
  175. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-prompts-prompt_manager.mdx +0 -0
  176. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-resources-__init__.mdx +0 -0
  177. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-resources-resource.mdx +0 -0
  178. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-resources-resource_manager.mdx +0 -0
  179. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-resources-template.mdx +0 -0
  180. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-resources-types.mdx +0 -0
  181. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-__init__.mdx +0 -0
  182. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-auth-__init__.mdx +0 -0
  183. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-auth-auth.mdx +0 -0
  184. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-auth-providers-__init__.mdx +0 -0
  185. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-auth-providers-bearer.mdx +0 -0
  186. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-auth-providers-bearer_env.mdx +0 -0
  187. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-auth-providers-in_memory.mdx +0 -0
  188. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-context.mdx +0 -0
  189. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-dependencies.mdx +0 -0
  190. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-http.mdx +0 -0
  191. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-middleware-__init__.mdx +0 -0
  192. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-middleware-error_handling.mdx +0 -0
  193. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-middleware-logging.mdx +0 -0
  194. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-middleware-middleware.mdx +0 -0
  195. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-middleware-rate_limiting.mdx +0 -0
  196. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-middleware-timing.mdx +0 -0
  197. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-middleware.mdx +0 -0
  198. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-openapi.mdx +0 -0
  199. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-proxy.mdx +0 -0
  200. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-server-server.mdx +0 -0
  201. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-settings.mdx +0 -0
  202. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-tools-__init__.mdx +0 -0
  203. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-tools-tool.mdx +0 -0
  204. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-tools-tool_manager.mdx +0 -0
  205. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-tools-tool_transform.mdx +0 -0
  206. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-utilities-__init__.mdx +0 -0
  207. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-utilities-cache.mdx +0 -0
  208. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-utilities-components.mdx +0 -0
  209. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-utilities-exceptions.mdx +0 -0
  210. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-utilities-http.mdx +0 -0
  211. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-utilities-inspect.mdx +0 -0
  212. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-utilities-json_schema.mdx +0 -0
  213. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-utilities-logging.mdx +0 -0
  214. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-utilities-mcp_config.mdx +0 -0
  215. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-utilities-openapi.mdx +0 -0
  216. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-utilities-tests.mdx +0 -0
  217. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/python-sdk/fastmcp-utilities-types.mdx +0 -0
  218. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/servers/composition.mdx +0 -0
  219. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/servers/openapi.mdx +0 -0
  220. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/servers/proxy.mdx +0 -0
  221. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/servers/resources.mdx +0 -0
  222. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/servers/server.mdx +0 -0
  223. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/snippets/version-badge.mdx +0 -0
  224. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/snippets/youtube-embed.mdx +0 -0
  225. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/tutorials/create-mcp-server.mdx +0 -0
  226. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/tutorials/mcp.mdx +0 -0
  227. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/tutorials/rest-api.mdx +0 -0
  228. {fastmcp-2.9.1 → fastmcp-2.10.0}/docs/updates.mdx +0 -0
  229. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/atproto_mcp/README.md +0 -0
  230. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/atproto_mcp/demo.py +0 -0
  231. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/atproto_mcp/pyproject.toml +0 -0
  232. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/atproto_mcp/src/atproto_mcp/__init__.py +0 -0
  233. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/atproto_mcp/src/atproto_mcp/__main__.py +0 -0
  234. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/atproto_mcp/src/atproto_mcp/_atproto/__init__.py +0 -0
  235. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/atproto_mcp/src/atproto_mcp/_atproto/_client.py +0 -0
  236. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/atproto_mcp/src/atproto_mcp/_atproto/_posts.py +0 -0
  237. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/atproto_mcp/src/atproto_mcp/_atproto/_profile.py +0 -0
  238. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/atproto_mcp/src/atproto_mcp/_atproto/_read.py +0 -0
  239. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/atproto_mcp/src/atproto_mcp/_atproto/_social.py +0 -0
  240. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/atproto_mcp/src/atproto_mcp/py.typed +0 -0
  241. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/atproto_mcp/src/atproto_mcp/server.py +0 -0
  242. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/atproto_mcp/src/atproto_mcp/settings.py +0 -0
  243. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/atproto_mcp/src/atproto_mcp/types.py +0 -0
  244. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/complex_inputs.py +0 -0
  245. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/config_server.py +0 -0
  246. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/desktop.py +0 -0
  247. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/echo.py +0 -0
  248. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/get_file.py +0 -0
  249. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/in_memory_proxy_example.py +0 -0
  250. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/memory.py +0 -0
  251. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/mount_example.py +0 -0
  252. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/sampling.py +0 -0
  253. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/screenshot.py +0 -0
  254. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/serializer.py +0 -0
  255. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/simple_echo.py +0 -0
  256. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/smart_home/README.md +0 -0
  257. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/smart_home/pyproject.toml +0 -0
  258. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/smart_home/src/smart_home/__init__.py +0 -0
  259. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/smart_home/src/smart_home/__main__.py +0 -0
  260. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/smart_home/src/smart_home/hub.py +0 -0
  261. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/smart_home/src/smart_home/lights/__init__.py +0 -0
  262. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/smart_home/src/smart_home/lights/hue_utils.py +0 -0
  263. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/smart_home/src/smart_home/lights/server.py +0 -0
  264. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/smart_home/src/smart_home/py.typed +0 -0
  265. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/smart_home/src/smart_home/settings.py +0 -0
  266. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/smart_home/uv.lock +0 -0
  267. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/tags_example.py +0 -0
  268. {fastmcp-2.9.1 → fastmcp-2.10.0}/examples/text_me.py +0 -0
  269. {fastmcp-2.9.1 → fastmcp-2.10.0}/justfile +0 -0
  270. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/__init__.py +0 -0
  271. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/cli/__init__.py +0 -0
  272. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/cli/claude.py +0 -0
  273. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/client/__init__.py +0 -0
  274. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/client/auth/__init__.py +0 -0
  275. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/client/auth/bearer.py +0 -0
  276. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/client/logging.py +0 -0
  277. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/client/messages.py +0 -0
  278. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/client/oauth_callback.py +0 -0
  279. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/client/progress.py +0 -0
  280. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/client/roots.py +0 -0
  281. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/client/sampling.py +0 -0
  282. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/contrib/README.md +0 -0
  283. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/contrib/bulk_tool_caller/README.md +0 -0
  284. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/contrib/bulk_tool_caller/__init__.py +0 -0
  285. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/contrib/bulk_tool_caller/bulk_tool_caller.py +0 -0
  286. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/contrib/bulk_tool_caller/example.py +0 -0
  287. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/contrib/mcp_mixin/README.md +0 -0
  288. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/contrib/mcp_mixin/__init__.py +0 -0
  289. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/contrib/mcp_mixin/example.py +0 -0
  290. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/contrib/mcp_mixin/mcp_mixin.py +0 -0
  291. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/exceptions.py +0 -0
  292. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/prompts/__init__.py +0 -0
  293. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/prompts/prompt_manager.py +0 -0
  294. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/py.typed +0 -0
  295. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/resources/__init__.py +0 -0
  296. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/resources/resource_manager.py +0 -0
  297. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/resources/types.py +0 -0
  298. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/server/__init__.py +0 -0
  299. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/server/auth/__init__.py +0 -0
  300. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/server/auth/providers/__init__.py +0 -0
  301. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/server/dependencies.py +0 -0
  302. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/server/middleware/error_handling.py +0 -0
  303. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/server/middleware/rate_limiting.py +0 -0
  304. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/server/middleware/timing.py +0 -0
  305. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/tools/__init__.py +0 -0
  306. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/utilities/__init__.py +0 -0
  307. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/utilities/cache.py +0 -0
  308. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/utilities/exceptions.py +0 -0
  309. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/utilities/http.py +0 -0
  310. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/utilities/inspect.py +0 -0
  311. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/utilities/json_schema.py +0 -0
  312. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/utilities/logging.py +0 -0
  313. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/utilities/mcp_config.py +0 -0
  314. {fastmcp-2.9.1 → fastmcp-2.10.0}/src/fastmcp/utilities/tests.py +0 -0
  315. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/__init__.py +0 -0
  316. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/auth/__init__.py +0 -0
  317. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/auth/providers/test_bearer.py +0 -0
  318. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/auth/providers/test_bearer_env.py +0 -0
  319. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/cli/__init__.py +0 -0
  320. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/cli/test_run.py +0 -0
  321. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/client/__init__.py +0 -0
  322. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/client/test_logs.py +0 -0
  323. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/client/test_progress.py +0 -0
  324. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/client/test_sse.py +0 -0
  325. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/conftest.py +0 -0
  326. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/contrib/__init__.py +0 -0
  327. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/contrib/test_mcp_mixin.py +0 -0
  328. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/deprecated/__init__.py +0 -0
  329. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/deprecated/test_deprecated.py +0 -0
  330. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/deprecated/test_mount_separators.py +0 -0
  331. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/deprecated/test_resource_prefixes.py +0 -0
  332. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/deprecated/test_route_type_ignore.py +0 -0
  333. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/deprecated/test_settings.py +0 -0
  334. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/prompts/__init__.py +0 -0
  335. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/prompts/test_prompt.py +0 -0
  336. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/prompts/test_prompt_manager.py +0 -0
  337. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/resources/__init__.py +0 -0
  338. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/resources/test_file_resources.py +0 -0
  339. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/resources/test_function_resources.py +0 -0
  340. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/resources/test_resource_manager.py +0 -0
  341. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/resources/test_resource_template.py +0 -0
  342. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/resources/test_resources.py +0 -0
  343. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/__init__.py +0 -0
  344. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/http/__init__.py +0 -0
  345. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/http/test_custom_routes.py +0 -0
  346. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/http/test_http_middleware.py +0 -0
  347. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/middleware/__init__.py +0 -0
  348. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/middleware/test_error_handling.py +0 -0
  349. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/openapi/__init__.py +0 -0
  350. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/openapi/test_route_map_fn.py +0 -0
  351. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/test_app_state.py +0 -0
  352. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/test_auth_integration.py +0 -0
  353. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/test_context.py +0 -0
  354. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/test_file_server.py +0 -0
  355. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/test_logging.py +0 -0
  356. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/test_resource_prefix_formats.py +0 -0
  357. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/server/test_run_server.py +0 -0
  358. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/test_servers/fastmcp_server.py +0 -0
  359. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/test_servers/sse.py +0 -0
  360. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/test_servers/stdio.py +0 -0
  361. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/tools/__init__.py +0 -0
  362. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/utilities/__init__.py +0 -0
  363. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/utilities/openapi/__init__.py +0 -0
  364. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/utilities/openapi/conftest.py +0 -0
  365. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/utilities/openapi/test_openapi_advanced.py +0 -0
  366. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/utilities/openapi/test_openapi_fastapi.py +0 -0
  367. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/utilities/test_cache.py +0 -0
  368. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/utilities/test_inspect.py +0 -0
  369. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/utilities/test_json_schema.py +0 -0
  370. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/utilities/test_logging.py +0 -0
  371. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/utilities/test_tests.py +0 -0
  372. {fastmcp-2.9.1 → fastmcp-2.10.0}/tests/utilities/test_typeadapter.py +0 -0
@@ -0,0 +1,7 @@
1
+ .pre-commit-config.yaml
2
+ .github/
3
+ docs/changelog.mdx
4
+ docs/python-sdk/
5
+ examples/
6
+ src/fastmcp/contrib/
7
+ tests/contrib/
@@ -1,5 +1,14 @@
1
1
  # FastMCP Development Guidelines
2
2
 
3
+ ## Git
4
+
5
+ This project uses `pre-commit` to run checks on all commits. If your commit doesn't pass the checks, it will not be created. Do not attempt to amend commits to pass checks.
6
+
7
+ ## Documentation
8
+
9
+ - Documentation uses the Mintlify framework
10
+ - Files must be present in docs.json to be included in the documentation
11
+
3
12
  ## Testing and Investigation
4
13
 
5
14
  ### In-Memory Transport - Always Preferred
@@ -34,4 +43,4 @@ async with Client(transport=StreamableHttpTransport(server_url)) as client:
34
43
  - You must always run pre-commit if you open a PR, because it is run as part of a required check.
35
44
  - When opening PRs, apply labels appropriately for bugs/breaking changes/enhancements/features. Generally, improvements are enhancements (not features) unless told otherwise.
36
45
  - NEVER modify files in docs/python-sdk/**, as they are auto-generated.
37
- - Use # type: ignore[attr-defined] in unit tests when accessing an MCP result of indeterminate type instead of asserting its type
46
+ - Use # type: ignore[attr-defined] in unit tests when accessing an MCP result of indeterminate type instead of asserting its type
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastmcp
3
- Version: 2.9.1
3
+ Version: 2.10.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
@@ -20,8 +20,9 @@ Requires-Python: >=3.10
20
20
  Requires-Dist: authlib>=1.5.2
21
21
  Requires-Dist: exceptiongroup>=1.2.2
22
22
  Requires-Dist: httpx>=0.28.1
23
- Requires-Dist: mcp<2.0.0,>=1.9.4
23
+ Requires-Dist: mcp>=1.10.0
24
24
  Requires-Dist: openapi-pydantic>=0.5.1
25
+ Requires-Dist: pydantic[email]>=2.11.7
25
26
  Requires-Dist: python-dotenv>=1.1.0
26
27
  Requires-Dist: rich>=13.9.4
27
28
  Requires-Dist: typer>=0.15.2
@@ -109,7 +109,7 @@ config = {
109
109
  },
110
110
  "local_server": {
111
111
  # Local stdio server
112
- "transport": "stdio"
112
+ "transport": "stdio",
113
113
  "command": "python",
114
114
  "args": ["./server.py", "--verbose"],
115
115
  "env": {"DEBUG": "true"},
@@ -0,0 +1,126 @@
1
+ ---
2
+ title: User Elicitation
3
+ sidebarTitle: Elicitation
4
+ description: Handle server-initiated user input requests with structured schemas.
5
+ icon: message-question
6
+ tag: NEW
7
+ ---
8
+
9
+ import { VersionBadge } from "/snippets/version-badge.mdx";
10
+
11
+ <VersionBadge version="2.10.0" />
12
+
13
+ ## What is Elicitation?
14
+
15
+ Elicitation allows MCP servers to request structured input from users during tool execution. Instead of requiring all inputs upfront, servers can interactively ask users for information as needed - like prompting for missing parameters, requesting clarification, or gathering additional context.
16
+
17
+ For example, a file management tool might ask "Which directory should I create?" or a data analysis tool might request "What date range should I analyze?"
18
+
19
+ ## How FastMCP Makes Elicitation Easy
20
+
21
+ FastMCP's client provides a helpful abstraction layer that:
22
+
23
+ - **Converts JSON schemas to Python types**: The raw MCP protocol uses JSON schemas, but FastMCP automatically converts these to Python dataclasses
24
+ - **Provides structured constructors**: Instead of manually building dictionaries that match the schema, you get dataclass constructors that ensure correct structure
25
+ - **Handles type conversion**: FastMCP takes care of converting between JSON representations and Python objects
26
+ - **Runtime introspection**: You can inspect the generated dataclass fields to understand the expected structure
27
+
28
+ When you implement an elicitation handler, FastMCP gives you a dataclass type that matches the server's schema, making it easy to create properly structured responses without having to manually parse JSON schemas.
29
+
30
+ ## Elicitation Handler
31
+
32
+ Provide an `elicitation_handler` function when creating the client. FastMCP automatically converts the server's JSON schema into a Python dataclass type, making it easy to construct the response:
33
+
34
+ ```python
35
+ from fastmcp import Client
36
+ from fastmcp.client.elicitation import ElicitResult
37
+
38
+ async def elicitation_handler(message: str, response_type: type, params, context):
39
+ # Present the message to the user and collect input
40
+ user_input = input(f"{message}: ")
41
+
42
+ # Create response using the provided dataclass type
43
+ # FastMCP converted the JSON schema to this Python type for you
44
+ response_data = response_type(value=user_input)
45
+
46
+ # You can return data directly - FastMCP will implicitly accept the elicitation
47
+ return response_data
48
+
49
+ # Or explicitly return an ElicitResult for more control
50
+ # return ElicitResult(action="accept", content=response_data)
51
+
52
+ client = Client(
53
+ "my_mcp_server.py",
54
+ elicitation_handler=elicitation_handler,
55
+ )
56
+ ```
57
+
58
+ ### Handler Parameters
59
+
60
+ The elicitation handler receives four parameters:
61
+
62
+ <Card icon="code" title="Elicitation Handler Parameters">
63
+ <ResponseField name="message" type="str">
64
+ The prompt message to display to the user
65
+ </ResponseField>
66
+
67
+ <ResponseField name="response_type" type="type">
68
+ A Python dataclass type that FastMCP created from the server's JSON schema. Use this to construct your response with proper typing and IDE support. If the server requests an empty object (indicating no response), this will be `None`.
69
+ </ResponseField>
70
+
71
+ <ResponseField name="params" type="ElicitRequestParams">
72
+ The original MCP elicitation request parameters, including the raw JSON schema in `params.requestedSchema` if you need it
73
+ </ResponseField>
74
+
75
+ <ResponseField name="context" type="RequestContext">
76
+ Request context containing metadata about the elicitation request
77
+ </ResponseField>
78
+ </Card>
79
+
80
+ ### Response Actions
81
+
82
+ The handler can return data directly (which implicitly accepts the elicitation) or an `ElicitResult` object for more control over the response action:
83
+
84
+ <Card icon="code" title="ElicitResult Structure">
85
+ <ResponseField name="action" type="Literal['accept', 'decline', 'cancel']">
86
+ How the user responded to the elicitation request
87
+ </ResponseField>
88
+
89
+ <ResponseField name="content" type="dataclass instance | dict | None">
90
+ The user's input data (required for "accept", omitted for "decline"/"cancel")
91
+ </ResponseField>
92
+ </Card>
93
+
94
+ **Action Types:**
95
+ - **`accept`**: User provided valid input - include their data in the `content` field
96
+ - **`decline`**: User chose not to provide the requested information - omit `content`
97
+ - **`cancel`**: User cancelled the entire operation - omit `content`
98
+
99
+ ## Basic Example
100
+
101
+ ```python
102
+ from fastmcp import Client
103
+ from fastmcp.client.elicitation import ElicitResult
104
+
105
+ async def basic_elicitation_handler(message: str, response_type: type, params, context):
106
+ print(f"Server asks: {message}")
107
+
108
+ # Simple text input for demonstration
109
+ user_response = input("Your response: ")
110
+
111
+ if not user_response:
112
+ # For non-acceptance, use ElicitResult explicitly
113
+ return ElicitResult(action="decline")
114
+
115
+ # Use the response_type dataclass to create a properly structured response
116
+ # FastMCP handles the conversion from JSON schema to Python type
117
+ # Return data directly - FastMCP will implicitly accept the elicitation
118
+ return response_type(value=user_response)
119
+
120
+ client = Client(
121
+ "my_mcp_server.py",
122
+ elicitation_handler=basic_elicitation_handler
123
+ )
124
+ ```
125
+
126
+
@@ -7,7 +7,7 @@ icon: envelope
7
7
 
8
8
  import { VersionBadge } from "/snippets/version-badge.mdx";
9
9
 
10
- <VersionBadge version="2.9.0" />
10
+ <VersionBadge version="2.9.1" />
11
11
 
12
12
  MCP clients can receive various types of messages from servers, including requests that need responses and notifications that don't. The message handler provides a unified way to process all these messages.
13
13
 
@@ -0,0 +1,241 @@
1
+ ---
2
+ title: Tool Operations
3
+ sidebarTitle: Tools
4
+ description: Discover and execute server-side tools with the FastMCP client.
5
+ icon: wrench
6
+ ---
7
+
8
+ import { VersionBadge } from '/snippets/version-badge.mdx'
9
+
10
+ <VersionBadge version="2.0.0" />
11
+
12
+ Tools are executable functions exposed by MCP servers. The FastMCP client provides methods to discover available tools and execute them with arguments.
13
+
14
+ ## Discovering Tools
15
+
16
+ Use `list_tools()` to retrieve all tools available on the server:
17
+
18
+ ```python
19
+ async with client:
20
+ tools = await client.list_tools()
21
+ # tools -> list[mcp.types.Tool]
22
+
23
+ for tool in tools:
24
+ print(f"Tool: {tool.name}")
25
+ print(f"Description: {tool.description}")
26
+ if tool.inputSchema:
27
+ print(f"Parameters: {tool.inputSchema}")
28
+ ```
29
+
30
+ ## Executing Tools
31
+
32
+ ### Basic Execution
33
+
34
+ Execute a tool using `call_tool()` with the tool name and arguments:
35
+
36
+ ```python
37
+ async with client:
38
+ # Simple tool call
39
+ result = await client.call_tool("add", {"a": 5, "b": 3})
40
+ # result -> CallToolResult with structured and unstructured data
41
+
42
+ # Access structured data (automatically deserialized)
43
+ print(result.data) # 8 (int) or {"result": 8} for primitive types
44
+
45
+ # Access traditional content blocks
46
+ print(result.content[0].text) # "8" (TextContent)
47
+ ```
48
+
49
+ ### Advanced Execution Options
50
+
51
+ The `call_tool()` method supports additional parameters for timeout control and progress monitoring:
52
+
53
+ ```python
54
+ async with client:
55
+ # With timeout (aborts if execution takes longer than 2 seconds)
56
+ result = await client.call_tool(
57
+ "long_running_task",
58
+ {"param": "value"},
59
+ timeout=2.0
60
+ )
61
+
62
+ # With progress handler (to track execution progress)
63
+ result = await client.call_tool(
64
+ "long_running_task",
65
+ {"param": "value"},
66
+ progress_handler=my_progress_handler
67
+ )
68
+ ```
69
+
70
+ **Parameters:**
71
+ - `name`: The tool name (string)
72
+ - `arguments`: Dictionary of arguments to pass to the tool (optional)
73
+ - `timeout`: Maximum execution time in seconds (optional, overrides client-level timeout)
74
+ - `progress_handler`: Progress callback function (optional, overrides client-level handler)
75
+
76
+ ## Handling Results
77
+
78
+ <VersionBadge version="2.10.0" />
79
+
80
+ Tool execution returns a `CallToolResult` object with both structured and traditional content. FastMCP's standout feature is the `.data` property, which doesn't just provide raw JSON but actually hydrates complete Python objects including complex types like datetimes, UUIDs, and custom classes.
81
+
82
+ ### CallToolResult Properties
83
+
84
+ <Card icon="code" title="CallToolResult Properties">
85
+ <ResponseField name=".data" type="Any">
86
+ **FastMCP exclusive**: Fully hydrated Python objects with complex type support (datetimes, UUIDs, custom classes). Goes beyond JSON to provide complete object reconstruction from output schemas.
87
+ </ResponseField>
88
+
89
+ <ResponseField name=".content" type="list[mcp.types.ContentBlock]">
90
+ Standard MCP content blocks (`TextContent`, `ImageContent`, `AudioContent`, etc.) available from all MCP servers.
91
+ </ResponseField>
92
+
93
+ <ResponseField name=".structured_content" type="dict[str, Any] | None">
94
+ Standard MCP structured JSON data as sent by the server, available from all MCP servers that support structured outputs.
95
+ </ResponseField>
96
+
97
+ <ResponseField name=".is_error" type="bool">
98
+ Boolean indicating if the tool execution failed.
99
+ </ResponseField>
100
+ </Card>
101
+
102
+ ### Structured Data Access
103
+
104
+ FastMCP's `.data` property provides fully hydrated Python objects, not just JSON dictionaries. This includes complex type reconstruction:
105
+
106
+ ```python
107
+ from datetime import datetime
108
+ from uuid import UUID
109
+
110
+ async with client:
111
+ result = await client.call_tool("get_weather", {"city": "London"})
112
+
113
+ # FastMCP reconstructs complete Python objects from the server's output schema
114
+ weather = result.data # Server-defined WeatherReport object
115
+ print(f"Temperature: {weather.temperature}°C at {weather.timestamp}")
116
+ print(f"Station: {weather.station_id}")
117
+ print(f"Humidity: {weather.humidity}%")
118
+
119
+ # The timestamp is a real datetime object, not a string!
120
+ assert isinstance(weather.timestamp, datetime)
121
+ assert isinstance(weather.station_id, UUID)
122
+
123
+ # Compare with raw structured JSON (standard MCP)
124
+ print(f"Raw JSON: {result.structured_content}")
125
+ # {"temperature": 20, "timestamp": "2024-01-15T14:30:00Z", "station_id": "123e4567-..."}
126
+
127
+ # Traditional content blocks (standard MCP)
128
+ print(f"Text content: {result.content[0].text}")
129
+ ```
130
+
131
+ ### Fallback Behavior
132
+
133
+ For tools without output schemas or when deserialization fails, `.data` will be `None`:
134
+
135
+ ```python
136
+ async with client:
137
+ result = await client.call_tool("legacy_tool", {"param": "value"})
138
+
139
+ if result.data is not None:
140
+ # Structured output available and successfully deserialized
141
+ print(f"Structured: {result.data}")
142
+ else:
143
+ # No structured output or deserialization failed - use content blocks
144
+ for content in result.content:
145
+ if hasattr(content, 'text'):
146
+ print(f"Text result: {content.text}")
147
+ elif hasattr(content, 'data'):
148
+ print(f"Binary data: {len(content.data)} bytes")
149
+ ```
150
+
151
+ ### Primitive Type Unwrapping
152
+
153
+ <Tip>
154
+ FastMCP servers automatically wrap non-object results (like `int`, `str`, `bool`) in a `{"result": value}` structure to create valid structured outputs. FastMCP clients understand this convention and automatically unwrap the value in `.data` for convenience, so you get the original primitive value instead of a wrapper object.
155
+ </Tip>
156
+
157
+ ```python
158
+ async with client:
159
+ result = await client.call_tool("calculate_sum", {"a": 5, "b": 3})
160
+
161
+ # FastMCP client automatically unwraps for convenience
162
+ print(result.data) # 8 (int) - the original value
163
+
164
+ # Raw structured content shows the server-side wrapping
165
+ print(result.structured_content) # {"result": 8}
166
+
167
+ # Other MCP clients would need to manually access ["result"]
168
+ # value = result.structured_content["result"] # Not needed with FastMCP!
169
+ ```
170
+
171
+ ## Error Handling
172
+
173
+ ### Exception-Based Error Handling
174
+
175
+ By default, `call_tool()` raises a `ToolError` if the tool execution fails:
176
+
177
+ ```python
178
+ from fastmcp.exceptions import ToolError
179
+
180
+ async with client:
181
+ try:
182
+ result = await client.call_tool("potentially_failing_tool", {"param": "value"})
183
+ print("Tool succeeded:", result.data)
184
+ except ToolError as e:
185
+ print(f"Tool failed: {e}")
186
+ ```
187
+
188
+ ### Manual Error Checking
189
+
190
+ You can disable automatic error raising and manually check the result:
191
+
192
+ ```python
193
+ async with client:
194
+ result = await client.call_tool(
195
+ "potentially_failing_tool",
196
+ {"param": "value"},
197
+ raise_on_error=False
198
+ )
199
+
200
+ if result.is_error:
201
+ print(f"Tool failed: {result.content[0].text}")
202
+ else:
203
+ print(f"Tool succeeded: {result.data}")
204
+ ```
205
+
206
+ ### Raw MCP Protocol Access
207
+
208
+ For complete control, use `call_tool_mcp()` which returns the raw MCP protocol object:
209
+
210
+ ```python
211
+ async with client:
212
+ result = await client.call_tool_mcp("potentially_failing_tool", {"param": "value"})
213
+ # result -> mcp.types.CallToolResult
214
+
215
+ if result.isError:
216
+ print(f"Tool failed: {result.content}")
217
+ else:
218
+ print(f"Tool succeeded: {result.content}")
219
+ # Note: No automatic deserialization with call_tool_mcp()
220
+ ```
221
+
222
+ ## Argument Handling
223
+
224
+ Arguments are passed as a dictionary to the tool:
225
+
226
+ ```python
227
+ async with client:
228
+ # Simple arguments
229
+ result = await client.call_tool("greet", {"name": "World"})
230
+
231
+ # Complex arguments
232
+ result = await client.call_tool("process_data", {
233
+ "config": {"format": "json", "validate": True},
234
+ "items": [1, 2, 3, 4, 5],
235
+ "metadata": {"source": "api", "version": "1.0"}
236
+ })
237
+ ```
238
+
239
+ <Tip>
240
+ For multi-server clients, tool names are automatically prefixed with the server name (e.g., `weather_get_forecast` for a tool named `get_forecast` on the `weather` server).
241
+ </Tip>
@@ -12,7 +12,7 @@
12
12
  "decoration": "windows"
13
13
  },
14
14
  "banner": {
15
- "content": "[FastMCP Cloud](https://fastmcp.link/x0Kyhy2) is coming!"
15
+ "content": "FastMCP Cloud is here! [Join the beta](https://fastmcp.link/x0Kyhy2)."
16
16
  },
17
17
  "colors": {
18
18
  "dark": "#f72585",
@@ -69,8 +69,18 @@
69
69
  "pages": [
70
70
  "servers/tools",
71
71
  "servers/resources",
72
- "servers/prompts",
73
- "servers/context"
72
+ "servers/prompts"
73
+ ]
74
+ },
75
+ {
76
+ "group": "Advanced Features",
77
+ "icon": "stars",
78
+ "pages": [
79
+ "servers/context",
80
+ "servers/elicitation",
81
+ "servers/logging",
82
+ "servers/progress",
83
+ "servers/sampling"
74
84
  ]
75
85
  },
76
86
  {
@@ -106,6 +116,7 @@
106
116
  "group": "Advanced Features",
107
117
  "icon": "stars",
108
118
  "pages": [
119
+ "clients/elicitation",
109
120
  "clients/logging",
110
121
  "clients/progress",
111
122
  "clients/sampling",
@@ -130,6 +141,7 @@
130
141
  "integrations/claude-desktop",
131
142
  "integrations/gemini",
132
143
  "integrations/openai",
144
+ "integrations/eunomia-authorization",
133
145
  "integrations/contrib"
134
146
  ]
135
147
  },
@@ -13,7 +13,7 @@ MCP integration with ChatGPT is currently limited to **Deep Research** functiona
13
13
  </Note>
14
14
 
15
15
  <Tip>
16
- OpenAI's official MCP documentation and examples are built with **FastMCP v2**! Check out their [sample MCP server](https://github.com/openai/mcp-server-sample) which demonstrates FastMCP in action.
16
+ OpenAI's official MCP documentation and examples are built with **FastMCP v2**! Check out their [simple Deep Research-style MCP server example](https://github.com/openai/sample-deep-research-mcp) for a quick reference similar to the one in this document, or their [more complete Deep Research example](https://github.com/openai/openai-cookbook/tree/main/examples/deep_research_api/how_to_build_a_deep_research_mcp_server) from the OpenAI Cookbook, which includes vector search and more.
17
17
  </Tip>
18
18
 
19
19
  ## Deep Research
@@ -42,7 +42,7 @@ A Deep Research-compatible server must implement these two required tools:
42
42
 
43
43
  The `search` tool should take a query (of any kind!) and return IDs. The `fetch` tool should take an ID and return the record.
44
44
 
45
- Here's a reference server implementation you can adapt (see also [OpenAI's sample server](https://github.com/openai/mcp-server-sample) for comparison):
45
+ Here's a reference server implementation you can adapt (see also [OpenAI's sample server](https://github.com/openai/sample-deep-research-mcp) for comparison):
46
46
 
47
47
  ```python server.py [expandable]
48
48
  import json
@@ -0,0 +1,108 @@
1
+ ---
2
+ title: Eunomia Authorization + FastMCP
3
+ sidebarTitle: Eunomia Authorization
4
+ description: Add policy-based authorization to your FastMCP servers
5
+ icon: layer-group
6
+ tag: NEW
7
+ ---
8
+
9
+ Add **policy-based authorization** to your FastMCP servers with minimal code changes using Eunomia authorization middleware.
10
+
11
+ Control which actions MCP clients can perform on your server by restricting how the agent can access resources, tools and prompts by using JSON-based policies, while obtaining a comprehensive audit log of all access attempts and violations.
12
+
13
+ ## Eunomia Authorization Middleware
14
+
15
+ The middleware intercepts all MCP requests to your server and automatically maps MCP methods to authorization checks.
16
+
17
+ ```mermaid
18
+ sequenceDiagram
19
+ participant MCPClient as MCP Client
20
+ participant EunomiaMiddleware as Eunomia Middleware
21
+ participant MCPServer as FastMCP Server
22
+ participant EunomiaServer as Eunomia Server
23
+
24
+ MCPClient->>EunomiaMiddleware: MCP Request
25
+ Note over MCPClient, EunomiaMiddleware: Middleware intercepts request to server
26
+ EunomiaMiddleware->>EunomiaServer: Authorization Check
27
+ EunomiaServer->>EunomiaMiddleware: Authorization Decision (allow/deny)
28
+ EunomiaMiddleware-->>MCPClient: MCP Unauthorized Error (if denied)
29
+ EunomiaMiddleware->>MCPServer: MCP Request (if allowed)
30
+ MCPServer-->>MCPClient: MCP Response (if allowed)
31
+ ```
32
+
33
+ <Note>
34
+ Eunomia is an AI-specific standalone authorization server that handles policy decisions. You must have an Eunomia server running alongside your FastMCP server for the middleware to function.
35
+
36
+ Run it in the background with Docker:
37
+
38
+ ```bash
39
+ docker run -d -p 8000:8000 ttommitt/eunomia-server:latest
40
+ ```
41
+
42
+ </Note>
43
+
44
+ ### Create a Server with Authorization
45
+
46
+ First, install the `eunomia-mcp` package:
47
+
48
+ ```bash
49
+ pip install eunomia-mcp
50
+ ```
51
+
52
+ Then create a FastMCP server and add the Eunomia middleware with a few lines of code:
53
+
54
+ ```python server.py
55
+ from fastmcp import FastMCP
56
+ from eunomia_mcp import create_eunomia_middleware
57
+
58
+ mcp = FastMCP("Secure FastMCP Server 🔒")
59
+
60
+ @mcp.tool()
61
+ def add(a: int, b: int) -> int:
62
+ """Add two numbers"""
63
+ return a + b
64
+
65
+ middleware = [create_eunomia_middleware()]
66
+ app = mcp.http_app(middleware=middleware)
67
+
68
+ if __name__ == "__main__":
69
+ import uvicorn
70
+ uvicorn.run(app, host="0.0.0.0", port=8080)
71
+ ```
72
+
73
+ ### Configure Access Policies
74
+
75
+ Use the `eunomia-mcp` CLI in your terminal to manage your authorization policies:
76
+
77
+ ```bash
78
+ # Create a default policy configuration file
79
+ eunomia-mcp init
80
+ ```
81
+
82
+ This creates a policy file you can customize to control access to your MCP tools and resources.
83
+
84
+ ```bash
85
+ # Once ready, validate your policy
86
+ eunomia-mcp validate mcp_policies.json
87
+
88
+ # And push it to the Eunomia server
89
+ eunomia-mcp push mcp_policies.json
90
+ ```
91
+
92
+ ### Run the Server
93
+
94
+ Start your FastMCP server normally:
95
+
96
+ ```bash
97
+ python server.py
98
+ ```
99
+
100
+ The middleware will now intercept all MCP requests and check them against your policies. Requests include agent identification through headers like `X-Agent-ID`, `X-User-ID`, or `Authorization` and an automatic mapping of MCP methods to authorization resources and actions.
101
+
102
+ <Tip>
103
+ For detailed policy configuration, custom authentication, and advanced
104
+ deployment patterns, visit the [Eunomia MCP Middleware
105
+ repository][eunomia-github].
106
+ </Tip>
107
+
108
+ [eunomia-github]: https://github.com/whataboutyou-ai/eunomia/tree/main/pkgs/extensions/mcp
@@ -46,6 +46,7 @@ This command runs the server directly in your current Python environment. You ar
46
46
  | Host | `--host` | Host to bind to when using http transport (default: 127.0.0.1) |
47
47
  | Port | `--port`, `-p` | Port to bind to when using http transport (default: 8000) |
48
48
  | Log Level | `--log-level`, `-l` | Log level (DEBUG, INFO, WARNING, ERROR, CRITICAL) |
49
+ | No Banner | `--no-banner` | Disable the startup banner display |
49
50
 
50
51
 
51
52
  #### Server Specification
@@ -89,6 +89,7 @@ The `Tool.from_tool()` class method is the primary way to create a transformed t
89
89
  - `description`: An optional description for the new tool.
90
90
  - `transform_args`: A dictionary of `ArgTransform` objects, one for each argument you want to modify.
91
91
  - `transform_fn`: An optional function that will be called instead of the parent tool's logic.
92
+ - `output_schema`: Control output schema and structured outputs (see [Output Schema Control](#output-schema-control)).
92
93
  - `tags`: An optional set of tags for the new tool.
93
94
  - `annotations`: An optional set of `ToolAnnotations` for the new tool.
94
95
  - `serializer`: An optional function that will be called to serialize the result of the new tool.
@@ -439,7 +440,44 @@ mcp.add_tool(new_tool)
439
440
 
440
441
  <Tip>
441
442
  In the above example, `**kwargs` receives the renamed argument `b`, not the original argument `y`. It is therefore recommended to use with `forward()`, not `forward_raw()`.
442
- </Tip>
443
+ </Tip>
444
+
445
+ ## Output Schema Control
446
+
447
+ <VersionBadge version="2.10.0" />
448
+
449
+ Transformed tools inherit output schemas from their parent by default, but you can control this behavior:
450
+
451
+ **Inherit from Parent (Default)**
452
+ ```python
453
+ Tool.from_tool(parent_tool, name="renamed_tool")
454
+ ```
455
+ The transformed tool automatically uses the parent tool's output schema and structured output behavior.
456
+
457
+ **Custom Output Schema**
458
+ ```python
459
+ Tool.from_tool(parent_tool, output_schema={
460
+ "type": "object",
461
+ "properties": {"status": {"type": "string"}}
462
+ })
463
+ ```
464
+ Provide your own schema that differs from the parent. The tool must return data matching this schema.
465
+
466
+ **Remove Output Schema**
467
+ ```python
468
+ Tool.from_tool(parent_tool, output_schema=False)
469
+ ```
470
+ Removes the output schema declaration. Automatic structured content still works for object-like returns (dict, dataclass, Pydantic models) but primitive types won't be structured.
471
+
472
+ **Full Control with Transform Functions**
473
+ ```python
474
+ async def custom_output(**kwargs) -> ToolResult:
475
+ result = await forward(**kwargs)
476
+ return ToolResult(content=[...], structured_content={...})
477
+
478
+ Tool.from_tool(parent_tool, transform_fn=custom_output)
479
+ ```
480
+ Use a transform function returning `ToolResult` for complete control over both content blocks and structured outputs.
443
481
 
444
482
  ## Common Patterns
445
483