@animalabs/agent-framework 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +233 -0
- package/dist/src/agent.d.ts +130 -0
- package/dist/src/agent.d.ts.map +1 -0
- package/dist/src/agent.js +406 -0
- package/dist/src/agent.js.map +1 -0
- package/dist/src/api/mcp-server.d.ts +37 -0
- package/dist/src/api/mcp-server.d.ts.map +1 -0
- package/dist/src/api/mcp-server.js +598 -0
- package/dist/src/api/mcp-server.js.map +1 -0
- package/dist/src/api/server.d.ts +83 -0
- package/dist/src/api/server.d.ts.map +1 -0
- package/dist/src/api/server.js +785 -0
- package/dist/src/api/server.js.map +1 -0
- package/dist/src/api/types.d.ts +395 -0
- package/dist/src/api/types.d.ts.map +1 -0
- package/dist/src/api/types.js +5 -0
- package/dist/src/api/types.js.map +1 -0
- package/dist/src/framework.d.ts +309 -0
- package/dist/src/framework.d.ts.map +1 -0
- package/dist/src/framework.js +2309 -0
- package/dist/src/framework.js.map +1 -0
- package/dist/src/gate/event-gate.d.ts +75 -0
- package/dist/src/gate/event-gate.d.ts.map +1 -0
- package/dist/src/gate/event-gate.js +503 -0
- package/dist/src/gate/event-gate.js.map +1 -0
- package/dist/src/gate/index.d.ts +3 -0
- package/dist/src/gate/index.d.ts.map +1 -0
- package/dist/src/gate/index.js +2 -0
- package/dist/src/gate/index.js.map +1 -0
- package/dist/src/gate/types.d.ts +82 -0
- package/dist/src/gate/types.d.ts.map +1 -0
- package/dist/src/gate/types.js +9 -0
- package/dist/src/gate/types.js.map +1 -0
- package/dist/src/index.d.ts +17 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +18 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/mcpl/channel-registry.d.ts +141 -0
- package/dist/src/mcpl/channel-registry.d.ts.map +1 -0
- package/dist/src/mcpl/channel-registry.js +647 -0
- package/dist/src/mcpl/channel-registry.js.map +1 -0
- package/dist/src/mcpl/checkpoint-manager.d.ts +79 -0
- package/dist/src/mcpl/checkpoint-manager.d.ts.map +1 -0
- package/dist/src/mcpl/checkpoint-manager.js +430 -0
- package/dist/src/mcpl/checkpoint-manager.js.map +1 -0
- package/dist/src/mcpl/errors.d.ts +52 -0
- package/dist/src/mcpl/errors.d.ts.map +1 -0
- package/dist/src/mcpl/errors.js +93 -0
- package/dist/src/mcpl/errors.js.map +1 -0
- package/dist/src/mcpl/feature-set-manager.d.ts +91 -0
- package/dist/src/mcpl/feature-set-manager.d.ts.map +1 -0
- package/dist/src/mcpl/feature-set-manager.js +250 -0
- package/dist/src/mcpl/feature-set-manager.js.map +1 -0
- package/dist/src/mcpl/hook-orchestrator.d.ts +51 -0
- package/dist/src/mcpl/hook-orchestrator.d.ts.map +1 -0
- package/dist/src/mcpl/hook-orchestrator.js +217 -0
- package/dist/src/mcpl/hook-orchestrator.js.map +1 -0
- package/dist/src/mcpl/index.d.ts +14 -0
- package/dist/src/mcpl/index.d.ts.map +1 -0
- package/dist/src/mcpl/index.js +21 -0
- package/dist/src/mcpl/index.js.map +1 -0
- package/dist/src/mcpl/inference-router.d.ts +67 -0
- package/dist/src/mcpl/inference-router.d.ts.map +1 -0
- package/dist/src/mcpl/inference-router.js +249 -0
- package/dist/src/mcpl/inference-router.js.map +1 -0
- package/dist/src/mcpl/push-handler.d.ts +60 -0
- package/dist/src/mcpl/push-handler.d.ts.map +1 -0
- package/dist/src/mcpl/push-handler.js +162 -0
- package/dist/src/mcpl/push-handler.js.map +1 -0
- package/dist/src/mcpl/scope-manager.d.ts +76 -0
- package/dist/src/mcpl/scope-manager.d.ts.map +1 -0
- package/dist/src/mcpl/scope-manager.js +213 -0
- package/dist/src/mcpl/scope-manager.js.map +1 -0
- package/dist/src/mcpl/server-connection.d.ts +174 -0
- package/dist/src/mcpl/server-connection.d.ts.map +1 -0
- package/dist/src/mcpl/server-connection.js +559 -0
- package/dist/src/mcpl/server-connection.js.map +1 -0
- package/dist/src/mcpl/server-registry.d.ts +63 -0
- package/dist/src/mcpl/server-registry.d.ts.map +1 -0
- package/dist/src/mcpl/server-registry.js +119 -0
- package/dist/src/mcpl/server-registry.js.map +1 -0
- package/dist/src/mcpl/types.d.ts +755 -0
- package/dist/src/mcpl/types.d.ts.map +1 -0
- package/dist/src/mcpl/types.js +48 -0
- package/dist/src/mcpl/types.js.map +1 -0
- package/dist/src/module-registry.d.ts +93 -0
- package/dist/src/module-registry.d.ts.map +1 -0
- package/dist/src/module-registry.js +386 -0
- package/dist/src/module-registry.js.map +1 -0
- package/dist/src/modules/api/index.d.ts +22 -0
- package/dist/src/modules/api/index.d.ts.map +1 -0
- package/dist/src/modules/api/index.js +63 -0
- package/dist/src/modules/api/index.js.map +1 -0
- package/dist/src/modules/discord/discord-js-client.d.ts +58 -0
- package/dist/src/modules/discord/discord-js-client.d.ts.map +1 -0
- package/dist/src/modules/discord/discord-js-client.js +273 -0
- package/dist/src/modules/discord/discord-js-client.js.map +1 -0
- package/dist/src/modules/discord/index.d.ts +82 -0
- package/dist/src/modules/discord/index.d.ts.map +1 -0
- package/dist/src/modules/discord/index.js +959 -0
- package/dist/src/modules/discord/index.js.map +1 -0
- package/dist/src/modules/discord/types.d.ts +327 -0
- package/dist/src/modules/discord/types.d.ts.map +1 -0
- package/dist/src/modules/discord/types.js +5 -0
- package/dist/src/modules/discord/types.js.map +1 -0
- package/dist/src/modules/index.d.ts +11 -0
- package/dist/src/modules/index.d.ts.map +1 -0
- package/dist/src/modules/index.js +7 -0
- package/dist/src/modules/index.js.map +1 -0
- package/dist/src/modules/workspace/index.d.ts +59 -0
- package/dist/src/modules/workspace/index.d.ts.map +1 -0
- package/dist/src/modules/workspace/index.js +831 -0
- package/dist/src/modules/workspace/index.js.map +1 -0
- package/dist/src/modules/workspace/sync.d.ts +48 -0
- package/dist/src/modules/workspace/sync.d.ts.map +1 -0
- package/dist/src/modules/workspace/sync.js +253 -0
- package/dist/src/modules/workspace/sync.js.map +1 -0
- package/dist/src/modules/workspace/types.d.ts +166 -0
- package/dist/src/modules/workspace/types.d.ts.map +1 -0
- package/dist/src/modules/workspace/types.js +5 -0
- package/dist/src/modules/workspace/types.js.map +1 -0
- package/dist/src/modules/workspace/watcher.d.ts +43 -0
- package/dist/src/modules/workspace/watcher.d.ts.map +1 -0
- package/dist/src/modules/workspace/watcher.js +120 -0
- package/dist/src/modules/workspace/watcher.js.map +1 -0
- package/dist/src/queue.d.ts +50 -0
- package/dist/src/queue.d.ts.map +1 -0
- package/dist/src/queue.js +95 -0
- package/dist/src/queue.js.map +1 -0
- package/dist/src/safe-slice.d.ts +8 -0
- package/dist/src/safe-slice.d.ts.map +1 -0
- package/dist/src/safe-slice.js +18 -0
- package/dist/src/safe-slice.js.map +1 -0
- package/dist/src/types/agent.d.ts +118 -0
- package/dist/src/types/agent.d.ts.map +1 -0
- package/dist/src/types/agent.js +2 -0
- package/dist/src/types/agent.js.map +1 -0
- package/dist/src/types/events.d.ts +220 -0
- package/dist/src/types/events.d.ts.map +1 -0
- package/dist/src/types/events.js +2 -0
- package/dist/src/types/events.js.map +1 -0
- package/dist/src/types/framework.d.ts +184 -0
- package/dist/src/types/framework.d.ts.map +1 -0
- package/dist/src/types/framework.js +2 -0
- package/dist/src/types/framework.js.map +1 -0
- package/dist/src/types/index.d.ts +7 -0
- package/dist/src/types/index.d.ts.map +1 -0
- package/dist/src/types/index.js +7 -0
- package/dist/src/types/index.js.map +1 -0
- package/dist/src/types/inference-log.d.ts +64 -0
- package/dist/src/types/inference-log.d.ts.map +1 -0
- package/dist/src/types/inference-log.js +5 -0
- package/dist/src/types/inference-log.js.map +1 -0
- package/dist/src/types/module.d.ts +302 -0
- package/dist/src/types/module.d.ts.map +1 -0
- package/dist/src/types/module.js +2 -0
- package/dist/src/types/module.js.map +1 -0
- package/dist/src/types/trace.d.ts +173 -0
- package/dist/src/types/trace.d.ts.map +1 -0
- package/dist/src/types/trace.js +2 -0
- package/dist/src/types/trace.js.map +1 -0
- package/dist/test/event-gate.test.d.ts +2 -0
- package/dist/test/event-gate.test.d.ts.map +1 -0
- package/dist/test/event-gate.test.js +535 -0
- package/dist/test/event-gate.test.js.map +1 -0
- package/dist/test/framework.test.d.ts +5 -0
- package/dist/test/framework.test.d.ts.map +1 -0
- package/dist/test/framework.test.js +738 -0
- package/dist/test/framework.test.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +58 -0
- package/src/agent.ts +512 -0
- package/src/api/mcp-server.ts +687 -0
- package/src/api/server.ts +1023 -0
- package/src/api/types.ts +542 -0
- package/src/framework.ts +2784 -0
- package/src/gate/event-gate.ts +623 -0
- package/src/gate/index.ts +12 -0
- package/src/gate/types.ts +112 -0
- package/src/index.ts +63 -0
- package/src/mcpl/channel-registry.ts +824 -0
- package/src/mcpl/checkpoint-manager.ts +545 -0
- package/src/mcpl/errors.ts +114 -0
- package/src/mcpl/feature-set-manager.ts +333 -0
- package/src/mcpl/hook-orchestrator.ts +281 -0
- package/src/mcpl/index.ts +134 -0
- package/src/mcpl/inference-router.ts +335 -0
- package/src/mcpl/push-handler.ts +232 -0
- package/src/mcpl/scope-manager.ts +262 -0
- package/src/mcpl/server-connection.ts +694 -0
- package/src/mcpl/server-registry.ts +144 -0
- package/src/mcpl/types.ts +991 -0
- package/src/module-registry.ts +547 -0
- package/src/modules/api/index.ts +94 -0
- package/src/modules/discord/discord-js-client.ts +353 -0
- package/src/modules/discord/index.ts +1146 -0
- package/src/modules/discord/types.ts +465 -0
- package/src/modules/index.ts +43 -0
- package/src/modules/workspace/index.ts +969 -0
- package/src/modules/workspace/sync.ts +314 -0
- package/src/modules/workspace/types.ts +202 -0
- package/src/modules/workspace/watcher.ts +142 -0
- package/src/queue.ts +106 -0
- package/src/safe-slice.ts +18 -0
- package/src/types/agent.ts +119 -0
- package/src/types/events.ts +252 -0
- package/src/types/framework.ts +211 -0
- package/src/types/index.ts +6 -0
- package/src/types/inference-log.ts +64 -0
- package/src/types/module.ts +367 -0
- package/src/types/trace.ts +196 -0
|
@@ -0,0 +1,559 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* McplServerConnection — manages a single JSON-RPC 2.0 connection to an MCPL server.
|
|
3
|
+
*
|
|
4
|
+
* Spawns a child process (stdio transport), performs the MCP initialize handshake
|
|
5
|
+
* with MCPL capability negotiation, and provides typed methods for all outbound
|
|
6
|
+
* MCPL messages plus EventEmitter events for inbound messages.
|
|
7
|
+
*/
|
|
8
|
+
import { spawn } from 'node:child_process';
|
|
9
|
+
import { createInterface } from 'node:readline';
|
|
10
|
+
import { EventEmitter } from 'node:events';
|
|
11
|
+
import { McplMethod } from './types.js';
|
|
12
|
+
/** Timeout for the initialize handshake in milliseconds.
|
|
13
|
+
* Spring Boot + JDA servers can take 5-10s to boot, so 30s is safe. */
|
|
14
|
+
const INITIALIZE_TIMEOUT_MS = 30_000;
|
|
15
|
+
/** MCP protocol version used in the initialize handshake. */
|
|
16
|
+
const MCP_PROTOCOL_VERSION = '2024-11-05';
|
|
17
|
+
/**
|
|
18
|
+
* McplServerConnection manages a single JSON-RPC 2.0 connection to an
|
|
19
|
+
* MCPL server over stdio. Use the static `connect()` factory to create
|
|
20
|
+
* and initialize a connection.
|
|
21
|
+
*
|
|
22
|
+
* Events emitted:
|
|
23
|
+
* - `'push-event'` — Server sent `push/event`
|
|
24
|
+
* - `'inference-request'` — Server sent `inference/request`
|
|
25
|
+
* - `'scope-elevate'` — Server sent `scope/elevate`
|
|
26
|
+
* - `'channels-register'` — Server sent `channels/register`
|
|
27
|
+
* - `'channels-changed'` — Server sent `channels/changed`
|
|
28
|
+
* - `'channels-incoming'` — Server sent `channels/incoming`
|
|
29
|
+
* - `'feature-sets-changed'` — Server sent `featureSets/changed`
|
|
30
|
+
* - `'error'` — Connection-level error
|
|
31
|
+
* - `'close'` — Connection closed
|
|
32
|
+
*/
|
|
33
|
+
export class McplServerConnection extends EventEmitter {
|
|
34
|
+
/** Unique server identifier from config. */
|
|
35
|
+
id;
|
|
36
|
+
/** MCPL capabilities negotiated during the initialize handshake, or null if the server does not support MCPL. */
|
|
37
|
+
capabilities;
|
|
38
|
+
process;
|
|
39
|
+
readline;
|
|
40
|
+
nextRequestId = 1;
|
|
41
|
+
pendingRequests = new Map();
|
|
42
|
+
closed = false;
|
|
43
|
+
// Event buffering: events emitted before ready() are queued, not lost
|
|
44
|
+
readyFlag = false;
|
|
45
|
+
bufferedEvents = [];
|
|
46
|
+
// Reconnect state (adapted from Anarchid/agent-framework@mcpl-module-proto)
|
|
47
|
+
config = null;
|
|
48
|
+
hostCapabilities = null;
|
|
49
|
+
reconnectEnabled = false;
|
|
50
|
+
reconnectIntervalMs = 5000;
|
|
51
|
+
reconnectTimer = null;
|
|
52
|
+
/**
|
|
53
|
+
* Private constructor. Use `McplServerConnection.connect()` instead.
|
|
54
|
+
*/
|
|
55
|
+
constructor(id, capabilities, childProcess, readline) {
|
|
56
|
+
super();
|
|
57
|
+
this.id = id;
|
|
58
|
+
this.capabilities = capabilities;
|
|
59
|
+
this.process = childProcess;
|
|
60
|
+
this.readline = readline;
|
|
61
|
+
// Skip setup for disconnected stubs (process/readline are null)
|
|
62
|
+
if (childProcess && readline) {
|
|
63
|
+
this.setupMessageRouting();
|
|
64
|
+
this.setupLifecycle();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// ==========================================================================
|
|
68
|
+
// Event buffering
|
|
69
|
+
// ==========================================================================
|
|
70
|
+
/**
|
|
71
|
+
* Mark the connection as ready — flushes any events that arrived between
|
|
72
|
+
* construction (when setupMessageRouting starts emitting) and now (when
|
|
73
|
+
* the caller has attached listeners via wireMcplEvents).
|
|
74
|
+
*/
|
|
75
|
+
ready() {
|
|
76
|
+
this.readyFlag = true;
|
|
77
|
+
for (const { event, args } of this.bufferedEvents) {
|
|
78
|
+
super.emit(event, ...args);
|
|
79
|
+
}
|
|
80
|
+
this.bufferedEvents = [];
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Override emit to buffer server→host events until ready() is called.
|
|
84
|
+
* Lifecycle events ('close', 'error', 'reconnect') always pass through.
|
|
85
|
+
*/
|
|
86
|
+
emit(event, ...args) {
|
|
87
|
+
const name = typeof event === 'string' ? event : '';
|
|
88
|
+
if (this.readyFlag || name === 'close' || name === 'error' || name === 'reconnect') {
|
|
89
|
+
return super.emit(event, ...args);
|
|
90
|
+
}
|
|
91
|
+
this.bufferedEvents.push({ event: name, args });
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
// ==========================================================================
|
|
95
|
+
// Static factory
|
|
96
|
+
// ==========================================================================
|
|
97
|
+
/**
|
|
98
|
+
* Spawn a server process, perform the MCP initialize handshake with MCPL
|
|
99
|
+
* capability negotiation, and return a ready-to-use connection.
|
|
100
|
+
*
|
|
101
|
+
* Throws if the process cannot be spawned or the handshake times out.
|
|
102
|
+
*/
|
|
103
|
+
static async connect(config, hostCapabilities) {
|
|
104
|
+
const child = spawn(config.command, config.args ?? [], {
|
|
105
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
106
|
+
env: { ...process.env, ...config.env },
|
|
107
|
+
});
|
|
108
|
+
// Fail fast if the process exits before the handshake completes
|
|
109
|
+
const earlyExitPromise = new Promise((_resolve, reject) => {
|
|
110
|
+
child.on('error', (err) => {
|
|
111
|
+
reject(new Error(`Failed to spawn MCPL server "${config.id}": ${err.message}`));
|
|
112
|
+
});
|
|
113
|
+
child.on('exit', (code) => {
|
|
114
|
+
reject(new Error(`MCPL server "${config.id}" exited before handshake (code ${code})`));
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
// Set up readline for newline-delimited JSON on stdout
|
|
118
|
+
const rl = createInterface({ input: child.stdout });
|
|
119
|
+
// -----------------------------------------------------------------------
|
|
120
|
+
// Perform initialize handshake
|
|
121
|
+
// -----------------------------------------------------------------------
|
|
122
|
+
// Step 1: Send `initialize` request
|
|
123
|
+
const initId = 0; // use id=0 for the handshake
|
|
124
|
+
const initRequest = {
|
|
125
|
+
jsonrpc: '2.0',
|
|
126
|
+
method: 'initialize',
|
|
127
|
+
id: initId,
|
|
128
|
+
params: {
|
|
129
|
+
protocolVersion: MCP_PROTOCOL_VERSION,
|
|
130
|
+
capabilities: {
|
|
131
|
+
experimental: {
|
|
132
|
+
mcpl: hostCapabilities,
|
|
133
|
+
},
|
|
134
|
+
},
|
|
135
|
+
clientInfo: {
|
|
136
|
+
name: 'agent-framework',
|
|
137
|
+
version: '1.0.0',
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
};
|
|
141
|
+
child.stdin.write(JSON.stringify(initRequest) + '\n');
|
|
142
|
+
// Step 2: Wait for the initialize response
|
|
143
|
+
const initResponse = await Promise.race([
|
|
144
|
+
new Promise((resolve, reject) => {
|
|
145
|
+
const onLine = (line) => {
|
|
146
|
+
try {
|
|
147
|
+
const msg = JSON.parse(line);
|
|
148
|
+
if (msg.id === initId) {
|
|
149
|
+
rl.off('line', onLine);
|
|
150
|
+
if (msg.error) {
|
|
151
|
+
reject(new Error(`MCPL server "${config.id}" initialize error: ${msg.error.message}`));
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
resolve(msg);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
// Ignore non-JSON lines (e.g. logback output from Java servers)
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
rl.on('line', onLine);
|
|
163
|
+
}),
|
|
164
|
+
earlyExitPromise,
|
|
165
|
+
new Promise((_resolve, reject) => setTimeout(() => {
|
|
166
|
+
reject(new Error(`MCPL server "${config.id}" initialize handshake timed out`));
|
|
167
|
+
}, INITIALIZE_TIMEOUT_MS)),
|
|
168
|
+
]);
|
|
169
|
+
// Parse MCPL capabilities from the response
|
|
170
|
+
const result = initResponse.result;
|
|
171
|
+
const caps = result?.capabilities;
|
|
172
|
+
const experimental = caps?.experimental;
|
|
173
|
+
const mcplCaps = experimental?.mcpl ?? null;
|
|
174
|
+
// Step 3: Send `initialized` notification (no id)
|
|
175
|
+
const initializedNotification = {
|
|
176
|
+
jsonrpc: '2.0',
|
|
177
|
+
method: 'notifications/initialized',
|
|
178
|
+
};
|
|
179
|
+
child.stdin.write(JSON.stringify(initializedNotification) + '\n');
|
|
180
|
+
// Remove the early-exit listener so normal close handling takes over
|
|
181
|
+
child.removeAllListeners('exit');
|
|
182
|
+
child.removeAllListeners('error');
|
|
183
|
+
const connection = new McplServerConnection(config.id, mcplCaps, child, rl);
|
|
184
|
+
// Store config for reconnection
|
|
185
|
+
if (config.reconnect) {
|
|
186
|
+
connection.config = config;
|
|
187
|
+
connection.hostCapabilities = hostCapabilities;
|
|
188
|
+
connection.reconnectEnabled = true;
|
|
189
|
+
connection.reconnectIntervalMs = config.reconnectIntervalMs ?? 5000;
|
|
190
|
+
}
|
|
191
|
+
return connection;
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Connect with reconnect support.
|
|
195
|
+
* When `config.reconnect` is true and the initial connection fails,
|
|
196
|
+
* resolves immediately with null capabilities and retries in the background.
|
|
197
|
+
* Adapted from Anarchid/agent-framework@mcpl-module-proto.
|
|
198
|
+
*/
|
|
199
|
+
static async connectWithReconnect(config, hostCapabilities) {
|
|
200
|
+
try {
|
|
201
|
+
return await McplServerConnection.connect(config, hostCapabilities);
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
if (!config.reconnect) {
|
|
205
|
+
throw error;
|
|
206
|
+
}
|
|
207
|
+
// Non-blocking start: create a disconnected stub that will reconnect in background
|
|
208
|
+
console.error(`MCPL server "${config.id}" initial connect failed, will retry:`, error.message);
|
|
209
|
+
return McplServerConnection.createDisconnectedStub(config, hostCapabilities);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Create a disconnected stub connection that will reconnect in the background.
|
|
214
|
+
* Used when initial connect fails and reconnect is enabled.
|
|
215
|
+
* @internal
|
|
216
|
+
*/
|
|
217
|
+
static createDisconnectedStub(config, hostCapabilities) {
|
|
218
|
+
// Use null! for process/readline since the connection is closed
|
|
219
|
+
const stub = new McplServerConnection(config.id, null, null, null);
|
|
220
|
+
stub.closed = true;
|
|
221
|
+
stub.config = config;
|
|
222
|
+
stub.hostCapabilities = hostCapabilities;
|
|
223
|
+
stub.reconnectEnabled = true;
|
|
224
|
+
stub.reconnectIntervalMs = config.reconnectIntervalMs ?? 5000;
|
|
225
|
+
// Schedule background reconnect
|
|
226
|
+
stub.scheduleReconnect();
|
|
227
|
+
return stub;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Extract internals for transfer during reconnection.
|
|
231
|
+
* Strips the source connection — caller takes ownership of the process/readline.
|
|
232
|
+
* @internal Used only by attemptReconnect().
|
|
233
|
+
*/
|
|
234
|
+
extractInternals() {
|
|
235
|
+
const result = { process: this.process, readline: this.readline };
|
|
236
|
+
// Prevent the source connection from killing the transferred process
|
|
237
|
+
this.closed = true;
|
|
238
|
+
return result;
|
|
239
|
+
}
|
|
240
|
+
// ==========================================================================
|
|
241
|
+
// Outbound requests (return Promises)
|
|
242
|
+
// ==========================================================================
|
|
243
|
+
/** Send `context/beforeInference` and await result. */
|
|
244
|
+
sendBeforeInference(params) {
|
|
245
|
+
return this.sendRequest(McplMethod.BeforeInference, params);
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Send `context/afterInference`.
|
|
249
|
+
* When `blocking` is true, sends as a request and awaits the result.
|
|
250
|
+
* When `blocking` is false (or omitted), sends as a notification.
|
|
251
|
+
*/
|
|
252
|
+
sendAfterInference(params, blocking) {
|
|
253
|
+
if (blocking) {
|
|
254
|
+
return this.sendRequest(McplMethod.AfterInference, params);
|
|
255
|
+
}
|
|
256
|
+
this.sendNotification(McplMethod.AfterInference, params);
|
|
257
|
+
return Promise.resolve();
|
|
258
|
+
}
|
|
259
|
+
/** Send `featureSets/update` notification. */
|
|
260
|
+
sendFeatureSetsUpdate(params) {
|
|
261
|
+
this.sendNotification(McplMethod.FeatureSetsUpdate, params);
|
|
262
|
+
}
|
|
263
|
+
/** Send `inference/chunk` notification. */
|
|
264
|
+
sendInferenceChunk(params) {
|
|
265
|
+
this.sendNotification(McplMethod.InferenceChunk, params);
|
|
266
|
+
}
|
|
267
|
+
/** Send `state/rollback` request and await result. */
|
|
268
|
+
sendStateRollback(params) {
|
|
269
|
+
return this.sendRequest(McplMethod.StateRollback, params);
|
|
270
|
+
}
|
|
271
|
+
/** Send `channels/open` request and await result. */
|
|
272
|
+
sendChannelsOpen(params) {
|
|
273
|
+
return this.sendRequest(McplMethod.ChannelsOpen, params);
|
|
274
|
+
}
|
|
275
|
+
/** Send `channels/close` request and await result. */
|
|
276
|
+
sendChannelsClose(params) {
|
|
277
|
+
return this.sendRequest(McplMethod.ChannelsClose, params);
|
|
278
|
+
}
|
|
279
|
+
/** Send `channels/list` request and await result. */
|
|
280
|
+
sendChannelsList() {
|
|
281
|
+
return this.sendRequest(McplMethod.ChannelsList, {});
|
|
282
|
+
}
|
|
283
|
+
/**
|
|
284
|
+
* Send `channels/publish`.
|
|
285
|
+
* May be sent as a request (if an ACK is desired) or notification.
|
|
286
|
+
* When `params.stream` is true, sends as a notification (no ACK).
|
|
287
|
+
*/
|
|
288
|
+
sendChannelsPublish(params) {
|
|
289
|
+
if (params.stream) {
|
|
290
|
+
this.sendNotification(McplMethod.ChannelsPublish, params);
|
|
291
|
+
return Promise.resolve();
|
|
292
|
+
}
|
|
293
|
+
return this.sendRequest(McplMethod.ChannelsPublish, params);
|
|
294
|
+
}
|
|
295
|
+
/** Send `channels/outgoing/chunk` notification. */
|
|
296
|
+
sendChannelsOutgoingChunk(params) {
|
|
297
|
+
this.sendNotification(McplMethod.ChannelsOutgoingChunk, params);
|
|
298
|
+
}
|
|
299
|
+
/** Send `channels/outgoing/complete` notification. */
|
|
300
|
+
sendChannelsOutgoingComplete(params) {
|
|
301
|
+
this.sendNotification(McplMethod.ChannelsOutgoingComplete, params);
|
|
302
|
+
}
|
|
303
|
+
/** Send `channels/typing` notification (best-effort). */
|
|
304
|
+
sendChannelsTyping(channelId) {
|
|
305
|
+
this.sendNotification(McplMethod.ChannelsTyping, { channelId });
|
|
306
|
+
}
|
|
307
|
+
// ==========================================================================
|
|
308
|
+
// Standard MCP methods
|
|
309
|
+
// ==========================================================================
|
|
310
|
+
/** Send `tools/list` and return the server's tool definitions. */
|
|
311
|
+
sendToolsList() {
|
|
312
|
+
return this.sendRequest('tools/list', {});
|
|
313
|
+
}
|
|
314
|
+
/** Send `tools/call` and return the result. Optionally includes state/checkpoint for stateful tools. */
|
|
315
|
+
sendToolsCall(name, args, stateParams) {
|
|
316
|
+
const params = { name, arguments: args };
|
|
317
|
+
if (stateParams?.state !== undefined)
|
|
318
|
+
params.state = stateParams.state;
|
|
319
|
+
if (stateParams?.checkpoint !== undefined)
|
|
320
|
+
params.checkpoint = stateParams.checkpoint;
|
|
321
|
+
return this.sendRequest('tools/call', params);
|
|
322
|
+
}
|
|
323
|
+
// ==========================================================================
|
|
324
|
+
// Lifecycle
|
|
325
|
+
// ==========================================================================
|
|
326
|
+
/** Close the connection: disable reconnect, kill the child process, and clean up resources. */
|
|
327
|
+
async close() {
|
|
328
|
+
// Disable reconnect before closing — explicit close means stop retrying
|
|
329
|
+
this.reconnectEnabled = false;
|
|
330
|
+
if (this.reconnectTimer) {
|
|
331
|
+
clearTimeout(this.reconnectTimer);
|
|
332
|
+
this.reconnectTimer = null;
|
|
333
|
+
}
|
|
334
|
+
if (this.closed) {
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
this.closed = true;
|
|
338
|
+
// Reject all pending requests
|
|
339
|
+
for (const [id, pending] of this.pendingRequests) {
|
|
340
|
+
pending.reject(new Error(`Connection to MCPL server "${this.id}" closed while awaiting response for ${pending.method} (id=${id})`));
|
|
341
|
+
}
|
|
342
|
+
this.pendingRequests.clear();
|
|
343
|
+
// Close readline
|
|
344
|
+
if (this.readline) {
|
|
345
|
+
this.readline.close();
|
|
346
|
+
}
|
|
347
|
+
// Kill the child process
|
|
348
|
+
if (this.process && !this.process.killed) {
|
|
349
|
+
this.process.kill();
|
|
350
|
+
}
|
|
351
|
+
// Wait for process to actually exit
|
|
352
|
+
if (this.process) {
|
|
353
|
+
await new Promise((resolve) => {
|
|
354
|
+
if (this.process.exitCode !== null || this.process.killed) {
|
|
355
|
+
resolve();
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
this.process.once('exit', () => resolve());
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
this.emit('close');
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Schedule a background reconnection attempt.
|
|
366
|
+
*/
|
|
367
|
+
scheduleReconnect() {
|
|
368
|
+
if (!this.reconnectEnabled || this.reconnectTimer)
|
|
369
|
+
return;
|
|
370
|
+
this.reconnectTimer = setTimeout(() => {
|
|
371
|
+
this.reconnectTimer = null;
|
|
372
|
+
this.attemptReconnect();
|
|
373
|
+
}, this.reconnectIntervalMs);
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Attempt to reconnect by spawning a new process and performing the handshake.
|
|
377
|
+
*/
|
|
378
|
+
async attemptReconnect() {
|
|
379
|
+
if (!this.reconnectEnabled || !this.config || !this.hostCapabilities)
|
|
380
|
+
return;
|
|
381
|
+
try {
|
|
382
|
+
const fresh = await McplServerConnection.connect(this.config, this.hostCapabilities);
|
|
383
|
+
const internals = fresh.extractInternals();
|
|
384
|
+
// Transfer state from fresh connection to this instance
|
|
385
|
+
this.process = internals.process;
|
|
386
|
+
this.readline = internals.readline;
|
|
387
|
+
this.capabilities = fresh.capabilities;
|
|
388
|
+
this.closed = false;
|
|
389
|
+
this.nextRequestId = 1;
|
|
390
|
+
this.pendingRequests.clear();
|
|
391
|
+
// Re-wire message routing and lifecycle on the new process
|
|
392
|
+
this.setupMessageRouting();
|
|
393
|
+
this.setupLifecycle();
|
|
394
|
+
this.readyFlag = true; // Listeners already attached from initial wire
|
|
395
|
+
console.error(`MCPL server "${this.id}" reconnected successfully`);
|
|
396
|
+
this.emit('reconnect');
|
|
397
|
+
}
|
|
398
|
+
catch (error) {
|
|
399
|
+
console.error(`MCPL server "${this.id}" reconnect failed:`, error.message);
|
|
400
|
+
this.scheduleReconnect();
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
// ==========================================================================
|
|
404
|
+
// Private: message sending
|
|
405
|
+
// ==========================================================================
|
|
406
|
+
/**
|
|
407
|
+
* Send a JSON-RPC request and return a promise that resolves with the result
|
|
408
|
+
* or rejects with a JSON-RPC error.
|
|
409
|
+
*/
|
|
410
|
+
sendRequest(method, params) {
|
|
411
|
+
if (this.closed) {
|
|
412
|
+
return Promise.reject(new Error(`Cannot send request: connection to "${this.id}" is closed`));
|
|
413
|
+
}
|
|
414
|
+
const id = this.nextRequestId++;
|
|
415
|
+
const request = {
|
|
416
|
+
jsonrpc: '2.0',
|
|
417
|
+
method,
|
|
418
|
+
id,
|
|
419
|
+
params,
|
|
420
|
+
};
|
|
421
|
+
return new Promise((resolve, reject) => {
|
|
422
|
+
this.pendingRequests.set(id, { resolve, reject, method });
|
|
423
|
+
this.process.stdin.write(JSON.stringify(request) + '\n');
|
|
424
|
+
});
|
|
425
|
+
}
|
|
426
|
+
/**
|
|
427
|
+
* Send a JSON-RPC notification (no `id`, no response expected).
|
|
428
|
+
*/
|
|
429
|
+
sendNotification(method, params) {
|
|
430
|
+
if (this.closed) {
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
const notification = {
|
|
434
|
+
jsonrpc: '2.0',
|
|
435
|
+
method,
|
|
436
|
+
params,
|
|
437
|
+
};
|
|
438
|
+
this.process.stdin.write(JSON.stringify(notification) + '\n');
|
|
439
|
+
}
|
|
440
|
+
// ==========================================================================
|
|
441
|
+
// Private: inbound message routing
|
|
442
|
+
// ==========================================================================
|
|
443
|
+
/**
|
|
444
|
+
* Map from JSON-RPC method name to the EventEmitter event name.
|
|
445
|
+
*/
|
|
446
|
+
static METHOD_TO_EVENT = {
|
|
447
|
+
[McplMethod.PushEvent]: 'push-event',
|
|
448
|
+
[McplMethod.InferenceRequest]: 'inference-request',
|
|
449
|
+
[McplMethod.ScopeElevate]: 'scope-elevate',
|
|
450
|
+
[McplMethod.ChannelsRegister]: 'channels-register',
|
|
451
|
+
[McplMethod.ChannelsChanged]: 'channels-changed',
|
|
452
|
+
[McplMethod.ChannelsIncoming]: 'channels-incoming',
|
|
453
|
+
[McplMethod.FeatureSetsChanged]: 'feature-sets-changed',
|
|
454
|
+
'notifications/tools/list_changed': 'tools-list-changed',
|
|
455
|
+
};
|
|
456
|
+
/**
|
|
457
|
+
* Wire up readline to route incoming JSON-RPC messages.
|
|
458
|
+
*/
|
|
459
|
+
setupMessageRouting() {
|
|
460
|
+
this.readline.on('line', (line) => {
|
|
461
|
+
let msg;
|
|
462
|
+
try {
|
|
463
|
+
msg = JSON.parse(line);
|
|
464
|
+
}
|
|
465
|
+
catch {
|
|
466
|
+
// Ignore non-JSON lines
|
|
467
|
+
return;
|
|
468
|
+
}
|
|
469
|
+
// Is this a response to one of our outbound requests?
|
|
470
|
+
if ('id' in msg && msg.id != null && !('method' in msg)) {
|
|
471
|
+
this.handleResponse(msg);
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
// It is an inbound request or notification from the server
|
|
475
|
+
const request = msg;
|
|
476
|
+
const eventName = McplServerConnection.METHOD_TO_EVENT[request.method];
|
|
477
|
+
if (eventName) {
|
|
478
|
+
// Emit the typed event with params and (for requests) a respond callback
|
|
479
|
+
if (request.id != null) {
|
|
480
|
+
// Server expects a response — provide a respond helper
|
|
481
|
+
this.emit(eventName, request.params, {
|
|
482
|
+
id: request.id,
|
|
483
|
+
respond: (result) => this.sendResponse(request.id, result),
|
|
484
|
+
respondError: (code, message, data) => this.sendErrorResponse(request.id, code, message, data),
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
else {
|
|
488
|
+
// Notification — no response expected
|
|
489
|
+
this.emit(eventName, request.params);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
/**
|
|
495
|
+
* Handle a JSON-RPC response by resolving/rejecting the corresponding pending request.
|
|
496
|
+
*/
|
|
497
|
+
handleResponse(response) {
|
|
498
|
+
const pending = this.pendingRequests.get(response.id);
|
|
499
|
+
if (!pending) {
|
|
500
|
+
return; // Orphaned response — ignore
|
|
501
|
+
}
|
|
502
|
+
this.pendingRequests.delete(response.id);
|
|
503
|
+
if (response.error) {
|
|
504
|
+
pending.reject(new Error(`MCPL server "${this.id}" returned error for ${pending.method}: [${response.error.code}] ${response.error.message}`));
|
|
505
|
+
}
|
|
506
|
+
else {
|
|
507
|
+
pending.resolve(response.result);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* Send a successful JSON-RPC response back to the server.
|
|
512
|
+
*/
|
|
513
|
+
sendResponse(id, result) {
|
|
514
|
+
if (this.closed)
|
|
515
|
+
return;
|
|
516
|
+
const response = { jsonrpc: '2.0', id, result };
|
|
517
|
+
this.process.stdin.write(JSON.stringify(response) + '\n');
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* Send a JSON-RPC error response back to the server.
|
|
521
|
+
*/
|
|
522
|
+
sendErrorResponse(id, code, message, data) {
|
|
523
|
+
if (this.closed)
|
|
524
|
+
return;
|
|
525
|
+
const response = {
|
|
526
|
+
jsonrpc: '2.0',
|
|
527
|
+
id,
|
|
528
|
+
error: { code, message, data },
|
|
529
|
+
};
|
|
530
|
+
this.process.stdin.write(JSON.stringify(response) + '\n');
|
|
531
|
+
}
|
|
532
|
+
// ==========================================================================
|
|
533
|
+
// Private: lifecycle
|
|
534
|
+
// ==========================================================================
|
|
535
|
+
/**
|
|
536
|
+
* Set up process error/exit handlers.
|
|
537
|
+
*/
|
|
538
|
+
setupLifecycle() {
|
|
539
|
+
this.process.on('error', (err) => {
|
|
540
|
+
this.emit('error', new Error(`MCPL server "${this.id}" process error: ${err.message}`));
|
|
541
|
+
});
|
|
542
|
+
this.process.on('exit', (code, signal) => {
|
|
543
|
+
if (!this.closed) {
|
|
544
|
+
this.closed = true;
|
|
545
|
+
// Reject all pending requests
|
|
546
|
+
for (const [id, pending] of this.pendingRequests) {
|
|
547
|
+
pending.reject(new Error(`MCPL server "${this.id}" exited unexpectedly (code=${code}, signal=${signal}) while awaiting ${pending.method} (id=${id})`));
|
|
548
|
+
}
|
|
549
|
+
this.pendingRequests.clear();
|
|
550
|
+
this.emit('close', code, signal);
|
|
551
|
+
// Schedule reconnect if enabled (unexpected exit triggers auto-reconnect)
|
|
552
|
+
if (this.reconnectEnabled) {
|
|
553
|
+
this.scheduleReconnect();
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
//# sourceMappingURL=server-connection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-connection.js","sourceRoot":"","sources":["../../../src/mcpl/server-connection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* McplServerRegistry — manages all connected MCPL server connections.
|
|
3
|
+
*
|
|
4
|
+
* Provides lookup by id, capability filtering, and feature set matching.
|
|
5
|
+
*/
|
|
6
|
+
import type { McplServerConfig, McplHostCapabilities } from './types.js';
|
|
7
|
+
import { McplServerConnection } from './server-connection.js';
|
|
8
|
+
/**
|
|
9
|
+
* Capability keys that can be queried via `getServersWithCapability`.
|
|
10
|
+
*/
|
|
11
|
+
export type McplCapabilityQuery = 'pushEvents' | 'contextHooks.beforeInference' | 'contextHooks.afterInference' | 'inferenceRequest' | 'modelInfo';
|
|
12
|
+
/**
|
|
13
|
+
* Container that manages all connected MCPL servers.
|
|
14
|
+
*
|
|
15
|
+
* Provides methods to add/remove servers, look up by id, and query
|
|
16
|
+
* servers by advertised capabilities or feature set names.
|
|
17
|
+
*/
|
|
18
|
+
export declare class McplServerRegistry {
|
|
19
|
+
private servers;
|
|
20
|
+
/**
|
|
21
|
+
* Connect to an MCPL server and register it.
|
|
22
|
+
*
|
|
23
|
+
* Throws if a server with the same id is already registered, or if
|
|
24
|
+
* the connection/handshake fails.
|
|
25
|
+
*/
|
|
26
|
+
addServer(config: McplServerConfig, hostCapabilities: McplHostCapabilities): Promise<McplServerConnection>;
|
|
27
|
+
/**
|
|
28
|
+
* Disconnect and remove a server by id.
|
|
29
|
+
*
|
|
30
|
+
* No-op if the server is not registered.
|
|
31
|
+
*/
|
|
32
|
+
removeServer(id: string): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Get a server connection by id, or null if not found.
|
|
35
|
+
*/
|
|
36
|
+
getServer(id: string): McplServerConnection | null;
|
|
37
|
+
/**
|
|
38
|
+
* Get all currently connected servers.
|
|
39
|
+
*/
|
|
40
|
+
getAllServers(): McplServerConnection[];
|
|
41
|
+
/**
|
|
42
|
+
* Get all servers that advertise a specific capability.
|
|
43
|
+
*
|
|
44
|
+
* Supported capability queries:
|
|
45
|
+
* - `'pushEvents'` — `capabilities.pushEvents === true`
|
|
46
|
+
* - `'contextHooks.beforeInference'` — `capabilities.contextHooks?.beforeInference === true`
|
|
47
|
+
* - `'contextHooks.afterInference'` — `capabilities.contextHooks?.afterInference` is truthy
|
|
48
|
+
* - `'inferenceRequest'` — `capabilities.inferenceRequest` is truthy
|
|
49
|
+
* - `'modelInfo'` — `capabilities.modelInfo === true`
|
|
50
|
+
*/
|
|
51
|
+
getServersWithCapability(cap: McplCapabilityQuery): McplServerConnection[];
|
|
52
|
+
/**
|
|
53
|
+
* Get all servers that declare a feature set with the given name.
|
|
54
|
+
*
|
|
55
|
+
* Checks `capabilities.featureSets` for a key matching `featureSet`.
|
|
56
|
+
*/
|
|
57
|
+
getServersForFeatureSet(featureSet: string): McplServerConnection[];
|
|
58
|
+
/**
|
|
59
|
+
* Close all server connections and clear the registry.
|
|
60
|
+
*/
|
|
61
|
+
closeAll(): Promise<void>;
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=server-registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server-registry.d.ts","sourceRoot":"","sources":["../../../src/mcpl/server-registry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAE9D;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAC3B,YAAY,GACZ,8BAA8B,GAC9B,6BAA6B,GAC7B,kBAAkB,GAClB,WAAW,CAAC;AAEhB;;;;;GAKG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,OAAO,CAA2C;IAE1D;;;;;OAKG;IACG,SAAS,CACb,MAAM,EAAE,gBAAgB,EACxB,gBAAgB,EAAE,oBAAoB,GACrC,OAAO,CAAC,oBAAoB,CAAC;IAyBhC;;;;OAIG;IACG,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAS7C;;OAEG;IACH,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,oBAAoB,GAAG,IAAI;IAIlD;;OAEG;IACH,aAAa,IAAI,oBAAoB,EAAE;IAIvC;;;;;;;;;OASG;IACH,wBAAwB,CAAC,GAAG,EAAE,mBAAmB,GAAG,oBAAoB,EAAE;IAsB1E;;;;OAIG;IACH,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,oBAAoB,EAAE;IAQnE;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAKhC"}
|