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\Result;
15:
16: use Nexus\Assert\Assert;
17: use Nexus\Mcp\Core\Schema\Arrayable;
18: use Nexus\Mcp\Core\Schema\Enum\ResultType;
19: use Nexus\Mcp\Core\Schema\MetaObject;
20: use Nexus\Mcp\Core\Schema\Prompt\PromptMessage;
21: use Nexus\Mcp\Core\Schema\Result;
22:
23: /**
24: * The result returned by the server for a `prompts/get` request.
25: *
26: * @extends Result<array{
27: * _meta?: template-type<MetaObject, Arrayable, 'T'>,
28: * resultType: non-empty-string,
29: * description?: non-empty-string,
30: * messages: list<template-type<PromptMessage, Arrayable, 'T'>>,
31: * }>
32: *
33: * @see https://modelcontextprotocol.io/specification/draft/schema#getpromptresult
34: */
35: final readonly class GetPromptResult extends Result implements ServerResult
36: {
37: /**
38: * @var list<PromptMessage>
39: */
40: public array $messages;
41:
42: /**
43: * @var null|non-empty-string
44: */
45: public ?string $description;
46:
47: /**
48: * @param list<PromptMessage> $messages
49: */
50: public function __construct(array $messages, ?string $description = null, MetaObject $meta = new MetaObject())
51: {
52: Assert::that($messages)->isList('"result.messages" must be a list, non-list array given.');
53:
54: foreach ($messages as $message) {
55: Assert::that($message)->isInstanceOf(PromptMessage::class);
56: }
57:
58: Assert::that($description)->nullOr()->isNonEmptyString('"result.description" must be a non-empty string or null.');
59:
60: $this->messages = $messages;
61: $this->description = $description;
62:
63: parent::__construct(meta: $meta);
64: }
65:
66: #[\Override]
67: public static function fromArray(array $data): static
68: {
69: Assert::that($data)->hasOffset('messages', '"result" is missing the required "messages" key.');
70: Assert::that($data['messages'])->isArray('"result.messages" must be an array, {type} given.');
71:
72: $messages = [];
73:
74: foreach ($data['messages'] as $entry) {
75: Assert::that($entry)
76: ->isArray('"result.message" must be an object, {type} given.')
77: ->isMap('"result.message" must be a string-keyed object.')
78: ;
79: $messages[] = PromptMessage::fromArray($entry);
80: }
81:
82: $description = $data['description'] ?? null;
83: Assert::that($description)->nullOr()->isString('"result.description" must be a string or null, {type} given.');
84:
85: $meta = new MetaObject();
86:
87: if (\array_key_exists('_meta', $data)) {
88: Assert::that($data['_meta'])
89: ->isArray('"result._meta" must be an object, {type} given.')
90: ->isMap('"result._meta" must be a string-keyed object.')
91: ;
92: $meta = MetaObject::fromArray($data['_meta']);
93: }
94:
95: return new self(messages: $messages, description: $description, meta: $meta);
96: }
97:
98: #[\Override]
99: public function toArray(): array
100: {
101: $data = [];
102: $meta = $this->meta->toArray();
103:
104: if ([] !== $meta) {
105: $data['_meta'] = $meta;
106: }
107:
108: $data['resultType'] = self::getResultType();
109:
110: if (null !== $this->description) {
111: $data['description'] = $this->description;
112: }
113:
114: $data['messages'] = array_map(
115: static fn(PromptMessage $message): array => $message->toArray(),
116: $this->messages,
117: );
118:
119: return $data;
120: }
121:
122: #[\Override]
123: protected function getResultType(): string
124: {
125: return ResultType::Complete->value;
126: }
127: }
128: