@wrongstack/mcp 0.264.0 → 0.267.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/dist/index.d.ts CHANGED
@@ -13,7 +13,9 @@ interface MCPClientOptions {
13
13
  startupTimeoutMs?: number | undefined;
14
14
  requestTimeoutMs?: number | undefined;
15
15
  }
16
- type ConnectionState = 'idle' | 'connecting' | 'connected' | 'disconnected' | 'reconnecting' | 'failed';
16
+ type ConnectionState = 'idle' | 'connecting' | 'connected' | 'disconnected' | 'reconnecting' | 'failed'
17
+ /** Lazy server: registered from a cached manifest, process not spawned. */
18
+ | 'dormant';
17
19
  interface MCPTool {
18
20
  name: string;
19
21
  description?: string | undefined;
@@ -115,12 +117,30 @@ declare class MCPClient {
115
117
  removeToolsChangedListener(listener: ToolsChangedListener): void;
116
118
  }
117
119
 
118
- declare function wrapMCPTool(serverName: string, mcpTool: MCPTool, client: MCPClient, permission?: Permission): Tool;
120
+ /**
121
+ * Resolves the live client for a tool call. A plain {@link MCPClient} for eager
122
+ * servers, or a thunk that connects-on-demand for lazy/dormant servers (the
123
+ * registry passes `() => this.ensureConnected(name)`).
124
+ */
125
+ type MCPClientResolver = MCPClient | (() => Promise<MCPClient>);
126
+ declare function wrapMCPTool(serverName: string, mcpTool: MCPTool, client: MCPClientResolver, permission?: Permission): Tool;
119
127
 
120
128
  interface MCPRegistryOptions {
121
129
  toolRegistry: ToolRegistry;
122
130
  events: EventBus;
123
131
  log: Logger;
132
+ /**
133
+ * Directory for the on-disk tool-manifest cache (lazy-connect). Without it,
134
+ * `lazy` servers cannot register tools cold and fall back to eager connect.
135
+ * Typically `wpaths.cacheDir` (`~/.wrongstack/cache`).
136
+ */
137
+ cacheDir?: string | undefined;
138
+ /**
139
+ * Idle window (ms) after which a connected lazy server is auto-stopped and
140
+ * re-woken on the next tool call. 0 disables idle auto-sleep.
141
+ * Default: {@link MCP_CONSTANTS.IDLE.DEFAULT_TIMEOUT_MS}.
142
+ */
143
+ idleTimeoutMs?: number | undefined;
124
144
  /**
125
145
  * Lazy mode: when true, MCP server tools are NOT registered into the
126
146
  * tool registry on connect. They are cached internally and can be
@@ -138,8 +158,24 @@ declare class MCPRegistry {
138
158
  private readonly events;
139
159
  private readonly log;
140
160
  private readonly lazyMode;
161
+ private readonly cacheDir?;
162
+ private readonly idleTimeoutMs;
163
+ /** Single shared idle sweep timer (started lazily; unref'd; cleared on stopAll). */
164
+ private idleTimer?;
141
165
  constructor(opts: MCPRegistryOptions);
142
166
  start(cfg: MCPServerConfig): Promise<void>;
167
+ /**
168
+ * Boot a lazy server WITHOUT spawning it. If a tool manifest is cached (from a
169
+ * prior connect with matching config), register resolver-backed wrappers and
170
+ * go `dormant` — the process spawns on the first tool call. If there is no
171
+ * cache yet, do a one-time cold discovery connect to learn + cache the tools.
172
+ */
173
+ private startLazy;
174
+ /**
175
+ * Ensure a lazy server is connected, spawning it on demand. Single-flight:
176
+ * concurrent first-calls share one connect. Resolver wrappers call this.
177
+ */
178
+ ensureConnected(name: string): Promise<MCPClient>;
143
179
  /**
144
180
  * Register all cached tools for a given server into the tool registry.
145
181
  * No-op if tools are already registered or the server is not connected.
@@ -162,7 +198,32 @@ declare class MCPRegistry {
162
198
  name: string;
163
199
  state: ConnectionState;
164
200
  toolCount: number;
201
+ tools: string[];
165
202
  }[];
203
+ /**
204
+ * Resolve the live tool names for a slot — the registered names in normal
205
+ * mode, or the cached lazy-tool names when running in lazy mode (where
206
+ * tools are connected but intentionally not registered).
207
+ */
208
+ private toolNamesForSlot;
209
+ /**
210
+ * Wrap + register (or cache) a server's tools. Lazy servers get resolver-backed
211
+ * wrappers that spawn the process on first use; eager servers bind the live
212
+ * client directly. Honours token-saving `lazyMode` (cache, don't register) and
213
+ * a register-once guard for lazy resolver wrappers (so a wake/reconnect reuses
214
+ * the existing registrations rather than churning the tool list).
215
+ */
216
+ private applyTools;
217
+ /** Start the shared idle sweep timer once (unref'd so it never holds the process). */
218
+ private ensureIdleSweep;
219
+ /** Auto-sleep connected lazy servers that have been idle past the timeout. */
220
+ private sweepIdle;
221
+ /**
222
+ * Soft stop: close the server process but KEEP its resolver wrappers and
223
+ * cached manifest registered, so the next tool call transparently re-wakes it.
224
+ * Distinct from {@link stop} (full teardown for disable/remove).
225
+ */
226
+ private sleepIdle;
166
227
  /**
167
228
  * Catalog of every server ever registered with this registry — includes
168
229
  * servers that are stopped, failed, or not yet started.
@@ -174,6 +235,7 @@ declare class MCPRegistry {
174
235
  state: ConnectionState;
175
236
  toolCount: number;
176
237
  enabled: boolean;
238
+ tools: string[];
177
239
  }[];
178
240
  stopAll(): Promise<void>;
179
241
  /**
@@ -212,6 +274,83 @@ declare class MCPRegistry {
212
274
  private attemptConnect;
213
275
  }
214
276
 
277
+ /** Transport values accepted from UI surfaces (UI also offers a bare "http"). */
278
+ type TransportInput = 'stdio' | 'sse' | 'streamable-http' | 'http';
279
+ /** Loosely-typed server input as it arrives from a UI or command surface. */
280
+ interface McpServerInput {
281
+ name: string;
282
+ transport?: TransportInput | string | undefined;
283
+ description?: string | undefined;
284
+ enabled?: boolean | undefined;
285
+ command?: string | undefined;
286
+ args?: string[] | undefined;
287
+ env?: Record<string, string> | undefined;
288
+ url?: string | undefined;
289
+ headers?: Record<string, string> | undefined;
290
+ allowedTools?: string[] | undefined;
291
+ permission?: Permission | undefined;
292
+ /** Lazy connect — spawn the process only on first tool call (see config). */
293
+ lazy?: boolean | undefined;
294
+ }
295
+ /** Projected view of one server, merging disk config with live registry state. */
296
+ interface McpServerInfo {
297
+ name: string;
298
+ transport: MCPServerConfig['transport'];
299
+ description?: string | undefined;
300
+ enabled: boolean;
301
+ /** Raw registry state ('connected' | 'connecting' | … | 'failed'), or 'stopped' when not running. */
302
+ status: string;
303
+ /** Real tool names discovered from the live server (empty when not connected). */
304
+ tools: string[];
305
+ url?: string | undefined;
306
+ command?: string | undefined;
307
+ /** Lazy-connect opt-in (spawn on first tool call). */
308
+ lazy?: boolean | undefined;
309
+ }
310
+ interface McpOpResult {
311
+ ok: boolean;
312
+ message: string;
313
+ /** The affected server's projected view, when applicable. */
314
+ server?: McpServerInfo | undefined;
315
+ /** Raw registry state after a start/restart attempt. */
316
+ state?: string | undefined;
317
+ /** Real tool names after a start/restart attempt. */
318
+ tools?: string[] | undefined;
319
+ /** Set when a config change persisted but the registry start/stop failed. */
320
+ registryError?: string | undefined;
321
+ }
322
+ interface McpManageDeps {
323
+ /** Absolute path to the global config.json that owns `mcpServers`. */
324
+ configPath: string;
325
+ /** Live registry for runtime start/stop/restart. */
326
+ registry: MCPRegistry;
327
+ /** Built-in presets (from core `allServers()`), used by name-only `add`. */
328
+ presets?: Record<string, MCPServerConfig> | undefined;
329
+ }
330
+ /** List all configured servers, merged with live registry status + tool names. */
331
+ declare function listMcp(deps: McpManageDeps): Promise<McpServerInfo[]>;
332
+ /**
333
+ * Add a new server. `input` may be a fully-specified config, or just a `name`
334
+ * matching a known preset (`deps.presets`). Fails if the server already exists.
335
+ * When enabled, the server is started immediately via the registry.
336
+ */
337
+ declare function addMcp(input: McpServerInput, deps: McpManageDeps): Promise<McpOpResult>;
338
+ /** Update an existing server's config, then re-apply it to the live registry. */
339
+ declare function updateMcp(input: McpServerInput, deps: McpManageDeps): Promise<McpOpResult>;
340
+ /** Remove a server from config and stop it if running. */
341
+ declare function removeMcp(name: string, deps: McpManageDeps): Promise<McpOpResult>;
342
+ /** Enable a server in config and start it. */
343
+ declare function enableMcp(name: string, deps: McpManageDeps): Promise<McpOpResult>;
344
+ /** Disable a server in config and stop it. */
345
+ declare function disableMcp(name: string, deps: McpManageDeps): Promise<McpOpResult>;
346
+ /** Restart a running server (or start it from config if registered but stopped). */
347
+ declare function restartMcp(name: string, deps: McpManageDeps): Promise<McpOpResult>;
348
+ /**
349
+ * Discover a server's tools. Tools are discovered on connect, so this ensures
350
+ * the server is running and returns its live tool list.
351
+ */
352
+ declare function discoverMcp(name: string, deps: McpManageDeps): Promise<McpOpResult>;
353
+
215
354
  /**
216
355
  * Server-side MCP. The mirror image of `MCPClient`: instead of consuming a
217
356
  * remote MCP server, this lets WrongStack *be* an MCP server — exposing its
@@ -357,6 +496,13 @@ declare const MCP_CONSTANTS: Readonly<{
357
496
  /** Ms after which the force disconnect is triggered. */
358
497
  FORCE_TIMEOUT_MS: 1200;
359
498
  }>;
499
+ /** Lazy-connect idle lifecycle. */
500
+ readonly IDLE: Readonly<{
501
+ /** Default ms a lazy server stays connected with no tool calls before auto-sleep. */
502
+ DEFAULT_TIMEOUT_MS: 300000;
503
+ /** How often the idle sweep runs (kept well below the timeout). */
504
+ SWEEP_INTERVAL_MS: 30000;
505
+ }>;
360
506
  /** JSON-RPC response timeout for outstanding requests. */
361
507
  readonly RESPONSE_TIMEOUT_MS: 500;
362
508
  /** Max buffer size for the SSE reader. */
@@ -365,6 +511,21 @@ declare const MCP_CONSTANTS: Readonly<{
365
511
  readonly REQUEST_LOG_CAP: 1024;
366
512
  }>;
367
513
 
514
+ /** Stable hash of the fields that define how/where we connect to a server. */
515
+ declare function manifestConfigHash(cfg: {
516
+ transport: string;
517
+ command?: string | undefined;
518
+ args?: string[] | undefined;
519
+ url?: string | undefined;
520
+ }): string;
521
+ /**
522
+ * Read a server's cached tools. Returns null when there is no cache or when the
523
+ * stored `configHash` no longer matches (server config changed → stale).
524
+ */
525
+ declare function readManifest(cacheDir: string, name: string, configHash: string): Promise<MCPTool[] | null>;
526
+ /** Persist a server's discovered tools. Best-effort — IO errors are swallowed. */
527
+ declare function writeManifest(cacheDir: string, name: string, configHash: string, tools: MCPTool[]): Promise<void>;
528
+
368
529
  interface HttpTransportOptions {
369
530
  name: string;
370
531
  url: string;
@@ -486,4 +647,4 @@ declare class StreamableHTTPTransport extends BaseHTTPTransport {
486
647
  close(): Promise<void>;
487
648
  }
488
649
 
489
- export { type ConnectionState, type HttpTransportOptions, MCPClient, type MCPClientOptions, MCPRegistry, type MCPRegistryOptions, MCPServer, type MCPServerCallResult, type MCPServerLogger, type MCPServerOptions, type MCPServerTool, type MCPServerToolHost, type MCPTool, MCP_CONSTANTS, SSEReader, SSETransport, type ServeHttpHandle, type ServeHttpOptions, type ServeStdioHandle, type ServeStdioOptions, StreamableHTTPTransport, type ToolCallResult, type Transport, serveHttp, serveStdio, toContentBlocks, wrapMCPTool };
650
+ export { type ConnectionState, type HttpTransportOptions, MCPClient, type MCPClientOptions, MCPRegistry, type MCPRegistryOptions, MCPServer, type MCPServerCallResult, type MCPServerLogger, type MCPServerOptions, type MCPServerTool, type MCPServerToolHost, type MCPTool, MCP_CONSTANTS, type McpManageDeps, type McpOpResult, type McpServerInfo, type McpServerInput, SSEReader, SSETransport, type ServeHttpHandle, type ServeHttpOptions, type ServeStdioHandle, type ServeStdioOptions, StreamableHTTPTransport, type ToolCallResult, type Transport, addMcp, disableMcp, discoverMcp, enableMcp, listMcp, manifestConfigHash, readManifest, removeMcp, restartMcp, serveHttp, serveStdio, toContentBlocks, updateMcp, wrapMCPTool, writeManifest };