fastmcp 2.6.1__tar.gz → 2.7.1__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 (226) hide show
  1. {fastmcp-2.6.1 → fastmcp-2.7.1}/.github/workflows/labeler.yml +1 -0
  2. {fastmcp-2.6.1 → fastmcp-2.7.1}/PKG-INFO +10 -9
  3. {fastmcp-2.6.1 → fastmcp-2.7.1}/README.md +7 -7
  4. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/clients/auth/bearer.mdx +1 -0
  5. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/clients/auth/oauth.mdx +1 -0
  6. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/clients/transports.mdx +1 -1
  7. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/deployment/asgi.mdx +1 -1
  8. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/deployment/running-server.mdx +14 -3
  9. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/docs.json +13 -1
  10. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/getting-started/quickstart.mdx +3 -3
  11. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/getting-started/welcome.mdx +1 -1
  12. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/integrations/anthropic.mdx +3 -2
  13. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/integrations/claude-desktop.mdx +1 -1
  14. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/integrations/contrib.mdx +1 -1
  15. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/integrations/gemini.mdx +3 -2
  16. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/integrations/openai.mdx +3 -2
  17. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/patterns/cli.mdx +1 -1
  18. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/patterns/decorating-methods.mdx +73 -49
  19. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/patterns/http-requests.mdx +2 -2
  20. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/patterns/testing.mdx +1 -1
  21. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/servers/auth/bearer.mdx +2 -1
  22. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/servers/composition.mdx +3 -3
  23. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/servers/context.mdx +11 -11
  24. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/servers/fastmcp.mdx +5 -5
  25. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/servers/prompts.mdx +10 -10
  26. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/servers/proxy.mdx +1 -1
  27. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/servers/tools.mdx +29 -29
  28. fastmcp-2.7.1/docs/style.css +119 -0
  29. fastmcp-2.7.1/docs/updates.mdx +21 -0
  30. {fastmcp-2.6.1 → fastmcp-2.7.1}/examples/complex_inputs.py +1 -1
  31. fastmcp-2.7.1/examples/config_server.py +46 -0
  32. {fastmcp-2.6.1 → fastmcp-2.7.1}/examples/desktop.py +1 -1
  33. {fastmcp-2.6.1 → fastmcp-2.7.1}/examples/echo.py +1 -1
  34. {fastmcp-2.6.1 → fastmcp-2.7.1}/examples/memory.py +2 -2
  35. {fastmcp-2.6.1 → fastmcp-2.7.1}/examples/mount_example.py +3 -3
  36. {fastmcp-2.6.1 → fastmcp-2.7.1}/examples/sampling.py +1 -1
  37. {fastmcp-2.6.1 → fastmcp-2.7.1}/examples/screenshot.py +1 -1
  38. {fastmcp-2.6.1 → fastmcp-2.7.1}/examples/serializer.py +1 -1
  39. {fastmcp-2.6.1 → fastmcp-2.7.1}/examples/simple_echo.py +1 -1
  40. {fastmcp-2.6.1 → fastmcp-2.7.1}/examples/smart_home/src/smart_home/hub.py +1 -1
  41. {fastmcp-2.6.1 → fastmcp-2.7.1}/examples/smart_home/src/smart_home/lights/server.py +9 -9
  42. {fastmcp-2.6.1 → fastmcp-2.7.1}/pyproject.toml +4 -2
  43. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/cli/cli.py +10 -2
  44. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/cli/run.py +32 -1
  45. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/client/transports.py +21 -13
  46. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/contrib/bulk_tool_caller/example.py +1 -1
  47. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/contrib/mcp_mixin/mcp_mixin.py +10 -3
  48. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/prompts/prompt.py +68 -30
  49. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/prompts/prompt_manager.py +13 -6
  50. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/resources/__init__.py +1 -2
  51. fastmcp-2.7.1/src/fastmcp/resources/resource.py +169 -0
  52. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/resources/resource_manager.py +17 -6
  53. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/resources/template.py +90 -56
  54. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/resources/types.py +0 -44
  55. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/server/context.py +1 -1
  56. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/server/dependencies.py +1 -0
  57. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/server/http.py +2 -1
  58. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/server/openapi.py +17 -32
  59. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/server/proxy.py +5 -8
  60. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/server/server.py +280 -95
  61. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/settings.py +1 -1
  62. fastmcp-2.7.1/src/fastmcp/tools/__init__.py +4 -0
  63. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/tools/tool.py +62 -22
  64. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/tools/tool_manager.py +9 -3
  65. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/utilities/mcp_config.py +17 -7
  66. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/utilities/openapi.py +56 -32
  67. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/utilities/types.py +7 -1
  68. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/auth/providers/test_bearer.py +1 -1
  69. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/auth/test_oauth_client.py +1 -1
  70. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/cli/test_cli.py +25 -0
  71. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/cli/test_run.py +36 -0
  72. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/client/test_client.py +80 -8
  73. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/client/test_logs.py +2 -2
  74. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/client/test_progress.py +1 -1
  75. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/client/test_roots.py +1 -1
  76. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/client/test_sampling.py +3 -3
  77. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/client/test_sse.py +4 -4
  78. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/client/test_stdio.py +1 -1
  79. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/client/test_streamable_http.py +4 -4
  80. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/contrib/test_bulk_tool_caller.py +4 -3
  81. fastmcp-2.7.1/tests/deprecated/__init__.py +4 -0
  82. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/deprecated/test_deprecated.py +5 -4
  83. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/deprecated/test_mount_separators.py +5 -2
  84. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/deprecated/test_resource_prefixes.py +5 -0
  85. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/deprecated/test_route_type_ignore.py +3 -0
  86. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/prompts/test_prompt_manager.py +4 -1
  87. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/resources/test_function_resources.py +1 -1
  88. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/resources/test_resource_manager.py +1 -1
  89. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/resources/test_resource_template.py +8 -7
  90. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/resources/test_resources.py +2 -1
  91. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/server/http/test_http_dependencies.py +2 -2
  92. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/server/openapi/test_openapi_path_parameters.py +7 -7
  93. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/server/test_file_server.py +1 -1
  94. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/server/test_import_server.py +19 -15
  95. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/server/test_mount.py +32 -19
  96. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/server/test_proxy.py +18 -10
  97. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/server/test_run_server.py +4 -4
  98. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/server/test_server.py +254 -41
  99. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/server/test_server_interactions.py +68 -110
  100. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/server/test_tool_annotations.py +6 -2
  101. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/server/test_tool_exclude_args.py +13 -2
  102. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/test_servers/fastmcp_server.py +4 -4
  103. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/tools/test_tool.py +236 -8
  104. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/tools/test_tool_manager.py +123 -69
  105. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/utilities/openapi/test_openapi.py +111 -1
  106. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/utilities/test_mcp_config.py +60 -1
  107. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/utilities/test_typeadapter.py +2 -2
  108. {fastmcp-2.6.1 → fastmcp-2.7.1}/uv.lock +6 -1
  109. fastmcp-2.6.1/docs/style.css +0 -52
  110. fastmcp-2.6.1/src/fastmcp/resources/resource.py +0 -83
  111. fastmcp-2.6.1/src/fastmcp/tools/__init__.py +0 -4
  112. fastmcp-2.6.1/src/fastmcp/utilities/decorators.py +0 -101
  113. fastmcp-2.6.1/tests/tools/__init__.py +0 -0
  114. fastmcp-2.6.1/tests/utilities/test_decorated_function.py +0 -222
  115. {fastmcp-2.6.1 → fastmcp-2.7.1}/.cursor/rules/core-mcp-objects.mdc +0 -0
  116. {fastmcp-2.6.1 → fastmcp-2.7.1}/.github/ISSUE_TEMPLATE/bug.yml +0 -0
  117. {fastmcp-2.6.1 → fastmcp-2.7.1}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  118. {fastmcp-2.6.1 → fastmcp-2.7.1}/.github/ISSUE_TEMPLATE/enhancement.yml +0 -0
  119. {fastmcp-2.6.1 → fastmcp-2.7.1}/.github/labeler.yml +0 -0
  120. {fastmcp-2.6.1 → fastmcp-2.7.1}/.github/release.yml +0 -0
  121. {fastmcp-2.6.1 → fastmcp-2.7.1}/.github/workflows/publish.yml +0 -0
  122. {fastmcp-2.6.1 → fastmcp-2.7.1}/.github/workflows/run-static.yml +0 -0
  123. {fastmcp-2.6.1 → fastmcp-2.7.1}/.github/workflows/run-tests.yml +0 -0
  124. {fastmcp-2.6.1 → fastmcp-2.7.1}/.gitignore +0 -0
  125. {fastmcp-2.6.1 → fastmcp-2.7.1}/.pre-commit-config.yaml +0 -0
  126. {fastmcp-2.6.1 → fastmcp-2.7.1}/AGENTS.md +0 -0
  127. {fastmcp-2.6.1 → fastmcp-2.7.1}/LICENSE +0 -0
  128. {fastmcp-2.6.1 → fastmcp-2.7.1}/Windows_Notes.md +0 -0
  129. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/assets/demo-inspector.png +0 -0
  130. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/assets/favicon.ico +0 -0
  131. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/assets/logo.png +0 -0
  132. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/clients/advanced-features.mdx +0 -0
  133. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/clients/client.mdx +0 -0
  134. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/getting-started/installation.mdx +0 -0
  135. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/servers/openapi.mdx +0 -0
  136. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/servers/resources.mdx +0 -0
  137. {fastmcp-2.6.1 → fastmcp-2.7.1}/docs/snippets/version-badge.mdx +0 -0
  138. {fastmcp-2.6.1 → fastmcp-2.7.1}/examples/in_memory_proxy_example.py +0 -0
  139. {fastmcp-2.6.1 → fastmcp-2.7.1}/examples/smart_home/README.md +0 -0
  140. {fastmcp-2.6.1 → fastmcp-2.7.1}/examples/smart_home/pyproject.toml +0 -0
  141. {fastmcp-2.6.1 → fastmcp-2.7.1}/examples/smart_home/src/smart_home/__init__.py +0 -0
  142. {fastmcp-2.6.1 → fastmcp-2.7.1}/examples/smart_home/src/smart_home/__main__.py +0 -0
  143. {fastmcp-2.6.1 → fastmcp-2.7.1}/examples/smart_home/src/smart_home/lights/__init__.py +0 -0
  144. {fastmcp-2.6.1 → fastmcp-2.7.1}/examples/smart_home/src/smart_home/lights/hue_utils.py +0 -0
  145. {fastmcp-2.6.1 → fastmcp-2.7.1}/examples/smart_home/src/smart_home/py.typed +0 -0
  146. {fastmcp-2.6.1 → fastmcp-2.7.1}/examples/smart_home/src/smart_home/settings.py +0 -0
  147. {fastmcp-2.6.1 → fastmcp-2.7.1}/examples/smart_home/uv.lock +0 -0
  148. {fastmcp-2.6.1 → fastmcp-2.7.1}/examples/tags_example.py +0 -0
  149. {fastmcp-2.6.1 → fastmcp-2.7.1}/examples/text_me.py +0 -0
  150. {fastmcp-2.6.1 → fastmcp-2.7.1}/justfile +0 -0
  151. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/__init__.py +0 -0
  152. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/cli/__init__.py +0 -0
  153. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/cli/claude.py +0 -0
  154. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/client/__init__.py +0 -0
  155. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/client/auth/__init__.py +0 -0
  156. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/client/auth/bearer.py +0 -0
  157. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/client/auth/oauth.py +0 -0
  158. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/client/client.py +0 -0
  159. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/client/logging.py +0 -0
  160. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/client/oauth_callback.py +0 -0
  161. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/client/progress.py +0 -0
  162. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/client/roots.py +0 -0
  163. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/client/sampling.py +0 -0
  164. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/contrib/README.md +0 -0
  165. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/contrib/bulk_tool_caller/README.md +0 -0
  166. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/contrib/bulk_tool_caller/__init__.py +0 -0
  167. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/contrib/bulk_tool_caller/bulk_tool_caller.py +0 -0
  168. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/contrib/mcp_mixin/README.md +0 -0
  169. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/contrib/mcp_mixin/__init__.py +0 -0
  170. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/contrib/mcp_mixin/example.py +0 -0
  171. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/exceptions.py +0 -0
  172. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/prompts/__init__.py +0 -0
  173. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/py.typed +0 -0
  174. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/server/__init__.py +0 -0
  175. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/server/auth/__init__.py +0 -0
  176. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/server/auth/auth.py +0 -0
  177. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/server/auth/providers/__init__.py +0 -0
  178. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/server/auth/providers/bearer.py +0 -0
  179. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/server/auth/providers/bearer_env.py +0 -0
  180. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/server/auth/providers/in_memory.py +0 -0
  181. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/utilities/__init__.py +0 -0
  182. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/utilities/cache.py +0 -0
  183. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/utilities/exceptions.py +0 -0
  184. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/utilities/http.py +0 -0
  185. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/utilities/json_schema.py +0 -0
  186. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/utilities/logging.py +0 -0
  187. {fastmcp-2.6.1 → fastmcp-2.7.1}/src/fastmcp/utilities/tests.py +0 -0
  188. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/__init__.py +0 -0
  189. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/auth/__init__.py +0 -0
  190. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/auth/providers/test_bearer_env.py +0 -0
  191. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/cli/__init__.py +0 -0
  192. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/client/__init__.py +0 -0
  193. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/client/test_openapi.py +0 -0
  194. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/conftest.py +0 -0
  195. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/contrib/__init__.py +0 -0
  196. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/contrib/test_mcp_mixin.py +0 -0
  197. {fastmcp-2.6.1/tests/deprecated → fastmcp-2.7.1/tests/prompts}/__init__.py +0 -0
  198. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/prompts/test_prompt.py +0 -0
  199. {fastmcp-2.6.1/tests/prompts → fastmcp-2.7.1/tests/resources}/__init__.py +0 -0
  200. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/resources/test_file_resources.py +0 -0
  201. {fastmcp-2.6.1/tests/resources → fastmcp-2.7.1/tests/server}/__init__.py +0 -0
  202. {fastmcp-2.6.1/tests/server → fastmcp-2.7.1/tests/server/http}/__init__.py +0 -0
  203. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/server/http/test_custom_routes.py +0 -0
  204. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/server/http/test_http_middleware.py +0 -0
  205. {fastmcp-2.6.1/tests/server/http → fastmcp-2.7.1/tests/server/openapi}/__init__.py +0 -0
  206. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/server/openapi/test_openapi.py +0 -0
  207. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/server/openapi/test_route_map_fn.py +0 -0
  208. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/server/test_app_state.py +0 -0
  209. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/server/test_auth_integration.py +0 -0
  210. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/server/test_context.py +0 -0
  211. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/server/test_logging.py +0 -0
  212. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/server/test_resource_prefix_formats.py +0 -0
  213. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/test_examples.py +0 -0
  214. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/test_servers/sse.py +0 -0
  215. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/test_servers/stdio.py +0 -0
  216. {fastmcp-2.6.1/tests/server/openapi → fastmcp-2.7.1/tests/tools}/__init__.py +0 -0
  217. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/utilities/__init__.py +0 -0
  218. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/utilities/openapi/__init__.py +0 -0
  219. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/utilities/openapi/conftest.py +0 -0
  220. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/utilities/openapi/test_openapi_advanced.py +0 -0
  221. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/utilities/openapi/test_openapi_fastapi.py +0 -0
  222. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/utilities/test_cache.py +0 -0
  223. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/utilities/test_json_schema.py +0 -0
  224. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/utilities/test_logging.py +0 -0
  225. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/utilities/test_tests.py +0 -0
  226. {fastmcp-2.6.1 → fastmcp-2.7.1}/tests/utilities/test_types.py +0 -0
