network-ai 5.10.2 → 5.11.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.
Files changed (272) hide show
  1. package/INTEGRATION_GUIDE.md +2 -2
  2. package/README.md +5 -3
  3. package/SKILL.md +3 -3
  4. package/dist/esm/adapters/a2a-adapter.js +235 -0
  5. package/dist/esm/adapters/a2a-adapter.js.map +1 -0
  6. package/dist/esm/adapters/adapter-registry.js +613 -0
  7. package/dist/esm/adapters/adapter-registry.js.map +1 -0
  8. package/dist/esm/adapters/agno-adapter.js +140 -0
  9. package/dist/esm/adapters/agno-adapter.js.map +1 -0
  10. package/dist/esm/adapters/anthropic-computer-use-adapter.js +180 -0
  11. package/dist/esm/adapters/anthropic-computer-use-adapter.js.map +1 -0
  12. package/dist/esm/adapters/aps-adapter.js +289 -0
  13. package/dist/esm/adapters/aps-adapter.js.map +1 -0
  14. package/dist/esm/adapters/autogen-adapter.js +141 -0
  15. package/dist/esm/adapters/autogen-adapter.js.map +1 -0
  16. package/dist/esm/adapters/base-adapter.js +104 -0
  17. package/dist/esm/adapters/base-adapter.js.map +1 -0
  18. package/dist/esm/adapters/browser-agent-adapter.js +219 -0
  19. package/dist/esm/adapters/browser-agent-adapter.js.map +1 -0
  20. package/dist/esm/adapters/codex-adapter.js +318 -0
  21. package/dist/esm/adapters/codex-adapter.js.map +1 -0
  22. package/dist/esm/adapters/copilot-adapter.js +132 -0
  23. package/dist/esm/adapters/copilot-adapter.js.map +1 -0
  24. package/dist/esm/adapters/crewai-adapter.js +148 -0
  25. package/dist/esm/adapters/crewai-adapter.js.map +1 -0
  26. package/dist/esm/adapters/custom-adapter.js +142 -0
  27. package/dist/esm/adapters/custom-adapter.js.map +1 -0
  28. package/dist/esm/adapters/custom-streaming-adapter.js +181 -0
  29. package/dist/esm/adapters/custom-streaming-adapter.js.map +1 -0
  30. package/dist/esm/adapters/dspy-adapter.js +127 -0
  31. package/dist/esm/adapters/dspy-adapter.js.map +1 -0
  32. package/dist/esm/adapters/haystack-adapter.js +149 -0
  33. package/dist/esm/adapters/haystack-adapter.js.map +1 -0
  34. package/dist/esm/adapters/hermes-adapter.js +217 -0
  35. package/dist/esm/adapters/hermes-adapter.js.map +1 -0
  36. package/dist/esm/adapters/index.js +109 -0
  37. package/dist/esm/adapters/index.js.map +1 -0
  38. package/dist/esm/adapters/langchain-adapter.js +134 -0
  39. package/dist/esm/adapters/langchain-adapter.js.map +1 -0
  40. package/dist/esm/adapters/langchain-streaming-adapter.js +161 -0
  41. package/dist/esm/adapters/langchain-streaming-adapter.js.map +1 -0
  42. package/dist/esm/adapters/langgraph-adapter.js +119 -0
  43. package/dist/esm/adapters/langgraph-adapter.js.map +1 -0
  44. package/dist/esm/adapters/llamaindex-adapter.js +135 -0
  45. package/dist/esm/adapters/llamaindex-adapter.js.map +1 -0
  46. package/dist/esm/adapters/mcp-adapter.js +200 -0
  47. package/dist/esm/adapters/mcp-adapter.js.map +1 -0
  48. package/dist/esm/adapters/minimax-adapter.js +233 -0
  49. package/dist/esm/adapters/minimax-adapter.js.map +1 -0
  50. package/dist/esm/adapters/nemoclaw-adapter.js +465 -0
  51. package/dist/esm/adapters/nemoclaw-adapter.js.map +1 -0
  52. package/dist/esm/adapters/openai-agents-adapter.js +118 -0
  53. package/dist/esm/adapters/openai-agents-adapter.js.map +1 -0
  54. package/dist/esm/adapters/openai-assistants-adapter.js +130 -0
  55. package/dist/esm/adapters/openai-assistants-adapter.js.map +1 -0
  56. package/dist/esm/adapters/openclaw-adapter.js +107 -0
  57. package/dist/esm/adapters/openclaw-adapter.js.map +1 -0
  58. package/dist/esm/adapters/orchestrator-adapter.js +218 -0
  59. package/dist/esm/adapters/orchestrator-adapter.js.map +1 -0
  60. package/dist/esm/adapters/pydantic-ai-adapter.js +163 -0
  61. package/dist/esm/adapters/pydantic-ai-adapter.js.map +1 -0
  62. package/dist/esm/adapters/rlm-adapter.js +167 -0
  63. package/dist/esm/adapters/rlm-adapter.js.map +1 -0
  64. package/dist/esm/adapters/semantic-kernel-adapter.js +123 -0
  65. package/dist/esm/adapters/semantic-kernel-adapter.js.map +1 -0
  66. package/dist/esm/adapters/streaming-base-adapter.js +74 -0
  67. package/dist/esm/adapters/streaming-base-adapter.js.map +1 -0
  68. package/dist/esm/adapters/vertex-ai-adapter.js +166 -0
  69. package/dist/esm/adapters/vertex-ai-adapter.js.map +1 -0
  70. package/dist/esm/demo-control-plane.js +147 -0
  71. package/dist/esm/demo-control-plane.js.map +1 -0
  72. package/dist/esm/demo-worktree-dashboard.js +131 -0
  73. package/dist/esm/demo-worktree-dashboard.js.map +1 -0
  74. package/dist/esm/examples/01-hello-swarm.js +165 -0
  75. package/dist/esm/examples/01-hello-swarm.js.map +1 -0
  76. package/dist/esm/examples/02-fsm-pipeline.js +189 -0
  77. package/dist/esm/examples/02-fsm-pipeline.js.map +1 -0
  78. package/dist/esm/examples/03-parallel-agents.js +192 -0
  79. package/dist/esm/examples/03-parallel-agents.js.map +1 -0
  80. package/dist/esm/examples/05-code-review-swarm.js +1177 -0
  81. package/dist/esm/examples/05-code-review-swarm.js.map +1 -0
  82. package/dist/esm/examples/06-ai-pipeline-demo.js +263 -0
  83. package/dist/esm/examples/06-ai-pipeline-demo.js.map +1 -0
  84. package/dist/esm/examples/07-full-showcase.js +946 -0
  85. package/dist/esm/examples/07-full-showcase.js.map +1 -0
  86. package/dist/esm/examples/08-control-plane-stress-demo.js +186 -0
  87. package/dist/esm/examples/08-control-plane-stress-demo.js.map +1 -0
  88. package/dist/esm/examples/09-real-langchain.js +231 -0
  89. package/dist/esm/examples/09-real-langchain.js.map +1 -0
  90. package/dist/esm/examples/10-nemoclaw-sandbox-swarm.js +270 -0
  91. package/dist/esm/examples/10-nemoclaw-sandbox-swarm.js.map +1 -0
  92. package/dist/esm/examples/demo-runner.js +119 -0
  93. package/dist/esm/examples/demo-runner.js.map +1 -0
  94. package/dist/esm/index.js +1352 -0
  95. package/dist/esm/index.js.map +1 -0
  96. package/dist/esm/lib/adapter-hooks.js +216 -0
  97. package/dist/esm/lib/adapter-hooks.js.map +1 -0
  98. package/dist/esm/lib/adapter-test-harness.js +118 -0
  99. package/dist/esm/lib/adapter-test-harness.js.map +1 -0
  100. package/dist/esm/lib/agent-conversation.js +155 -0
  101. package/dist/esm/lib/agent-conversation.js.map +1 -0
  102. package/dist/esm/lib/agent-debate.js +146 -0
  103. package/dist/esm/lib/agent-debate.js.map +1 -0
  104. package/dist/esm/lib/agent-memory.js +336 -0
  105. package/dist/esm/lib/agent-memory.js.map +1 -0
  106. package/dist/esm/lib/agent-runtime.js +818 -0
  107. package/dist/esm/lib/agent-runtime.js.map +1 -0
  108. package/dist/esm/lib/agent-vcr.js +218 -0
  109. package/dist/esm/lib/agent-vcr.js.map +1 -0
  110. package/dist/esm/lib/anomaly-detector.js +178 -0
  111. package/dist/esm/lib/anomaly-detector.js.map +1 -0
  112. package/dist/esm/lib/approval-inbox.js +385 -0
  113. package/dist/esm/lib/approval-inbox.js.map +1 -0
  114. package/dist/esm/lib/auth-guardian.js +692 -0
  115. package/dist/esm/lib/auth-guardian.js.map +1 -0
  116. package/dist/esm/lib/auth-validator.js +32 -0
  117. package/dist/esm/lib/auth-validator.js.map +1 -0
  118. package/dist/esm/lib/blackboard-backend-crdt.js +251 -0
  119. package/dist/esm/lib/blackboard-backend-crdt.js.map +1 -0
  120. package/dist/esm/lib/blackboard-backend-redis.js +244 -0
  121. package/dist/esm/lib/blackboard-backend-redis.js.map +1 -0
  122. package/dist/esm/lib/blackboard-backend.js +141 -0
  123. package/dist/esm/lib/blackboard-backend.js.map +1 -0
  124. package/dist/esm/lib/blackboard-validator.js +985 -0
  125. package/dist/esm/lib/blackboard-validator.js.map +1 -0
  126. package/dist/esm/lib/circuit-breaker.js +164 -0
  127. package/dist/esm/lib/circuit-breaker.js.map +1 -0
  128. package/dist/esm/lib/claim-verifier.js +173 -0
  129. package/dist/esm/lib/claim-verifier.js.map +1 -0
  130. package/dist/esm/lib/comparison-runner.js +138 -0
  131. package/dist/esm/lib/comparison-runner.js.map +1 -0
  132. package/dist/esm/lib/compliance-monitor.js +261 -0
  133. package/dist/esm/lib/compliance-monitor.js.map +1 -0
  134. package/dist/esm/lib/confidence-filter.js +210 -0
  135. package/dist/esm/lib/confidence-filter.js.map +1 -0
  136. package/dist/esm/lib/config-watcher.js +215 -0
  137. package/dist/esm/lib/config-watcher.js.map +1 -0
  138. package/dist/esm/lib/consistency.js +274 -0
  139. package/dist/esm/lib/consistency.js.map +1 -0
  140. package/dist/esm/lib/console-ui.js +276 -0
  141. package/dist/esm/lib/console-ui.js.map +1 -0
  142. package/dist/esm/lib/context-throttler.js +171 -0
  143. package/dist/esm/lib/context-throttler.js.map +1 -0
  144. package/dist/esm/lib/control-plane.js +527 -0
  145. package/dist/esm/lib/control-plane.js.map +1 -0
  146. package/dist/esm/lib/cost-governor.js +128 -0
  147. package/dist/esm/lib/cost-governor.js.map +1 -0
  148. package/dist/esm/lib/cost-heatmap.js +161 -0
  149. package/dist/esm/lib/cost-heatmap.js.map +1 -0
  150. package/dist/esm/lib/coverage-gate.js +213 -0
  151. package/dist/esm/lib/coverage-gate.js.map +1 -0
  152. package/dist/esm/lib/coverage-reporter.js +177 -0
  153. package/dist/esm/lib/coverage-reporter.js.map +1 -0
  154. package/dist/esm/lib/crdt.js +141 -0
  155. package/dist/esm/lib/crdt.js.map +1 -0
  156. package/dist/esm/lib/dashboard-server.js +403 -0
  157. package/dist/esm/lib/dashboard-server.js.map +1 -0
  158. package/dist/esm/lib/dry-run.js +130 -0
  159. package/dist/esm/lib/dry-run.js.map +1 -0
  160. package/dist/esm/lib/env-manager.js +518 -0
  161. package/dist/esm/lib/env-manager.js.map +1 -0
  162. package/dist/esm/lib/errors.js +201 -0
  163. package/dist/esm/lib/errors.js.map +1 -0
  164. package/dist/esm/lib/event-bus.js +229 -0
  165. package/dist/esm/lib/event-bus.js.map +1 -0
  166. package/dist/esm/lib/explainability.js +102 -0
  167. package/dist/esm/lib/explainability.js.map +1 -0
  168. package/dist/esm/lib/fan-out.js +237 -0
  169. package/dist/esm/lib/fan-out.js.map +1 -0
  170. package/dist/esm/lib/federated-budget.js +322 -0
  171. package/dist/esm/lib/federated-budget.js.map +1 -0
  172. package/dist/esm/lib/fsm-journey.js +478 -0
  173. package/dist/esm/lib/fsm-journey.js.map +1 -0
  174. package/dist/esm/lib/goal-decomposer.js +698 -0
  175. package/dist/esm/lib/goal-decomposer.js.map +1 -0
  176. package/dist/esm/lib/goal-dsl.js +391 -0
  177. package/dist/esm/lib/goal-dsl.js.map +1 -0
  178. package/dist/esm/lib/job-queue.js +310 -0
  179. package/dist/esm/lib/job-queue.js.map +1 -0
  180. package/dist/esm/lib/landscape-agent.js +134 -0
  181. package/dist/esm/lib/landscape-agent.js.map +1 -0
  182. package/dist/esm/lib/learning-loop.js +181 -0
  183. package/dist/esm/lib/learning-loop.js.map +1 -0
  184. package/dist/esm/lib/lifecycle-hooks.js +148 -0
  185. package/dist/esm/lib/lifecycle-hooks.js.map +1 -0
  186. package/dist/esm/lib/locked-blackboard.js +1295 -0
  187. package/dist/esm/lib/locked-blackboard.js.map +1 -0
  188. package/dist/esm/lib/logger.js +150 -0
  189. package/dist/esm/lib/logger.js.map +1 -0
  190. package/dist/esm/lib/mcp-blackboard-tools.js +298 -0
  191. package/dist/esm/lib/mcp-blackboard-tools.js.map +1 -0
  192. package/dist/esm/lib/mcp-bridge.js +357 -0
  193. package/dist/esm/lib/mcp-bridge.js.map +1 -0
  194. package/dist/esm/lib/mcp-tool-consumer.js +287 -0
  195. package/dist/esm/lib/mcp-tool-consumer.js.map +1 -0
  196. package/dist/esm/lib/mcp-tools-control.js +392 -0
  197. package/dist/esm/lib/mcp-tools-control.js.map +1 -0
  198. package/dist/esm/lib/mcp-tools-extended.js +371 -0
  199. package/dist/esm/lib/mcp-tools-extended.js.map +1 -0
  200. package/dist/esm/lib/mcp-transport-http.js +528 -0
  201. package/dist/esm/lib/mcp-transport-http.js.map +1 -0
  202. package/dist/esm/lib/mcp-transport-sse.js +503 -0
  203. package/dist/esm/lib/mcp-transport-sse.js.map +1 -0
  204. package/dist/esm/lib/metrics.js +284 -0
  205. package/dist/esm/lib/metrics.js.map +1 -0
  206. package/dist/esm/lib/orchestrator-types.js +66 -0
  207. package/dist/esm/lib/orchestrator-types.js.map +1 -0
  208. package/dist/esm/lib/otel-bridge.js +167 -0
  209. package/dist/esm/lib/otel-bridge.js.map +1 -0
  210. package/dist/esm/lib/partition-planner.js +246 -0
  211. package/dist/esm/lib/partition-planner.js.map +1 -0
  212. package/dist/esm/lib/phase-pipeline.js +367 -0
  213. package/dist/esm/lib/phase-pipeline.js.map +1 -0
  214. package/dist/esm/lib/playground.js +224 -0
  215. package/dist/esm/lib/playground.js.map +1 -0
  216. package/dist/esm/lib/qa-orchestrator.js +296 -0
  217. package/dist/esm/lib/qa-orchestrator.js.map +1 -0
  218. package/dist/esm/lib/quadtree.js +259 -0
  219. package/dist/esm/lib/quadtree.js.map +1 -0
  220. package/dist/esm/lib/route-classifier.js +217 -0
  221. package/dist/esm/lib/route-classifier.js.map +1 -0
  222. package/dist/esm/lib/semantic-search.js +235 -0
  223. package/dist/esm/lib/semantic-search.js.map +1 -0
  224. package/dist/esm/lib/shared-blackboard.js +249 -0
  225. package/dist/esm/lib/shared-blackboard.js.map +1 -0
  226. package/dist/esm/lib/skill-composer.js +190 -0
  227. package/dist/esm/lib/skill-composer.js.map +1 -0
  228. package/dist/esm/lib/speculative-executor.js +107 -0
  229. package/dist/esm/lib/speculative-executor.js.map +1 -0
  230. package/dist/esm/lib/strategy-agent.js +626 -0
  231. package/dist/esm/lib/strategy-agent.js.map +1 -0
  232. package/dist/esm/lib/swarm-transport.js +307 -0
  233. package/dist/esm/lib/swarm-transport.js.map +1 -0
  234. package/dist/esm/lib/swarm-utils.js +510 -0
  235. package/dist/esm/lib/swarm-utils.js.map +1 -0
  236. package/dist/esm/lib/task-decomposer.js +272 -0
  237. package/dist/esm/lib/task-decomposer.js.map +1 -0
  238. package/dist/esm/lib/telemetry-provider.js +207 -0
  239. package/dist/esm/lib/telemetry-provider.js.map +1 -0
  240. package/dist/esm/lib/timeline-scrubber.js +173 -0
  241. package/dist/esm/lib/timeline-scrubber.js.map +1 -0
  242. package/dist/esm/lib/topology.js +591 -0
  243. package/dist/esm/lib/topology.js.map +1 -0
  244. package/dist/esm/lib/transport-agent.js +366 -0
  245. package/dist/esm/lib/transport-agent.js.map +1 -0
  246. package/dist/esm/lib/work-tree-dashboard.js +583 -0
  247. package/dist/esm/lib/work-tree-dashboard.js.map +1 -0
  248. package/dist/esm/lib/work-tree-ui.js +333 -0
  249. package/dist/esm/lib/work-tree-ui.js.map +1 -0
  250. package/dist/esm/lib/work-tree.js +480 -0
  251. package/dist/esm/lib/work-tree.js.map +1 -0
  252. package/dist/esm/run.js +144 -0
  253. package/dist/esm/run.js.map +1 -0
  254. package/dist/esm/security.js +1122 -0
  255. package/dist/esm/security.js.map +1 -0
  256. package/dist/index.d.ts +2 -0
  257. package/dist/index.d.ts.map +1 -1
  258. package/dist/index.js +6 -1
  259. package/dist/index.js.map +1 -1
  260. package/dist/lib/mcp-transport-http.d.ts +203 -0
  261. package/dist/lib/mcp-transport-http.d.ts.map +1 -0
  262. package/dist/lib/mcp-transport-http.js +528 -0
  263. package/dist/lib/mcp-transport-http.js.map +1 -0
  264. package/dist/lib/phase-pipeline.d.ts +31 -0
  265. package/dist/lib/phase-pipeline.d.ts.map +1 -1
  266. package/dist/lib/phase-pipeline.js +93 -1
  267. package/dist/lib/phase-pipeline.js.map +1 -1
  268. package/dist/lib/semantic-search.d.ts +42 -6
  269. package/dist/lib/semantic-search.d.ts.map +1 -1
  270. package/dist/lib/semantic-search.js +87 -6
  271. package/dist/lib/semantic-search.js.map +1 -1
  272. package/package.json +24 -4
