33
44Claimed-shape servers here are real `MCPServer`s whose SEP-2133 server extension
55rewrites `tools/call` results via `intercept_tool_call` — the full public-API loop.
6- The in-process server can only deliver claimed fields the v2026 tools/call surface
7- keeps (`resultType`, `requestState`, `inputRequests`, `_meta`): the server-side
8- `serialize_server_result` drops anything else, so claimed payloads here ride
9- `requestState`.
6+ A short-circuiting interceptor's dict reaches the client verbatim (the runner trusts
7+ it as a well-formed result), so the claimed models carry vendor top-level fields.
108
119`tools/call` is never cached (`Client.call_tool` has no `_cached_fetch` weave and the
1210SEP-2549 cacheable verbs do not include it), so the claim path needs no cache tests.
@@ -48,11 +46,11 @@ def _name_elicitation() -> types.ElicitRequest:
4846
4947
5048class VoucherResult (Result ):
51- """The claimed `tools/call` shape, tagged `voucher`; its payload rides `requestState`
52- (the only open payload-bearing field the in-process server's surface dump keeps )."""
49+ """The claimed `tools/call` shape, tagged `voucher`, carrying a vendor top-level field
50+ (a short-circuiting server interceptor 's dict reaches the client verbatim )."""
5351
5452 result_type : Literal ["voucher" ] = "voucher"
55- request_state : str | None = None
53+ voucher_code : str | None = None
5654
5755
5856_Resolver = Callable [[VoucherResult , ClaimContext ], Awaitable [CallToolResult ]]
@@ -78,7 +76,7 @@ class _VoucherIssuer(Extension):
7876 async def intercept_tool_call (
7977 self , params : types .CallToolRequestParams , ctx : ServerRequestContext [Any , Any ], call_next : CallNext
8078 ) -> HandlerResult :
81- return {"resultType" : "voucher" , "requestState " : "v-42" }
79+ return {"resultType" : "voucher" , "voucherCode " : "v-42" }
8280
8381
8482class _TwoRoundVoucherIssuer (Extension ):
@@ -91,7 +89,7 @@ async def intercept_tool_call(
9189 ) -> HandlerResult :
9290 if params .input_responses is None :
9391 return types .InputRequiredResult (input_requests = {"user_name" : _name_elicitation ()})
94- return {"resultType" : "voucher" , "requestState " : "after-input" }
92+ return {"resultType" : "voucher" , "voucherCode " : "after-input" }
9593
9694
9795def _voucher_server (issuer : Extension | None = None ) -> MCPServer :
@@ -414,7 +412,7 @@ async def test_claimed_result_resolves_transparently_to_the_resolvers_result() -
414412
415413 async def resolve (claimed : VoucherResult , ctx : ClaimContext ) -> CallToolResult :
416414 received .append (claimed )
417- product = CallToolResult (content = [TextContent (text = f"honored { claimed .request_state } " )])
415+ product = CallToolResult (content = [TextContent (text = f"honored { claimed .voucher_code } " )])
418416 produced .append (product )
419417 return product
420418
@@ -423,7 +421,7 @@ async def resolve(claimed: VoucherResult, ctx: ClaimContext) -> CallToolResult:
423421 result = await client .call_tool ("issue" , {})
424422 assert_type (result , CallToolResult )
425423
426- assert [claimed .request_state for claimed in received ] == ["v-42" ]
424+ assert [claimed .voucher_code for claimed in received ] == ["v-42" ]
427425 assert result is produced [0 ]
428426 assert result .content == [TextContent (text = "honored v-42" )]
429427
@@ -442,7 +440,7 @@ async def resolve(claimed: VoucherResult, ctx: ClaimContext) -> CallToolResult:
442440 async with Client (_voucher_server (), extensions = extensions ) as client :
443441 result = await client .call_tool ("issue" , {})
444442
445- assert [claimed .request_state for claimed in received ] == ["v-42" ]
443+ assert [claimed .voucher_code for claimed in received ] == ["v-42" ]
446444 assert result .content == [TextContent (text = "routed" )]
447445
448446
@@ -586,7 +584,7 @@ async def elicitation_callback(
586584
587585 async def resolve (claimed : VoucherResult , ctx : ClaimContext ) -> CallToolResult :
588586 received .append (claimed )
589- return CallToolResult (content = [TextContent (text = f"honored { claimed .request_state } " )])
587+ return CallToolResult (content = [TextContent (text = f"honored { claimed .voucher_code } " )])
590588
591589 server = _voucher_server (issuer = _TwoRoundVoucherIssuer ())
592590 with anyio .fail_after (5 ):
@@ -596,7 +594,7 @@ async def resolve(claimed: VoucherResult, ctx: ClaimContext) -> CallToolResult:
596594 result = await client .call_tool ("issue" , {})
597595
598596 assert prompted == ["What is your name?" ]
599- assert [claimed .request_state for claimed in received ] == ["after-input" ]
597+ assert [claimed .voucher_code for claimed in received ] == ["after-input" ]
600598 assert result .content == [TextContent (text = "honored after-input" )]
601599
602600
0 commit comments