@@ -7,6 +7,7 @@ jobs:
7
7
  permissions:
8
8
  contents: read
9
9
  pull-requests: write
10
+ issues: write
10
11
  runs-on: ubuntu-latest
11
12
  steps:
12
13
  - uses: actions/labeler@v5
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fastmcp
3
- Version: 2.6.1
3
+ Version: 2.7.1
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
@@ -25,7 +25,8 @@ Requires-Dist: openapi-pydantic>=0.5.1
25
25
  Requires-Dist: python-dotenv>=1.1.0
26
26
  Requires-Dist: rich>=13.9.4
27
27
  Requires-Dist: typer>=0.15.2
28
- Requires-Dist: websockets>=14.0
28
+ Provides-Extra: websockets
29
+ Requires-Dist: websockets>=15.0.1; extra == 'websockets'
29
30
  Description-Content-Type: text/markdown
30
31
 
31
32
  <div align="center">
@@ -61,7 +62,7 @@ from fastmcp import FastMCP
61
62
 
62
63
  mcp = FastMCP("Demo 🚀")
63
64
 
64
- @mcp.tool()
65
+ @mcp.tool
65
66
  def add(a: int, b: int) -> int:
66
67
  """Add two numbers"""
67
68
  return a + b
@@ -174,7 +175,7 @@ Learn more in the [**FastMCP Server Documentation**](https://gofastmcp.com/serve
174
175
  Tools allow LLMs to perform actions by executing your Python functions (sync or async). Ideal for computations, API calls, or side effects (like `POST`/`PUT`). FastMCP handles schema generation from type hints and docstrings. Tools can return various types, including text, JSON-serializable objects, and even images using the [`fastmcp.Image`](https://gofastmcp.com/servers/tools#return-values) helper.
175
176
 
176
177
  ```python
177
- @mcp.tool()
178
+ @mcp.tool
178
179
  def multiply(a: float, b: float) -> float:
179
180
  """Multiplies two numbers."""
180
181
  return a * b
@@ -203,10 +204,10 @@ Learn more in the [**Resources & Templates Documentation**](https://gofastmcp.co
203
204
 
204
205
  ### Prompts
205
206
 
206
- Prompts define reusable message templates to guide LLM interactions. Decorate functions with `@mcp.prompt()`. Return strings or `Message` objects.
207
+ Prompts define reusable message templates to guide LLM interactions. Decorate functions with `@mcp.prompt`. Return strings or `Message` objects.
207
208
 
208
209
  ```python
209
- @mcp.prompt()
210
+ @mcp.prompt
210
211
  def summarize_request(text: str) -> str:
211
212
  """Generate a prompt asking for a summary."""
212
213
  return f"Please summarize the following text:\n\n{text}"
@@ -231,7 +232,7 @@ from fastmcp import FastMCP, Context
231
232
 
232
233
  mcp = FastMCP("My MCP Server")
233
234
 
234
- @mcp.tool()
235
+ @mcp.tool
235
236
  async def process_data(uri: str, ctx: Context):
236
237
  # Log a message to the client
237
238
  await ctx.info(f"Processing {uri}...")
@@ -329,7 +330,7 @@ Learn more in the [**Composition Documentation**](https://gofastmcp.com/patterns
329
330
 
330
331
  Automatically generate FastMCP servers from existing OpenAPI specifications (`FastMCP.from_openapi()`) or FastAPI applications (`FastMCP.from_fastapi()`), instantly bringing your web APIs to the MCP ecosystem.
331
332
 
332
- Learn more: [**OpenAPI Integration**](https://gofastmcp.com/patterns/openapi) | [**FastAPI Integration**](https://gofastmcp.com/patterns/fastapi).
333
+ Learn more: [**OpenAPI Integration**](https://gofastmcp.com/servers/openapi#openapi-integration) | [**FastAPI Integration**](https://gofastmcp.com/deployment/asgi#fastapi-integration).
333
334
 
334
335
  ### Authentication & Security
335
336
 
@@ -351,7 +352,7 @@ from fastmcp import FastMCP
351
352
 
352
353
  mcp = FastMCP("Demo 🚀")
353
354
 
354
- @mcp.tool()
355
+ @mcp.tool
355
356
  def hello(name: str) -> str:
356
357
  return f"Hello, {name}!"
357
358
 
@@ -31,7 +31,7 @@ from fastmcp import FastMCP
31
31
 
32
32
  mcp = FastMCP("Demo 🚀")
33
33
 
34
- @mcp.tool()
34
+ @mcp.tool
35
35
  def add(a: int, b: int) -> int:
36
36
  """Add two numbers"""
37
37
  return a + b
@@ -144,7 +144,7 @@ Learn more in the [**FastMCP Server Documentation**](https://gofastmcp.com/serve
144
144
  Tools allow LLMs to perform actions by executing your Python functions (sync or async). Ideal for computations, API calls, or side effects (like `POST`/`PUT`). FastMCP handles schema generation from type hints and docstrings. Tools can return various types, including text, JSON-serializable objects, and even images using the [`fastmcp.Image`](https://gofastmcp.com/servers/tools#return-values) helper.
145
145
 
146
146
  ```python
147
- @mcp.tool()
147
+ @mcp.tool
148
148
  def multiply(a: float, b: float) -> float:
149
149
  """Multiplies two numbers."""
150
150
  return a * b
@@ -173,10 +173,10 @@ Learn more in the [**Resources & Templates Documentation**](https://gofastmcp.co
173
173
 
174
174
  ### Prompts
175
175
 
176
- Prompts define reusable message templates to guide LLM interactions. Decorate functions with `@mcp.prompt()`. Return strings or `Message` objects.
176
+ Prompts define reusable message templates to guide LLM interactions. Decorate functions with `@mcp.prompt`. Return strings or `Message` objects.
177
177
 
178
178
  ```python
179
- @mcp.prompt()
179
+ @mcp.prompt
180
180
  def summarize_request(text: str) -> str:
181
181
  """Generate a prompt asking for a summary."""
182
182
  return f"Please summarize the following text:\n\n{text}"
@@ -201,7 +201,7 @@ from fastmcp import FastMCP, Context
201
201
 
202
202
  mcp = FastMCP("My MCP Server")
203
203
 
204
- @mcp.tool()
204
+ @mcp.tool
205
205
  async def process_data(uri: str, ctx: Context):
206
206
  # Log a message to the client
207
207
  await ctx.info(f"Processing {uri}...")
@@ -299,7 +299,7 @@ Learn more in the [**Composition Documentation**](https://gofastmcp.com/patterns
299
299
 
300
300
  Automatically generate FastMCP servers from existing OpenAPI specifications (`FastMCP.from_openapi()`) or FastAPI applications (`FastMCP.from_fastapi()`), instantly bringing your web APIs to the MCP ecosystem.
301
301
 
302
- Learn more: [**OpenAPI Integration**](https://gofastmcp.com/patterns/openapi) | [**FastAPI Integration**](https://gofastmcp.com/patterns/fastapi).
302
+ Learn more: [**OpenAPI Integration**](https://gofastmcp.com/servers/openapi#openapi-integration) | [**FastAPI Integration**](https://gofastmcp.com/deployment/asgi#fastapi-integration).
303
303
 
304
304
  ### Authentication & Security
305
305
 
@@ -321,7 +321,7 @@ from fastmcp import FastMCP
321
321
 
322
322
  mcp = FastMCP("Demo 🚀")
323
323
 
324
- @mcp.tool()
324
+ @mcp.tool
325
325
  def hello(name: str) -> str:
326
326
  return f"Hello, {name}!"
327
327
 
@@ -3,6 +3,7 @@ title: Bearer Token Authentication
3
3
  sidebarTitle: Bearer Auth
4
4
  description: Authenticate your FastMCP client with a Bearer token.
5
5
  icon: key
6
+ tag: "New!"
6
7
  ---
7
8
 
8
9
  import { VersionBadge } from "/snippets/version-badge.mdx"
@@ -3,6 +3,7 @@ title: OAuth Authentication
3
3
  sidebarTitle: OAuth
4
4
  description: Authenticate your FastMCP client via OAuth 2.1.
5
5
  icon: window
6
+ tag: "New!"
6
7
  ---
7
8
 
8
9
  import { VersionBadge } from "/snippets/version-badge.mdx"
@@ -359,7 +359,7 @@ import asyncio
359
359
  # 1. Create your FastMCP server instance
360
360
  server = FastMCP(name="InMemoryServer")
361
361
 
362
- @server.tool()
362
+ @server.tool
363
363
  def ping():
364
364
  return "pong"
365
365
 
@@ -32,7 +32,7 @@ from fastmcp import FastMCP
32
32
 
33
33
  mcp = FastMCP("MyServer")
34
34
 
35
- @mcp.tool()
35
+ @mcp.tool
36
36
  def hello(name: str) -> str:
37
37
  return f"Hello, {name}!"
38
38
 
@@ -22,7 +22,7 @@ from fastmcp import FastMCP
22
22
 
23
23
  mcp = FastMCP(name="MyServer")
24
24
 
25
- @mcp.tool()
25
+ @mcp.tool
26
26
  def hello(name: str) -> str:
27
27
  return f"Hello, {name}!"
28
28
 
@@ -61,6 +61,17 @@ fastmcp dev server.py
61
61
 
62
62
  See the [CLI documentation](/patterns/cli) for detailed information about all available commands and options.
63
63
 
64
+ ### Passing Arguments to Servers
65
+
66
+ When servers accept command line arguments (using argparse, click, or other libraries), you can pass them after `--`:
67
+
68
+ ```bash
69
+ fastmcp run config_server.py -- --config config.json
70
+ fastmcp run database_server.py -- --database-path /tmp/db.sqlite --debug
71
+ ```
72
+
73
+ This is useful for servers that need configuration files, database paths, API keys, or other runtime options.
74
+
64
75
  ## Transport Options
65
76
 
66
77
  Below is a comparison of available transport options to help you choose the right one for your needs:
@@ -233,7 +244,7 @@ import asyncio
233
244
 
234
245
  mcp = FastMCP(name="MyServer")
235
246
 
236
- @mcp.tool()
247
+ @mcp.tool
237
248
  def hello(name: str) -> str:
238
249
  return f"Hello, {name}!"
239
250
 
@@ -270,4 +281,4 @@ async def health_check(request: Request) -> PlainTextResponse:
270
281
 
271
282
  if __name__ == "__main__":
272
283
  mcp.run()
273
- ```
284
+ ```
@@ -11,11 +11,22 @@
11
11
  },
12
12
  "decoration": "windows"
13
13
  },
14
+ "banner": {
15
+ "content": "[FastMCP Cloud](https://fastmcp.link/x0Kyhy2) is coming!"
16
+ },
14
17
  "colors": {
15
18
  "dark": "#f72585",
16
19
  "light": "#4cc9f0",
17
20
  "primary": "#2d00f7"
18
21
  },
22
+ "contextual": {
23
+ "options": [
24
+ "copy",
25
+ "view",
26
+ "chatgpt",
27
+ "claude"
28
+ ]
29
+ },
19
30
  "description": "The fast, Pythonic way to build MCP servers and clients.",
20
31
  "favicon": {
21
32
  "dark": "/assets/favicon.ico",
@@ -47,7 +58,8 @@
47
58
  "pages": [
48
59
  "getting-started/welcome",
49
60
  "getting-started/installation",
50
- "getting-started/quickstart"
61
+ "getting-started/quickstart",
62
+ "updates"
51
63
  ]
52
64
  },
53
65
  {
@@ -32,7 +32,7 @@ from fastmcp import FastMCP
32
32
 
33
33
  mcp = FastMCP("My MCP Server")
34
34
 
35
- @mcp.tool()
35
+ @mcp.tool
36
36
  def greet(name: str) -> str:
37
37
  return f"Hello, {name}!"
38
38
  ```
@@ -49,7 +49,7 @@ from fastmcp import FastMCP, Client
49
49
 
50
50
  mcp = FastMCP("My MCP Server")
51
51
 
52
- @mcp.tool()
52
+ @mcp.tool
53
53
  def greet(name: str) -> str:
54
54
  return f"Hello, {name}!"
55
55
 
@@ -76,7 +76,7 @@ from fastmcp import FastMCP
76
76
 
77
77
  mcp = FastMCP("My MCP Server")
78
78
 
79
- @mcp.tool()
79
+ @mcp.tool
80
80
  def greet(name: str) -> str:
81
81
  return f"Hello, {name}!"
82
82
 
@@ -14,7 +14,7 @@ from fastmcp import FastMCP
14
14
 
15
15
  mcp = FastMCP("Demo 🚀")
16
16
 
17
- @mcp.tool()
17
+ @mcp.tool
18
18
  def add(a: int, b: int) -> int:
19
19
  """Add two numbers"""
20
20
  return a + b
@@ -3,6 +3,7 @@ title: Anthropic
3
3
  sidebarTitle: Anthropic
4
4
  description: Call FastMCP servers from the Anthropic API
5
5
  icon: message-smile
6
+ tag: "New!"
6
7
  ---
7
8
 
8
9
  import { VersionBadge } from "/snippets/version-badge.mdx"
@@ -27,7 +28,7 @@ from fastmcp import FastMCP
27
28
 
28
29
  mcp = FastMCP(name="Dice Roller")
29
30
 
30
- @mcp.tool()
31
+ @mcp.tool
31
32
  def roll_dice(n_dice: int) -> list[int]:
32
33
  """Roll `n_dice` 6-sided dice and return the results."""
33
34
  return [random.randint(1, 6) for _ in range(n_dice)]
@@ -170,7 +171,7 @@ auth = BearerAuthProvider(
170
171
 
171
172
  mcp = FastMCP(name="Dice Roller", auth=auth)
172
173
 
173
- @mcp.tool()
174
+ @mcp.tool
174
175
  def roll_dice(n_dice: int) -> list[int]:
175
176
  """Roll `n_dice` 6-sided dice and return the results."""
176
177
  return [random.randint(1, 6) for _ in range(n_dice)]
@@ -31,7 +31,7 @@ from fastmcp import FastMCP
31
31
 
32
32
  mcp = FastMCP(name="Dice Roller")
33
33
 
34
- @mcp.tool()
34
+ @mcp.tool
35
35
  def roll_dice(n_dice: int) -> list[int]:
36
36
  """Roll `n_dice` 6-sided dice and return the results."""
37
37
  return [random.randint(1, 6) for _ in range(n_dice)]
@@ -12,7 +12,7 @@ FastMCP includes a `contrib` package that holds community-contributed modules. T
12
12
 
13
13
  Contrib modules provide additional features, integrations, or patterns that complement the core FastMCP library. They offer a way for the community to share useful extensions while keeping the core library focused and maintainable.
14
14
 
15
- The available modules can be viewed in the [contrib directory](https://github.com/jlowin/fastmcp/tree/main/src/contrib).
15
+ The available modules can be viewed in the [contrib directory](https://github.com/jlowin/fastmcp/tree/main/src/fastmcp/contrib).
16
16
 
17
17
  ## Usage
18
18
 
@@ -3,6 +3,7 @@ title: Gemini SDK
3
3
  sidebarTitle: Gemini SDK
4
4
  description: Call FastMCP servers from the Google Gemini SDK
5
5
  icon: message-smile
6
+ tag: "New!"
6
7
  ---
7
8
 
8
9
  import { VersionBadge } from "/snippets/version-badge.mdx"
@@ -31,7 +32,7 @@ from fastmcp import FastMCP
31
32
 
32
33
  mcp = FastMCP(name="Dice Roller")
33
34
 
34
- @mcp.tool()
35
+ @mcp.tool
35
36
  def roll_dice(n_dice: int) -> list[int]:
36
37
  """Roll `n_dice` 6-sided dice and return the results."""
37
38
  return [random.randint(1, 6) for _ in range(n_dice)]
@@ -66,7 +67,7 @@ mcp_client = Client("server.py")
66
67
  gemini_client = genai.Client()
67
68
 
68
69
  async def main():
69
- async with client:
70
+ async with mcp_client:
70
71
  response = await gemini_client.aio.models.generate_content(
71
72
  model="gemini-2.0-flash",
72
73
  contents="Roll 3 dice!",
@@ -3,6 +3,7 @@ title: OpenAI
3
3
  sidebarTitle: OpenAI
4
4
  description: Call FastMCP servers from the OpenAI API
5
5
  icon: message-smile
6
+ tag: "New!"
6
7
  ---
7
8
 
8
9
  import { VersionBadge } from "/snippets/version-badge.mdx"
@@ -32,7 +33,7 @@ from fastmcp import FastMCP
32
33
 
33
34
  mcp = FastMCP(name="Dice Roller")
34
35
 
35
- @mcp.tool()
36
+ @mcp.tool
36
37
  def roll_dice(n_dice: int) -> list[int]:
37
38
  """Roll `n_dice` 6-sided dice and return the results."""
38
39
  return [random.randint(1, 6) for _ in range(n_dice)]
@@ -165,7 +166,7 @@ auth = BearerAuthProvider(
165
166
 
166
167
  mcp = FastMCP(name="Dice Roller", auth=auth)
167
168
 
168
- @mcp.tool()
169
+ @mcp.tool
169
170
  def roll_dice(n_dice: int) -> list[int]:
170
171
  """Roll `n_dice` 6-sided dice and return the results."""
171
172
  return [random.randint(1, 6) for _ in range(n_dice)]
@@ -66,7 +66,7 @@ from fastmcp import FastMCP
66
66
 
67
67
  mcp = FastMCP("MyServer")
68
68
 
69
- @mcp.tool()
69
+ @mcp.tool
70
70
  def hello(name: str) -> str:
71
71
  return f"Hello, {name}!"
72
72
 
@@ -5,22 +5,47 @@ description: Properly use instance methods, class methods, and static methods wi
5
5
  icon: at
6
6
  ---
7
7
 
8
- FastMCP's decorator system is designed to work with functions, but you may see unexpected behavior if you try to decorate an instance or class method. This guide explains the correct approach for using methods with all FastMCP decorators (`@tool()`, `@resource()`, and `@prompt()`).
8
+ FastMCP's decorator system is designed to work with functions, but you may see unexpected behavior if you try to decorate an instance or class method. This guide explains the correct approach for using methods with all FastMCP decorators (`@tool`, `@resource`, and `.prompt`).
9
9
 
10
10
  ## Why Are Methods Hard?
11
11
 
12
- When you apply a FastMCP decorator like `@tool()`, `@resource()`, or `@prompt()` to a method, the decorator captures the function at decoration time. For instance methods and class methods, this poses a challenge because:
12
+ When you apply a FastMCP decorator like `@tool`, `@resource`, or `@prompt` to a method, the decorator captures the function at decoration time. For instance methods and class methods, this poses a challenge because:
13
13
 
14
14
  1. For instance methods: The decorator gets the unbound method before any instance exists
15
15
  2. For class methods: The decorator gets the function before it's bound to the class
16
16
 
17
17
  This means directly decorating these methods doesn't work as expected. In practice, the LLM would see parameters like `self` or `cls` that it cannot provide values for.
18
18
 
19
+ Additionally, **FastMCP decorators return objects (Tool, Resource, or Prompt instances) rather than the original function**. This means that when you decorate a method directly, the method becomes the returned object and is no longer callable by your code:
20
+
21
+ <Warning>
22
+ **Don't do this!**
23
+
24
+ The method will no longer be callable from Python, and the tool won't be callable by LLMs.
25
+
26
+ ```python
27
+
28
+ from fastmcp import FastMCP
29
+ mcp = FastMCP()
30
+
31
+ class MyClass:
32
+ @mcp.tool
33
+ def my_method(self, x: int) -> int:
34
+ return x * 2
35
+
36
+ obj = MyClass()
37
+ obj.my_method(5) # Fails - my_method is a Tool, not a function
38
+ ```
39
+ </Warning>
40
+
41
+ This is another important reason to register methods functionally after defining the class.
42
+
19
43
  ## Recommended Patterns
20
44
 
21
45
  ### Instance Methods
22
46
 
23
- **Don't do this** (it doesn't work properly):
47
+ <Warning>
48
+ **Don't do this!**
24
49
 
25
50
  ```python
26
51
  from fastmcp import FastMCP
@@ -28,17 +53,14 @@ from fastmcp import FastMCP
28
53
  mcp = FastMCP()
29
54
 
30
55
  class MyClass:
31
- @mcp.tool() # This won't work correctly
56
+ @mcp.tool # This won't work correctly
32
57
  def add(self, x, y):
33
58
  return x + y
34
-
35
- @mcp.resource("resource://{param}") # This won't work correctly
36
- def get_resource(self, param: str):
37
- return f"Resource data for {param}"
38
59
  ```
39
-
60
+ </Warning>
40
61
  When the decorator is applied this way, it captures the unbound method. When the LLM later tries to use this component, it will see `self` as a required parameter, but it won't know what to provide for it, causing errors or unexpected behavior.
41
62
 
63
+ <Check>
42
64
  **Do this instead**:
43
65
 
44
66
  ```python
@@ -49,21 +71,15 @@ mcp = FastMCP()
49
71
  class MyClass:
50
72
  def add(self, x, y):
51
73
  return x + y
52
-
53
- def get_resource(self, param: str):
54
- return f"Resource data for {param}"
55
74
 
56
- # Create an instance first, then add the bound methods
75
+ # Create an instance first, then register the bound methods
57
76
  obj = MyClass()
58
- mcp.add_tool(obj.add)
59
- mcp.add_resource_fn(obj.get_resource, uri="resource://{param}") # For resources or templates
60
-
61
- # Note: FastMCP provides add_resource() for adding Resource objects directly and
62
- # add_resource_fn() for adding functions that generate resources or templates
77
+ mcp.tool(obj.add)
63
78
 
64
79
  # Now you can call it without 'self' showing up as a parameter
65
- await mcp.call_tool('add', {'x': 1, 'y': 2}) # Returns 3
80
+ await mcp._mcp_call_tool('add', {'x': 1, 'y': 2}) # Returns 3
66
81
  ```
82
+ </Check>
67
83
 
68
84
  This approach works because:
69
85
  1. You first create an instance of the class (`obj`)
@@ -72,9 +88,10 @@ This approach works because:
72
88
 
73
89
  ### Class Methods
74
90
 
75
- Similar to instance methods, decorating class methods directly doesn't work properly:
91
+ The behavior of decorating class methods depends on the order of decorators:
76
92
 
77
- **Don't do this**:
93
+ <Warning>
94
+ **Don't do this** (decorator order matters):
78
95
 
79
96
  ```python
80
97
  from fastmcp import FastMCP
@@ -83,13 +100,21 @@ mcp = FastMCP()
83
100
 
84
101
  class MyClass:
85
102
  @classmethod
86
- @mcp.tool() # This won't work correctly
87
- def from_string(cls, s):
103
+ @mcp.tool # This won't work but won't raise an error
104
+ def from_string_v1(cls, s):
105
+ return cls(s)
106
+
107
+ @mcp.tool
108
+ @classmethod # This will raise a helpful ValueError
109
+ def from_string_v2(cls, s):
88
110
  return cls(s)
89
111
  ```
112
+ </Warning>
90
113
 
91
- The problem here is that the FastMCP decorator is applied before the `@classmethod` decorator (Python applies decorators bottom-to-top). So it captures the function before it's transformed into a class method, leading to incorrect behavior.
114
+ - If `@classmethod` comes first, then `@mcp.tool`: No error is raised, but it won't work correctly
115
+ - If `@mcp.tool` comes first, then `@classmethod`: FastMCP will detect this and raise a helpful `ValueError` with guidance
92
116
 
117
+ <Check>
93
118
  **Do this instead**:
94
119
 
95
120
  ```python
@@ -102,9 +127,10 @@ class MyClass:
102
127
  def from_string(cls, s):
103
128
  return cls(s)
104
129
 
105
- # Add the class method after the class is defined
106
- mcp.add_tool(MyClass.from_string)
130
+ # Register the class method after the class is defined
131
+ mcp.tool(MyClass.from_string)
107
132
  ```
133
+ </Check>
108
134
 
109
135
  This works because:
110
136
  1. The `@classmethod` decorator is applied properly during class definition
@@ -113,7 +139,10 @@ This works because:
113
139
 
114
140
  ### Static Methods
115
141
 
116
- Unlike instance and class methods, static methods work fine with FastMCP decorators:
142
+ Static methods "work" with FastMCP decorators, but this is not recommended because the FastMCP decorator will not return a callable method. Therefore, you should register static methods the same way as other methods.
143
+
144
+ <Warning>
145
+ **This is not recommended, though it will work.**
117
146
 
118
147
  ```python
119
148
  from fastmcp import FastMCP
@@ -121,23 +150,17 @@ from fastmcp import FastMCP
121
150
  mcp = FastMCP()
122
151
 
123
152
  class MyClass:
153
+ @mcp.tool
124
154
  @staticmethod
125
- @mcp.tool() # This works!
126
155
  def utility(x, y):
127
156
  return x + y
128
-
129
- @staticmethod
130
- @mcp.resource("resource://data") # This works too!
131
- def get_data():
132
- return "Static resource data"
133
157
  ```
158
+ </Warning>
134
159
 
135
- This approach works because:
136
- 1. The `@staticmethod` decorator is applied first (executed last), transforming the method into a regular function
137
- 2. When the FastMCP decorator is applied, it's capturing what is effectively just a regular function
138
- 3. A static method doesn't have any binding requirements - it doesn't receive a `self` or `cls` parameter
160
+ This works because `@staticmethod` converts the method to a regular function, which the FastMCP decorator can then properly process. However, this is not recommended because the FastMCP decorator will not return a callable staticmethod. Therefore, you should register static methods the same way as other methods.
139
161
 
140
- Alternatively, you can use the same pattern as the other methods:
162
+ <Check>
163
+ **Prefer this pattern:**
141
164
 
142
165
  ```python
143
166
  from fastmcp import FastMCP
@@ -150,10 +173,9 @@ class MyClass:
150
173
  return x + y
151
174
 
152
175
  # This also works
153
- mcp.add_tool(MyClass.utility)
176
+ mcp.tool(MyClass.utility)
154
177
  ```
155
-
156
- This works for the same reason - a static method is essentially just a function in a class namespace.
178
+ </Check>
157
179
 
158
180
  ## Additional Patterns
159
181
 
@@ -169,8 +191,8 @@ mcp = FastMCP()
169
191
  class ComponentProvider:
170
192
  def __init__(self, mcp_instance):
171
193
  # Register methods
172
- mcp_instance.add_tool(self.tool_method)
173
- mcp_instance.add_resource_fn(self.resource_method, uri="resource://data")
194
+ mcp_instance.tool(self.tool_method)
195
+ mcp_instance.resource("resource://data")(self.resource_method)
174
196
 
175
197
  def tool_method(self, x):
176
198
  return x * 2
@@ -191,11 +213,13 @@ The class automatically registers its methods during initialization, ensuring th
191
213
 
192
214
  ## Summary
193
215
 
194
- While FastMCP's decorator pattern works seamlessly with regular functions and static methods, for instance methods and class methods, you should add them after creating the instance or class. This ensures that the methods are properly bound before being registered.
216
+ The current behavior of FastMCP decorators with methods is:
217
+
218
+ - **Static methods**: Can be decorated directly and work perfectly with all FastMCP decorators
219
+ - **Class methods**: Cannot be decorated directly and will raise a helpful `ValueError` with guidance
220
+ - **Instance methods**: Should be registered after creating an instance using the decorator calls
221
+
222
+ For class and instance methods, you should register them after creating the instance or class to ensure proper method binding. This ensures that the methods are properly bound before being registered.
195
223
 
196
- These patterns apply to all FastMCP decorators and registration methods:
197
- - `@tool()` and `add_tool()`
198
- - `@resource()` and `add_resource_fn()`
199
- - `@prompt()` and `add_prompt()`
200
224
 
201
- Understanding these patterns allows you to effectively organize your components into classes while maintaining proper method binding, giving you the benefits of object-oriented design without sacrificing the simplicity of FastMCP's decorator system.
225
+ Understanding these patterns allows you to effectively organize your components into classes while maintaining proper method binding, giving you the benefits of object-oriented design without sacrificing the simplicity of FastMCP's decorator system.
@@ -25,7 +25,7 @@ from starlette.requests import Request
25
25
 
26
26
  mcp = FastMCP(name="HTTP Request Demo")
27
27
 
28
- @mcp.tool()
28
+ @mcp.tool
29
29
  async def user_agent_info() -> dict:
30
30
  """Return information about the user agent."""
31
31
  # Get the HTTP request
@@ -58,7 +58,7 @@ from fastmcp.server.dependencies import get_http_headers
58
58
 
59
59
  mcp = FastMCP(name="Headers Demo")
60
60
 
61
- @mcp.tool()
61
+ @mcp.tool
62
62
  async def safe_header_info() -> dict:
63
63
  """Safely get header information without raising errors."""
64
64
  # Get headers (returns empty dict if no request context)
@@ -22,7 +22,7 @@ from fastmcp import FastMCP, Client
22
22
  def mcp_server():
23
23
  server = FastMCP("TestServer")
24
24
 
25
- @server.tool()
25
+ @server.tool
26
26
  def greet(name: str) -> str:
27
27
  return f"Hello, {name}!"
28
28