pilotswarm 0.0.1 → 0.4.1

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 (150) hide show
  1. package/README.md +37 -1
  2. package/mcp/README.md +484 -0
  3. package/mcp/dist/bin/pilotswarm-mcp.d.ts +3 -0
  4. package/mcp/dist/bin/pilotswarm-mcp.d.ts.map +1 -0
  5. package/mcp/dist/bin/pilotswarm-mcp.js +367 -0
  6. package/mcp/dist/bin/pilotswarm-mcp.js.map +1 -0
  7. package/mcp/dist/src/auth.d.ts +7 -0
  8. package/mcp/dist/src/auth.d.ts.map +1 -0
  9. package/mcp/dist/src/auth.js +99 -0
  10. package/mcp/dist/src/auth.js.map +1 -0
  11. package/mcp/dist/src/context.d.ts +48 -0
  12. package/mcp/dist/src/context.d.ts.map +1 -0
  13. package/mcp/dist/src/context.js +83 -0
  14. package/mcp/dist/src/context.js.map +1 -0
  15. package/mcp/dist/src/index.d.ts +4 -0
  16. package/mcp/dist/src/index.d.ts.map +1 -0
  17. package/mcp/dist/src/index.js +3 -0
  18. package/mcp/dist/src/index.js.map +1 -0
  19. package/mcp/dist/src/prompts/skills.d.ts +4 -0
  20. package/mcp/dist/src/prompts/skills.d.ts.map +1 -0
  21. package/mcp/dist/src/prompts/skills.js +11 -0
  22. package/mcp/dist/src/prompts/skills.js.map +1 -0
  23. package/mcp/dist/src/resources/agents.d.ts +4 -0
  24. package/mcp/dist/src/resources/agents.d.ts.map +1 -0
  25. package/mcp/dist/src/resources/agents.js +64 -0
  26. package/mcp/dist/src/resources/agents.js.map +1 -0
  27. package/mcp/dist/src/resources/facts.d.ts +4 -0
  28. package/mcp/dist/src/resources/facts.d.ts.map +1 -0
  29. package/mcp/dist/src/resources/facts.js +125 -0
  30. package/mcp/dist/src/resources/facts.js.map +1 -0
  31. package/mcp/dist/src/resources/models.d.ts +4 -0
  32. package/mcp/dist/src/resources/models.d.ts.map +1 -0
  33. package/mcp/dist/src/resources/models.js +43 -0
  34. package/mcp/dist/src/resources/models.js.map +1 -0
  35. package/mcp/dist/src/resources/sessions.d.ts +4 -0
  36. package/mcp/dist/src/resources/sessions.d.ts.map +1 -0
  37. package/mcp/dist/src/resources/sessions.js +190 -0
  38. package/mcp/dist/src/resources/sessions.js.map +1 -0
  39. package/mcp/dist/src/resources/subscriptions.d.ts +9 -0
  40. package/mcp/dist/src/resources/subscriptions.d.ts.map +1 -0
  41. package/mcp/dist/src/resources/subscriptions.js +157 -0
  42. package/mcp/dist/src/resources/subscriptions.js.map +1 -0
  43. package/mcp/dist/src/server.d.ts +4 -0
  44. package/mcp/dist/src/server.d.ts.map +1 -0
  45. package/mcp/dist/src/server.js +59 -0
  46. package/mcp/dist/src/server.js.map +1 -0
  47. package/mcp/dist/src/tools/agents.d.ts +4 -0
  48. package/mcp/dist/src/tools/agents.d.ts.map +1 -0
  49. package/mcp/dist/src/tools/agents.js +317 -0
  50. package/mcp/dist/src/tools/agents.js.map +1 -0
  51. package/mcp/dist/src/tools/facts.d.ts +4 -0
  52. package/mcp/dist/src/tools/facts.d.ts.map +1 -0
  53. package/mcp/dist/src/tools/facts.js +151 -0
  54. package/mcp/dist/src/tools/facts.js.map +1 -0
  55. package/mcp/dist/src/tools/models.d.ts +4 -0
  56. package/mcp/dist/src/tools/models.d.ts.map +1 -0
  57. package/mcp/dist/src/tools/models.js +256 -0
  58. package/mcp/dist/src/tools/models.js.map +1 -0
  59. package/mcp/dist/src/tools/sessions.d.ts +4 -0
  60. package/mcp/dist/src/tools/sessions.d.ts.map +1 -0
  61. package/mcp/dist/src/tools/sessions.js +606 -0
  62. package/mcp/dist/src/tools/sessions.js.map +1 -0
  63. package/mcp/dist/src/util/command.d.ts +52 -0
  64. package/mcp/dist/src/util/command.d.ts.map +1 -0
  65. package/mcp/dist/src/util/command.js +78 -0
  66. package/mcp/dist/src/util/command.js.map +1 -0
  67. package/package.json +82 -6
  68. package/tui/README.md +35 -0
  69. package/tui/bin/tui.js +30 -0
  70. package/tui/plugins/.mcp.json +7 -0
  71. package/tui/plugins/plugin.json +13 -0
  72. package/tui/plugins/session-policy.json +8 -0
  73. package/tui/src/app.js +850 -0
  74. package/tui/src/auth/cli.js +111 -0
  75. package/tui/src/auth/entra-auth.js +218 -0
  76. package/tui/src/bootstrap-env.js +176 -0
  77. package/tui/src/embedded-workers.js +79 -0
  78. package/tui/src/http-transport-host.js +106 -0
  79. package/tui/src/index.js +340 -0
  80. package/tui/src/node-sdk-transport.js +1794 -0
  81. package/tui/src/platform.js +984 -0
  82. package/tui/src/plugin-config.js +273 -0
  83. package/tui/src/portal.js +7 -0
  84. package/tui/src/version.js +7 -0
  85. package/tui/tui-splash-mobile.txt +7 -0
  86. package/tui/tui-splash.txt +11 -0
  87. package/ui/core/README.md +6 -0
  88. package/ui/core/src/commands.js +93 -0
  89. package/ui/core/src/context-usage.js +212 -0
  90. package/ui/core/src/controller.js +6201 -0
  91. package/ui/core/src/formatting.js +1036 -0
  92. package/ui/core/src/history.js +950 -0
  93. package/ui/core/src/index.js +13 -0
  94. package/ui/core/src/layout.js +332 -0
  95. package/ui/core/src/reducer.js +1952 -0
  96. package/ui/core/src/selectors.js +5419 -0
  97. package/ui/core/src/session-errors.js +14 -0
  98. package/ui/core/src/session-tree.js +151 -0
  99. package/ui/core/src/state.js +251 -0
  100. package/ui/core/src/store.js +23 -0
  101. package/ui/core/src/system-titles.js +24 -0
  102. package/ui/core/src/themes/catppuccin-mocha.js +56 -0
  103. package/ui/core/src/themes/cobalt2.js +56 -0
  104. package/ui/core/src/themes/dark-high-contrast.js +56 -0
  105. package/ui/core/src/themes/daylight.js +62 -0
  106. package/ui/core/src/themes/dracula.js +56 -0
  107. package/ui/core/src/themes/github-dark.js +56 -0
  108. package/ui/core/src/themes/github-light.js +59 -0
  109. package/ui/core/src/themes/gruvbox-dark.js +56 -0
  110. package/ui/core/src/themes/hacker-x-matrix.js +56 -0
  111. package/ui/core/src/themes/hacker-x-orion-prime.js +56 -0
  112. package/ui/core/src/themes/helpers.js +79 -0
  113. package/ui/core/src/themes/high-contrast-mono.js +59 -0
  114. package/ui/core/src/themes/index.js +52 -0
  115. package/ui/core/src/themes/light-high-contrast.js +62 -0
  116. package/ui/core/src/themes/noctis-obscuro.js +56 -0
  117. package/ui/core/src/themes/noctis.js +56 -0
  118. package/ui/core/src/themes/paper-ink.js +62 -0
  119. package/ui/core/src/themes/solarized-ops.js +59 -0
  120. package/ui/core/src/themes/terminal-green.js +59 -0
  121. package/ui/core/src/themes/tokyo-night.js +56 -0
  122. package/ui/react/README.md +5 -0
  123. package/ui/react/src/chat-status.js +39 -0
  124. package/ui/react/src/components.js +1989 -0
  125. package/ui/react/src/index.js +4 -0
  126. package/ui/react/src/platform.js +15 -0
  127. package/ui/react/src/use-controller-state.js +38 -0
  128. package/ui/react/src/web-app.js +4457 -0
  129. package/web/README.md +198 -0
  130. package/web/api/router.js +196 -0
  131. package/web/api/ws.js +152 -0
  132. package/web/auth/authz/engine.js +204 -0
  133. package/web/auth/config.js +115 -0
  134. package/web/auth/index.js +175 -0
  135. package/web/auth/normalize/entra.js +22 -0
  136. package/web/auth/providers/entra.js +76 -0
  137. package/web/auth/providers/none.js +24 -0
  138. package/web/auth.js +10 -0
  139. package/web/bin/serve.js +53 -0
  140. package/web/config.js +20 -0
  141. package/web/dist/app.js +469 -0
  142. package/web/dist/assets/index-DmGOcKR-.css +1 -0
  143. package/web/dist/assets/index-xJ8IzIZY.js +24 -0
  144. package/web/dist/assets/msal-CytV9RFv.js +7 -0
  145. package/web/dist/assets/pilotswarm-D9pEmenA.js +90 -0
  146. package/web/dist/assets/react-CEPDSRB6.js +1 -0
  147. package/web/dist/index.html +16 -0
  148. package/web/runtime.js +455 -0
  149. package/web/server.js +276 -0
  150. package/index.js +0 -1
