Skip to content

Commit 5ebaf73

Browse files
committed
fix(server): preserve legacy elicitation errors
Signed-off-by: Ruiming Zhao <uuzzrm@gmail.com>
1 parent 1bea479 commit 5ebaf73

3 files changed

Lines changed: 7 additions & 8 deletions

File tree

src/mcp/server/elicitation.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from pydantic_core import core_schema
1414
from typing_extensions import TypeAliasType
1515

16+
from mcp.server.mcpserver.exceptions import ToolError
1617
from mcp.server.session import ServerSession
1718

1819
ElicitSchemaModelT = TypeVar("ElicitSchemaModelT", bound=BaseModel)
@@ -116,7 +117,7 @@ async def elicit_with_validation(
116117
For sensitive data like credentials or OAuth flows, use elicit_url() instead.
117118
118119
Raises:
119-
ValueError: If the client accepted the elicitation without supplying
120+
ToolError: If the client accepted the elicitation without supplying
120121
content, or with content that does not match the requested schema.
121122
"""
122123
json_schema = render_elicitation_schema(schema)
@@ -129,13 +130,11 @@ async def elicit_with_validation(
129130

130131
if result.action == "accept":
131132
if result.content is None:
132-
raise ValueError("Received an accepted elicitation with no content")
133+
raise ToolError("Received an accepted elicitation with no content")
133134
try:
134135
validated_data = schema.model_validate(result.content)
135136
except ValidationError as e:
136-
raise ValueError(
137-
"Received an accepted elicitation whose content does not match the requested schema"
138-
) from e
137+
raise ToolError("Received an accepted elicitation whose content does not match the requested schema") from e
139138
return AcceptedElicitation(data=validated_data)
140139
if result.action == "decline":
141140
return DeclinedElicitation()

tests/interaction/mcpserver/test_prompts.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ async def test_get_prompt_with_a_wrong_type_argument_is_rejected_before_the_func
124124
The decorated function is wrapped in pydantic's validate_call, so a value that cannot be
125125
coerced to the parameter's annotation fails before the body executes. The function body
126126
raises NotImplementedError to prove it never ran. The error is logged server-side and the
127-
client receives the same sanitized tool result as other unexpected exceptions.
127+
client receives the raw validation message with the stable rendering-error prefix.
128128
"""
129129
mcp = MCPServer("prompter")
130130

tests/server/mcpserver/test_resolve.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,7 +1051,7 @@ async def empty_accept(context: ClientRequestContext, params: ElicitRequestParam
10511051
if mode == "auto":
10521052
assert "received an accepted elicitation with no content" in result.content[0].text
10531053
else:
1054-
assert result.content[0].text == "An unexpected error occurred while executing tool tool"
1054+
assert result.content[0].text == "Received an accepted elicitation with no content"
10551055

10561056

10571057
@pytest.mark.anyio
@@ -1432,7 +1432,7 @@ async def whoami(login: Annotated[Login, Resolve(ask)]) -> str:
14321432
assert "does not match the requested schema" in text
14331433
assert "Resolver" in text
14341434
else:
1435-
assert text == "An unexpected error occurred while executing tool whoami"
1435+
assert text == "Received an accepted elicitation whose content does not match the requested schema"
14361436
assert "errors.pydantic.dev" not in text
14371437

14381438

0 commit comments

Comments
 (0)