@@ -0,0 +1,503 @@
1
+ "use strict";
2
+ /**
3
+ * MCP SSE/HTTP Transport — Phase 6 Part 1
4
+ *
5
+ * Makes the MCP bridge network-accessible over HTTP + Server-Sent Events so
6
+ * any MCP-compatible AI (Claude Desktop, Cursor, Cline, etc.) can connect
7
+ * to Network-AI from outside the process.
8
+ *
9
+ * Architecture:
10
+ *
11
+ * External AI agent
12
+ * │ POST /mcp (JSON-RPC 2.0 request)
13
+ * ▼
14
+ * McpSseServer (HTTP, port 3001)
15
+ * │ handleRPC()
16
+ * ▼
17
+ * McpCombinedBridge
18
+ * ├── blackboard tools (read/write/list/delete/exists)
19
+ * ├── extended tools (budget/token/audit)
20
+ * └── control tools (config/agent/fsm)
21
+ *
22
+ * External AI agent
23
+ * │ GET /sse (SSE connection — server pushes events)
24
+ * ▼
25
+ * McpSseServer broadcasts events to all connected clients
26
+ *
27
+ * Zero external dependencies — uses Node.js built-in `node:http` only.
28
+ *
29
+ * @module mcp-transport-sse
30
+ * @version 1.0.0
31
+ */
32
+ Object.defineProperty(exports, "__esModule", { value: true });
33
+ exports.McpSseTransport = exports.McpSseServer = exports.McpBlackboardBridgeAdapter = exports.McpCombinedBridge = void 0;
34
+ // Lazy-loaded network modules — deferred so that importing this file does not
35
+ // pull in node:http / node:https unless the SSE transport is actually used.
36
+ let _http;
37
+ let _https;
38
+ /** @internal */
39
+ function requireHttp() {
40
+ if (!_http)
41
+ _http = require('node:http');
42
+ return _http;
43
+ }
44
+ /** @internal */
45
+ function requireHttps() {
46
+ if (!_https)
47
+ _https = require('node:https');
48
+ return _https;
49
+ }
50
+ // ============================================================================
51
+ // COMBINED BRIDGE — aggregates multiple tool providers
52
+ // ============================================================================
53
+ /**
54
+ * Aggregates multiple `McpToolProvider` instances into a single MCP bridge.
55
+ *
56
+ * Handles `tools/list` by merging all definitions, and routes `tools/call`
57
+ * to the first provider that owns the requested tool name.
58
+ *
59
+ * @example
60
+ * ```typescript
61
+ * const combined = new McpCombinedBridge('network-ai');
62
+ * combined.register(new McpBlackboardBridgeAdapter(myBridge));
63
+ * combined.register(new ExtendedMcpTools({ budget }));
64
+ * combined.register(new ControlMcpTools({ config, orchestrator }));
65
+ *
66
+ * const server = new McpSseServer(combined, { port: 3001, secret: process.env['NETWORK_AI_MCP_SECRET']! });
67
+ * await server.listen();
68
+ * ```
69
+ */
70
+ class McpCombinedBridge {
71
+ name;
72
+ _providers = [];
73
+ _toolIndex = new Map();
74
+ constructor(name = 'network-ai') {
75
+ this.name = name;
76
+ }
77
+ /**
78
+ * Register a tool provider. Tools names must be globally unique across all
79
+ * registered providers — duplicate names are silently overwritten with the
80
+ * latest registration.
81
+ */
82
+ register(provider) {
83
+ this._providers.push(provider);
84
+ for (const def of provider.getDefinitions()) {
85
+ this._toolIndex.set(def.name, provider);
86
+ }
87
+ }
88
+ /** All tool definitions across every registered provider. */
89
+ allDefinitions() {
90
+ return this._providers.flatMap(p => p.getDefinitions());
91
+ }
92
+ /**
93
+ * Handle a single JSON-RPC 2.0 request. Never rejects — errors are encoded
94
+ * in the response `error` field.
95
+ */
96
+ async handleRPC(request) {
97
+ if (!request || request.jsonrpc !== '2.0') {
98
+ return this._error(null, -32600 /* McpErrorCode.InvalidRequest */, 'Invalid JSON-RPC 2.0 request');
99
+ }
100
+ const { id, method } = request;
101
+ try {
102
+ switch (method) {
103
+ // MCP handshake — required before any tool calls
104
+ case 'initialize':
105
+ return this._ok(id, {
106
+ protocolVersion: '2024-11-05',
107
+ capabilities: { tools: {} },
108
+ serverInfo: { name: this.name ?? 'network-ai', version: '4.0.13' },
109
+ });
110
+ // Client signals it's ready — notification (no response needed, but
111
+ // some clients send it as a request with an id)
112
+ case 'notifications/initialized':
113
+ return this._ok(id, {});
114
+ // Return empty lists so clients don't abort on missing methods
115
+ case 'resources/list':
116
+ return this._ok(id, { resources: [] });
117
+ case 'prompts/list':
118
+ return this._ok(id, { prompts: [] });
119
+ case 'tools/list':
120
+ return this._ok(id, { tools: this.allDefinitions() });
121
+ case 'tools/call': {
122
+ const params = request.params;
123
+ if (!params || typeof params !== 'object') {
124
+ return this._error(id, -32602 /* McpErrorCode.InvalidParams */, 'tools/call requires params object');
125
+ }
126
+ const toolName = params['name'];
127
+ const toolArgs = (params['arguments'] ?? {});
128
+ if (typeof toolName !== 'string' || !toolName) {
129
+ return this._error(id, -32602 /* McpErrorCode.InvalidParams */, 'tools/call: "name" must be a non-empty string');
130
+ }
131
+ const provider = this._toolIndex.get(toolName);
132
+ if (!provider) {
133
+ return this._error(id, -32601 /* McpErrorCode.MethodNotFound */, `Unknown tool: "${toolName}"`);
134
+ }
135
+ const result = await provider.call(toolName, toolArgs);
136
+ return this._ok(id, {
137
+ content: [{ type: 'text', text: JSON.stringify(result) }],
138
+ isError: !result.ok,
139
+ });
140
+ }
141
+ default:
142
+ return this._error(id, -32601 /* McpErrorCode.MethodNotFound */, `Method not found: "${method}"`);
143
+ }
144
+ }
145
+ catch (err) {
146
+ return this._error(id, -32603 /* McpErrorCode.InternalError */, err instanceof Error ? err.message : String(err));
147
+ }
148
+ }
149
+ _ok(id, result) {
150
+ return { jsonrpc: '2.0', id, result };
151
+ }
152
+ _error(id, code, message) {
153
+ return { jsonrpc: '2.0', id, error: { code, message } };
154
+ }
155
+ }
156
+ exports.McpCombinedBridge = McpCombinedBridge;
157
+ // ============================================================================
158
+ // BRIDGE ADAPTER — wraps McpBlackboardBridge as a McpToolProvider
159
+ // ============================================================================
160
+ /**
161
+ * Wraps an existing `McpBlackboardBridge` as a `McpToolProvider` so it can be
162
+ * registered with `McpCombinedBridge` alongside extended and control tools.
163
+ */
164
+ class McpBlackboardBridgeAdapter {
165
+ bridge;
166
+ constructor(bridge) {
167
+ this.bridge = bridge;
168
+ }
169
+ getDefinitions() {
170
+ return this.bridge.listTools();
171
+ }
172
+ async call(toolName, args) {
173
+ return this.bridge.callTool(toolName, args);
174
+ }
175
+ }
176
+ exports.McpBlackboardBridgeAdapter = McpBlackboardBridgeAdapter;
177
+ /**
178
+ * HTTP server that exposes a `McpCombinedBridge` (or any object with
179
+ * `handleRPC`) over two endpoints:
180
+ *
181
+ * - `GET /sse` — Server-Sent Events stream; sends initial `endpoint` event
182
+ * - `POST /mcp` — Receive JSON-RPC 2.0 requests, return responses
183
+ * - `GET /health` — Health check returning `{ status: 'ok', bridge, clients }`
184
+ * - `GET /tools` — List all available tools as JSON
185
+ *
186
+ * No external packages required — built on Node.js `node:http`.
187
+ */
188
+ class McpSseServer {
189
+ _bridge;
190
+ _opts;
191
+ _server;
192
+ _sseClients = new Set();
193
+ constructor(bridge, options = {}) {
194
+ this._bridge = bridge;
195
+ this._opts = {
196
+ port: options.port ?? 3001,
197
+ host: options.host ?? '127.0.0.1',
198
+ heartbeatMs: options.heartbeatMs ?? 15000,
199
+ secret: options.secret ?? '',
200
+ };
201
+ }
202
+ /** Start listening. Resolves when the server is ready. */
203
+ listen() {
204
+ // Fail closed: refuse to bind if no secret is configured.
205
+ // An empty secret would allow every unauthenticated request through
206
+ // (CWE-306/CWE-862). Callers must supply a non-empty secret for SSE
207
+ // mode; for local stdio use McpStdioTransport instead.
208
+ if (!this._opts.secret) {
209
+ return Promise.reject(new Error('McpSseServer requires a non-empty secret. ' +
210
+ 'Set McpSseServerOptions.secret or the NETWORK_AI_MCP_SECRET env var. ' +
211
+ 'For stdio mode (Claude Desktop / Cursor / Glama) use --stdio instead.'));
212
+ }
213
+ this._server = requireHttp().createServer((req, res) => this._handleRequest(req, res));
214
+ // Warn when binding to a non-loopback address — defence-in-depth notice
215
+ const isLoopback = this._opts.host === '127.0.0.1' || this._opts.host === 'localhost' || this._opts.host === '::1';
216
+ if (!isLoopback) {
217
+ process.stderr.write('[network-ai] WARNING: MCP server is binding to ' + this._opts.host +
218
+ ' (non-loopback). Ensure your network perimeter restricts access to' +
219
+ ' this port. Bearer token authentication is enforced on all tool calls.\n');
220
+ }
221
+ return new Promise(resolve => {
222
+ this._server.listen(this._opts.port, this._opts.host, () => resolve());
223
+ });
224
+ }
225
+ /** Stop the server and close all SSE streams. */
226
+ close() {
227
+ for (const client of this._sseClients) {
228
+ try {
229
+ client.end();
230
+ }
231
+ catch { /* ignore */ }
232
+ }
233
+ this._sseClients.clear();
234
+ return new Promise((resolve, reject) => {
235
+ this._server.close(err => (err ? reject(err) : resolve()));
236
+ });
237
+ }
238
+ /** Current TCP port (useful when port was auto-assigned). */
239
+ get port() { return this._opts.port; }
240
+ /** Number of currently connected SSE clients. */
241
+ get clientCount() { return this._sseClients.size; }
242
+ /**
243
+ * Broadcast an event to every connected SSE client.
244
+ * Useful for pushing agent status updates, budget alerts, etc.
245
+ */
246
+ broadcast(eventName, data) {
247
+ const msg = `event: ${eventName}\ndata: ${JSON.stringify(data)}\n\n`;
248
+ for (const client of this._sseClients) {
249
+ try {
250
+ client.write(msg);
251
+ }
252
+ catch { /* client disconnected */ }
253
+ }
254
+ }
255
+ // --------------------------------------------------------------------------
256
+ // AUTH
257
+ // --------------------------------------------------------------------------
258
+ /**
259
+ * Returns true when the request carries a valid `Authorization: Bearer <secret>`
260
+ * header. Fails closed: an empty or missing secret always returns false.
261
+ * (CWE-306 / CWE-862 — incomplete fix guard: empty secret must never grant access.)
262
+ */
263
+ _isAuthorized(req) {
264
+ if (!this._opts.secret)
265
+ return false; // fail closed — no secret → deny all
266
+ const authHeader = req.headers['authorization'];
267
+ if (typeof authHeader !== 'string')
268
+ return false;
269
+ const parts = authHeader.split(' ');
270
+ return parts[0]?.toLowerCase() === 'bearer' && parts[1] === this._opts.secret;
271
+ }
272
+ _unauthorized(res) {
273
+ res.writeHead(401, { 'Content-Type': 'application/json', 'WWW-Authenticate': 'Bearer realm="network-ai"' });
274
+ res.end(JSON.stringify({ error: 'Unauthorized', message: 'Provide Authorization: Bearer <secret>' }));
275
+ }
276
+ // --------------------------------------------------------------------------
277
+ // REQUEST ROUTING
278
+ // --------------------------------------------------------------------------
279
+ _handleRequest(req, res) {
280
+ const base = `http://${req.headers.host ?? `localhost:${this._opts.port}`}`;
281
+ let parsed;
282
+ try {
283
+ parsed = new URL(req.url ?? '/', base);
284
+ }
285
+ catch {
286
+ res.writeHead(400);
287
+ res.end('Bad request');
288
+ return;
289
+ }
290
+ const path = parsed.pathname;
291
+ // CORS — restrict to localhost origins only (prevents cross-origin browser attacks)
292
+ const origin = req.headers['origin'] ?? '';
293
+ const isLocalOrigin = /^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/.test(origin);
294
+ if (isLocalOrigin) {
295
+ res.setHeader('Access-Control-Allow-Origin', origin);
296
+ res.setHeader('Vary', 'Origin');
297
+ }
298
+ res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
299
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
300
+ if (req.method === 'OPTIONS') {
301
+ res.writeHead(204);
302
+ res.end();
303
+ return;
304
+ }
305
+ if (req.method === 'GET' && (path === '/sse' || path === '/')) {
306
+ if (!this._isAuthorized(req)) {
307
+ this._unauthorized(res);
308
+ return;
309
+ }
310
+ this._handleSse(req, res);
311
+ }
312
+ else if (req.method === 'POST' && (path === '/mcp' || path === '/')) {
313
+ if (!this._isAuthorized(req)) {
314
+ this._unauthorized(res);
315
+ return;
316
+ }
317
+ this._handlePost(req, res);
318
+ }
319
+ else if (req.method === 'GET' && path === '/health') {
320
+ this._handleHealth(res);
321
+ }
322
+ else if (req.method === 'GET' && path === '/tools') {
323
+ this._handleTools(res);
324
+ }
325
+ else {
326
+ res.writeHead(404, { 'Content-Type': 'application/json' });
327
+ res.end(JSON.stringify({ error: 'Not found', endpoints: ['/', '/sse', '/mcp', '/health', '/tools'] }));
328
+ }
329
+ }
330
+ _handleSse(req, res) {
331
+ res.writeHead(200, {
332
+ 'Content-Type': 'text/event-stream',
333
+ 'Cache-Control': 'no-cache',
334
+ 'Connection': 'keep-alive',
335
+ 'X-Accel-Buffering': 'no', // Disable nginx buffering
336
+ });
337
+ // MCP SSE protocol: send endpoint URL so client knows where to POST
338
+ res.write(`event: endpoint\ndata: /mcp\n\n`);
339
+ this._sseClients.add(res);
340
+ // Heartbeat keeps the connection alive through proxies/load balancers
341
+ let heartbeat = null;
342
+ if (this._opts.heartbeatMs > 0) {
343
+ heartbeat = setInterval(() => {
344
+ try {
345
+ res.write(': heartbeat\n\n');
346
+ }
347
+ catch { /* closed */ }
348
+ }, this._opts.heartbeatMs);
349
+ }
350
+ req.on('close', () => {
351
+ if (heartbeat)
352
+ clearInterval(heartbeat);
353
+ this._sseClients.delete(res);
354
+ });
355
+ }
356
+ _handlePost(req, res) {
357
+ let body = '';
358
+ const MAX_BODY = 4 * 1024 * 1024; // 4 MB
359
+ let bodySize = 0;
360
+ req.on('data', (chunk) => {
361
+ bodySize += chunk.length;
362
+ if (bodySize > MAX_BODY) {
363
+ res.writeHead(413, { 'Content-Type': 'application/json' });
364
+ res.end(JSON.stringify({ error: 'Request body too large' }));
365
+ req.destroy();
366
+ return;
367
+ }
368
+ body += chunk.toString();
369
+ });
370
+ req.on('end', async () => {
371
+ try {
372
+ const rpc = JSON.parse(body);
373
+ const response = await this._bridge.handleRPC(rpc);
374
+ res.writeHead(200, { 'Content-Type': 'application/json' });
375
+ res.end(JSON.stringify(response));
376
+ // Optionally broadcast the call as an event to SSE clients
377
+ if (this._sseClients.size > 0 && rpc.method === 'tools/call') {
378
+ this.broadcast('tool_called', { method: rpc.method, params: rpc.params, ts: Date.now() });
379
+ }
380
+ }
381
+ catch (err) {
382
+ const errMsg = err instanceof Error ? err.message : String(err);
383
+ res.writeHead(400, { 'Content-Type': 'application/json' });
384
+ res.end(JSON.stringify({
385
+ jsonrpc: '2.0',
386
+ id: null,
387
+ error: { code: -32700 /* McpErrorCode.ParseError */, message: `Parse error: ${errMsg}` },
388
+ }));
389
+ }
390
+ });
391
+ req.on('error', () => {
392
+ try {
393
+ res.writeHead(500);
394
+ res.end();
395
+ }
396
+ catch { /* already sent */ }
397
+ });
398
+ }
399
+ _handleHealth(res) {
400
+ res.writeHead(200, { 'Content-Type': 'application/json' });
401
+ res.end(JSON.stringify({
402
+ status: 'ok',
403
+ bridge: this._bridge.name ?? 'network-ai',
404
+ clients: this._sseClients.size,
405
+ ts: new Date().toISOString(),
406
+ }));
407
+ }
408
+ _handleTools(res) {
409
+ const defs = this._bridge.allDefinitions?.() ?? [];
410
+ res.writeHead(200, { 'Content-Type': 'application/json' });
411
+ res.end(JSON.stringify({ tools: defs, count: defs.length }));
412
+ }
413
+ }
414
+ exports.McpSseServer = McpSseServer;
415
+ // ============================================================================
416
+ // SSE TRANSPORT (CLIENT SIDE)
417
+ // ============================================================================
418
+ /**
419
+ * `McpTransport` implementation that sends JSON-RPC requests to a remote
420
+ * `McpSseServer` via HTTP POST.
421
+ *
422
+ * Use this when the MCP client and server are in different processes or
423
+ * machines. Pairs with `McpBridgeClient` as a drop-in replacement for
424
+ * `McpInProcessTransport`.
425
+ *
426
+ * @example
427
+ * ```typescript
428
+ * import { McpBridgeClient } from 'network-ai';
429
+ * import { McpSseTransport } from 'network-ai';
430
+ *
431
+ * const transport = new McpSseTransport('http://localhost:3001', process.env['NETWORK_AI_MCP_SECRET']!);
432
+ * const client = new McpBridgeClient(transport);
433
+ *
434
+ * const tools = await client.listTools();
435
+ * const result = await client.callTool('blackboard_read', { key: 'status', agent_id: 'my-agent' });
436
+ * ```
437
+ */
438
+ class McpSseTransport {
439
+ _postUrl;
440
+ _secret;
441
+ _idCounter = 0;
442
+ /**
443
+ * @param baseUrl Base URL of the `McpSseServer`, e.g. `'http://localhost:3001'`.
444
+ * The transport will POST to `<baseUrl>/mcp`.
445
+ * @param secret Bearer token matching `McpSseServerOptions.secret`. Required
446
+ * because `McpSseServer` now rejects all requests when no secret
447
+ * is configured. Pass the same value set on the server.
448
+ */
449
+ constructor(baseUrl, secret = '') {
450
+ // Strip trailing slashes without regex to avoid ReDoS on adversarial input.
451
+ let clean = baseUrl;
452
+ while (clean.endsWith('/'))
453
+ clean = clean.slice(0, -1);
454
+ this._postUrl = clean.endsWith('/mcp') ? clean : `${clean}/mcp`;
455
+ this._secret = secret;
456
+ }
457
+ /** Send a JSON-RPC request and wait for the response. */
458
+ async send(request) {
459
+ const body = JSON.stringify(request);
460
+ const parsed = new URL(this._postUrl);
461
+ const isHttps = parsed.protocol === 'https:';
462
+ const lib = isHttps ? requireHttps() : requireHttp();
463
+ return new Promise((resolve, reject) => {
464
+ const headers = {
465
+ 'Content-Type': 'application/json',
466
+ 'Content-Length': Buffer.byteLength(body),
467
+ };
468
+ if (this._secret)
469
+ headers['Authorization'] = `Bearer ${this._secret}`;
470
+ const options = {
471
+ hostname: parsed.hostname,
472
+ port: parseInt(parsed.port || (isHttps ? '443' : '80'), 10),
473
+ path: parsed.pathname + (parsed.search || ''),
474
+ method: 'POST',
475
+ headers,
476
+ };
477
+ const req = lib.request(options, resp => {
478
+ let data = '';
479
+ resp.on('data', (chunk) => { data += chunk.toString(); });
480
+ resp.on('end', () => {
481
+ try {
482
+ resolve(JSON.parse(data));
483
+ }
484
+ catch {
485
+ reject(new Error(`McpSseTransport: invalid JSON from server: ${data.slice(0, 200)}`));
486
+ }
487
+ });
488
+ });
489
+ req.on('error', reject);
490
+ req.setTimeout(30000, () => {
491
+ req.destroy(new Error('McpSseTransport: request timed out after 30s'));
492
+ });
493
+ req.write(body);
494
+ req.end();
495
+ });
496
+ }
497
+ /** Generate a unique request ID. */
498
+ nextId() {
499
+ return ++this._idCounter;
500
+ }
501
+ }
502
+ exports.McpSseTransport = McpSseTransport;
503
+ //# sourceMappingURL=mcp-transport-sse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-transport-sse.js","sourceRoot":"","sources":["../../../lib/mcp-transport-sse.ts"],"names":[],"mappings":"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"}