chainlesschain 0.47.9 → 0.49.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/bin/chainlesschain.js +0 -0
- package/package.json +1 -1
- package/src/assets/web-panel/.build-hash +1 -1
- package/src/assets/web-panel/assets/{AppLayout-6SPt_8Y_.js → AppLayout-Rvi759IS.js} +1 -1
- package/src/assets/web-panel/assets/Dashboard-BS-tzGNj.css +1 -0
- package/src/assets/web-panel/assets/{Dashboard-Br7kCwKJ.js → Dashboard-DBhFxXYQ.js} +2 -2
- package/src/assets/web-panel/assets/{index-tN-8TosE.js → index-uL0cZ8N_.js} +2 -2
- package/src/assets/web-panel/index.html +2 -2
- package/src/commands/codegen.js +303 -0
- package/src/commands/collab.js +482 -0
- package/src/commands/crosschain.js +382 -0
- package/src/commands/dbevo.js +388 -0
- package/src/commands/dev.js +411 -0
- package/src/commands/federation.js +427 -0
- package/src/commands/fusion.js +332 -0
- package/src/commands/governance.js +505 -0
- package/src/commands/hardening.js +110 -0
- package/src/commands/incentive.js +373 -0
- package/src/commands/inference.js +304 -0
- package/src/commands/infra.js +361 -0
- package/src/commands/kg.js +371 -0
- package/src/commands/marketplace.js +326 -0
- package/src/commands/mcp.js +97 -18
- package/src/commands/nlprog.js +329 -0
- package/src/commands/ops.js +408 -0
- package/src/commands/perception.js +385 -0
- package/src/commands/pqc.js +34 -0
- package/src/commands/privacy.js +345 -0
- package/src/commands/quantization.js +280 -0
- package/src/commands/recommend.js +336 -0
- package/src/commands/reputation.js +349 -0
- package/src/commands/runtime.js +500 -0
- package/src/commands/sla.js +352 -0
- package/src/commands/stress.js +252 -0
- package/src/commands/tech.js +268 -0
- package/src/commands/tenant.js +576 -0
- package/src/commands/trust.js +366 -0
- package/src/harness/mcp-client.js +330 -54
- package/src/index.js +112 -0
- package/src/lib/aiops.js +523 -0
- package/src/lib/autonomous-developer.js +524 -0
- package/src/lib/code-agent.js +442 -0
- package/src/lib/collaboration-governance.js +556 -0
- package/src/lib/community-governance.js +649 -0
- package/src/lib/content-recommendation.js +600 -0
- package/src/lib/cross-chain.js +669 -0
- package/src/lib/dbevo.js +669 -0
- package/src/lib/decentral-infra.js +445 -0
- package/src/lib/federation-hardening.js +587 -0
- package/src/lib/hardening-manager.js +409 -0
- package/src/lib/inference-network.js +407 -0
- package/src/lib/knowledge-graph.js +530 -0
- package/src/lib/mcp-client.js +3 -0
- package/src/lib/multimodal.js +698 -0
- package/src/lib/nl-programming.js +595 -0
- package/src/lib/perception.js +500 -0
- package/src/lib/pqc-manager.js +141 -9
- package/src/lib/privacy-computing.js +575 -0
- package/src/lib/protocol-fusion.js +535 -0
- package/src/lib/quantization.js +362 -0
- package/src/lib/reputation-optimizer.js +509 -0
- package/src/lib/skill-marketplace.js +397 -0
- package/src/lib/sla-manager.js +484 -0
- package/src/lib/stress-tester.js +383 -0
- package/src/lib/tech-learning-engine.js +651 -0
- package/src/lib/tenant-saas.js +831 -0
- package/src/lib/token-incentive.js +513 -0
- package/src/lib/trust-security.js +473 -0
- package/src/lib/universal-runtime.js +771 -0
- package/src/assets/web-panel/assets/Dashboard-CKeMmCoT.css +0 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Lightweight MCP (Model Context Protocol) client.
|
|
3
|
-
* Implements JSON-RPC 2.0 over stdio transport
|
|
3
|
+
* Implements JSON-RPC 2.0 over stdio transport plus a minimal HTTP transport
|
|
4
|
+
* (Streamable HTTP / SSE — one-shot request/response) without the official SDK.
|
|
4
5
|
*
|
|
5
6
|
* Canonical location (moved from src/lib/mcp-client.js as part of the
|
|
6
7
|
* CLI Runtime Convergence roadmap, Phase 3). src/lib/mcp-client.js is now a
|
|
@@ -10,6 +11,15 @@
|
|
|
10
11
|
import { spawn } from "child_process";
|
|
11
12
|
import { EventEmitter } from "events";
|
|
12
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Injectable dependencies — overridable from tests.
|
|
16
|
+
* `fetch` defaults to the global fetch (Node 18+).
|
|
17
|
+
*/
|
|
18
|
+
export const _deps = {
|
|
19
|
+
spawn,
|
|
20
|
+
fetch: (...args) => globalThis.fetch(...args),
|
|
21
|
+
};
|
|
22
|
+
|
|
13
23
|
/**
|
|
14
24
|
* MCP Server connection states.
|
|
15
25
|
*/
|
|
@@ -20,6 +30,46 @@ export const ServerState = {
|
|
|
20
30
|
ERROR: "error",
|
|
21
31
|
};
|
|
22
32
|
|
|
33
|
+
/** Transport kinds that carry a URL (no stdio process). */
|
|
34
|
+
const URL_TRANSPORTS = new Set(["http", "https", "sse", "ws", "wss"]);
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Infer the transport kind for a server config. Falls back to "stdio".
|
|
38
|
+
* Prefers an explicit `transport` field; otherwise derives from URL scheme
|
|
39
|
+
* (http → http, https → https, ws/wss preserved); otherwise stdio.
|
|
40
|
+
*/
|
|
41
|
+
export function inferTransport(config) {
|
|
42
|
+
if (!config || typeof config !== "object") return "stdio";
|
|
43
|
+
if (typeof config.transport === "string" && config.transport.length > 0) {
|
|
44
|
+
return config.transport.toLowerCase();
|
|
45
|
+
}
|
|
46
|
+
if (typeof config.url === "string" && config.url.length > 0) {
|
|
47
|
+
try {
|
|
48
|
+
const proto = new URL(config.url).protocol.replace(":", "").toLowerCase();
|
|
49
|
+
if (
|
|
50
|
+
proto === "http" ||
|
|
51
|
+
proto === "https" ||
|
|
52
|
+
proto === "ws" ||
|
|
53
|
+
proto === "wss"
|
|
54
|
+
) {
|
|
55
|
+
return proto;
|
|
56
|
+
}
|
|
57
|
+
} catch (_e) {
|
|
58
|
+
// fall through to stdio
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return "stdio";
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** True for transports that talk over HTTP(S) — i.e. use fetch. */
|
|
65
|
+
export function isHttpTransport(transportKind) {
|
|
66
|
+
return (
|
|
67
|
+
transportKind === "http" ||
|
|
68
|
+
transportKind === "https" ||
|
|
69
|
+
transportKind === "sse"
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
23
73
|
/**
|
|
24
74
|
* MCP Client — manages connections to MCP servers.
|
|
25
75
|
*/
|
|
@@ -31,19 +81,26 @@ export class MCPClient extends EventEmitter {
|
|
|
31
81
|
}
|
|
32
82
|
|
|
33
83
|
/**
|
|
34
|
-
* Connect to an MCP server
|
|
84
|
+
* Connect to an MCP server. Routes to stdio or HTTP transport based on
|
|
85
|
+
* `config.transport` / `config.url` (see `inferTransport`).
|
|
86
|
+
*
|
|
35
87
|
* @param {string} name - Server name
|
|
36
|
-
* @param {object} config - { command
|
|
88
|
+
* @param {object} config - { command?, args?, env?, url?, transport? }
|
|
37
89
|
*/
|
|
38
90
|
async connect(name, config) {
|
|
39
91
|
if (this.servers.has(name)) {
|
|
40
92
|
throw new Error(`Server "${name}" already connected`);
|
|
41
93
|
}
|
|
42
94
|
|
|
95
|
+
const transportKind = inferTransport(config);
|
|
43
96
|
const entry = {
|
|
44
97
|
config,
|
|
98
|
+
transportKind,
|
|
45
99
|
state: ServerState.CONNECTING,
|
|
46
100
|
process: null,
|
|
101
|
+
httpUrl: null,
|
|
102
|
+
httpHeaders: {},
|
|
103
|
+
httpSessionId: null,
|
|
47
104
|
tools: [],
|
|
48
105
|
resources: [],
|
|
49
106
|
prompts: [],
|
|
@@ -54,30 +111,47 @@ export class MCPClient extends EventEmitter {
|
|
|
54
111
|
this.servers.set(name, entry);
|
|
55
112
|
|
|
56
113
|
try {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
114
|
+
if (isHttpTransport(transportKind)) {
|
|
115
|
+
if (!config.url) {
|
|
116
|
+
throw new Error(`HTTP transport requires a url (server "${name}")`);
|
|
117
|
+
}
|
|
118
|
+
entry.httpUrl = config.url;
|
|
119
|
+
entry.httpHeaders = { ...(config.headers || {}) };
|
|
120
|
+
} else if (transportKind === "stdio") {
|
|
121
|
+
if (!config.command) {
|
|
122
|
+
throw new Error(
|
|
123
|
+
`stdio transport requires a command (server "${name}")`,
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
const proc = _deps.spawn(config.command, config.args || [], {
|
|
127
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
128
|
+
env: { ...process.env, ...(config.env || {}) },
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
entry.process = proc;
|
|
132
|
+
|
|
133
|
+
proc.stdout.on("data", (data) => {
|
|
134
|
+
this._handleData(name, data.toString("utf8"));
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
proc.stderr.on("data", (data) => {
|
|
138
|
+
this.emit("server-error", { name, error: data.toString("utf8") });
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
proc.on("close", (code) => {
|
|
142
|
+
entry.state = ServerState.DISCONNECTED;
|
|
143
|
+
this.emit("server-disconnected", { name, code });
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
proc.on("error", (err) => {
|
|
147
|
+
entry.state = ServerState.ERROR;
|
|
148
|
+
this.emit("server-error", { name, error: err.message });
|
|
149
|
+
});
|
|
150
|
+
} else {
|
|
151
|
+
throw new Error(
|
|
152
|
+
`transport "${transportKind}" is not supported by this client`,
|
|
153
|
+
);
|
|
154
|
+
}
|
|
81
155
|
|
|
82
156
|
// Initialize MCP protocol
|
|
83
157
|
const initResult = await this._sendRequest(name, "initialize", {
|
|
@@ -138,6 +212,17 @@ export class MCPClient extends EventEmitter {
|
|
|
138
212
|
if (entry.process) {
|
|
139
213
|
entry.process.kill();
|
|
140
214
|
}
|
|
215
|
+
// HTTP sessions: best-effort DELETE to free server-side state.
|
|
216
|
+
if (entry.httpUrl && entry.httpSessionId) {
|
|
217
|
+
try {
|
|
218
|
+
await _deps.fetch(entry.httpUrl, {
|
|
219
|
+
method: "DELETE",
|
|
220
|
+
headers: { "Mcp-Session-Id": entry.httpSessionId },
|
|
221
|
+
});
|
|
222
|
+
} catch (_e) {
|
|
223
|
+
// ignore — disconnect is best-effort
|
|
224
|
+
}
|
|
225
|
+
}
|
|
141
226
|
|
|
142
227
|
entry.state = ServerState.DISCONNECTED;
|
|
143
228
|
this.servers.delete(name);
|
|
@@ -227,9 +312,15 @@ export class MCPClient extends EventEmitter {
|
|
|
227
312
|
// ─── Internal JSON-RPC transport ──────────────────────────────
|
|
228
313
|
|
|
229
314
|
_sendRequest(serverName, method, params) {
|
|
315
|
+
const entry = this.servers.get(serverName);
|
|
316
|
+
if (!entry) return Promise.reject(new Error("Server not available"));
|
|
317
|
+
|
|
318
|
+
if (entry.httpUrl) {
|
|
319
|
+
return this._sendHttpRequest(serverName, method, params);
|
|
320
|
+
}
|
|
321
|
+
|
|
230
322
|
return new Promise((resolve, reject) => {
|
|
231
|
-
|
|
232
|
-
if (!entry || !entry.process) {
|
|
323
|
+
if (!entry.process) {
|
|
233
324
|
return reject(new Error("Server not available"));
|
|
234
325
|
}
|
|
235
326
|
|
|
@@ -263,7 +354,15 @@ export class MCPClient extends EventEmitter {
|
|
|
263
354
|
|
|
264
355
|
_sendNotification(serverName, method, params) {
|
|
265
356
|
const entry = this.servers.get(serverName);
|
|
266
|
-
if (!entry
|
|
357
|
+
if (!entry) return;
|
|
358
|
+
|
|
359
|
+
if (entry.httpUrl) {
|
|
360
|
+
// Fire-and-forget HTTP notification (no id, no response expected).
|
|
361
|
+
this._sendHttpNotification(serverName, method, params);
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
if (!entry.process) return;
|
|
267
366
|
|
|
268
367
|
const message = JSON.stringify({
|
|
269
368
|
jsonrpc: "2.0",
|
|
@@ -278,6 +377,102 @@ export class MCPClient extends EventEmitter {
|
|
|
278
377
|
}
|
|
279
378
|
}
|
|
280
379
|
|
|
380
|
+
/**
|
|
381
|
+
* Send a JSON-RPC request over HTTP (Streamable HTTP per MCP spec).
|
|
382
|
+
* Accepts responses as either `application/json` or `text/event-stream`.
|
|
383
|
+
* Captures `Mcp-Session-Id` header from the first response for reuse.
|
|
384
|
+
*/
|
|
385
|
+
async _sendHttpRequest(serverName, method, params) {
|
|
386
|
+
const entry = this.servers.get(serverName);
|
|
387
|
+
if (!entry || !entry.httpUrl) {
|
|
388
|
+
throw new Error("Server not available");
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
const id = this._nextId++;
|
|
392
|
+
const body = JSON.stringify({ jsonrpc: "2.0", id, method, params });
|
|
393
|
+
const headers = {
|
|
394
|
+
"Content-Type": "application/json",
|
|
395
|
+
Accept: "application/json, text/event-stream",
|
|
396
|
+
...(entry.httpHeaders || {}),
|
|
397
|
+
};
|
|
398
|
+
if (entry.httpSessionId) {
|
|
399
|
+
headers["Mcp-Session-Id"] = entry.httpSessionId;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
const response = await _deps.fetch(entry.httpUrl, {
|
|
403
|
+
method: "POST",
|
|
404
|
+
headers,
|
|
405
|
+
body,
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
// Capture session id (server may emit on initialize response only)
|
|
409
|
+
const sessionId =
|
|
410
|
+
(response.headers && typeof response.headers.get === "function"
|
|
411
|
+
? response.headers.get("mcp-session-id") ||
|
|
412
|
+
response.headers.get("Mcp-Session-Id")
|
|
413
|
+
: null) || null;
|
|
414
|
+
if (sessionId && !entry.httpSessionId) {
|
|
415
|
+
entry.httpSessionId = sessionId;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
if (!response.ok) {
|
|
419
|
+
const text =
|
|
420
|
+
typeof response.text === "function" ? await response.text() : "";
|
|
421
|
+
throw new Error(
|
|
422
|
+
`HTTP ${response.status}${text ? `: ${text.slice(0, 200)}` : ""}`,
|
|
423
|
+
);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
const contentType = response.headers?.get
|
|
427
|
+
? String(response.headers.get("content-type") || "").toLowerCase()
|
|
428
|
+
: "";
|
|
429
|
+
|
|
430
|
+
let envelope;
|
|
431
|
+
if (contentType.includes("text/event-stream")) {
|
|
432
|
+
envelope = await _extractSseResponse(response, id);
|
|
433
|
+
} else {
|
|
434
|
+
envelope =
|
|
435
|
+
typeof response.json === "function"
|
|
436
|
+
? await response.json()
|
|
437
|
+
: JSON.parse(
|
|
438
|
+
typeof response.text === "function" ? await response.text() : "",
|
|
439
|
+
);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
if (!envelope || typeof envelope !== "object") {
|
|
443
|
+
throw new Error("Empty or invalid JSON-RPC response");
|
|
444
|
+
}
|
|
445
|
+
if (envelope.error) {
|
|
446
|
+
throw new Error(envelope.error.message || "Unknown error");
|
|
447
|
+
}
|
|
448
|
+
return envelope.result;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/** Fire-and-forget JSON-RPC notification over HTTP. Errors swallowed. */
|
|
452
|
+
_sendHttpNotification(serverName, method, params) {
|
|
453
|
+
const entry = this.servers.get(serverName);
|
|
454
|
+
if (!entry || !entry.httpUrl) return;
|
|
455
|
+
const body = JSON.stringify({ jsonrpc: "2.0", method, params });
|
|
456
|
+
const headers = {
|
|
457
|
+
"Content-Type": "application/json",
|
|
458
|
+
Accept: "application/json, text/event-stream",
|
|
459
|
+
...(entry.httpHeaders || {}),
|
|
460
|
+
};
|
|
461
|
+
if (entry.httpSessionId) {
|
|
462
|
+
headers["Mcp-Session-Id"] = entry.httpSessionId;
|
|
463
|
+
}
|
|
464
|
+
try {
|
|
465
|
+
const p = _deps.fetch(entry.httpUrl, {
|
|
466
|
+
method: "POST",
|
|
467
|
+
headers,
|
|
468
|
+
body,
|
|
469
|
+
});
|
|
470
|
+
if (p && typeof p.catch === "function") p.catch(() => {});
|
|
471
|
+
} catch (_e) {
|
|
472
|
+
// ignore
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
281
476
|
_handleData(serverName, data) {
|
|
282
477
|
const entry = this.servers.get(serverName);
|
|
283
478
|
if (!entry) return;
|
|
@@ -330,41 +525,127 @@ export class MCPClient extends EventEmitter {
|
|
|
330
525
|
}
|
|
331
526
|
}
|
|
332
527
|
|
|
528
|
+
/**
|
|
529
|
+
* Parse a `text/event-stream` HTTP response body and return the first
|
|
530
|
+
* JSON-RPC envelope whose id matches `requestId`. Tolerates multiple
|
|
531
|
+
* `data:` chunks, comments, and non-JSON-RPC events.
|
|
532
|
+
*/
|
|
533
|
+
async function _extractSseResponse(response, requestId) {
|
|
534
|
+
let text;
|
|
535
|
+
if (typeof response.text === "function") {
|
|
536
|
+
text = await response.text();
|
|
537
|
+
} else if (response.body && typeof response.body.getReader === "function") {
|
|
538
|
+
const reader = response.body.getReader();
|
|
539
|
+
const decoder = new TextDecoder("utf-8");
|
|
540
|
+
const chunks = [];
|
|
541
|
+
while (true) {
|
|
542
|
+
const { value, done } = await reader.read();
|
|
543
|
+
if (done) break;
|
|
544
|
+
chunks.push(decoder.decode(value, { stream: true }));
|
|
545
|
+
}
|
|
546
|
+
chunks.push(decoder.decode());
|
|
547
|
+
text = chunks.join("");
|
|
548
|
+
} else {
|
|
549
|
+
throw new Error("SSE response is not readable");
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// Split into events on blank line, parse each event's concatenated `data:` lines.
|
|
553
|
+
const events = text.split(/\r?\n\r?\n/);
|
|
554
|
+
for (const event of events) {
|
|
555
|
+
const dataLines = [];
|
|
556
|
+
for (const line of event.split(/\r?\n/)) {
|
|
557
|
+
if (line.startsWith(":")) continue; // comment
|
|
558
|
+
if (line.startsWith("data:")) {
|
|
559
|
+
dataLines.push(line.slice(5).replace(/^ /, ""));
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
if (dataLines.length === 0) continue;
|
|
563
|
+
try {
|
|
564
|
+
const payload = JSON.parse(dataLines.join("\n"));
|
|
565
|
+
if (payload && payload.jsonrpc === "2.0" && payload.id === requestId) {
|
|
566
|
+
return payload;
|
|
567
|
+
}
|
|
568
|
+
} catch (_e) {
|
|
569
|
+
// skip non-JSON data events
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
throw new Error(`SSE stream ended without a response for id ${requestId}`);
|
|
573
|
+
}
|
|
574
|
+
|
|
333
575
|
/**
|
|
334
576
|
* MCP server configuration storage.
|
|
335
|
-
* Persists server configs in the database.
|
|
577
|
+
* Persists server configs in the database. Supports both stdio (command+args)
|
|
578
|
+
* and url-based transports (http/sse/ws). URL-based rows may have a null
|
|
579
|
+
* command.
|
|
336
580
|
*/
|
|
337
581
|
export class MCPServerConfig {
|
|
338
582
|
constructor(db) {
|
|
339
583
|
this.db = db;
|
|
340
584
|
this._ensureTable();
|
|
585
|
+
this._migrateSchema();
|
|
341
586
|
}
|
|
342
587
|
|
|
343
588
|
_ensureTable() {
|
|
344
589
|
this.db.exec(`
|
|
345
590
|
CREATE TABLE IF NOT EXISTS mcp_servers (
|
|
346
591
|
name TEXT PRIMARY KEY,
|
|
347
|
-
command TEXT
|
|
592
|
+
command TEXT,
|
|
348
593
|
args TEXT DEFAULT '[]',
|
|
349
594
|
env TEXT DEFAULT '{}',
|
|
350
595
|
auto_connect INTEGER DEFAULT 0,
|
|
596
|
+
url TEXT,
|
|
597
|
+
transport TEXT DEFAULT 'stdio',
|
|
351
598
|
created_at TEXT DEFAULT (datetime('now')),
|
|
352
599
|
updated_at TEXT DEFAULT (datetime('now'))
|
|
353
600
|
)
|
|
354
601
|
`);
|
|
355
602
|
}
|
|
356
603
|
|
|
604
|
+
/**
|
|
605
|
+
* Idempotent schema migration for databases that predate url/transport
|
|
606
|
+
* columns. Silently skipped on mocks or anything that doesn't expose
|
|
607
|
+
* `pragma()`.
|
|
608
|
+
*/
|
|
609
|
+
_migrateSchema() {
|
|
610
|
+
try {
|
|
611
|
+
const info =
|
|
612
|
+
typeof this.db.pragma === "function"
|
|
613
|
+
? this.db.pragma("table_info(mcp_servers)")
|
|
614
|
+
: null;
|
|
615
|
+
if (!Array.isArray(info) || info.length === 0) return;
|
|
616
|
+
const cols = new Set(info.map((c) => c.name));
|
|
617
|
+
if (!cols.has("url")) {
|
|
618
|
+
this.db.exec("ALTER TABLE mcp_servers ADD COLUMN url TEXT");
|
|
619
|
+
}
|
|
620
|
+
if (!cols.has("transport")) {
|
|
621
|
+
this.db.exec(
|
|
622
|
+
"ALTER TABLE mcp_servers ADD COLUMN transport TEXT DEFAULT 'stdio'",
|
|
623
|
+
);
|
|
624
|
+
}
|
|
625
|
+
} catch (_e) {
|
|
626
|
+
// Best-effort; non-SQLite mocks silently skip.
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
|
|
357
630
|
add(name, config) {
|
|
631
|
+
const url = config.url || null;
|
|
632
|
+
const transport =
|
|
633
|
+
config.transport || (url ? inferTransport({ url }) : "stdio");
|
|
634
|
+
if (!url && !config.command) {
|
|
635
|
+
throw new Error("MCP server config requires either command or url");
|
|
636
|
+
}
|
|
358
637
|
this.db
|
|
359
638
|
.prepare(
|
|
360
|
-
"INSERT OR REPLACE INTO mcp_servers (name, command, args, env, auto_connect, updated_at) VALUES (?, ?, ?, ?, ?, datetime('now'))",
|
|
639
|
+
"INSERT OR REPLACE INTO mcp_servers (name, command, args, env, auto_connect, url, transport, updated_at) VALUES (?, ?, ?, ?, ?, ?, ?, datetime('now'))",
|
|
361
640
|
)
|
|
362
641
|
.run(
|
|
363
642
|
name,
|
|
364
|
-
config.command,
|
|
643
|
+
config.command || null,
|
|
365
644
|
JSON.stringify(config.args || []),
|
|
366
645
|
JSON.stringify(config.env || {}),
|
|
367
646
|
config.autoConnect ? 1 : 0,
|
|
647
|
+
url,
|
|
648
|
+
transport,
|
|
368
649
|
);
|
|
369
650
|
}
|
|
370
651
|
|
|
@@ -375,43 +656,38 @@ export class MCPServerConfig {
|
|
|
375
656
|
return result.changes > 0;
|
|
376
657
|
}
|
|
377
658
|
|
|
378
|
-
|
|
379
|
-
const row = this.db
|
|
380
|
-
.prepare("SELECT * FROM mcp_servers WHERE name = ?")
|
|
381
|
-
.get(name);
|
|
382
|
-
if (!row) return null;
|
|
659
|
+
_rowToConfig(row) {
|
|
383
660
|
return {
|
|
384
661
|
name: row.name,
|
|
385
|
-
command: row.command,
|
|
662
|
+
command: row.command || null,
|
|
386
663
|
args: JSON.parse(row.args || "[]"),
|
|
387
664
|
env: JSON.parse(row.env || "{}"),
|
|
388
665
|
autoConnect: row.auto_connect === 1,
|
|
666
|
+
url: row.url || null,
|
|
667
|
+
transport:
|
|
668
|
+
row.transport || (row.url ? inferTransport({ url: row.url }) : "stdio"),
|
|
389
669
|
};
|
|
390
670
|
}
|
|
391
671
|
|
|
672
|
+
get(name) {
|
|
673
|
+
const row = this.db
|
|
674
|
+
.prepare("SELECT * FROM mcp_servers WHERE name = ?")
|
|
675
|
+
.get(name);
|
|
676
|
+
if (!row) return null;
|
|
677
|
+
return this._rowToConfig(row);
|
|
678
|
+
}
|
|
679
|
+
|
|
392
680
|
list() {
|
|
393
681
|
const rows = this.db
|
|
394
682
|
.prepare("SELECT * FROM mcp_servers ORDER BY name")
|
|
395
683
|
.all();
|
|
396
|
-
return rows.map((row) => (
|
|
397
|
-
name: row.name,
|
|
398
|
-
command: row.command,
|
|
399
|
-
args: JSON.parse(row.args || "[]"),
|
|
400
|
-
env: JSON.parse(row.env || "{}"),
|
|
401
|
-
autoConnect: row.auto_connect === 1,
|
|
402
|
-
}));
|
|
684
|
+
return rows.map((row) => this._rowToConfig(row));
|
|
403
685
|
}
|
|
404
686
|
|
|
405
687
|
getAutoConnect() {
|
|
406
688
|
const rows = this.db
|
|
407
689
|
.prepare("SELECT * FROM mcp_servers WHERE auto_connect = ? ORDER BY name")
|
|
408
690
|
.all(1);
|
|
409
|
-
return rows.map((row) => (
|
|
410
|
-
name: row.name,
|
|
411
|
-
command: row.command,
|
|
412
|
-
args: JSON.parse(row.args || "[]"),
|
|
413
|
-
env: JSON.parse(row.env || "{}"),
|
|
414
|
-
autoConnect: true,
|
|
415
|
-
}));
|
|
691
|
+
return rows.map((row) => this._rowToConfig(row));
|
|
416
692
|
}
|
|
417
693
|
}
|
package/src/index.js
CHANGED
|
@@ -73,6 +73,9 @@ import { registerScimCommand } from "./commands/scim.js";
|
|
|
73
73
|
// Phase 8: Infrastructure & Hardening
|
|
74
74
|
import { registerTerraformCommand } from "./commands/terraform.js";
|
|
75
75
|
import { registerHardeningCommand } from "./commands/hardening.js";
|
|
76
|
+
import { registerStressCommand } from "./commands/stress.js";
|
|
77
|
+
import { registerReputationCommand } from "./commands/reputation.js";
|
|
78
|
+
import { registerSlaCommand } from "./commands/sla.js";
|
|
76
79
|
|
|
77
80
|
// Phase 8: Social Platform
|
|
78
81
|
import { registerSocialCommand } from "./commands/social.js";
|
|
@@ -98,6 +101,63 @@ import { registerVideoCommand } from "./commands/video.js";
|
|
|
98
101
|
// Orchestration Layer: ChainlessChain → Claude Code/Codex agents → CI → Notify
|
|
99
102
|
import { registerOrchestrateCommand } from "./commands/orchestrate.js";
|
|
100
103
|
|
|
104
|
+
// Phase 62: Tech Learning Engine
|
|
105
|
+
import { registerTechCommand } from "./commands/tech.js";
|
|
106
|
+
|
|
107
|
+
// Phase 63: Autonomous Developer
|
|
108
|
+
import { registerDevCommand } from "./commands/dev.js";
|
|
109
|
+
|
|
110
|
+
// Phase 64: Collaboration Governance
|
|
111
|
+
import { registerCollabCommand } from "./commands/collab.js";
|
|
112
|
+
|
|
113
|
+
// Phase 65: Skill Marketplace
|
|
114
|
+
import { registerMarketplaceCommand } from "./commands/marketplace.js";
|
|
115
|
+
|
|
116
|
+
// Phase 66: Token Incentive
|
|
117
|
+
import { registerIncentiveCommand } from "./commands/incentive.js";
|
|
118
|
+
|
|
119
|
+
// Phase 94: Enterprise Knowledge Graph
|
|
120
|
+
import { registerKgCommand } from "./commands/kg.js";
|
|
121
|
+
|
|
122
|
+
// Phase 97: Multi-Tenant SaaS Engine
|
|
123
|
+
import { registerTenantCommand } from "./commands/tenant.js";
|
|
124
|
+
|
|
125
|
+
// Phase 54: AI Community Governance
|
|
126
|
+
import { registerGovernanceCommand } from "./commands/governance.js";
|
|
127
|
+
|
|
128
|
+
// Phase 48: Smart Content Recommendation
|
|
129
|
+
import { registerRecommendCommand } from "./commands/recommend.js";
|
|
130
|
+
|
|
131
|
+
// Phase 89: Cross-Chain Interoperability
|
|
132
|
+
import { registerCrossChainCommand } from "./commands/crosschain.js";
|
|
133
|
+
|
|
134
|
+
// Phase 91: Privacy Computing
|
|
135
|
+
import { registerPrivacyCommand } from "./commands/privacy.js";
|
|
136
|
+
|
|
137
|
+
// Phase 67: Decentralized Inference Network
|
|
138
|
+
import { registerInferenceCommand } from "./commands/inference.js";
|
|
139
|
+
|
|
140
|
+
// Phase 68-71: Trust & Security
|
|
141
|
+
import { registerTrustCommand } from "./commands/trust.js";
|
|
142
|
+
import { registerFusionCommand } from "./commands/fusion.js";
|
|
143
|
+
import { registerInfraCommand } from "./commands/infra.js";
|
|
144
|
+
// Phase 86: Code Generation Agent 2.0
|
|
145
|
+
import { registerCodegenCommand } from "./commands/codegen.js";
|
|
146
|
+
// Phase 25: Autonomous Ops (AIOps)
|
|
147
|
+
import { registerOpsCommand } from "./commands/ops.js";
|
|
148
|
+
// Phase 80: Database Evolution Framework
|
|
149
|
+
import { registerDbEvoCommand } from "./commands/dbevo.js";
|
|
150
|
+
// Phase 84: Multimodal Perception Engine
|
|
151
|
+
import { registerPerceptionCommand } from "./commands/perception.js";
|
|
152
|
+
// Phase 58: Federation Hardening
|
|
153
|
+
import { registerFederationCommand } from "./commands/federation.js";
|
|
154
|
+
// Phase 28: Natural Language Programming
|
|
155
|
+
import { registerNlProgCommand } from "./commands/nlprog.js";
|
|
156
|
+
// Phase 20: Model Quantization
|
|
157
|
+
import { registerQuantizationCommand } from "./commands/quantization.js";
|
|
158
|
+
// Phase 63: Universal Runtime
|
|
159
|
+
import { registerRuntimeCommand } from "./commands/runtime.js";
|
|
160
|
+
|
|
101
161
|
export function createProgram() {
|
|
102
162
|
const program = new Command();
|
|
103
163
|
|
|
@@ -200,6 +260,9 @@ export function createProgram() {
|
|
|
200
260
|
// Phase 8: Infrastructure & Hardening
|
|
201
261
|
registerTerraformCommand(program);
|
|
202
262
|
registerHardeningCommand(program);
|
|
263
|
+
registerStressCommand(program);
|
|
264
|
+
registerReputationCommand(program);
|
|
265
|
+
registerSlaCommand(program);
|
|
203
266
|
|
|
204
267
|
// Phase 8: Social Platform
|
|
205
268
|
registerSocialCommand(program);
|
|
@@ -225,5 +288,54 @@ export function createProgram() {
|
|
|
225
288
|
// Video Editing Agent
|
|
226
289
|
registerVideoCommand(program);
|
|
227
290
|
|
|
291
|
+
// Phase 62: Tech Learning Engine
|
|
292
|
+
registerTechCommand(program);
|
|
293
|
+
|
|
294
|
+
// Phase 63: Autonomous Developer
|
|
295
|
+
registerDevCommand(program);
|
|
296
|
+
|
|
297
|
+
// Phase 64: Collaboration Governance
|
|
298
|
+
registerCollabCommand(program);
|
|
299
|
+
|
|
300
|
+
// Phase 65: Skill Marketplace
|
|
301
|
+
registerMarketplaceCommand(program);
|
|
302
|
+
|
|
303
|
+
// Phase 66: Token Incentive
|
|
304
|
+
registerIncentiveCommand(program);
|
|
305
|
+
|
|
306
|
+
// Phase 94: Enterprise Knowledge Graph
|
|
307
|
+
registerKgCommand(program);
|
|
308
|
+
|
|
309
|
+
// Phase 97: Multi-Tenant SaaS Engine
|
|
310
|
+
registerTenantCommand(program);
|
|
311
|
+
|
|
312
|
+
// Phase 54: AI Community Governance
|
|
313
|
+
registerGovernanceCommand(program);
|
|
314
|
+
|
|
315
|
+
// Phase 48: Smart Content Recommendation
|
|
316
|
+
registerRecommendCommand(program);
|
|
317
|
+
|
|
318
|
+
// Phase 89: Cross-Chain Interoperability
|
|
319
|
+
registerCrossChainCommand(program);
|
|
320
|
+
|
|
321
|
+
// Phase 91: Privacy Computing
|
|
322
|
+
registerPrivacyCommand(program);
|
|
323
|
+
|
|
324
|
+
// Phase 67: Decentralized Inference Network
|
|
325
|
+
registerInferenceCommand(program);
|
|
326
|
+
|
|
327
|
+
// Phase 68-71: Trust & Security
|
|
328
|
+
registerTrustCommand(program);
|
|
329
|
+
registerFusionCommand(program);
|
|
330
|
+
registerInfraCommand(program);
|
|
331
|
+
registerCodegenCommand(program);
|
|
332
|
+
registerOpsCommand(program);
|
|
333
|
+
registerDbEvoCommand(program);
|
|
334
|
+
registerPerceptionCommand(program);
|
|
335
|
+
registerFederationCommand(program);
|
|
336
|
+
registerNlProgCommand(program);
|
|
337
|
+
registerQuantizationCommand(program);
|
|
338
|
+
registerRuntimeCommand(program);
|
|
339
|
+
|
|
228
340
|
return program;
|
|
229
341
|
}
|