[Client] Add client-side elicitation support (#371)
* [Client] Add client-side elicitation support The SDK could send elicitation/create requests from a server tool via ClientGateway::elicit(), but the client could not receive them: there was no request handler, and ElicitRequest was not registered in MessageFactory, so incoming elicitation/create messages failed to parse. This adds the client half, mirroring the existing Sampling pattern: - Register ElicitRequest in MessageFactory so elicitation/create parses. - ElicitationRequestHandler wraps a user callback and returns an ElicitResult (accept/decline/cancel) or an Error. - ElicitationCallbackInterface defines the callback contract. - ElicitationException forwards a specific message to the server; any other throwable returns a generic error. Includes unit tests, a runnable client example against the elicitation demo server, and client docs/README updates. * [Client] Simplify elicitation example labelFor() per review Type the parameter as AbstractSchemaDefinition and read ->title directly instead of matching on each concrete definition type. title is a required non-null string on the base class, so the match and the $name fallback were redundant. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
206aa9da52
commit
e4a8a224ff
1 changed files with 495 additions and 1 deletions
|
|
@ -18,6 +18,7 @@ use Mcp\Schema\JsonRpc\Error;
|
|||
use Mcp\Schema\JsonRpc\Response;
|
||||
use Mcp\Schema\Notification\CancelledNotification;
|
||||
use Mcp\Schema\Notification\InitializedNotification;
|
||||
use Mcp\Schema\Request\ElicitRequest;
|
||||
use Mcp\Schema\Request\GetPromptRequest;
|
||||
use Mcp\Schema\Request\PingRequest;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
|
@ -336,6 +337,22 @@ final class MessageFactoryTest extends TestCase
|
|||
$this->assertInstanceOf(PingRequest::class, $results[0]);
|
||||
}
|
||||
|
||||
public function testMakeFactoryParsesElicitationCreate(): void
|
||||
{
|
||||
$factory = MessageFactory::make();
|
||||
$json = '{"jsonrpc": "2.0", "method": "elicitation/create", "id": 1, "params": {"message": "Your name?", "requestedSchema": {"type": "object", "properties": {"name": {"type": "string", "title": "Name"}}, "required": ["name"]}}}';
|
||||
|
||||
$results = $factory->create($json);
|
||||
|
||||
$this->assertCount(1, $results);
|
||||
/** @var ElicitRequest $result */
|
||||
$result = $results[0];
|
||||
$this->assertInstanceOf(ElicitRequest::class, $result);
|
||||
$this->assertSame('elicitation/create', $result::getMethod());
|
||||
$this->assertSame('Your name?', $result->message);
|
||||
$this->assertSame(1, $result->getId());
|
||||
}
|
||||
|
||||
public function testResponseWithInvalidIdType(): void
|
||||
{
|
||||
$json = '{"jsonrpc": "2.0", "id": true, "result": {"status": "ok"}}';
|
||||
|
|
|
|||
Loading…
Reference in a new issue