Skip to content

Commit 6cdd97b

Browse files
Merge pull request #19 from modelcontextprotocol/justin/upgrade-spec
Upgrade to protocol version 2024-10-07
2 parents 59199d7 + 9eb239b commit 6cdd97b

File tree

7 files changed

+80
-23
lines changed

7 files changed

+80
-23
lines changed

mcp_python/client/session.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
from pydantic import AnyUrl
33

44
from mcp_python.shared.session import BaseSession
5-
from mcp_python.shared.version import SUPPORTED_PROTOCOL_VERSION
5+
from mcp_python.shared.version import SUPPORTED_PROTOCOL_VERSIONS
66
from mcp_python.types import (
7+
LATEST_PROTOCOL_VERSION,
78
CallToolResult,
89
ClientCapabilities,
910
ClientNotification,
@@ -49,7 +50,7 @@ async def initialize(self) -> InitializeResult:
4950
InitializeRequest(
5051
method="initialize",
5152
params=InitializeRequestParams(
52-
protocolVersion=SUPPORTED_PROTOCOL_VERSION,
53+
protocolVersion=LATEST_PROTOCOL_VERSION,
5354
capabilities=ClientCapabilities(
5455
sampling=None, experimental=None
5556
),
@@ -60,7 +61,7 @@ async def initialize(self) -> InitializeResult:
6061
InitializeResult,
6162
)
6263

63-
if result.protocolVersion != SUPPORTED_PROTOCOL_VERSION:
64+
if result.protocolVersion not in SUPPORTED_PROTOCOL_VERSIONS:
6465
raise RuntimeError(
6566
"Unsupported protocol version from the server: "
6667
f"{result.protocolVersion}"

mcp_python/server/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ def decorator(func: Callable[[], Awaitable[list[Resource]]]):
162162
async def handler(_: Any):
163163
resources = await func()
164164
return ServerResult(
165-
ListResourcesResult(resources=resources, resourceTemplates=None)
165+
ListResourcesResult(resources=resources)
166166
)
167167

168168
self.request_handlers[ListResourcesRequest] = handler

mcp_python/server/session.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
BaseSession,
1212
RequestResponder,
1313
)
14-
from mcp_python.shared.version import SUPPORTED_PROTOCOL_VERSION
1514
from mcp_python.types import (
15+
LATEST_PROTOCOL_VERSION,
1616
ClientNotification,
1717
ClientRequest,
1818
CreateMessageResult,
@@ -67,7 +67,7 @@ async def _received_request(
6767
await responder.respond(
6868
ServerResult(
6969
InitializeResult(
70-
protocolVersion=SUPPORTED_PROTOCOL_VERSION,
70+
protocolVersion=LATEST_PROTOCOL_VERSION,
7171
capabilities=self._init_options.capabilities,
7272
serverInfo=Implementation(
7373
name=self._init_options.server_name,

mcp_python/shared/version.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
SUPPORTED_PROTOCOL_VERSION = 1
1+
from mcp_python.types import LATEST_PROTOCOL_VERSION
2+
3+
SUPPORTED_PROTOCOL_VERSIONS = [1, LATEST_PROTOCOL_VERSION]

mcp_python/types.py

+59-11
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@
2121
not separate types in the schema.
2222
"""
2323

24+
LATEST_PROTOCOL_VERSION = "2024-10-07"
2425

2526
ProgressToken = str | int
27+
Cursor = str
2628

2729

2830
class RequestParams(BaseModel):
@@ -64,6 +66,14 @@ class Request(BaseModel, Generic[RequestParamsT, MethodT]):
6466
model_config = ConfigDict(extra="allow")
6567

6668

69+
class PaginatedRequest(Request[RequestParamsT, MethodT]):
70+
cursor: Cursor | None = None
71+
"""
72+
An opaque token representing the current pagination position.
73+
If provided, the server should return results starting after this cursor.
74+
"""
75+
76+
6777
class Notification(BaseModel, Generic[NotificationParamsT, MethodT]):
6878
"""Base class for JSON-RPC notifications."""
6979

@@ -83,6 +93,14 @@ class Result(BaseModel):
8393
"""
8494

8595

96+
class PaginatedResult(Result):
97+
nextCursor: Cursor | None = None
98+
"""
99+
An opaque token representing the pagination position after the last returned result.
100+
If present, there may be more results available.
101+
"""
102+
103+
86104
RequestId = str | int
87105

88106

@@ -115,6 +133,7 @@ class JSONRPCResponse(BaseModel):
115133
INVALID_REQUEST = -32600
116134
METHOD_NOT_FOUND = -32601
117135
INVALID_PARAMS = -32602
136+
INTERNAL_ERROR = -32603
118137

119138

120139
class ErrorData(BaseModel):
@@ -191,7 +210,7 @@ class ServerCapabilities(BaseModel):
191210
class InitializeRequestParams(RequestParams):
192211
"""Parameters for the initialize request."""
193212

194-
protocolVersion: Literal[1]
213+
protocolVersion: str | int
195214
"""The latest version of the Model Context Protocol that the client supports."""
196215
capabilities: ClientCapabilities
197216
clientInfo: Implementation
@@ -211,7 +230,7 @@ class InitializeRequest(Request):
211230
class InitializeResult(Result):
212231
"""After receiving an initialize request from the client, the server sends this."""
213232

214-
protocolVersion: Literal[1]
233+
protocolVersion: str | int
215234
"""The version of the Model Context Protocol that the server wants to use."""
216235
capabilities: ServerCapabilities
217236
serverInfo: Implementation
@@ -265,7 +284,7 @@ class ProgressNotification(Notification):
265284
params: ProgressNotificationParams
266285

267286

268-
class ListResourcesRequest(Request):
287+
class ListResourcesRequest(PaginatedRequest):
269288
"""Sent from the client to request a list of resources the server has."""
270289

271290
method: Literal["resources/list"]
@@ -277,6 +296,10 @@ class Resource(BaseModel):
277296

278297
uri: AnyUrl
279298
"""The URI of this resource."""
299+
name: str
300+
"""A human-readable name for this resource."""
301+
description: str | None = None
302+
"""A description of what this resource represents."""
280303
mimeType: str | None = None
281304
"""The MIME type of this resource, if known."""
282305
model_config = ConfigDict(extra="allow")
@@ -290,7 +313,7 @@ class ResourceTemplate(BaseModel):
290313
A URI template (according to RFC 6570) that can be used to construct resource
291314
URIs.
292315
"""
293-
name: str | None = None
316+
name: str
294317
"""A human-readable name for the type of resource this template refers to."""
295318
description: str | None = None
296319
"""A human-readable description of what this template is for."""
@@ -302,11 +325,23 @@ class ResourceTemplate(BaseModel):
302325
model_config = ConfigDict(extra="allow")
303326

304327

305-
class ListResourcesResult(Result):
328+
class ListResourcesResult(PaginatedResult):
306329
"""The server's response to a resources/list request from the client."""
307330

308-
resourceTemplates: list[ResourceTemplate] | None = None
309-
resources: list[Resource] | None = None
331+
resources: list[Resource]
332+
333+
334+
class ListResourceTemplatesRequest(PaginatedRequest):
335+
"""Sent from the client to request a list of resource templates the server has."""
336+
337+
method: Literal["resources/templates/list"]
338+
params: RequestParams | None = None
339+
340+
341+
class ListResourceTemplatesResult(PaginatedResult):
342+
"""The server's response to a resources/templates/list request from the client."""
343+
344+
resourceTemplates: list[ResourceTemplate]
310345

311346

312347
class ReadResourceRequestParams(RequestParams):
@@ -430,7 +465,7 @@ class ResourceUpdatedNotification(Notification):
430465
params: ResourceUpdatedNotificationParams
431466

432467

433-
class ListPromptsRequest(Request):
468+
class ListPromptsRequest(PaginatedRequest):
434469
"""Sent from the client to request a list of prompts and prompt templates."""
435470

436471
method: Literal["prompts/list"]
@@ -461,7 +496,7 @@ class Prompt(BaseModel):
461496
model_config = ConfigDict(extra="allow")
462497

463498

464-
class ListPromptsResult(Result):
499+
class ListPromptsResult(PaginatedResult):
465500
"""The server's response to a prompts/list request from the client."""
466501

467502
prompts: list[Prompt]
@@ -526,7 +561,17 @@ class GetPromptResult(Result):
526561
messages: list[SamplingMessage]
527562

528563

529-
class ListToolsRequest(Request):
564+
class PromptListChangedNotification(Notification):
565+
"""
566+
An optional notification from the server to the client, informing it that the list
567+
of prompts it offers has changed.
568+
"""
569+
570+
method: Literal["notifications/prompts/list_changed"]
571+
params: NotificationParams | None = None
572+
573+
574+
class ListToolsRequest(PaginatedRequest):
530575
"""Sent from the client to request a list of tools the server has."""
531576

532577
method: Literal["tools/list"]
@@ -545,7 +590,7 @@ class Tool(BaseModel):
545590
model_config = ConfigDict(extra="allow")
546591

547592

548-
class ListToolsResult(Result):
593+
class ListToolsResult(PaginatedResult):
549594
"""The server's response to a tools/list request from the client."""
550595

551596
tools: list[Tool]
@@ -742,6 +787,7 @@ class ClientRequest(
742787
| GetPromptRequest
743788
| ListPromptsRequest
744789
| ListResourcesRequest
790+
| ListResourceTemplatesRequest
745791
| ReadResourceRequest
746792
| SubscribeRequest
747793
| UnsubscribeRequest
@@ -771,6 +817,7 @@ class ServerNotification(
771817
| ResourceUpdatedNotification
772818
| ResourceListChangedNotification
773819
| ToolListChangedNotification
820+
| PromptListChangedNotification
774821
]
775822
):
776823
pass
@@ -784,6 +831,7 @@ class ServerResult(
784831
| GetPromptResult
785832
| ListPromptsResult
786833
| ListResourcesResult
834+
| ListResourceTemplatesResult
787835
| ReadResourceResult
788836
| CallToolResult
789837
| ListToolsResult

tests/client/test_session.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
from mcp_python.client.session import ClientSession
55
from mcp_python.types import (
6+
LATEST_PROTOCOL_VERSION,
67
ClientNotification,
78
ClientRequest,
89
Implementation,
@@ -41,7 +42,7 @@ async def mock_server():
4142

4243
result = ServerResult(
4344
InitializeResult(
44-
protocolVersion=1,
45+
protocolVersion=LATEST_PROTOCOL_VERSION,
4546
capabilities=ServerCapabilities(
4647
logging=None,
4748
resources=None,
@@ -88,7 +89,7 @@ async def listen_session():
8889

8990
# Assert the result
9091
assert isinstance(result, InitializeResult)
91-
assert result.protocolVersion == 1
92+
assert result.protocolVersion == LATEST_PROTOCOL_VERSION
9293
assert isinstance(result.capabilities, ServerCapabilities)
9394
assert result.serverInfo == Implementation(name="mock-server", version="0.1.0")
9495

tests/test_types.py

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
from mcp_python.types import ClientRequest, JSONRPCMessage, JSONRPCRequest
1+
from mcp_python.types import (
2+
LATEST_PROTOCOL_VERSION,
3+
ClientRequest,
4+
JSONRPCMessage,
5+
JSONRPCRequest,
6+
)
27

38

49
def test_jsonrpc_request():
@@ -7,7 +12,7 @@ def test_jsonrpc_request():
712
"id": 1,
813
"method": "initialize",
914
"params": {
10-
"protocolVersion": 1,
15+
"protocolVersion": LATEST_PROTOCOL_VERSION,
1116
"capabilities": {"batch": None, "sampling": None},
1217
"clientInfo": {"name": "mcp_python", "version": "0.1.0"},
1318
},
@@ -21,4 +26,4 @@ def test_jsonrpc_request():
2126
assert request.root.id == 1
2227
assert request.root.method == "initialize"
2328
assert request.root.params is not None
24-
assert request.root.params["protocolVersion"] == 1
29+
assert request.root.params["protocolVersion"] == LATEST_PROTOCOL_VERSION

0 commit comments

Comments
 (0)