Skip to content

Commit c022cfe

Browse files
test: reproduce #1574
Github-Issue: #1574
1 parent f2b89ec commit c022cfe

File tree

1 file changed

+85
-0
lines changed

1 file changed

+85
-0
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
"""Tests for issue #1574: Python SDK incorrectly validates Resource URIs.
2+
3+
The Python SDK uses Pydantic's AnyUrl for URI fields, which rejects relative paths
4+
like 'users/me' that are valid according to the MCP spec and accepted by the
5+
TypeScript SDK.
6+
7+
The spec defines uri fields as plain strings with no JSON Schema format validation.
8+
"""
9+
10+
from mcp import types
11+
12+
13+
class TestResourceUriValidation:
14+
"""Test that Resource URI fields accept all valid MCP URIs."""
15+
16+
def test_relative_path_uri(self):
17+
"""
18+
REPRODUCER: Relative paths like 'users/me' should be accepted.
19+
20+
Currently fails with:
21+
ValidationError: Input should be a valid URL, relative URL without a base
22+
"""
23+
# This should NOT raise - relative paths are valid per MCP spec
24+
resource = types.Resource(name="test", uri="users/me")
25+
assert str(resource.uri) == "users/me"
26+
27+
def test_custom_scheme_uri(self):
28+
"""Custom scheme URIs should be accepted."""
29+
resource = types.Resource(name="test", uri="custom://resource")
30+
assert str(resource.uri) == "custom://resource"
31+
32+
def test_file_url(self):
33+
"""File URLs should be accepted."""
34+
resource = types.Resource(name="test", uri="file:///path/to/file")
35+
assert str(resource.uri) == "file:///path/to/file"
36+
37+
def test_http_url(self):
38+
"""HTTP URLs should be accepted."""
39+
resource = types.Resource(name="test", uri="https://example.com/resource")
40+
assert str(resource.uri) == "https://example.com/resource"
41+
42+
43+
class TestReadResourceRequestParamsUri:
44+
"""Test that ReadResourceRequestParams.uri accepts all valid MCP URIs."""
45+
46+
def test_relative_path_uri(self):
47+
"""Relative paths should be accepted in read requests."""
48+
params = types.ReadResourceRequestParams(uri="users/me")
49+
assert str(params.uri) == "users/me"
50+
51+
52+
class TestResourceContentsUri:
53+
"""Test that ResourceContents.uri accepts all valid MCP URIs."""
54+
55+
def test_relative_path_uri(self):
56+
"""Relative paths should be accepted in resource contents."""
57+
contents = types.TextResourceContents(uri="users/me", text="content")
58+
assert str(contents.uri) == "users/me"
59+
60+
61+
class TestSubscribeRequestParamsUri:
62+
"""Test that SubscribeRequestParams.uri accepts all valid MCP URIs."""
63+
64+
def test_relative_path_uri(self):
65+
"""Relative paths should be accepted in subscribe requests."""
66+
params = types.SubscribeRequestParams(uri="users/me")
67+
assert str(params.uri) == "users/me"
68+
69+
70+
class TestUnsubscribeRequestParamsUri:
71+
"""Test that UnsubscribeRequestParams.uri accepts all valid MCP URIs."""
72+
73+
def test_relative_path_uri(self):
74+
"""Relative paths should be accepted in unsubscribe requests."""
75+
params = types.UnsubscribeRequestParams(uri="users/me")
76+
assert str(params.uri) == "users/me"
77+
78+
79+
class TestResourceUpdatedNotificationParamsUri:
80+
"""Test that ResourceUpdatedNotificationParams.uri accepts all valid MCP URIs."""
81+
82+
def test_relative_path_uri(self):
83+
"""Relative paths should be accepted in resource updated notifications."""
84+
params = types.ResourceUpdatedNotificationParams(uri="users/me")
85+
assert str(params.uri) == "users/me"

0 commit comments

Comments
 (0)