-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Description
Initial Checks
- I confirm that I'm using the latest version of MCP Python SDK
- I confirm that I searched for my issue in https://github.com/modelcontextprotocol/python-sdk/issues before opening this issue
Description
It appears to be unclear as to how an MCP server should respond to a read resource request if the resource is not found, however, FastMCP returns error code 0, which seems likely incorrect regardless.
In the Error Handling part of the protocol specification it states:
Resource not found:
-32002
However, the python SDK's FastMCP attempts to raise a ResourceError, except it appears that code would never get executed because a ValueError is raised in ResourceManager first.
The net result of this is that servers implemented using FastMCP return the following for resource-not-found:
{"jsonrpc":"2.0","id":7,"error":{"code":0,"message":"Unknown resource: https://example.com/does-not-exist"}}For the purposes of comparison, I compared this to the (presumably reference) typescript implementation, which raises an MCP error with InvalidParams: code -32602 - see here
-32602 is notably similar to -32002, but also seemingly incorrect (though in a different way ☹).
As things stand today, it is rather difficult to reliably write clients that behave predictably due to this. I understand this may be more of a protocol specification problem than a python-sdk problem, but error code 0 seems incorrect either way, so thought I'd report it.
Example Code
Basic server (anything will do):
from mcp.server.fastmcp import FastMCP
mcp = FastMCP('Pydantic AI MCP Server')
log_level = 'unset'
@mcp.resource('resource://user_name.txt', mime_type='text/plain')
async def user_name_resource() -> str:
return 'Alice'
if __name__ == '__main__':
mcp.run(transport='streamable-http')Then try to fetch any resource via whatever MCP client you like, eg (manual curl):
MCP_URL="http://localhost:8000/mcp"
SESSION_ID=""
# Step 1: Initialize and get session ID
echo "1. Initializing MCP server..."
INIT_RESPONSE=$(curl -s -D - -X POST "$MCP_URL" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": {},
"clientInfo": {
"name": "test-mcp-script",
"version": "1.0.0"
}
},
"id": 1
}')
# Extract session ID from headers
SESSION_ID=$(echo "$INIT_RESPONSE" | grep -i 'mcp-session-id:' | cut -d' ' -f2 | tr -d '\r')
# Try to read resource:
curl -s -X POST "$MCP_URL" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "Mcp-Session-Id: $SESSION_ID" \
-d '{
"jsonrpc": "2.0",
"method": "resources/read",
"params": {
"uri": "https://example.com/does-not-exist"
},
"id": 7
}'
# > event: message
# > data: {"jsonrpc":"2.0","id":7,"error":{"code":0,"message":"Unknown resource: https://example.com/does-not-exist"}}Python & MCP Python SDK
`main`