1010from mcp .server .fastmcp .resources .base import Resource
1111from mcp .server .fastmcp .resources .templates import ResourceTemplate
1212from mcp .server .fastmcp .utilities .logging import get_logger
13- from mcp .types import Annotations , Icon
13+ from mcp .shared .exceptions import McpError
14+ from mcp .types import RESOURCE_NOT_FOUND , Annotations , ErrorData , Icon
1415
1516if TYPE_CHECKING :
1617 from mcp .server .fastmcp .server import Context
@@ -85,8 +86,12 @@ async def get_resource(
8586 self ,
8687 uri : AnyUrl | str ,
8788 context : Context [ServerSessionT , LifespanContextT , RequestT ] | None = None ,
88- ) -> Resource | None :
89- """Get resource by URI, checking concrete resources first, then templates."""
89+ ) -> Resource :
90+ """Get resource by URI, checking concrete resources first, then templates.
91+
92+ Raises:
93+ McpError: If the resource is not found (RESOURCE_NOT_FOUND error code).
94+ """
9095 uri_str = str (uri )
9196 logger .debug ("Getting resource" , extra = {"uri" : uri_str })
9297
@@ -102,7 +107,8 @@ async def get_resource(
102107 except Exception as e : # pragma: no cover
103108 raise ValueError (f"Error creating resource from template: { e } " )
104109
105- raise ValueError (f"Unknown resource: { uri } " )
110+ # Resource not found is a protocol error per MCP spec
111+ raise McpError (ErrorData (code = RESOURCE_NOT_FOUND , message = f"Unknown resource: { uri } " ))
106112
107113 def list_resources (self ) -> list [Resource ]:
108114 """List all registered resources."""
0 commit comments