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\MetaObject;
15:
16: use Nexus\Assert\Assert;
17: use Nexus\Mcp\Core\Schema\MetaObject;
18: use Nexus\Mcp\Core\Schema\RequestId;
19:
20: /**
21: * Extends `MetaObject` with additional notification-specific fields. All key naming rules from `MetaObject` apply.
22: *
23: * @extends MetaObject<array<array-key, mixed>>
24: *
25: * @see https://modelcontextprotocol.io/specification/2026-07-28/schema#notificationmetaobject
26: */
27: final readonly class NotificationMetaObject extends MetaObject
28: {
29: public const string SUBSCRIPTION_ID_KEY = 'io.modelcontextprotocol/subscriptionId';
30:
31: /**
32: * @param array<array-key, mixed> $extras
33: */
34: public function __construct(
35: public ?RequestId $subscriptionId = null,
36: array $extras = [],
37: ) {
38: parent::__construct(extras: $extras);
39: }
40:
41: #[\Override]
42: public static function fromArray(array $data): static
43: {
44: $subscriptionId = null;
45:
46: if (\array_key_exists(self::SUBSCRIPTION_ID_KEY, $data)) {
47: Assert::that($data[self::SUBSCRIPTION_ID_KEY])->isIntOrNonEmptyString(
48: \sprintf('"_meta.%s" must be an int or a non-empty string, {type} given.', self::SUBSCRIPTION_ID_KEY),
49: );
50: $subscriptionId = new RequestId($data[self::SUBSCRIPTION_ID_KEY]);
51: unset($data[self::SUBSCRIPTION_ID_KEY]);
52: }
53:
54: return new self(subscriptionId: $subscriptionId, extras: $data);
55: }
56:
57: #[\Override]
58: public function toArray(): array
59: {
60: $out = [];
61:
62: if (null !== $this->subscriptionId) {
63: $out[self::SUBSCRIPTION_ID_KEY] = $this->subscriptionId->id;
64: }
65:
66: return $out + $this->extras;
67: }
68: }
69: