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