@@ -0,0 +1,367 @@
1
+ #!/usr/bin/env node
2
+ import { parseArgs } from "node:util";
3
+ import { randomUUID, timingSafeEqual } from "node:crypto";
4
+ import { Buffer } from "node:buffer";
5
+ import { createContext } from "../src/context.js";
6
+ import { createMcpServer } from "../src/server.js";
7
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
8
+ const { values } = parseArgs({
9
+ options: {
10
+ transport: { type: "string", default: "stdio" },
11
+ port: { type: "string", default: "3100" },
12
+ host: { type: "string" },
13
+ "allowed-hosts": { type: "string" },
14
+ "max-sessions": { type: "string" },
15
+ "session-idle-timeout-ms": { type: "string" },
16
+ store: { type: "string" },
17
+ "api-url": { type: "string" },
18
+ plugin: { type: "string", multiple: true },
19
+ "model-providers": { type: "string" },
20
+ "log-level": { type: "string", default: "error" },
21
+ },
22
+ });
23
+ // Log-level wiring — gates the lifecycle messages emitted by the bin
24
+ // (startup banner, signal handlers, shutdown). Lower tiers also include the
25
+ // higher tiers; "silent" suppresses everything. Fatal `Error:` messages on
26
+ // stderr before process.exit() always print regardless of level.
27
+ const LOG_LEVELS = ["debug", "info", "warn", "error", "silent"];
28
+ const requestedLevel = (values["log-level"] ?? "error").toLowerCase();
29
+ const activeLevel = LOG_LEVELS.includes(requestedLevel)
30
+ ? requestedLevel
31
+ : "error";
32
+ const activeLevelIdx = LOG_LEVELS.indexOf(activeLevel);
33
+ const log = {
34
+ debug: (msg) => { if (activeLevelIdx <= 0)
35
+ console.error(msg); },
36
+ info: (msg) => { if (activeLevelIdx <= 1)
37
+ console.error(msg); },
38
+ warn: (msg) => { if (activeLevelIdx <= 2)
39
+ console.error(msg); },
40
+ error: (msg) => { if (activeLevelIdx <= 3)
41
+ console.error(msg); },
42
+ };
43
+ // Web API mode (supported): no database credentials in this process. Direct
44
+ // --store mode remains for trusted/co-located placement and internal testing.
45
+ const apiUrl = (values["api-url"] ?? process.env.PILOTSWARM_API_URL)?.trim();
46
+ const store = values.store ?? process.env.DATABASE_URL;
47
+ if (apiUrl && values.store) {
48
+ console.error("Error: pass either --api-url (Web API mode) or --store (direct mode), not both.");
49
+ process.exit(1);
50
+ }
51
+ if (!apiUrl && !store) {
52
+ console.error("Error: --api-url <url> (Web API mode) or --store <url> / DATABASE_URL (direct mode) is required.");
53
+ process.exit(1);
54
+ }
55
+ const ctx = await createContext({
56
+ ...(apiUrl ? { apiUrl } : { store }),
57
+ modelProvidersPath: values["model-providers"],
58
+ pluginDirs: values.plugin,
59
+ });
60
+ if (values.transport === "stdio") {
61
+ const server = createMcpServer(ctx);
62
+ const transport = new StdioServerTransport();
63
+ await server.connect(transport);
64
+ const shutdown = async (signal) => {
65
+ log.info(`[pilotswarm-mcp] ${signal} received — closing stdio transport`);
66
+ try {
67
+ await transport.close?.();
68
+ }
69
+ catch { /* ignore */ }
70
+ try {
71
+ await ctx.client.stop?.();
72
+ }
73
+ catch { /* ignore */ }
74
+ try {
75
+ await ctx.mgmt.stop?.();
76
+ }
77
+ catch { /* ignore */ }
78
+ try {
79
+ await ctx.facts.close?.();
80
+ }
81
+ catch { /* ignore */ }
82
+ process.exit(0);
83
+ };
84
+ process.on("SIGTERM", () => void shutdown("SIGTERM"));
85
+ process.on("SIGINT", () => void shutdown("SIGINT"));
86
+ }
87
+ else if (values.transport === "http") {
88
+ const mcpKey = process.env.PILOTSWARM_MCP_KEY;
89
+ if (!mcpKey) {
90
+ console.error("Error: PILOTSWARM_MCP_KEY env var required for HTTP transport.");
91
+ process.exit(1);
92
+ }
93
+ const expectedAuthBuf = Buffer.from(`Bearer ${mcpKey}`);
94
+ const { WebStandardStreamableHTTPServerTransport } = await import("@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js");
95
+ const { Hono } = await import("hono");
96
+ const { cors } = await import("hono/cors");
97
+ const { serve } = await import("@hono/node-server");
98
+ const port = parseInt(values.port ?? "3100", 10);
99
+ const host = values.host ??
100
+ process.env.PILOTSWARM_MCP_HOST ??
101
+ "127.0.0.1";
102
+ // allowedHosts — Host header allowlist to prevent DNS-rebinding attacks.
103
+ // Defaults to localhost-equivalents on the chosen port plus the host:port the
104
+ // server is bound to. Operators bridging through reverse proxies / public DNS
105
+ // must pass --allowed-hosts (or PILOTSWARM_MCP_ALLOWED_HOSTS) explicitly.
106
+ const allowedHostsSrc = values["allowed-hosts"] ??
107
+ process.env.PILOTSWARM_MCP_ALLOWED_HOSTS ??
108
+ "";
109
+ const allowedHosts = new Set(allowedHostsSrc
110
+ .split(",")
111
+ .map((s) => s.trim().toLowerCase())
112
+ .filter((s) => s.length > 0));
113
+ // Always permit the bound host:port + standard localhost aliases on the
114
+ // configured port so the default `--transport http` invocation works without
115
+ // additional flags.
116
+ allowedHosts.add(`${host}:${port}`.toLowerCase());
117
+ allowedHosts.add(`127.0.0.1:${port}`);
118
+ allowedHosts.add(`localhost:${port}`);
119
+ allowedHosts.add(`[::1]:${port}`);
120
+ // max-sessions — concurrent MCP session cap. New sessions beyond this cap are
121
+ // rejected with a 503 + JSON-RPC service-unavailable shape so memory cannot be
122
+ // exhausted by an unbounded number of long-lived SSE connections.
123
+ const maxSessionsRaw = values["max-sessions"] ??
124
+ process.env.PILOTSWARM_MCP_MAX_SESSIONS ??
125
+ "256";
126
+ const parsedMax = parseInt(maxSessionsRaw, 10);
127
+ const maxSessions = Number.isFinite(parsedMax) && parsedMax > 0 ? parsedMax : 256;
128
+ // session-idle-timeout-ms — close + free sessions whose last request was
129
+ // more than this many milliseconds ago. Required because one-shot HTTP
130
+ // clients (initialize + disconnect without DELETE /mcp) never trigger
131
+ // transport.onclose, which would otherwise leak max-sessions slots.
132
+ // Default: 5 minutes (300_000 ms). Set to 0 to disable the sweeper.
133
+ const idleTimeoutRaw = values["session-idle-timeout-ms"] ??
134
+ process.env.PILOTSWARM_MCP_SESSION_IDLE_MS ??
135
+ "300000";
136
+ const parsedIdle = parseInt(idleTimeoutRaw, 10);
137
+ const sessionIdleTimeoutMs = Number.isFinite(parsedIdle) && parsedIdle >= 0 ? parsedIdle : 300_000;
138
+ // Sweep cadence: every 30s, but never longer than the idle threshold itself
139
+ // (otherwise tiny test thresholds are missed entirely).
140
+ const sweepIntervalMs = sessionIdleTimeoutMs > 0
141
+ ? Math.max(1_000, Math.min(30_000, Math.floor(sessionIdleTimeoutMs / 2) || 1_000))
142
+ : 0;
143
+ const app = new Hono();
144
+ const sessions = new Map();
145
+ // Atomic in-flight counter for the max-sessions cap — incremented BEFORE
146
+ // transport construction (so concurrent bursts cannot all observe
147
+ // sessions.size < maxSessions and slip past the gate) and decremented on
148
+ // construction failure or transport close. The counter is the source of
149
+ // truth for cap enforcement; `sessions` is just the lookup table.
150
+ let inFlightSessionCount = 0;
151
+ const acquireSlot = () => {
152
+ if (inFlightSessionCount >= maxSessions)
153
+ return false;
154
+ inFlightSessionCount++;
155
+ return true;
156
+ };
157
+ const releaseSlot = () => {
158
+ if (inFlightSessionCount > 0)
159
+ inFlightSessionCount--;
160
+ };
161
+ const touchSession = (id) => {
162
+ const entry = sessions.get(id);
163
+ if (entry)
164
+ entry.lastActivityAt = Date.now();
165
+ };
166
+ // Track in-flight HTTP request handlers so SIGTERM can wait for them to drain
167
+ // instead of severing connections mid-response.
168
+ const inFlight = new Set();
169
+ let shuttingDown = false;
170
+ app.use("*", async (c, next) => {
171
+ if (shuttingDown) {
172
+ return c.json({ error: "Server shutting down" }, 503);
173
+ }
174
+ // DNS-rebinding defense: validate Host header against the allowlist.
175
+ const hostHeader = (c.req.header("host") ?? "").toLowerCase();
176
+ if (!allowedHosts.has(hostHeader)) {
177
+ return c.json({ error: "Host not allowed" }, 403);
178
+ }
179
+ await next();
180
+ });
181
+ app.use("*", cors({
182
+ origin: "*",
183
+ allowMethods: ["GET", "POST", "DELETE", "OPTIONS"],
184
+ allowHeaders: ["Content-Type", "Authorization", "mcp-session-id", "Last-Event-ID", "mcp-protocol-version"],
185
+ exposeHeaders: ["mcp-session-id", "mcp-protocol-version"],
186
+ }));
187
+ // Bearer token auth middleware — constant-time comparison to avoid leaking
188
+ // the token via timing side-channels.
189
+ app.use("/mcp", async (c, next) => {
190
+ const auth = c.req.header("authorization") ?? "";
191
+ const authBuf = Buffer.from(auth);
192
+ const ok = authBuf.length === expectedAuthBuf.length &&
193
+ timingSafeEqual(authBuf, expectedAuthBuf);
194
+ if (!ok) {
195
+ return c.json({ error: "Unauthorized" }, 401);
196
+ }
197
+ await next();
198
+ });
199
+ app.post("/mcp", async (c) => {
200
+ const sessionId = c.req.header("mcp-session-id");
201
+ if (sessionId && sessions.has(sessionId)) {
202
+ touchSession(sessionId);
203
+ const p = sessions.get(sessionId).transport.handleRequest(c.req.raw);
204
+ inFlight.add(p);
205
+ try {
206
+ return await p;
207
+ }
208
+ finally {
209
+ inFlight.delete(p);
210
+ touchSession(sessionId);
211
+ }
212
+ }
213
+ if (sessionId && !sessions.has(sessionId)) {
214
+ return c.json({ error: "Unknown session" }, 404);
215
+ }
216
+ // Atomic cap check — increment BEFORE constructing the transport so
217
+ // concurrent bursts cannot all observe spare capacity simultaneously.
218
+ if (!acquireSlot()) {
219
+ return c.json({
220
+ jsonrpc: "2.0",
221
+ error: {
222
+ code: -32000,
223
+ message: `Server at session capacity (${maxSessions}); try again later.`,
224
+ },
225
+ id: null,
226
+ }, 503);
227
+ }
228
+ // New session — create per-session server+transport pair. The slot is
229
+ // already reserved; releaseSlot is called exactly once via
230
+ // transport.onclose (which fires from DELETE /mcp, the idle sweeper,
231
+ // shutdown, or any underlying transport-level close).
232
+ let transport;
233
+ try {
234
+ transport = new WebStandardStreamableHTTPServerTransport({
235
+ sessionIdGenerator: () => randomUUID(),
236
+ onsessioninitialized: (id) => {
237
+ sessions.set(id, { transport, lastActivityAt: Date.now() });
238
+ },
239
+ });
240
+ let slotReleased = false;
241
+ transport.onclose = () => {
242
+ if (transport.sessionId)
243
+ sessions.delete(transport.sessionId);
244
+ if (!slotReleased) {
245
+ slotReleased = true;
246
+ releaseSlot();
247
+ }
248
+ };
249
+ const server = createMcpServer(ctx);
250
+ await server.connect(transport);
251
+ }
252
+ catch (err) {
253
+ releaseSlot();
254
+ throw err;
255
+ }
256
+ const p = transport.handleRequest(c.req.raw);
257
+ inFlight.add(p);
258
+ try {
259
+ return await p;
260
+ }
261
+ finally {
262
+ inFlight.delete(p);
263
+ if (transport.sessionId)
264
+ touchSession(transport.sessionId);
265
+ }
266
+ });
267
+ // SSE stream endpoint
268
+ app.get("/mcp", async (c) => {
269
+ const sessionId = c.req.header("mcp-session-id");
270
+ if (sessionId && sessions.has(sessionId)) {
271
+ touchSession(sessionId);
272
+ return sessions.get(sessionId).transport.handleRequest(c.req.raw);
273
+ }
274
+ return c.json({ error: "Invalid or missing session" }, 400);
275
+ });
276
+ // Session cleanup endpoint (per MCP spec)
277
+ app.delete("/mcp", async (c) => {
278
+ const sessionId = c.req.header("mcp-session-id");
279
+ if (!sessionId || !sessions.has(sessionId)) {
280
+ return c.json({ error: "Unknown session" }, 404);
281
+ }
282
+ const entry = sessions.get(sessionId);
283
+ await entry.transport.close();
284
+ sessions.delete(sessionId);
285
+ return c.json({ closed: true });
286
+ });
287
+ // Idle-session sweeper — reaps sessions whose last request was more than
288
+ // sessionIdleTimeoutMs ago. This is the primary defense against
289
+ // max-sessions slot leaks from one-shot HTTP clients that disconnect
290
+ // without sending DELETE /mcp (transport.onclose only fires when the
291
+ // SDK observes an explicit transport close, which one-shot HTTP requests
292
+ // do not trigger).
293
+ let sweeperTimer = null;
294
+ if (sessionIdleTimeoutMs > 0 && sweepIntervalMs > 0) {
295
+ sweeperTimer = setInterval(() => {
296
+ const cutoff = Date.now() - sessionIdleTimeoutMs;
297
+ // Snapshot keys to avoid mutating during iteration.
298
+ const expired = [];
299
+ for (const [id, entry] of sessions) {
300
+ if (entry.lastActivityAt < cutoff)
301
+ expired.push([id, entry]);
302
+ }
303
+ for (const [id, entry] of expired) {
304
+ log.debug(`[pilotswarm-mcp] sweeping idle session ${id}`);
305
+ sessions.delete(id);
306
+ // transport.close() will fire onclose, which calls releaseSlot.
307
+ Promise.resolve(entry.transport.close()).catch(() => { });
308
+ }
309
+ }, sweepIntervalMs);
310
+ sweeperTimer.unref?.();
311
+ }
312
+ const httpServer = serve({ fetch: app.fetch, port, hostname: host }, () => {
313
+ log.info(`PilotSwarm MCP server listening on http://${host}:${port}/mcp`);
314
+ });
315
+ const shutdown = async (signal) => {
316
+ if (shuttingDown)
317
+ return;
318
+ shuttingDown = true;
319
+ log.info(`[pilotswarm-mcp] ${signal} received — draining ${inFlight.size} in-flight request(s), closing ${sessions.size} session(s)`);
320
+ if (sweeperTimer) {
321
+ clearInterval(sweeperTimer);
322
+ sweeperTimer = null;
323
+ }
324
+ const drainTimeoutMs = 5_000;
325
+ await Promise.race([
326
+ Promise.allSettled([...inFlight]),
327
+ new Promise((r) => setTimeout(r, drainTimeoutMs)),
328
+ ]);
329
+ for (const entry of sessions.values()) {
330
+ try {
331
+ await entry.transport.close();
332
+ }
333
+ catch { /* ignore */ }
334
+ }
335
+ sessions.clear();
336
+ await new Promise((resolve) => {
337
+ try {
338
+ httpServer.close(() => resolve());
339
+ }
340
+ catch {
341
+ resolve();
342
+ }
343
+ setTimeout(() => resolve(), drainTimeoutMs).unref?.();
344
+ });
345
+ try {
346
+ await ctx.client.stop?.();
347
+ }
348
+ catch { /* ignore */ }
349
+ try {
350
+ await ctx.mgmt.stop?.();
351
+ }
352
+ catch { /* ignore */ }
353
+ try {
354
+ await ctx.facts.close?.();
355
+ }
356
+ catch { /* ignore */ }
357
+ log.info(`[pilotswarm-mcp] shutdown complete`);
358
+ process.exit(0);
359
+ };
360
+ process.on("SIGTERM", () => void shutdown("SIGTERM"));
361
+ process.on("SIGINT", () => void shutdown("SIGINT"));
362
+ }
363
+ else {
364
+ console.error(`Unknown transport: ${values.transport}. Use "stdio" or "http".`);
365
+ process.exit(1);
366
+ }
367
+ //# sourceMappingURL=pilotswarm-mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pilotswarm-mcp.js","sourceRoot":"","sources":["../../bin/pilotswarm-mcp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Resolve a `getAccessToken` callback for a Web API deployment, or null when
3
+ * the deployment needs no auth. Throws with actionable guidance when an Entra
4
+ * deployment has no usable credential.
5
+ */
6
+ export declare function createApiTokenProvider(apiUrl: string): Promise<(() => Promise<string | null>) | null>;
7
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/auth.ts"],"names":[],"mappings":"AAuEA;;;;GAIG;AACH,wBAAsB,sBAAsB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,MAAM,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC,CA8B3G"}
@@ -0,0 +1,99 @@
1
+ import fs from "node:fs";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { ApiClient } from "pilotswarm-sdk/api";
5
+ /**
6
+ * Bearer-token supplier for the MCP server's Web API (`--api-url`) mode.
7
+ *
8
+ * The MCP server is headless (launched by an MCP host), so it cannot run the
9
+ * interactive browser sign-in the TUI uses. Two credential paths, discovered
10
+ * from the deployment's public `GET /api/v1/auth/config`:
11
+ *
12
+ * - **no-auth deployments** → no token.
13
+ * - **Entra deployments** →
14
+ * 1. `PILOTSWARM_API_TOKEN` (static bearer — service principal / CI), else
15
+ * 2. the cached user token the TUI writes at
16
+ * `~/.config/pilotswarm/auth/<origin>.json` — run `pilotswarm auth
17
+ * login --api-url <url>` once, and the MCP server acquires silently
18
+ * from that cache (dev convenience).
19
+ */
20
+ const AUTH_CACHE_DIR = path.join(process.env.XDG_CONFIG_HOME || path.join(os.homedir(), ".config"), "pilotswarm", "auth");
21
+ function cacheFileForOrigin(apiUrl) {
22
+ const origin = new URL(apiUrl).origin.replace(/[^\w.-]+/g, "_");
23
+ return path.join(AUTH_CACHE_DIR, `${origin}.json`);
24
+ }
25
+ async function silentTokenProviderFromCache(apiUrl, client) {
26
+ let msal;
27
+ try {
28
+ msal = await import("@azure/msal-node");
29
+ }
30
+ catch {
31
+ return null;
32
+ }
33
+ const cacheFile = cacheFileForOrigin(apiUrl);
34
+ const app = new msal.PublicClientApplication({
35
+ auth: { clientId: client.clientId, authority: client.authority },
36
+ cache: {
37
+ cachePlugin: {
38
+ beforeCacheAccess: async (ctx) => {
39
+ try {
40
+ ctx.tokenCache.deserialize(await fs.promises.readFile(cacheFile, "utf8"));
41
+ }
42
+ catch { }
43
+ },
44
+ afterCacheAccess: async (ctx) => {
45
+ if (!ctx.cacheHasChanged)
46
+ return;
47
+ await fs.promises.mkdir(AUTH_CACHE_DIR, { recursive: true, mode: 0o700 });
48
+ await fs.promises.writeFile(cacheFile, ctx.tokenCache.serialize(), { mode: 0o600 });
49
+ },
50
+ },
51
+ },
52
+ });
53
+ const scopes = [`${client.clientId}/.default`];
54
+ return async () => {
55
+ const accounts = await app.getTokenCache().getAllAccounts();
56
+ const account = accounts[0];
57
+ if (!account)
58
+ return null;
59
+ try {
60
+ const result = await app.acquireTokenSilent({ account, scopes });
61
+ return result?.accessToken || null;
62
+ }
63
+ catch {
64
+ return null;
65
+ }
66
+ };
67
+ }
68
+ /**
69
+ * Resolve a `getAccessToken` callback for a Web API deployment, or null when
70
+ * the deployment needs no auth. Throws with actionable guidance when an Entra
71
+ * deployment has no usable credential.
72
+ */
73
+ export async function createApiTokenProvider(apiUrl) {
74
+ const api = new ApiClient({ apiUrl });
75
+ const authConfig = await api.getAuthConfig();
76
+ if (!authConfig?.enabled || authConfig?.provider === "none") {
77
+ return null;
78
+ }
79
+ if (authConfig.provider !== "entra") {
80
+ throw new Error(`Unsupported auth provider '${authConfig.provider}' reported by ${apiUrl}.`);
81
+ }
82
+ const staticToken = String(process.env.PILOTSWARM_API_TOKEN || "").trim();
83
+ if (staticToken) {
84
+ return async () => staticToken;
85
+ }
86
+ const client = authConfig.client;
87
+ if (client?.clientId && client?.authority) {
88
+ const provider = await silentTokenProviderFromCache(apiUrl, client);
89
+ if (provider) {
90
+ // Verify the cache actually yields a token; fail fast otherwise.
91
+ const token = await provider();
92
+ if (token)
93
+ return provider;
94
+ }
95
+ }
96
+ throw new Error(`${apiUrl} requires Entra auth but no credential is available. Set PILOTSWARM_API_TOKEN `
97
+ + `(service principal / CI), or run: pilotswarm auth login --api-url ${apiUrl}`);
98
+ }
99
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import { PilotSwarmClient, PilotSwarmManagementClient, ModelProviderRegistry, loadAgentFiles, type FactStore } from "pilotswarm-sdk";
2
+ type AgentConfig = ReturnType<typeof loadAgentFiles>[number];
3
+ export interface ServerContext {
4
+ client: PilotSwarmClient;
5
+ mgmt: PilotSwarmManagementClient;
6
+ facts: FactStore;
7
+ /** True when running over the Web API (`--api-url`); false in direct mode. */
8
+ webMode: boolean;
9
+ models: ModelProviderRegistry | null;
10
+ skills: Array<{
11
+ name: string;
12
+ description: string;
13
+ prompt: string;
14
+ }>;
15
+ /**
16
+ * Agent definitions visible to this MCP server, loaded from
17
+ * `<pluginDir>/agents/*.agent.md` for each configured plugin dir.
18
+ * Used by the read-only `list_registered_agents` tool. Workers in
19
+ * different processes may have a different catalog — see the tool
20
+ * description for the divergence note.
21
+ */
22
+ registeredAgents: AgentConfig[];
23
+ /**
24
+ * Set of agentIds for sessions where `isSystem === true`, derived from
25
+ * `mgmt.listSessions()` at startup. Used by resource registrations and
26
+ * subscription filters that need to enumerate system agents without
27
+ * hardcoding their names.
28
+ */
29
+ systemAgentIds: Set<string>;
30
+ /**
31
+ * Re-query the management API to refresh `systemAgentIds`. Tool/resource
32
+ * handlers may call this when they suspect the list has drifted (e.g. a
33
+ * new system agent was registered after server startup). Cheap to call —
34
+ * shares the same listSessions() call already used elsewhere.
35
+ */
36
+ refreshSystemAgentIds(): Promise<void>;
37
+ }
38
+ export interface CreateContextOptions {
39
+ /** Direct database URL (internal/trusted placement). Mutually exclusive with apiUrl. */
40
+ store?: string;
41
+ /** Web API base URL (supported remote mode). Mutually exclusive with store. */
42
+ apiUrl?: string;
43
+ modelProvidersPath?: string;
44
+ pluginDirs?: string[];
45
+ }
46
+ export declare function createContext(opts: CreateContextOptions): Promise<ServerContext>;
47
+ export {};
48
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,gBAAgB,EAChB,0BAA0B,EAI1B,qBAAqB,EAErB,cAAc,EACd,KAAK,SAAS,EACjB,MAAM,gBAAgB,CAAC;AAIxB,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAE7D,MAAM,WAAW,aAAa;IAC1B,MAAM,EAAE,gBAAgB,CAAC;IACzB,IAAI,EAAE,0BAA0B,CAAC;IACjC,KAAK,EAAE,SAAS,CAAC;IACjB,8EAA8E;IAC9E,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACrC,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrE;;;;;;OAMG;IACH,gBAAgB,EAAE,WAAW,EAAE,CAAC;IAChC;;;;;OAKG;IACH,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5B;;;;;OAKG;IACH,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,oBAAoB;IACjC,wFAAwF;IACxF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,aAAa,CAAC,CA8EtF"}
@@ -0,0 +1,83 @@
1
+ import { PilotSwarmClient, PilotSwarmManagementClient, createFactStoreForUrl, createWebFactStore, loadModelProviders, loadSkills, loadAgentFiles, } from "pilotswarm-sdk";
2
+ import { ApiClient } from "pilotswarm-sdk/api";
3
+ import { createApiTokenProvider } from "./auth.js";
4
+ export async function createContext(opts) {
5
+ let client;
6
+ let mgmt;
7
+ let facts;
8
+ if (opts.apiUrl) {
9
+ // Web API mode (supported): no database credentials in this process.
10
+ const getAccessToken = await createApiTokenProvider(opts.apiUrl) ?? undefined;
11
+ client = new PilotSwarmClient({ apiUrl: opts.apiUrl, getAccessToken });
12
+ await client.start();
13
+ mgmt = new PilotSwarmManagementClient({ apiUrl: opts.apiUrl, getAccessToken });
14
+ await mgmt.start();
15
+ const api = new ApiClient({ apiUrl: opts.apiUrl, getAccessToken });
16
+ facts = await createWebFactStore(api);
17
+ }
18
+ else if (opts.store) {
19
+ // Direct mode (internal/testing): straight to the datastore.
20
+ client = new PilotSwarmClient({ store: opts.store });
21
+ await client.start();
22
+ mgmt = new PilotSwarmManagementClient({ store: opts.store });
23
+ await mgmt.start();
24
+ facts = await createFactStoreForUrl(opts.store);
25
+ await facts.initialize();
26
+ }
27
+ else {
28
+ throw new Error("createContext requires either apiUrl (web mode) or store (direct mode).");
29
+ }
30
+ const models = loadModelProviders(opts.modelProvidersPath ?? undefined) ?? null;
31
+ let skills = [];
32
+ if (opts.pluginDirs) {
33
+ for (const dir of opts.pluginDirs) {
34
+ try {
35
+ const loaded = await loadSkills(dir + "/skills");
36
+ skills.push(...loaded.map(s => ({ name: s.name, description: s.description, prompt: s.prompt })));
37
+ }
38
+ catch {
39
+ // Directory may not have skills — skip
40
+ }
41
+ }
42
+ }
43
+ let registeredAgents = [];
44
+ if (opts.pluginDirs) {
45
+ // Mirror the worker's loading semantics: name-keyed, last-write-wins
46
+ // (see packages/sdk/src/worker.ts ~line 720). Keying on `id ?? name`
47
+ // would let the MCP catalog diverge from any specific worker's
48
+ // runtime when two plugin dirs share a name but differ on id.
49
+ const byName = new Map();
50
+ for (const dir of opts.pluginDirs) {
51
+ try {
52
+ const loaded = loadAgentFiles(dir + "/agents");
53
+ for (const agent of loaded) {
54
+ if (!agent.name)
55
+ continue;
56
+ byName.set(agent.name, agent);
57
+ }
58
+ }
59
+ catch {
60
+ // Directory may not have agents — skip
61
+ }
62
+ }
63
+ registeredAgents = Array.from(byName.values());
64
+ }
65
+ const systemAgentIds = new Set();
66
+ async function refreshSystemAgentIds() {
67
+ try {
68
+ const sessions = await mgmt.listSessions();
69
+ systemAgentIds.clear();
70
+ for (const s of sessions) {
71
+ if (s?.isSystem && typeof s.agentId === "string" && s.agentId.length > 0) {
72
+ systemAgentIds.add(s.agentId);
73
+ }
74
+ }
75
+ }
76
+ catch {
77
+ // Best-effort — leave existing set untouched if mgmt is transiently unavailable.
78
+ }
79
+ }
80
+ await refreshSystemAgentIds();
81
+ return { client, mgmt, facts, webMode: Boolean(opts.apiUrl), models, skills, registeredAgents, systemAgentIds, refreshSystemAgentIds };
82
+ }
83
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"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"}