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\Transport;
15:
16: use Nexus\Mcp\Core\Exception\TransportAlreadyClosedException;
17: use Nexus\Mcp\Core\Exception\TransportAlreadyStartedException;
18: use Nexus\Mcp\Core\Exception\TransportNotStartedException;
19: use Nexus\Mcp\Core\Schema\JsonRpc\JsonRpcMessage;
20:
21: /**
22: * Bidirectional JSON-RPC envelope duplex between this SDK and a connected peer.
23: */
24: interface TransportInterface
25: {
26: /**
27: * Begins consuming inbound envelopes from the peer, returning immediately.
28: *
29: * @throws TransportAlreadyStartedException
30: * @throws TransportAlreadyClosedException
31: */
32: public function start(): void;
33:
34: /**
35: * Enqueues an outbound JSON-RPC message to the peer, close listeners firing before a write failure is rethrown.
36: *
37: * @throws TransportNotStartedException
38: * @throws TransportAlreadyClosedException
39: * @throws \Throwable
40: */
41: public function send(JsonRpcMessage $message, ?SendContext $context = null): void;
42:
43: /**
44: * Closes the connection once, firing `onClose()` after the underlying streams close, which an
45: * implementation MUST also do after a fatal error since `Server::run()` blocks on that signal.
46: * A call from another fiber while a close is in progress MUST block until that close settles,
47: * while one re-entering from the closing fiber returns immediately.
48: */
49: public function close(): void;
50:
51: /**
52: * A transport multiplexing several peers MUST namespace or rewrite inbound request ids before
53: * emitting them, since the protocol layer correlates and cancels by id alone.
54: *
55: * @param \Closure(array<string, mixed>, ReceiveContext): void $listener
56: */
57: public function onMessage(\Closure $listener): ListenerHandleInterface;
58:
59: /**
60: * @param \Closure(\Throwable): void $listener
61: */
62: public function onError(\Closure $listener): ListenerHandleInterface;
63:
64: /**
65: * Register a drain listener that fires before `close()`.
66: *
67: * @param \Closure(): void $listener
68: */
69: public function onDrain(\Closure $listener): ListenerHandleInterface;
70:
71: /**
72: * @param \Closure(): void $listener
73: */
74: public function onClose(\Closure $listener): ListenerHandleInterface;
75: }
76: