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\Elicitation\ElicitResult;
18: use Nexus\Mcp\Core\Schema\MetaObject;
19: use Nexus\Mcp\Core\Schema\MetaObject\RequestMetaObject;
20: use Nexus\Mcp\Core\Schema\Result\InputResponse;
21:
22: /**
23: * Parameters for a `prompts/get` request.
24: *
25: * @extends InputResponseRequestParams<array{
26: * _meta: template-type<RequestMetaObject, MetaObject, 'T'>,
27: * name: non-empty-string,
28: * arguments?: array<array-key, string>,
29: * inputResponses?: array<int|non-empty-string, array<string, mixed>>,
30: * requestState?: string,
31: * }>
32: *
33: * @see https://modelcontextprotocol.io/specification/2026-07-28/schema#getpromptrequestparams
34: */
35: final readonly class GetPromptRequestParams extends InputResponseRequestParams
36: {
37: /**
38: * @param non-empty-string $name
39: * @param null|array<array-key, string> $arguments
40: * @param null|array<int|non-empty-string, InputResponse> $inputResponses
41: */
42: public function __construct(
43: public string $name,
44: RequestMetaObject $meta,
45: public ?array $arguments = null,
46: ?array $inputResponses = null,
47: ?string $requestState = null,
48: ) {
49: Assert::that($name)->isNonEmptyString('"params.name" must be a non-empty string, {type} given.');
50:
51: if (null !== $arguments) {
52: Assert::that($arguments)->values()->isString('"params.arguments" values must all be strings, {type} given.');
53: }
54:
55: parent::__construct(inputResponses: $inputResponses, requestState: $requestState, meta: $meta);
56: }
57:
58: #[\Override]
59: public static function fromArray(array $data): static
60: {
61: Assert::that($data)->hasOffset('name', '"params" is missing the required "name" key.');
62: $name = $data['name'];
63: Assert::that($name)->isNonEmptyString('"params.name" must be a non-empty string, {type} given.');
64:
65: $arguments = null;
66:
67: if (\array_key_exists('arguments', $data)) {
68: Assert::that($data['arguments'])
69: ->isArray('"params.arguments" must be an object, {type} given.')
70: ->values()->isString('"params.arguments" value must be a string, {type} given.')
71: ;
72: $arguments = $data['arguments'];
73: }
74:
75: $inputResponses = null;
76:
77: if (\array_key_exists('inputResponses', $data)) {
78: Assert::that($data['inputResponses'])
79: ->isArray('"params.inputResponses" must be an object, {type} given.')
80: ->keys()->isIntOrNonEmptyString('each "params.inputResponses" key must be an int or non-empty string.')
81: ;
82: Assert::that($data['inputResponses'])
83: ->values()
84: ->isArray('each "params.inputResponses" entry must be an object, {type} given.')
85: ->isMap('each "params.inputResponses" entry must be a string-keyed object.')
86: ;
87: $inputResponses = array_map(ElicitResult::fromArray(...), $data['inputResponses']);
88: }
89:
90: $requestState = null;
91:
92: if (\array_key_exists('requestState', $data)) {
93: Assert::that($data['requestState'])->isString('"params.requestState" must be a string, {type} given.');
94: $requestState = $data['requestState'];
95: }
96:
97: Assert::that($data)->hasOffset('_meta', '"params" is missing the required "_meta" key.');
98: Assert::that($data['_meta'])
99: ->isArray('"params._meta" must be an object, {type} given.')
100: ->not()->isNonEmptyList('"params._meta" must be a string-keyed object.')
101: ;
102: $meta = RequestMetaObject::fromArray($data['_meta']);
103:
104: return new self(
105: name: $name,
106: meta: $meta,
107: arguments: $arguments,
108: inputResponses: $inputResponses,
109: requestState: $requestState,
110: );
111: }
112:
113: #[\Override]
114: public function toArray(): array
115: {
116: $data = [
117: '_meta' => $this->meta->toArray(),
118: 'name' => $this->name,
119: ];
120:
121: if (null !== $this->arguments && [] !== $this->arguments) {
122: $data['arguments'] = $this->arguments;
123: }
124:
125: if (null !== $this->inputResponses) {
126: $data['inputResponses'] = array_map(
127: static fn(InputResponse $response): array => $response->toArray(),
128: $this->inputResponses,
129: );
130: }
131:
132: if (null !== $this->requestState) {
133: $data['requestState'] = $this->requestState;
134: }
135:
136: return $data;
137: }
138:
139: #[\Override]
140: public function jsonSerialize(): array
141: {
142: $data = parent::jsonSerialize();
143:
144: if (null !== $this->inputResponses) {
145: $data['inputResponses'] = array_map(
146: static fn(InputResponse $response): array|\stdClass => $response->jsonSerialize(),
147: $this->inputResponses,
148: );
149:
150: if (array_is_list($this->inputResponses)) {
151: $data['inputResponses'] = (object) $data['inputResponses'];
152: }
153: }
154:
155: if (null !== $this->arguments && array_is_list($this->arguments) && [] !== $this->arguments) {
156: $data['arguments'] = (object) $this->arguments;
157: }
158:
159: return $data;
160: }
161: }
162: