1: <?php
2:
3: declare(strict_types=1);
4:
5: /**
6: * This file is part of the Nexus MCP SDK package.
7: *
8: * (c) 2026 John Paul E. Balandan, CPA <paulbalandan@gmail.com>
9: *
10: * For the full copyright and license information, please view
11: * the LICENSE file that was distributed with this source code.
12: */
13:
14: namespace Nexus\Mcp\Core\Schema\RequestParams;
15:
16: use Nexus\Assert\Assert;
17: use Nexus\Mcp\Core\Schema\Arrayable;
18: use Nexus\Mcp\Core\Schema\Elicitation\ElicitRequestedSchema;
19:
20: /**
21: * The parameters for a request to elicit non-sensitive information from the user via a form in the client.
22: *
23: * @implements Arrayable<array{mode?: 'form', message: non-empty-string, requestedSchema: array<string, mixed>}>
24: * @implements ElicitRequestParams<array{mode?: 'form', message: non-empty-string, requestedSchema: array<string, mixed>}>
25: *
26: * @see https://modelcontextprotocol.io/specification/2026-07-28/schema#elicitrequestformparams
27: */
28: final readonly class ElicitRequestFormParams implements Arrayable, ElicitRequestParams
29: {
30: public const string MODE = 'form';
31:
32: /**
33: * @param non-empty-string $message
34: * @param 'form' $mode
35: */
36: public function __construct(
37: public string $message,
38: public ElicitRequestedSchema $requestedSchema,
39: public string $mode = self::MODE,
40: ) {
41: Assert::that($message)->isNonEmptyString('"params.message" must be a non-empty string.');
42: Assert::that($mode)->isIdentical(self::MODE, '"params.mode" must be {other}, {value} given.');
43: }
44:
45: #[\Override]
46: public static function fromArray(array $data): static
47: {
48: $mode = $data['mode'] ?? self::MODE;
49: Assert::that($mode)->isIdentical(self::MODE, '"params.mode" must be {other}, {value} given.');
50:
51: Assert::that($data)->hasOffset('message', '"params" is missing the required "message" key.');
52: $message = $data['message'];
53: Assert::that($message)->isNonEmptyString('"params.message" must be a non-empty string, {type} given.');
54:
55: Assert::that($data)->hasOffset('requestedSchema', '"params" is missing the required "requestedSchema" key.');
56: Assert::that($data['requestedSchema'])
57: ->isArray('"params.requestedSchema" must be an object, {type} given.')
58: ->isMap('"params.requestedSchema" must be a string-keyed object.')
59: ;
60: $requestedSchema = ElicitRequestedSchema::fromArray($data['requestedSchema']);
61:
62: return new self(message: $message, requestedSchema: $requestedSchema, mode: $mode);
63: }
64:
65: #[\Override]
66: public function toArray(): array
67: {
68: return [
69: 'mode' => $this->mode,
70: 'message' => $this->message,
71: 'requestedSchema' => $this->requestedSchema->toArray(),
72: ];
73: }
74:
75: #[\Override]
76: public function jsonSerialize(): array
77: {
78: $data = $this->toArray();
79: $data['requestedSchema'] = $this->requestedSchema->jsonSerialize();
80:
81: return $data;
82: }
83: }
84: