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\Implementation;
18: use Nexus\Mcp\Core\Schema\MetaObject;
19: use Nexus\Mcp\Core\Schema\ProtocolVersion;
20: use Nexus\Mcp\Core\Schema\Result;
21: use Nexus\Mcp\Core\Schema\ServerCapabilities;
22:
23: /**
24: * After receiving an initialize request from the client, the server sends this response.
25: *
26: * @see https://modelcontextprotocol.io/specification/2025-11-25/schema#initializeresult
27: */
28: final readonly class InitializeResult extends Result implements ServerResult
29: {
30: /**
31: * @var null|non-empty-string
32: */
33: public ?string $instructions;
34:
35: public function __construct(
36: public ProtocolVersion $protocolVersion,
37: public ServerCapabilities $capabilities,
38: public Implementation $serverInfo,
39: ?string $instructions = null,
40: MetaObject $meta = new MetaObject(),
41: ) {
42: Assert::that($instructions)->nullOr()->isNonEmptyString('"result.instructions" must be a non-empty string or null.');
43:
44: $this->instructions = $instructions;
45:
46: parent::__construct($meta);
47: }
48:
49: #[\Override]
50: public static function fromArray(array $data): static
51: {
52: Assert::that($data)->hasOffset('protocolVersion', '"result" missing the required "protocolVersion" key.');
53: $protocolVersion = $data['protocolVersion'];
54: Assert::that($protocolVersion)->isString('"result.protocolVersion" must be a string, {type} given.');
55:
56: Assert::that($data)->hasOffset('capabilities', '"result" missing the required "capabilities" key.');
57: Assert::that($data['capabilities'])
58: ->isArray('"result.capabilities" must be an object, {type} given.')
59: ->isMap('"result.capabilities" must be a string-keyed object.')
60: ;
61:
62: Assert::that($data)->hasOffset('serverInfo', '"result" missing the required "serverInfo" key.');
63: Assert::that($data['serverInfo'])
64: ->isArray('"result.serverInfo" must be an object, {type} given.')
65: ->isMap('"result.serverInfo" must be a string-keyed object.')
66: ;
67:
68: $instructions = $data['instructions'] ?? null;
69: Assert::that($instructions)->nullOr()->isString('"result.instructions" must be a string or null, {type} given.');
70:
71: $meta = new MetaObject();
72:
73: if (\array_key_exists('_meta', $data)) {
74: Assert::that($data['_meta'])
75: ->isArray('"result._meta" must be an object, {type} given.')
76: ->isMap('"result._meta" must be a string-keyed object.')
77: ;
78: $meta = MetaObject::fromArray($data['_meta']);
79: }
80:
81: return new self(
82: new ProtocolVersion($protocolVersion),
83: ServerCapabilities::fromArray($data['capabilities']),
84: Implementation::fromArray($data['serverInfo']),
85: $instructions,
86: $meta,
87: );
88: }
89:
90: #[\Override]
91: public function toArray(): array
92: {
93: $data = [
94: ...parent::toArray(),
95: 'protocolVersion' => $this->protocolVersion->version,
96: 'capabilities' => $this->capabilities->toArray(),
97: 'serverInfo' => $this->serverInfo->toArray(),
98: ];
99:
100: if (null !== $this->instructions) {
101: $data['instructions'] = $this->instructions;
102: }
103:
104: return $data;
105: }
106:
107: #[\Override]
108: public function jsonSerialize(): array
109: {
110: $data = [
111: ...parent::toArray(),
112: 'protocolVersion' => $this->protocolVersion->version,
113: 'capabilities' => $this->capabilities->jsonSerialize(),
114: 'serverInfo' => $this->serverInfo->jsonSerialize(),
115: ];
116:
117: if (null !== $this->instructions) {
118: $data['instructions'] = $this->instructions;
119: }
120:
121: return $data;
122: }
123: }
124: