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\ResultMetaObject;
20: use Nexus\Mcp\Core\Schema\MetaObject\SubscriptionsListenResultMetaObject;
21: use Nexus\Mcp\Core\Schema\Result;
22:
23: /**
24: * The response to a `subscriptions/listen` request, signalling that the subscription has ended gracefully
25: * (for example, during server shutdown). Because the listen stream is long-lived, this result is sent only
26: * when the server tears the subscription down; an abrupt transport close carries no response. The result
27: * body is otherwise empty.
28: *
29: * @property-read SubscriptionsListenResultMetaObject $meta
30: *
31: * @extends Result<array{
32: * _meta: template-type<SubscriptionsListenResultMetaObject, Arrayable, 'T'>,
33: * resultType: non-empty-string,
34: * }>
35: *
36: * @see https://modelcontextprotocol.io/specification/2026-07-28/schema#subscriptionslistenresult
37: */
38: final readonly class SubscriptionsListenResult extends Result implements ServerResult
39: {
40: public function __construct(SubscriptionsListenResultMetaObject $meta)
41: {
42: parent::__construct(meta: $meta);
43: }
44:
45: #[\Override]
46: public static function fromArray(array $data): static
47: {
48: Assert::that($data)->hasOffset('_meta', '"result" is missing the required "_meta" key.');
49: Assert::that($data['_meta'])
50: ->isArray('"result._meta" must be an object, {type} given.')
51: ->isMap('"result._meta" must be a string-keyed object.')
52: ;
53:
54: return new self(meta: SubscriptionsListenResultMetaObject::fromArray($data['_meta']));
55: }
56:
57: #[\Override]
58: public function toArray(): array
59: {
60: return [
61: '_meta' => $this->meta->toArray(),
62: 'resultType' => self::getResultType(),
63: ];
64: }
65:
66: #[\Override]
67: public function rebuildWithMeta(ResultMetaObject $meta): static
68: {
69: // `_meta` is required here and names the stream, so a caller handing over a
70: // plain `ResultMetaObject` keeps this result's own subscription identity.
71: return new self(meta: new SubscriptionsListenResultMetaObject(
72: subscriptionId: $this->meta->subscriptionId,
73: serverInfo: $meta->serverInfo,
74: extras: $meta->extras,
75: ));
76: }
77:
78: #[\Override]
79: protected function getResultType(): string
80: {
81: return ResultType::Complete->value;
82: }
83: }
84: