Skip to content

Commit 31a38b5

Browse files
authored
fix: correct Context type parameters across examples and tests (#2256)
1 parent 51c53f2 commit 31a38b5

File tree

13 files changed

+59
-75
lines changed

13 files changed

+59
-75
lines changed

README.v2.md

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -346,13 +346,12 @@ Tools can optionally receive a Context object by including a parameter with the
346346
<!-- snippet-source examples/snippets/servers/tool_progress.py -->
347347
```python
348348
from mcp.server.mcpserver import Context, MCPServer
349-
from mcp.server.session import ServerSession
350349

351350
mcp = MCPServer(name="Progress Example")
352351

353352

354353
@mcp.tool()
355-
async def long_running_task(task_name: str, ctx: Context[ServerSession, None], steps: int = 5) -> str:
354+
async def long_running_task(task_name: str, ctx: Context, steps: int = 5) -> str:
356355
"""Execute a task with progress updates."""
357356
await ctx.info(f"Starting: {task_name}")
358357

@@ -694,13 +693,12 @@ The Context object provides the following capabilities:
694693
<!-- snippet-source examples/snippets/servers/tool_progress.py -->
695694
```python
696695
from mcp.server.mcpserver import Context, MCPServer
697-
from mcp.server.session import ServerSession
698696

699697
mcp = MCPServer(name="Progress Example")
700698

701699

702700
@mcp.tool()
703-
async def long_running_task(task_name: str, ctx: Context[ServerSession, None], steps: int = 5) -> str:
701+
async def long_running_task(task_name: str, ctx: Context, steps: int = 5) -> str:
704702
"""Execute a task with progress updates."""
705703
await ctx.info(f"Starting: {task_name}")
706704

@@ -826,7 +824,6 @@ import uuid
826824
from pydantic import BaseModel, Field
827825

828826
from mcp.server.mcpserver import Context, MCPServer
829-
from mcp.server.session import ServerSession
830827
from mcp.shared.exceptions import UrlElicitationRequiredError
831828
from mcp.types import ElicitRequestURLParams
832829

@@ -844,7 +841,7 @@ class BookingPreferences(BaseModel):
844841

845842

846843
@mcp.tool()
847-
async def book_table(date: str, time: str, party_size: int, ctx: Context[ServerSession, None]) -> str:
844+
async def book_table(date: str, time: str, party_size: int, ctx: Context) -> str:
848845
"""Book a table with date availability check.
849846
850847
This demonstrates form mode elicitation for collecting non-sensitive user input.
@@ -868,7 +865,7 @@ async def book_table(date: str, time: str, party_size: int, ctx: Context[ServerS
868865

869866

870867
@mcp.tool()
871-
async def secure_payment(amount: float, ctx: Context[ServerSession, None]) -> str:
868+
async def secure_payment(amount: float, ctx: Context) -> str:
872869
"""Process a secure payment requiring URL confirmation.
873870
874871
This demonstrates URL mode elicitation using ctx.elicit_url() for
@@ -892,7 +889,7 @@ async def secure_payment(amount: float, ctx: Context[ServerSession, None]) -> st
892889

893890

894891
@mcp.tool()
895-
async def connect_service(service_name: str, ctx: Context[ServerSession, None]) -> str:
892+
async def connect_service(service_name: str, ctx: Context) -> str:
896893
"""Connect to a third-party service requiring OAuth authorization.
897894
898895
This demonstrates the "throw error" pattern using UrlElicitationRequiredError.
@@ -933,14 +930,13 @@ Tools can interact with LLMs through sampling (generating text):
933930
<!-- snippet-source examples/snippets/servers/sampling.py -->
934931
```python
935932
from mcp.server.mcpserver import Context, MCPServer
936-
from mcp.server.session import ServerSession
937933
from mcp.types import SamplingMessage, TextContent
938934

939935
mcp = MCPServer(name="Sampling Example")
940936

941937

942938
@mcp.tool()
943-
async def generate_poem(topic: str, ctx: Context[ServerSession, None]) -> str:
939+
async def generate_poem(topic: str, ctx: Context) -> str:
944940
"""Generate a poem using LLM sampling."""
945941
prompt = f"Write a short poem about {topic}"
946942

@@ -970,13 +966,12 @@ Tools can send logs and notifications through the context:
970966
<!-- snippet-source examples/snippets/servers/notifications.py -->
971967
```python
972968
from mcp.server.mcpserver import Context, MCPServer
973-
from mcp.server.session import ServerSession
974969

975970
mcp = MCPServer(name="Notifications Example")
976971

977972

978973
@mcp.tool()
979-
async def process_data(data: str, ctx: Context[ServerSession, None]) -> str:
974+
async def process_data(data: str, ctx: Context) -> str:
980975
"""Process data with logging."""
981976
# Different log levels
982977
await ctx.debug(f"Debug: Processing '{data}'")

examples/servers/everything-server/mcp_everything_server/server.py

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
from mcp.server import ServerRequestContext
1414
from mcp.server.mcpserver import Context, MCPServer
1515
from mcp.server.mcpserver.prompts.base import UserMessage
16-
from mcp.server.session import ServerSession
1716
from mcp.server.streamable_http import EventCallback, EventMessage, EventStore
1817
from mcp.types import (
1918
AudioContent,
@@ -142,7 +141,7 @@ def test_multiple_content_types() -> list[TextContent | ImageContent | EmbeddedR
142141

143142

144143
@mcp.tool()
145-
async def test_tool_with_logging(ctx: Context[ServerSession, None]) -> str:
144+
async def test_tool_with_logging(ctx: Context) -> str:
146145
"""Tests tool that emits log messages during execution"""
147146
await ctx.info("Tool execution started")
148147
await asyncio.sleep(0.05)
@@ -155,7 +154,7 @@ async def test_tool_with_logging(ctx: Context[ServerSession, None]) -> str:
155154

156155

157156
@mcp.tool()
158-
async def test_tool_with_progress(ctx: Context[ServerSession, None]) -> str:
157+
async def test_tool_with_progress(ctx: Context) -> str:
159158
"""Tests tool that reports progress notifications"""
160159
await ctx.report_progress(progress=0, total=100, message="Completed step 0 of 100")
161160
await asyncio.sleep(0.05)
@@ -173,7 +172,7 @@ async def test_tool_with_progress(ctx: Context[ServerSession, None]) -> str:
173172

174173

175174
@mcp.tool()
176-
async def test_sampling(prompt: str, ctx: Context[ServerSession, None]) -> str:
175+
async def test_sampling(prompt: str, ctx: Context) -> str:
177176
"""Tests server-initiated sampling (LLM completion request)"""
178177
try:
179178
# Request sampling from client
@@ -198,7 +197,7 @@ class UserResponse(BaseModel):
198197

199198

200199
@mcp.tool()
201-
async def test_elicitation(message: str, ctx: Context[ServerSession, None]) -> str:
200+
async def test_elicitation(message: str, ctx: Context) -> str:
202201
"""Tests server-initiated elicitation (user input request)"""
203202
try:
204203
# Request user input from client
@@ -230,7 +229,7 @@ class SEP1034DefaultsSchema(BaseModel):
230229

231230

232231
@mcp.tool()
233-
async def test_elicitation_sep1034_defaults(ctx: Context[ServerSession, None]) -> str:
232+
async def test_elicitation_sep1034_defaults(ctx: Context) -> str:
234233
"""Tests elicitation with default values for all primitive types (SEP-1034)"""
235234
try:
236235
# Request user input with defaults for all primitive types
@@ -289,7 +288,7 @@ class EnumSchemasTestSchema(BaseModel):
289288

290289

291290
@mcp.tool()
292-
async def test_elicitation_sep1330_enums(ctx: Context[ServerSession, None]) -> str:
291+
async def test_elicitation_sep1330_enums(ctx: Context) -> str:
293292
"""Tests elicitation with enum schema variations per SEP-1330"""
294293
try:
295294
result = await ctx.elicit(
@@ -313,7 +312,7 @@ def test_error_handling() -> str:
313312

314313

315314
@mcp.tool()
316-
async def test_reconnection(ctx: Context[ServerSession, None]) -> str:
315+
async def test_reconnection(ctx: Context) -> str:
317316
"""Tests SSE polling by closing stream mid-call (SEP-1699)"""
318317
await ctx.info("Before disconnect")
319318

examples/snippets/servers/elicitation.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
from pydantic import BaseModel, Field
1111

1212
from mcp.server.mcpserver import Context, MCPServer
13-
from mcp.server.session import ServerSession
1413
from mcp.shared.exceptions import UrlElicitationRequiredError
1514
from mcp.types import ElicitRequestURLParams
1615

@@ -28,7 +27,7 @@ class BookingPreferences(BaseModel):
2827

2928

3029
@mcp.tool()
31-
async def book_table(date: str, time: str, party_size: int, ctx: Context[ServerSession, None]) -> str:
30+
async def book_table(date: str, time: str, party_size: int, ctx: Context) -> str:
3231
"""Book a table with date availability check.
3332
3433
This demonstrates form mode elicitation for collecting non-sensitive user input.
@@ -52,7 +51,7 @@ async def book_table(date: str, time: str, party_size: int, ctx: Context[ServerS
5251

5352

5453
@mcp.tool()
55-
async def secure_payment(amount: float, ctx: Context[ServerSession, None]) -> str:
54+
async def secure_payment(amount: float, ctx: Context) -> str:
5655
"""Process a secure payment requiring URL confirmation.
5756
5857
This demonstrates URL mode elicitation using ctx.elicit_url() for
@@ -76,7 +75,7 @@ async def secure_payment(amount: float, ctx: Context[ServerSession, None]) -> st
7675

7776

7877
@mcp.tool()
79-
async def connect_service(service_name: str, ctx: Context[ServerSession, None]) -> str:
78+
async def connect_service(service_name: str, ctx: Context) -> str:
8079
"""Connect to a third-party service requiring OAuth authorization.
8180
8281
This demonstrates the "throw error" pattern using UrlElicitationRequiredError.

examples/snippets/servers/notifications.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
from mcp.server.mcpserver import Context, MCPServer
2-
from mcp.server.session import ServerSession
32

43
mcp = MCPServer(name="Notifications Example")
54

65

76
@mcp.tool()
8-
async def process_data(data: str, ctx: Context[ServerSession, None]) -> str:
7+
async def process_data(data: str, ctx: Context) -> str:
98
"""Process data with logging."""
109
# Different log levels
1110
await ctx.debug(f"Debug: Processing '{data}'")

examples/snippets/servers/sampling.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
from mcp.server.mcpserver import Context, MCPServer
2-
from mcp.server.session import ServerSession
32
from mcp.types import SamplingMessage, TextContent
43

54
mcp = MCPServer(name="Sampling Example")
65

76

87
@mcp.tool()
9-
async def generate_poem(topic: str, ctx: Context[ServerSession, None]) -> str:
8+
async def generate_poem(topic: str, ctx: Context) -> str:
109
"""Generate a poem using LLM sampling."""
1110
prompt = f"Write a short poem about {topic}"
1211

examples/snippets/servers/tool_progress.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
from mcp.server.mcpserver import Context, MCPServer
2-
from mcp.server.session import ServerSession
32

43
mcp = MCPServer(name="Progress Example")
54

65

76
@mcp.tool()
8-
async def long_running_task(task_name: str, ctx: Context[ServerSession, None], steps: int = 5) -> str:
7+
async def long_running_task(task_name: str, ctx: Context, steps: int = 5) -> str:
98
"""Execute a task with progress updates."""
109
await ctx.info(f"Starting: {task_name}")
1110

tests/client/test_list_roots_callback.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ async def list_roots_callback(
2525
return callback_return
2626

2727
@server.tool("test_list_roots")
28-
async def test_list_roots(context: Context[None], message: str):
28+
async def test_list_roots(context: Context, message: str):
2929
roots = await context.session.list_roots()
3030
assert roots == callback_return
3131
return True

tests/server/mcpserver/test_elicitation.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from mcp import Client, types
99
from mcp.client.session import ClientSession, ElicitationFnT
1010
from mcp.server.mcpserver import Context, MCPServer
11-
from mcp.server.session import ServerSession
1211
from mcp.shared._context import RequestContext
1312
from mcp.types import ElicitRequestParams, ElicitResult, TextContent
1413

@@ -22,7 +21,7 @@ def create_ask_user_tool(mcp: MCPServer):
2221
"""Create a standard ask_user tool that handles all elicitation responses."""
2322

2423
@mcp.tool(description="A tool that uses elicitation")
25-
async def ask_user(prompt: str, ctx: Context[ServerSession, None]) -> str:
24+
async def ask_user(prompt: str, ctx: Context) -> str:
2625
result = await ctx.elicit(message=f"Tool wants to ask: {prompt}", schema=AnswerSchema)
2726

2827
if result.action == "accept" and result.data:
@@ -97,7 +96,7 @@ async def test_elicitation_schema_validation():
9796

9897
def create_validation_tool(name: str, schema_class: type[BaseModel]):
9998
@mcp.tool(name=name, description=f"Tool testing {name}")
100-
async def tool(ctx: Context[ServerSession, None]) -> str:
99+
async def tool(ctx: Context) -> str:
101100
try:
102101
await ctx.elicit(message="This should fail validation", schema=schema_class)
103102
return "Should not reach here" # pragma: no cover
@@ -147,7 +146,7 @@ class OptionalSchema(BaseModel):
147146
subscribe: bool | None = Field(default=False, description="Subscribe to newsletter?")
148147

149148
@mcp.tool(description="Tool with optional fields")
150-
async def optional_tool(ctx: Context[ServerSession, None]) -> str:
149+
async def optional_tool(ctx: Context) -> str:
151150
result = await ctx.elicit(message="Please provide your information", schema=OptionalSchema)
152151

153152
if result.action == "accept" and result.data:
@@ -188,7 +187,7 @@ class InvalidOptionalSchema(BaseModel):
188187
optional_list: list[int] | None = Field(default=None, description="Invalid optional list")
189188

190189
@mcp.tool(description="Tool with invalid optional field")
191-
async def invalid_optional_tool(ctx: Context[ServerSession, None]) -> str:
190+
async def invalid_optional_tool(ctx: Context) -> str:
192191
try:
193192
await ctx.elicit(message="This should fail", schema=InvalidOptionalSchema)
194193
return "Should not reach here" # pragma: no cover
@@ -214,7 +213,7 @@ class ValidMultiSelectSchema(BaseModel):
214213
tags: list[str] = Field(description="Tags")
215214

216215
@mcp.tool(description="Tool with valid list[str] field")
217-
async def valid_multiselect_tool(ctx: Context[ServerSession, None]) -> str:
216+
async def valid_multiselect_tool(ctx: Context) -> str:
218217
result = await ctx.elicit(message="Please provide tags", schema=ValidMultiSelectSchema)
219218
if result.action == "accept" and result.data:
220219
return f"Name: {result.data.name}, Tags: {', '.join(result.data.tags)}"
@@ -233,7 +232,7 @@ class OptionalMultiSelectSchema(BaseModel):
233232
tags: list[str] | None = Field(default=None, description="Optional tags")
234233

235234
@mcp.tool(description="Tool with optional list[str] field")
236-
async def optional_multiselect_tool(ctx: Context[ServerSession, None]) -> str:
235+
async def optional_multiselect_tool(ctx: Context) -> str:
237236
result = await ctx.elicit(message="Please provide optional tags", schema=OptionalMultiSelectSchema)
238237
if result.action == "accept" and result.data:
239238
tags_str = ", ".join(result.data.tags) if result.data.tags else "none"
@@ -262,7 +261,7 @@ class DefaultsSchema(BaseModel):
262261
email: str = Field(description="Email address (required)")
263262

264263
@mcp.tool(description="Tool with default values")
265-
async def defaults_tool(ctx: Context[ServerSession, None]) -> str:
264+
async def defaults_tool(ctx: Context) -> str:
266265
result = await ctx.elicit(message="Please provide your information", schema=DefaultsSchema)
267266

268267
if result.action == "accept" and result.data:
@@ -327,7 +326,7 @@ class FavoriteColorSchema(BaseModel):
327326
)
328327

329328
@mcp.tool(description="Single color selection")
330-
async def select_favorite_color(ctx: Context[ServerSession, None]) -> str:
329+
async def select_favorite_color(ctx: Context) -> str:
331330
result = await ctx.elicit(message="Select your favorite color", schema=FavoriteColorSchema)
332331
if result.action == "accept" and result.data:
333332
return f"User: {result.data.user_name}, Favorite: {result.data.favorite_color}"
@@ -351,7 +350,7 @@ class FavoriteColorsSchema(BaseModel):
351350
)
352351

353352
@mcp.tool(description="Multiple color selection")
354-
async def select_favorite_colors(ctx: Context[ServerSession, None]) -> str:
353+
async def select_favorite_colors(ctx: Context) -> str:
355354
result = await ctx.elicit(message="Select your favorite colors", schema=FavoriteColorsSchema)
356355
if result.action == "accept" and result.data:
357356
return f"User: {result.data.user_name}, Colors: {', '.join(result.data.favorite_colors)}"
@@ -366,7 +365,7 @@ class LegacyColorSchema(BaseModel):
366365
)
367366

368367
@mcp.tool(description="Legacy enum format")
369-
async def select_color_legacy(ctx: Context[ServerSession, None]) -> str:
368+
async def select_color_legacy(ctx: Context) -> str:
370369
result = await ctx.elicit(message="Select a color (legacy format)", schema=LegacyColorSchema)
371370
if result.action == "accept" and result.data:
372371
return f"User: {result.data.user_name}, Color: {result.data.color}"

0 commit comments

Comments
 (0)