77from asyncio import Lock
88from collections .abc import AsyncIterator , Awaitable , Callable , Sequence
99from contextlib import AbstractAsyncContextManager , AsyncExitStack , asynccontextmanager
10- from dataclasses import field , replace
10+ from dataclasses import dataclass , field , replace
1111from datetime import timedelta
1212from pathlib import Path
1313from typing import Annotated , Any , overload
5151 'MCPServerStreamableHTTP' ,
5252 'load_mcp_servers' ,
5353 'MCPError' ,
54+ 'Resource' ,
55+ 'ResourceTemplate' ,
56+ 'ServerCapabilities' ,
5457)
5558
5659
@@ -96,6 +99,88 @@ def __str__(self) -> str:
9699 return f'{ self .message } (code: { self .code } )'
97100
98101
102+ @dataclass (repr = False , kw_only = True )
103+ class ResourceAnnotations :
104+ """Additional properties describing MCP entities."""
105+
106+ audience : list [mcp_types .Role ] | None = None
107+ """Intended audience for this entity."""
108+
109+ priority : Annotated [float , Field (ge = 0.0 , le = 1.0 )] | None = None
110+ """Priority level for this entity, ranging from 0.0 to 1.0."""
111+
112+ __repr__ = _utils .dataclasses_no_defaults_repr
113+
114+
115+ @dataclass (repr = False , kw_only = True )
116+ class BaseResource (ABC ):
117+ """Base class for MCP resources."""
118+
119+ name : str
120+ """The programmatic name of the resource."""
121+
122+ title : str | None = None
123+ """Human-readable title for UI contexts."""
124+
125+ description : str | None = None
126+ """A description of what this resource represents."""
127+
128+ mime_type : str | None = None
129+ """The MIME type of the resource, if known."""
130+
131+ annotations : ResourceAnnotations | None = None
132+ """Optional annotations for the resource."""
133+
134+ metadata : dict [str , Any ] | None = None
135+ """Optional metadata for the resource."""
136+
137+ __repr__ = _utils .dataclasses_no_defaults_repr
138+
139+
140+ @dataclass (repr = False , kw_only = True )
141+ class Resource (BaseResource ):
142+ """A resource that can be read from an MCP server."""
143+
144+ uri : str
145+ """The URI of the resource."""
146+
147+ size : int | None = None
148+ """The size of the raw resource content in bytes (before base64 encoding), if known."""
149+
150+
151+ @dataclass (repr = False , kw_only = True )
152+ class ResourceTemplate (BaseResource ):
153+ """A template for parameterized resources on an MCP server."""
154+
155+ uri_template : str
156+ """URI template (RFC 6570) for constructing resource URIs."""
157+
158+
159+ @dataclass (repr = False , kw_only = True )
160+ class ServerCapabilities :
161+ """Capabilities that an MCP server supports."""
162+
163+ experimental : list [str ] | None = None
164+ """Experimental, non-standard capabilities that the server supports."""
165+
166+ logging : bool = False
167+ """Whether the server supports sending log messages to the client."""
168+
169+ prompts : bool = False
170+ """Whether the server offers any prompt templates."""
171+
172+ resources : bool = False
173+ """Whether the server offers any resources to read."""
174+
175+ tools : bool = False
176+ """Whether the server offers any tools to call."""
177+
178+ completions : bool = False
179+ """Whether the server offers autocompletion suggestions for prompts and resources."""
180+
181+ __repr__ = _utils .dataclasses_no_defaults_repr
182+
183+
99184TOOL_SCHEMA_VALIDATOR = pydantic_core .SchemaValidator (
100185 schema = pydantic_core .core_schema .dict_schema (
101186 pydantic_core .core_schema .str_schema (), pydantic_core .core_schema .any_schema ()
@@ -164,7 +249,7 @@ class MCPServer(AbstractToolset[Any], ABC):
164249 _read_stream : MemoryObjectReceiveStream [SessionMessage | Exception ]
165250 _write_stream : MemoryObjectSendStream [SessionMessage ]
166251 _server_info : mcp_types .Implementation
167- _server_capabilities : _mcp . ServerCapabilities
252+ _server_capabilities : ServerCapabilities
168253
169254 def __init__ (
170255 self ,
@@ -244,7 +329,7 @@ def server_info(self) -> mcp_types.Implementation:
244329 return self ._server_info
245330
246331 @property
247- def capabilities (self ) -> _mcp . ServerCapabilities :
332+ def capabilities (self ) -> ServerCapabilities :
248333 """Access the capabilities advertised by the MCP server during initialization."""
249334 if getattr (self , '_server_capabilities' , None ) is None :
250335 raise AttributeError (
@@ -364,7 +449,7 @@ def tool_for_tool_def(self, tool_def: ToolDefinition) -> ToolsetTool[Any]:
364449 args_validator = TOOL_SCHEMA_VALIDATOR ,
365450 )
366451
367- async def list_resources (self ) -> list [_mcp . Resource ]:
452+ async def list_resources (self ) -> list [Resource ]:
368453 """Retrieve resources that are currently present on the server.
369454
370455 Note:
@@ -383,7 +468,7 @@ async def list_resources(self) -> list[_mcp.Resource]:
383468 raise MCPError .from_mcp_sdk_error (e ) from e
384469 return [_mcp .map_from_mcp_resource (r ) for r in result .resources ]
385470
386- async def list_resource_templates (self ) -> list [_mcp . ResourceTemplate ]:
471+ async def list_resource_templates (self ) -> list [ResourceTemplate ]:
387472 """Retrieve resource templates that are currently present on the server.
388473
389474 Raises:
@@ -405,11 +490,11 @@ async def read_resource(
405490
406491 @overload
407492 async def read_resource (
408- self , uri : _mcp . Resource
493+ self , uri : Resource
409494 ) -> str | messages .BinaryContent | list [str | messages .BinaryContent ] | None : ...
410495
411496 async def read_resource (
412- self , uri : str | _mcp . Resource
497+ self , uri : str | Resource
413498 ) -> str | messages .BinaryContent | list [str | messages .BinaryContent ] | None :
414499 """Read the contents of a specific resource by URI.
415500
0 commit comments