@modelprofile.com/mcp-crossharness 5.0.0 → 5.2.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.
@@ -2,19 +2,22 @@ import * as plugins from './plugins.js';
2
2
  import { commitinfo } from './00_commitinfo_data.js';
3
3
  import { ConnectionRegistry } from './classes.connectionregistry.js';
4
4
  import { DispatchRegistry } from './classes.dispatchregistry.js';
5
- const harnessNameSchema = plugins.z.enum(['claudecode', 'opencode', 'codex']);
5
+ import { CrossHarnessMcpToolRegistrar } from './classes.mcptoolregistrar.js';
6
6
  export class CrossHarnessMcpServer {
7
+ registrar;
7
8
  connections;
8
9
  dispatches;
9
10
  activeServer;
11
+ activeTransport;
12
+ transportCloseNeedsRetry = false;
10
13
  stdinEndHandler;
11
14
  stdinEndSource;
12
15
  closePromise;
13
- resourceShutdownPromise;
14
16
  startCalled = false;
15
17
  constructor(connectionsArg = new ConnectionRegistry(), dispatchesArg = new DispatchRegistry()) {
16
- this.connections = connectionsArg;
17
- this.dispatches = dispatchesArg;
18
+ this.registrar = new CrossHarnessMcpToolRegistrar(connectionsArg, dispatchesArg);
19
+ this.connections = this.registrar.connections;
20
+ this.dispatches = this.registrar.dispatches;
18
21
  }
19
22
  async start(transportArg = new plugins.StdioServerTransport(), stdinArg = process.stdin) {
20
23
  if (this.startCalled)
@@ -24,216 +27,88 @@ export class CrossHarnessMcpServer {
24
27
  name: 'mcp-crossharness',
25
28
  version: commitinfo.version,
26
29
  });
27
- server.registerTool('connect_harness', {
28
- title: 'Connect to harness server',
29
- description: 'Establish an explicit connection to an allowlisted harness web server. The exact origin must be listed in CROSSHARNESS_ALLOWED_SERVER_URLS. OpenCode uses http(s), Codex uses ws(s), and Claude Code is rejected because it exposes no URL-addressable session server. Returns a connectionId required by every connection-scoped operation; list_connections remains global.',
30
- inputSchema: {
31
- harness: harnessNameSchema,
32
- serverUrl: plugins.z.string().max(2048).url().describe('Allowlisted harness server origin'),
33
- directory: plugins.z
34
- .string()
35
- .max(4096)
36
- .startsWith('/')
37
- .describe('Absolute project directory on the harness server'),
38
- },
39
- }, async (args, extra) => this.wrapToolCall(async () => {
40
- const info = await this.connections.connect(args.harness, args.serverUrl, args.directory, extra.signal);
41
- return this.describeConnection(info);
42
- }));
43
- server.registerTool('disconnect_harness', {
44
- title: 'Disconnect harness server',
45
- description: 'Close and remove an established harness connection. In-flight requests fail; async dispatch records remain inspectable with check_reply.',
46
- inputSchema: {
47
- connectionId: plugins.z.string().max(128).describe('Connection id returned by connect_harness'),
48
- },
49
- }, async (args, extra) => this.wrapToolCall(async () => this.describeConnection(await this.connections.disconnect(args.connectionId))));
50
- server.registerTool('list_connections', {
51
- title: 'List harness connections',
52
- description: 'List explicit harness web-server connections established in this MCP process.',
53
- inputSchema: {},
54
- }, async () => this.wrapToolCall(async () => {
55
- const connections = this.connections.list();
56
- return connections.length > 0
57
- ? connections.map((connection) => this.describeConnection(connection)).join('\n\n')
58
- : 'No harness server connections established.';
59
- }));
60
- server.registerTool('connection_status', {
61
- title: 'Check harness connection',
62
- description: 'Run the protocol health check for one explicit harness server connection.',
63
- inputSchema: {
64
- connectionId: plugins.z.string().max(128).describe('Connection id returned by connect_harness'),
65
- },
66
- }, async (args) => this.wrapToolCall(async () => {
67
- const status = await this.connections.get(args.connectionId).getStatus();
68
- return `${this.describeConnection(status)}\nhealthy: ${status.healthy ? 'yes' : 'no'}\ndetail: ${status.detail}`;
69
- }));
70
- server.registerTool('list_chats', {
71
- title: 'List harness chats',
72
- description: 'List chats from the server and directory bound to an explicit connection. No local session stores are read.',
73
- inputSchema: {
74
- connectionId: plugins.z.string().max(128).describe('Connection id returned by connect_harness'),
75
- limit: plugins.z.number().int().min(1).max(100).optional(),
76
- },
77
- }, async (args) => this.wrapToolCall(async () => {
78
- const chats = await this.connections.get(args.connectionId).listChats(args.limit ?? 10);
79
- if (chats.length === 0)
80
- return 'No chats found for this connection.';
81
- return [
82
- 'harness\tchatId\tupdatedAt\tactivity\ttitle',
83
- ...chats.map((chat) => `${chat.harness}\t${chat.chatId}\t${chat.updatedAt}\t${chat.isActive ? 'active' : 'idle'}\t${chat.title.replace(/\s+/g, ' ').slice(0, 120)}`),
84
- ].join('\n');
85
- }));
86
- server.registerTool('read_chat', {
87
- title: 'Read harness chat',
88
- description: 'Read a chat through the harness web server bound to an explicit connection.',
89
- inputSchema: {
90
- connectionId: plugins.z.string().max(128).describe('Connection id returned by connect_harness'),
91
- chatId: plugins.z.string().min(1).max(1024),
92
- limit: plugins.z.number().int().min(1).max(500).optional(),
93
- maxChars: plugins.z.number().int().min(200).max(50000).optional(),
94
- },
95
- }, async (args) => this.wrapToolCall(async () => {
96
- const transcript = await this.connections
97
- .get(args.connectionId)
98
- .readChat(args.chatId, args.limit ?? 20, args.maxChars ?? 2000);
99
- const header = [
100
- `harness: ${transcript.harness}`,
101
- `chatId: ${transcript.chatId}`,
102
- `title: ${transcript.title}`,
103
- `directory: ${transcript.directory}`,
104
- transcript.totalMessages === undefined
105
- ? `messages: showing ${transcript.messages.length}; server total unavailable`
106
- : `messages: showing ${transcript.messages.length} of ${transcript.totalMessages}`,
107
- ].join('\n');
108
- const body = transcript.messages
109
- .map((message) => `-- [${message.role}]${message.timestamp ? ` ${message.timestamp}` : ''}\n${message.text}`)
110
- .join('\n');
111
- return `${header}\n\n${body}`;
112
- }));
113
- server.registerTool('send_message', {
114
- title: 'Send message through harness server',
115
- description: 'Send a message only through the harness web server bound to an explicit connection and wait for the reply. There is no CLI, process, local-store, discovery, or retry fallback.',
116
- inputSchema: {
117
- connectionId: plugins.z.string().max(128).describe('Connection id returned by connect_harness'),
118
- chatId: plugins.z.string().min(1).max(1024),
119
- message: plugins.z.string().min(1).max(1024 * 1024),
120
- timeoutSeconds: plugins.z.number().int().min(1).max(3600).optional(),
121
- },
122
- }, async (args, extra) => this.wrapToolCall(async () => {
123
- const result = await this.connections
124
- .get(args.connectionId)
125
- .sendMessage(args.chatId, args.message, args.timeoutSeconds ?? 300, extra.signal);
126
- return `${result.reply}\n\n[crossharness transport: ${result.via}]`;
127
- }));
128
- server.registerTool('send_message_async', {
129
- title: 'Send message through harness server asynchronously',
130
- description: 'Start a server-only send and return a dispatchId immediately. Both this connectionId and the dispatchId are required by check_reply.',
131
- inputSchema: {
132
- connectionId: plugins.z.string().max(128).describe('Connection id returned by connect_harness'),
133
- chatId: plugins.z.string().min(1).max(1024),
134
- message: plugins.z.string().min(1).max(1024 * 1024),
135
- timeoutSeconds: plugins.z.number().int().min(1).max(3600).optional(),
136
- },
137
- }, async (args) => this.wrapToolCall(async () => {
138
- const connection = this.connections.get(args.connectionId);
139
- const record = this.dispatches.track(args.connectionId, connection.harness, args.chatId, () => connection.sendMessage(args.chatId, args.message, args.timeoutSeconds ?? 900));
140
- return [
141
- `connectionId: ${record.connectionId}`,
142
- `dispatchId: ${record.dispatchId}`,
143
- `harness: ${record.harness}`,
144
- `chatId: ${record.chatId}`,
145
- `startedAt: ${record.startedAt}`,
146
- ].join('\n');
147
- }));
148
- server.registerTool('check_reply', {
149
- title: 'Check async server send',
150
- description: 'Check an asynchronous send. The connectionId must own the dispatch. Records remain inspectable after disconnect.',
151
- inputSchema: {
152
- connectionId: plugins.z.string().max(128).describe('Connection id used for send_message_async'),
153
- dispatchId: plugins.z.string().max(128).describe('Dispatch id returned by send_message_async'),
154
- waitSeconds: plugins.z.number().int().min(0).max(60).optional(),
155
- },
156
- }, async (args, extra) => this.wrapToolCall(async () => {
157
- const record = await this.dispatches.waitFor(args.connectionId, args.dispatchId, (args.waitSeconds ?? 0) * 1000, extra.signal);
158
- if (!record)
159
- throw new Error('unknown dispatchId for this connectionId');
160
- const header = [
161
- `connectionId: ${record.connectionId}`,
162
- `dispatchId: ${record.dispatchId}`,
163
- `status: ${record.status}`,
164
- `harness: ${record.harness}`,
165
- `chatId: ${record.chatId}`,
166
- `startedAt: ${record.startedAt}`,
167
- ...(record.completedAt ? [`completedAt: ${record.completedAt}`] : []),
168
- ].join('\n');
169
- if (record.status === 'working')
170
- return `${header}\n\nStill working.`;
171
- if (record.status === 'failed')
172
- return `${header}\n\nError: ${record.error}`;
173
- return `${header}\n\n${record.reply}\n\n[crossharness transport: ${record.via}]`;
174
- }));
30
+ this.registrar.register(server);
175
31
  this.activeServer = server;
32
+ this.activeTransport = transportArg;
176
33
  this.stdinEndHandler = () => this.triggerClose();
177
34
  this.stdinEndSource = stdinArg;
178
35
  this.stdinEndSource.once('end', this.stdinEndHandler);
179
36
  this.stdinEndSource.once('close', this.stdinEndHandler);
180
37
  this.stdinEndSource.once('error', this.stdinEndHandler);
181
- server.server.onclose = () => {
182
- this.clearTransportReferences();
183
- void this.ensureResourceShutdown().catch(() => undefined);
184
- };
38
+ server.server.onclose = () => this.triggerClose();
185
39
  try {
186
40
  await server.connect(transportArg);
187
41
  }
188
42
  catch (error) {
189
- this.clearTransportReferences();
190
- await transportArg.close().catch(() => { });
191
- await this.ensureResourceShutdown();
43
+ let cleanupError;
44
+ try {
45
+ await this.close();
46
+ }
47
+ catch (errorArg) {
48
+ cleanupError = errorArg;
49
+ }
50
+ if (cleanupError !== undefined) {
51
+ const cleanupErrors = cleanupError instanceof AggregateError
52
+ ? cleanupError.errors
53
+ : [cleanupError];
54
+ throw new AggregateError([error, ...cleanupErrors], 'Crossharness MCP startup and cleanup failed.');
55
+ }
192
56
  throw error;
193
57
  }
194
58
  }
