fastmcp 2.8.0__py3-none-any.whl → 2.8.1__py3-none-any.whl

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.
fastmcp/__init__.py CHANGED
@@ -1,5 +1,6 @@
1
1
  """FastMCP - An ergonomic MCP interface."""
2
2
 
3
+ import warnings
3
4
  from importlib.metadata import version
4
5
  from fastmcp.settings import Settings
5
6
 
@@ -10,15 +11,40 @@ from fastmcp.server.context import Context
10
11
  import fastmcp.server
11
12
 
12
13
  from fastmcp.client import Client
13
- from fastmcp.utilities.types import Image
14
14
  from . import client
15
15
 
16
16
  __version__ = version("fastmcp")
17
+
18
+
19
+ # ensure deprecation warnings are displayed by default
20
+ if settings.deprecation_warnings:
21
+ warnings.simplefilter("default", DeprecationWarning)
22
+
23
+
24
+ def __getattr__(name: str):
25
+ """
26
+ Used to deprecate the module-level Image class; can be removed once it is no longer imported to root.
27
+ """
28
+ if name == "Image":
29
+ # Deprecated in 2.8.1
30
+ if settings.deprecation_warnings:
31
+ warnings.warn(
32
+ "The top-level `fastmcp.Image` import is deprecated "
33
+ "and will be removed in a future version. "
34
+ "Please use `fastmcp.utilities.types.Image` instead.",
35
+ DeprecationWarning,
36
+ stacklevel=2,
37
+ )
38
+ from fastmcp.utilities.types import Image
39
+
40
+ return Image
41
+ raise AttributeError(f"module '{__name__}' has no attribute '{name}'")
42
+
43
+
17
44
  __all__ = [
18
45
  "FastMCP",
19
46
  "Context",
20
47
  "client",
21
48
  "Client",
22
49
  "settings",
23
- "Image",
24
50
  ]
fastmcp/client/client.py CHANGED
@@ -29,6 +29,7 @@ from fastmcp.exceptions import ToolError
29
29
  from fastmcp.server import FastMCP
30
30
  from fastmcp.utilities.exceptions import get_catch_handlers
31
31
  from fastmcp.utilities.mcp_config import MCPConfig
32
+ from fastmcp.utilities.types import MCPContent
32
33
 
