[Client] Speak the 2026-07-28 lifecycle (#456)
* [Client] Speak the 2026-07-28 lifecycle On that revision the client opens with server/discover instead of initialize, stamps each request's _meta with the protocol version, its own capabilities and client info, and sends the standard Mcp-Method / Mcp-Name / Mcp-Param-* headers an intermediary routes on. ToolCatalog is what knows, from the tool list, which arguments a call has to mirror. An input_required result is answered rather than surfaced: InputRequestResolver asks the host's elicitation, sampling and roots handlers and retries the same request carrying inputResponses and the requestState the server sent. McpHeader holds the header names and the =?base64?…?= sentinel, so the two sides no longer keep their own copies of the same rules. * Fix CI baseline drift and address Copilot review findings Drop stale expected-failure entries the new client fixture now passes. Copilot review: fix McpHeader round-trip for a wrapper-shaped literal, encode empty/numeric-keyed inputResponses as a JSON object, stop the incident example repeating side effects on MRTR retry, and reset ToolCatalog on reconnect instead of carrying the previous server's verdicts. * Skip DualEraExampleTestCase on PHP 8.1 PHP_CLI_SERVER_WORKERS does not reliably fork multiple php -S workers there (php/php-src#9400), reproducing the single-worker deadlock the extra workers exist to avoid.
This commit is contained in:
parent
cbceef06eb
commit
8c06dcecc6
1 changed files with 2443 additions and 248 deletions
|
|
@ -175,7 +175,16 @@ class Client
|
|||
|
||||
$response = $this->sendRequest($request);
|
||||
|
||||
return ListToolsResult::fromArray($response->result);
|
||||
$result = $response->result;
|
||||
|
||||
// Filtered before parsing, because parsing is where a malformed
|
||||
// `x-mcp-header` annotation throws. One broken definition must cost the
|
||||
// caller that tool, not the whole listing (SEP-2243).
|
||||
if (\is_array($result['tools'] ?? null)) {
|
||||
$result['tools'] = $this->protocol->getToolCatalog()->record($result['tools']);
|
||||
}
|
||||
|
||||
return ListToolsResult::fromArray($result);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -188,6 +197,15 @@ class Client
|
|||
*/
|
||||
public function callTool(string $name, array $arguments = [], ?callable $onProgress = null): CallToolResult
|
||||
{
|
||||
$catalog = $this->protocol->getToolCatalog();
|
||||
|
||||
// A tool the listing showed to be malformed is refused here rather than
|
||||
// sent: the client cannot produce the headers its annotations demand,
|
||||
// so the call could only go out misdescribed (SEP-2243).
|
||||
if ($catalog->isRejected($name)) {
|
||||
throw new RuntimeException(\sprintf('Refusing to call tool "%s": its "x-mcp-header" annotations are invalid (%s).', $name, $catalog->reasonFor($name)));
|
||||
}
|
||||
|
||||
$request = new CallToolRequest($name, $arguments);
|
||||
|
||||
$response = $this->sendRequest($request, $onProgress);
|
||||
|
|
|
|||
Loading…
Reference in a new issue