195
59
  async close() {
196
60
  if (this.closePromise)
197
61
  return this.closePromise;
198
- this.closePromise = (async () => {
62
+ let finalPromise;
63
+ const closeOperation = Promise.resolve().then(async () => {
64
+ const errors = [];
199
65
  const server = this.activeServer;
200
- let closeError;
66
+ const transport = this.activeTransport;
67
+ let transportClosed = transport === undefined;
201
68
  try {
202
- if (server)
203
- await server.close();
69
+ if (transport) {
70
+ if (this.transportCloseNeedsRetry || !server) {
71
+ await transport.close();
72
+ }
73
+ else {
74
+ await server.close();
75
+ }
76
+ }
77
+ transportClosed = true;
78
+ this.transportCloseNeedsRetry = false;
204
79
  }
205
80
  catch (error) {
206
- closeError = error;
81
+ this.transportCloseNeedsRetry = true;
82
+ errors.push(error);
207
83
  }
208
- finally {
84
+ if (transportClosed
85
+ && this.activeServer === server
86
+ && this.activeTransport === transport) {
209
87
  this.clearTransportReferences();
210
- await this.ensureResourceShutdown();
211
88
  }
212
- if (closeError)
213
- throw closeError;
214
- })().finally(() => {
215
- this.closePromise = undefined;
89
+ try {
90
+ await this.registrar.close();
91
+ }
92
+ catch (error) {
93
+ errors.push(error);
94
+ }
95
+ if (errors.length === 1) {
96
+ throw errors[0];
97
+ }
98
+ if (errors.length > 1) {
99
+ throw new AggregateError(errors, 'Crossharness MCP transport and tool-resource shutdown failed.');
100
+ }
216
101
  });
217
- return this.closePromise;
102
+ finalPromise = closeOperation.finally(() => {
103
+ if (this.closePromise === finalPromise)
104
+ this.closePromise = undefined;
105
+ });
106
+ this.closePromise = finalPromise;
107
+ return finalPromise;
218
108
  }
219
109
  triggerClose() {
220
110
  void this.close().catch(() => { });
221
111
  }
222
- ensureResourceShutdown() {
223
- if (this.resourceShutdownPromise)
224
- return this.resourceShutdownPromise;
225
- let shutdownPromise;
226
- shutdownPromise = this.connections.closeAll().finally(() => {
227
- this.dispatches.dispose();
228
- }).catch((errorArg) => {
229
- if (this.resourceShutdownPromise === shutdownPromise) {
230
- this.resourceShutdownPromise = undefined;
231
- }
232
- throw errorArg;
233
- });
234
- this.resourceShutdownPromise = shutdownPromise;
235
- return shutdownPromise;
236
- }
237
112
  clearTransportReferences() {
238
113
  if (this.stdinEndHandler) {
239
114
  this.stdinEndSource?.off('end', this.stdinEndHandler);
@@ -243,34 +118,7 @@ export class CrossHarnessMcpServer {
243
118
  this.stdinEndHandler = undefined;
244
119
  this.stdinEndSource = undefined;
245
120
  this.activeServer = undefined;
246
- }
247
- describeConnection(infoArg) {
248
- return [
249
- `connectionId: ${infoArg.connectionId}`,
250
- `harness: ${infoArg.harness}`,
251
- `serverUrl: ${infoArg.serverUrl}`,
252
- `directory: ${infoArg.directory}`,
253
- `state: ${infoArg.state}`,
254
- `connectedAt: ${infoArg.connectedAt}`,
255
- ...(infoArg.serverVersion ? [`serverVersion: ${infoArg.serverVersion}`] : []),
256
- ].join('\n');
257
- }
258
- async wrapToolCall(handlerArg) {
259
- try {
260
- const text = await handlerArg();
261
- return { content: [{ type: 'text', text: text.slice(0, 100000) }] };
262
- }
263
- catch (error) {
264
- return {
265
- content: [
266
- {
267
- type: 'text',
268
- text: `Error: ${error instanceof Error ? error.message : String(error)}`.slice(0, 100000),
269
- },
270
- ],
271
- isError: true,
272
- };
273
- }
121
+ this.activeTransport = undefined;
274
122
  }
275
123
  }
276
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5tY3BzZXJ2ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLm1jcHNlcnZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFckQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDckUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFFakUsTUFBTSxpQkFBaUIsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLFlBQVksRUFBRSxVQUFVLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztBQUU5RSxNQUFNLE9BQU8scUJBQXFCO0lBQ2hCLFdBQVcsQ0FBcUI7SUFDaEMsVUFBVSxDQUFtQjtJQUNyQyxZQUFZLENBQXFEO0lBQ2pFLGVBQWUsQ0FBMkI7SUFDMUMsY0FBYyxDQUFvQztJQUNsRCxZQUFZLENBQTRCO0lBQ3hDLHVCQUF1QixDQUE0QjtJQUNuRCxXQUFXLEdBQUcsS0FBSyxDQUFDO0lBRTVCLFlBQVksY0FBYyxHQUFHLElBQUksa0JBQWtCLEVBQUUsRUFBRSxhQUFhLEdBQUcsSUFBSSxnQkFBZ0IsRUFBRTtRQUMzRixJQUFJLENBQUMsV0FBVyxHQUFHLGNBQWMsQ0FBQztRQUNsQyxJQUFJLENBQUMsVUFBVSxHQUFHLGFBQWEsQ0FBQztJQUNsQyxDQUFDO0lBRU0sS0FBSyxDQUFDLEtBQUssQ0FDaEIsZUFBa0MsSUFBSSxPQUFPLENBQUMsb0JBQW9CLEVBQUUsRUFDcEUsV0FBa0MsT0FBTyxDQUFDLEtBQUs7UUFFL0MsSUFBSSxJQUFJLENBQUMsV0FBVztZQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0RBQWdELENBQUMsQ0FBQztRQUN4RixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FB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
124
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5tY3BzZXJ2ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLm1jcHNlcnZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDckQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDckUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDakUsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFFN0UsTUFBTSxPQUFPLHFCQUFxQjtJQUNoQixTQUFTLENBQStCO0lBQ3hDLFdBQVcsQ0FBcUI7SUFDaEMsVUFBVSxDQUFtQjtJQUNyQyxZQUFZLENBQXFEO0lBQ2pFLGVBQWUsQ0FBZ0M7SUFDL0Msd0JBQXdCLEdBQUcsS0FBSyxDQUFDO0lBQ2pDLGVBQWUsQ0FBMkI7SUFDMUMsY0FBYyxDQUFvQztJQUNsRCxZQUFZLENBQTRCO0lBQ3hDLFdBQVcsR0FBRyxLQUFLLENBQUM7SUFFNUIsWUFBWSxjQUFjLEdBQUcsSUFBSSxrQkFBa0IsRUFBRSxFQUFFLGFBQWEsR0FBRyxJQUFJLGdCQUFnQixFQUFFO1FBQzNGLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSw0QkFBNEIsQ0FBQyxjQUFjLEVBQUUsYUFBYSxDQUFDLENBQUM7UUFDakYsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQztRQUM5QyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDO0lBQzlDLENBQUM7SUFFTSxLQUFLLENBQUMsS0FBSyxDQUNoQixlQUFrQyxJQUFJLE9BQU8sQ0FBQyxvQkFBb0IsRUFBRSxFQUNwRSxXQUFrQyxPQUFPLENBQUMsS0FBSztRQUUv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
@@ -0,0 +1,26 @@
1
+ import * as plugins from './plugins.js';
2
+ import { ConnectionRegistry } from './classes.connectionregistry.js';
3
+ import { DispatchRegistry } from './classes.dispatchregistry.js';
4
+ /**
5
+ * Registers the Crossharness tool surface on an externally owned MCP server and
6
+ * owns only the resources used by those tools.
7
+ */
8
+ export declare class CrossHarnessMcpToolRegistrar {
9
+ readonly connections: ConnectionRegistry;
10
+ readonly dispatches: DispatchRegistry;
11
+ private registeredTools;
12
+ private registeredServer;
13
+ private registered;
14
+ private closeStarted;
15
+ private closePromise;
16
+ private resourceShutdownPromise;
17
+ constructor(connectionsArg?: ConnectionRegistry, dispatchesArg?: DispatchRegistry);
18
+ /** Register the tool surface before the externally owned MCP server connects. */
19
+ register(serverArg: InstanceType<typeof plugins.McpServer>): void;
20
+ /** Close the externally owned MCP server before closing this registrar. */
21
+ close(): Promise<void>;
22
+ private removeRegisteredTools;
23
+ private ensureResourceShutdown;
24
+ private describeConnection;
25
+ private wrapToolCall;
26
+ }