33
34
  from .transports import (
34
35
  ClientTransportT,
@@ -658,9 +659,7 @@ class Client(Generic[ClientTransportT]):
658
659
  arguments: dict[str, Any] | None = None,
659
660
  timeout: datetime.timedelta | float | int | None = None,
660
661
  progress_handler: ProgressHandler | None = None,
661
- ) -> list[
662
- mcp.types.TextContent | mcp.types.ImageContent | mcp.types.EmbeddedResource
663
- ]:
662
+ ) -> list[MCPContent]:
664
663
  """Call a tool on the server.
665
664
 
666
665
  Unlike call_tool_mcp, this method raises a ToolError if the tool call results in an error.
@@ -672,7 +671,7 @@ class Client(Generic[ClientTransportT]):
672
671
  progress_handler (ProgressHandler | None, optional): The progress handler to use for the tool call. Defaults to None.
673
672
 
674
673
  Returns:
675
- list[mcp.types.TextContent | mcp.types.ImageContent | mcp.types.EmbeddedResource]:
674
+ list[mcp.types.TextContent | mcp.types.ImageContent | mcp.types.AudioContent | mcp.types.EmbeddedResource]:
676
675
  The content returned by the tool.
677
676
 
678
677
  Raises:
@@ -9,13 +9,7 @@ from mcp.shared.context import LifespanContextT, RequestContext
9
9
  from mcp.types import CreateMessageRequestParams as SamplingParams
10
10
  from mcp.types import SamplingMessage
11
11
 
12
- __all__ = ["SamplingMessage", "SamplingParams", "MessageResult", "SamplingHandler"]
13
-
14
-
15
- class MessageResult(CreateMessageResult):
16
- role: mcp.types.Role = "assistant"
17
- content: mcp.types.TextContent | mcp.types.ImageContent
18
- model: str = "client-model"
12
+ __all__ = ["SamplingMessage", "SamplingParams", "SamplingHandler"]
19
13
 
20
14
 
21
15
  SamplingHandler: TypeAlias = Callable[
@@ -39,8 +33,10 @@ def create_sampling_callback(sampling_handler: SamplingHandler) -> SamplingFnT:
39
33
  result = await result
40
34
 
41
35
  if isinstance(result, str):
42
- result = MessageResult(
43
- content=mcp.types.TextContent(type="text", text=result)
36
+ result = CreateMessageResult(
37
+ role="assistant",
38
+ model="fastmcp-client",
39
+ content=mcp.types.TextContent(type="text", text=result),
44
40
  )
45
41
  return result
46
42
  except Exception as e:
@@ -20,6 +20,7 @@ from mcp.shared.memory import create_client_server_memory_streams
20
20
  from pydantic import AnyUrl
21
21
  from typing_extensions import Unpack
22
22
 
23
+ import fastmcp
23
24
  from fastmcp.client.auth.bearer import BearerAuth
24
25
  from fastmcp.client.auth.oauth import OAuth
25
26
  from fastmcp.server.dependencies import get_http_headers
@@ -109,11 +110,12 @@ class WSTransport(ClientTransport):
109
110
 
110
111
  def __init__(self, url: str | AnyUrl):
111
112
  # we never really used this transport, so it can be removed at any time
112
- warnings.warn(
113
- "WSTransport is a deprecated MCP transport and will be removed in a future version. Use StreamableHttpTransport instead.",
114
- DeprecationWarning,
115
- stacklevel=2,
116
- )
113
+ if fastmcp.settings.deprecation_warnings:
114
+ warnings.warn(
115
+ "WSTransport is a deprecated MCP transport and will be removed in a future version. Use StreamableHttpTransport instead.",
116
+ DeprecationWarning,
117
+ stacklevel=2,
118
+ )
117
119
  if isinstance(url, AnyUrl):
118
120
  url = str(url)
119
121
  if not isinstance(url, str) or not url.startswith("ws"):
fastmcp/prompts/prompt.py CHANGED
@@ -8,9 +8,9 @@ from collections.abc import Awaitable, Callable, Sequence
8
8
  from typing import TYPE_CHECKING, Any
9
9
 
10
10
  import pydantic_core
11
- from mcp.types import EmbeddedResource, ImageContent, PromptMessage, Role, TextContent
12
11
  from mcp.types import Prompt as MCPPrompt
13
12
  from mcp.types import PromptArgument as MCPPromptArgument
13
+ from mcp.types import PromptMessage, Role, TextContent
14
14
  from pydantic import Field, TypeAdapter, validate_call
15
15
 
16
16
  from fastmcp.exceptions import PromptError
@@ -20,6 +20,7 @@ from fastmcp.utilities.json_schema import compress_schema
20
20
  from fastmcp.utilities.logging import get_logger
21
21
  from fastmcp.utilities.types import (
22
22
  FastMCPBaseModel,
23
+ MCPContent,
23
24
  find_kwarg_by_type,
24
25
  get_cached_typeadapter,
25
26
  )
@@ -27,13 +28,12 @@ from fastmcp.utilities.types import (
27
28
  if TYPE_CHECKING:
28
29
  pass
29
30
 
30
- CONTENT_TYPES = TextContent | ImageContent | EmbeddedResource
31
31
 
32
32
  logger = get_logger(__name__)
33
33
 
34
34
 
35
35
  def Message(
36
- content: str | CONTENT_TYPES, role: Role | None = None, **kwargs: Any
36
+ content: str | MCPContent, role: Role | None = None, **kwargs: Any
37
37
  ) -> PromptMessage:
38
38
  """A user-friendly constructor for PromptMessage."""
39
39
  if isinstance(content, str):
@@ -60,11 +60,12 @@ class PromptManager:
60
60
  ) -> FunctionPrompt:
61
61
  """Create a prompt from a function."""
62
62
  # deprecated in 2.7.0
63
- warnings.warn(
64
- "PromptManager.add_prompt_from_fn() is deprecated. Use Prompt.from_function() and call add_prompt() instead.",
65
- DeprecationWarning,
66
- stacklevel=2,
67
- )
63
+ if settings.deprecation_warnings:
64
+ warnings.warn(
65
+ "PromptManager.add_prompt_from_fn() is deprecated. Use Prompt.from_function() and call add_prompt() instead.",
66
+ DeprecationWarning,
67
+ stacklevel=2,
68
+ )
68
69
  prompt = FunctionPrompt.from_function(
69
70
  fn, name=name, description=description, tags=tags
70
71
  )
@@ -123,11 +123,12 @@ class ResourceManager:
123
123
  returns the existing resource.
124
124
  """
125
125
  # deprecated in 2.7.0
126
- warnings.warn(
127
- "add_resource_from_fn is deprecated. Use Resource.from_function() and call add_resource() instead.",
128
- DeprecationWarning,
129
- stacklevel=2,
130
- )
126
+ if settings.deprecation_warnings:
127
+ warnings.warn(
128
+ "add_resource_from_fn is deprecated. Use Resource.from_function() and call add_resource() instead.",
129
+ DeprecationWarning,
130
+ stacklevel=2,
131
+ )
131
132
  resource = Resource.from_function(
132
133
  fn=fn,
133
134
  uri=uri,
@@ -180,11 +181,12 @@ class ResourceManager:
180
181
  ) -> ResourceTemplate:
181
182
  """Create a template from a function."""
182
183
  # deprecated in 2.7.0
183
- warnings.warn(
184
- "add_template_from_fn is deprecated. Use ResourceTemplate.from_function() and call add_template() instead.",
185
- DeprecationWarning,
186
- stacklevel=2,
187
- )
184
+ if settings.deprecation_warnings:
185
+ warnings.warn(
186
+ "add_template_from_fn is deprecated. Use ResourceTemplate.from_function() and call add_template() instead.",
187
+ DeprecationWarning,
188
+ stacklevel=2,
189
+ )
188
190
  template = ResourceTemplate.from_function(
189
191
  fn,
190
192
  uri_template=uri_template,
@@ -184,7 +184,7 @@ class InMemoryOAuthProvider(OAuthProvider):
184
184
 
185
185
  return OAuthToken(
186
186
  access_token=access_token_value,
187
- token_type="bearer",
187
+ token_type="Bearer",
188
188
  expires_in=DEFAULT_ACCESS_TOKEN_EXPIRY_SECONDS,
189
189
  refresh_token=refresh_token_value,
190
190
  scope=" ".join(authorization_code.scopes),
@@ -254,7 +254,7 @@ class InMemoryOAuthProvider(OAuthProvider):
254
254
 
255
255
  return OAuthToken(
256
256
  access_token=new_access_token_value,
257
- token_type="bearer",
257
+ token_type="Bearer",
258
258
  expires_in=DEFAULT_ACCESS_TOKEN_EXPIRY_SECONDS,
259
259
  refresh_token=new_refresh_token_value,
260
260
  scope=" ".join(scopes),
fastmcp/server/context.py CHANGED
@@ -11,7 +11,6 @@ from mcp.server.lowlevel.helper_types import ReadResourceContents
11
11
  from mcp.shared.context import RequestContext
12
12
  from mcp.types import (
13
13
  CreateMessageResult,
14
- ImageContent,
15
14
  ModelHint,
16
15
  ModelPreferences,
17
16
  Root,
@@ -22,8 +21,10 @@ from pydantic.networks import AnyUrl
22
21
  from starlette.requests import Request
23
22
 
24
23
  import fastmcp.server.dependencies
24
+ from fastmcp import settings
25
25
  from fastmcp.server.server import FastMCP
26
26
  from fastmcp.utilities.logging import get_logger
27
+ from fastmcp.utilities.types import MCPContent
27
28
 
28
29
  logger = get_logger(__name__)
29
30
 
@@ -203,7 +204,7 @@ class Context:
203
204
  temperature: float | None = None,
204
205
  max_tokens: int | None = None,
205
206
  model_preferences: ModelPreferences | str | list[str] | None = None,
206
- ) -> TextContent | ImageContent:
207
+ ) -> MCPContent:
207
208
  """
208
209
  Send a sampling request to the client and await the response.
209
210
 
@@ -242,14 +243,15 @@ class Context:
242
243
  def get_http_request(self) -> Request:
243
244
  """Get the active starlette request."""
244
245
 
245
- # Deprecation warning, added in FastMCP 2.2.11
246
- warnings.warn(
247
- "Context.get_http_request() is deprecated and will be removed in a future version. "
248
- "Use get_http_request() from fastmcp.server.dependencies instead. "
249
- "See https://gofastmcp.com/patterns/http-requests for more details.",
250
- DeprecationWarning,
251
- stacklevel=2,
252
- )
246
+ # Deprecated in 2.2.11
247
+ if settings.deprecation_warnings:
248
+ warnings.warn(
249
+ "Context.get_http_request() is deprecated and will be removed in a future version. "
250
+ "Use get_http_request() from fastmcp.server.dependencies instead. "
251
+ "See https://gofastmcp.com/patterns/http-requests for more details.",
252
+ DeprecationWarning,
253
+ stacklevel=2,
254
+ )
253
255
 
254
256
  return fastmcp.server.dependencies.get_http_request()
255
257
 
fastmcp/server/openapi.py CHANGED
@@ -13,9 +13,10 @@ from re import Pattern
13
13
  from typing import TYPE_CHECKING, Any, Literal
14
14
 
15
15
  import httpx
16
- from mcp.types import EmbeddedResource, ImageContent, TextContent, ToolAnnotations
16
+ from mcp.types import ToolAnnotations
17
17
  from pydantic.networks import AnyUrl
18
18
 
19
+ import fastmcp
19
20
  from fastmcp.exceptions import ToolError
20
21
  from fastmcp.resources import Resource, ResourceTemplate
21
22
  from fastmcp.server.dependencies import get_http_headers
@@ -28,6 +29,7 @@ from fastmcp.utilities.openapi import (
28
29
  _combine_schemas,
29
30
  format_description_with_responses,
30
31
  )
32
+ from fastmcp.utilities.types import MCPContent
31
33
 
32
34
  if TYPE_CHECKING:
33
35
  from fastmcp.server import Context
@@ -129,27 +131,30 @@ class RouteMap:
129
131
  """Validate and process the route map after initialization."""
130
132
  # Handle backward compatibility for route_type, deprecated in 2.5.0
131
133
  if self.mcp_type is None and self.route_type is not None:
132
- warnings.warn(
133
- "The 'route_type' parameter is deprecated and will be removed in a future version. "
134
- "Use 'mcp_type' instead with the appropriate MCPType value.",
135
- DeprecationWarning,
136
- stacklevel=2,
137
- )
138
- if isinstance(self.route_type, RouteType):
134
+ if fastmcp.settings.deprecation_warnings:
139
135
  warnings.warn(
140
- "The RouteType class is deprecated and will be removed in a future version. "
141
- "Use MCPType instead.",
136
+ "The 'route_type' parameter is deprecated and will be removed in a future version. "
137
+ "Use 'mcp_type' instead with the appropriate MCPType value.",
142
138
  DeprecationWarning,
143
139
  stacklevel=2,
144
140
  )
141
+ if isinstance(self.route_type, RouteType):
142
+ if fastmcp.settings.deprecation_warnings:
143
+ warnings.warn(
144
+ "The RouteType class is deprecated and will be removed in a future version. "
145
+ "Use MCPType instead.",
146
+ DeprecationWarning,
147
+ stacklevel=2,
148
+ )
145
149
  # Check for the deprecated IGNORE value
146
150
  if self.route_type == RouteType.IGNORE:
147
- warnings.warn(
148
- "RouteType.IGNORE is deprecated and will be removed in a future version. "
149
- "Use MCPType.EXCLUDE instead.",
150
- DeprecationWarning,
151
- stacklevel=2,
152
- )
151
+ if fastmcp.settings.deprecation_warnings:
152
+ warnings.warn(
153
+ "RouteType.IGNORE is deprecated and will be removed in a future version. "
154
+ "Use MCPType.EXCLUDE instead.",
155
+ DeprecationWarning,
156
+ stacklevel=2,
157
+ )
153
158
 
154
159
  # Convert from RouteType to MCPType if needed
155
160
  if isinstance(self.route_type, RouteType):
@@ -250,9 +255,7 @@ class OpenAPITool(Tool):
250
255
  """Custom representation to prevent recursion errors when printing."""
251
256
  return f"OpenAPITool(name={self.name!r}, method={self._route.method}, path={self._route.path})"
252
257
 
253
- async def run(
254
- self, arguments: dict[str, Any]
255
- ) -> list[TextContent | ImageContent | EmbeddedResource]:
258
+ async def run(self, arguments: dict[str, Any]) -> list[MCPContent]:
256
259
  """Execute the HTTP request based on the route configuration."""
257
260
 
258
261
  # Prepare URL
fastmcp/server/proxy.py CHANGED
@@ -9,10 +9,7 @@ from mcp.shared.exceptions import McpError
9
9
  from mcp.types import (
10
10
  METHOD_NOT_FOUND,
11
11
  BlobResourceContents,
12
- EmbeddedResource,
13
12
  GetPromptResult,
14
- ImageContent,
15
- TextContent,
16
13
  TextResourceContents,
17
14
  )
18
15
  from pydantic.networks import AnyUrl
@@ -25,6 +22,7 @@ from fastmcp.server.context import Context
25
22
  from fastmcp.server.server import FastMCP
26
23
  from fastmcp.tools.tool import Tool
27
24
  from fastmcp.utilities.logging import get_logger
25
+ from fastmcp.utilities.types import MCPContent
28
26
 
29
27
  if TYPE_CHECKING:
30
28
  from fastmcp.server import Context
@@ -50,7 +48,7 @@ class ProxyTool(Tool):
50
48
  self,
51
49
  arguments: dict[str, Any],
52
50
  context: Context | None = None,
53
- ) -> list[TextContent | ImageContent | EmbeddedResource]:
51
+ ) -> list[MCPContent]:
54
52
  # the client context manager will swallow any exceptions inside a TaskGroup
55
53
  # so we return the raw result and raise an exception ourselves
56
54
  async with self._client:
@@ -254,9 +252,7 @@ class FastMCPProxy(FastMCP):
254
252
 
255
253
  return prompts
256
254
 
257
- async def _call_tool(
258
- self, key: str, arguments: dict[str, Any]
259
- ) -> list[TextContent | ImageContent | EmbeddedResource]:
255
+ async def _call_tool(self, key: str, arguments: dict[str, Any]) -> list[MCPContent]:
260
256
  try:
261
257
  result = await super()._call_tool(key, arguments)
262
258
  return result