@wrongstack/mcp 0.284.0 → 0.285.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/client.d.ts +134 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/constants.d.ts +51 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/index.d.ts +9 -665
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +67 -26
- package/dist/index.js.map +7 -1
- package/dist/manage.d.ts +82 -0
- package/dist/manage.d.ts.map +1 -0
- package/dist/manifest-cache.d.ts +16 -0
- package/dist/manifest-cache.d.ts.map +1 -0
- package/dist/registry.d.ts +151 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/server.d.ts +109 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/test-helpers/mock-server.d.ts +34 -0
- package/dist/test-helpers/mock-server.d.ts.map +1 -0
- package/dist/tool-schema.d.ts +3 -0
- package/dist/tool-schema.d.ts.map +1 -0
- package/dist/transport.d.ts +145 -0
- package/dist/transport.d.ts.map +1 -0
- package/dist/wrap-tool.d.ts +10 -0
- package/dist/wrap-tool.d.ts.map +1 -0
- package/package.json +4 -5
package/dist/manage.d.ts
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { MCPServerConfig, Permission } from '@wrongstack/core';
|
|
2
|
+
import type { MCPRegistry } from './registry.js';
|
|
3
|
+
/** Transport values accepted from UI surfaces (UI also offers a bare "http"). */
|
|
4
|
+
type TransportInput = 'stdio' | 'sse' | 'streamable-http' | 'http';
|
|
5
|
+
/** Loosely-typed server input as it arrives from a UI or command surface. */
|
|
6
|
+
export interface McpServerInput {
|
|
7
|
+
name: string;
|
|
8
|
+
transport?: TransportInput | string | undefined;
|
|
9
|
+
description?: string | undefined;
|
|
10
|
+
enabled?: boolean | undefined;
|
|
11
|
+
command?: string | undefined;
|
|
12
|
+
args?: string[] | undefined;
|
|
13
|
+
env?: Record<string, string> | undefined;
|
|
14
|
+
url?: string | undefined;
|
|
15
|
+
headers?: Record<string, string> | undefined;
|
|
16
|
+
allowedTools?: string[] | undefined;
|
|
17
|
+
permission?: Permission | undefined;
|
|
18
|
+
/** Lazy connect — spawn the process only on first tool call (see config). */
|
|
19
|
+
lazy?: boolean | undefined;
|
|
20
|
+
/** Env var names to forward from parent process at spawn time. */
|
|
21
|
+
passthroughEnv?: string[] | undefined;
|
|
22
|
+
}
|
|
23
|
+
/** Projected view of one server, merging disk config with live registry state. */
|
|
24
|
+
export interface McpServerInfo {
|
|
25
|
+
name: string;
|
|
26
|
+
transport: MCPServerConfig['transport'];
|
|
27
|
+
description?: string | undefined;
|
|
28
|
+
enabled: boolean;
|
|
29
|
+
/** Raw registry state ('connected' | 'connecting' | … | 'failed'), or 'stopped' when not running. */
|
|
30
|
+
status: string;
|
|
31
|
+
/** Real tool names discovered from the live server (empty when not connected). */
|
|
32
|
+
tools: string[];
|
|
33
|
+
url?: string | undefined;
|
|
34
|
+
command?: string | undefined;
|
|
35
|
+
/** Lazy-connect opt-in (spawn on first tool call). */
|
|
36
|
+
lazy?: boolean | undefined;
|
|
37
|
+
}
|
|
38
|
+
export interface McpOpResult {
|
|
39
|
+
ok: boolean;
|
|
40
|
+
message: string;
|
|
41
|
+
/** The affected server's projected view, when applicable. */
|
|
42
|
+
server?: McpServerInfo | undefined;
|
|
43
|
+
/** Raw registry state after a start/restart attempt. */
|
|
44
|
+
state?: string | undefined;
|
|
45
|
+
/** Real tool names after a start/restart attempt. */
|
|
46
|
+
tools?: string[] | undefined;
|
|
47
|
+
/** Set when a config change persisted but the registry start/stop failed. */
|
|
48
|
+
registryError?: string | undefined;
|
|
49
|
+
}
|
|
50
|
+
export interface McpManageDeps {
|
|
51
|
+
/** Absolute path to the global config.json that owns `mcpServers`. */
|
|
52
|
+
configPath: string;
|
|
53
|
+
/** Live registry for runtime start/stop/restart. */
|
|
54
|
+
registry: MCPRegistry;
|
|
55
|
+
/** Built-in presets (from core `allServers()`), used by name-only `add`. */
|
|
56
|
+
presets?: Record<string, MCPServerConfig> | undefined;
|
|
57
|
+
}
|
|
58
|
+
/** List all configured servers, merged with live registry status + tool names. */
|
|
59
|
+
export declare function listMcp(deps: McpManageDeps): Promise<McpServerInfo[]>;
|
|
60
|
+
/**
|
|
61
|
+
* Add a new server. `input` may be a fully-specified config, or just a `name`
|
|
62
|
+
* matching a known preset (`deps.presets`). Fails if the server already exists.
|
|
63
|
+
* When enabled, the server is started immediately via the registry.
|
|
64
|
+
*/
|
|
65
|
+
export declare function addMcp(input: McpServerInput, deps: McpManageDeps): Promise<McpOpResult>;
|
|
66
|
+
/** Update an existing server's config, then re-apply it to the live registry. */
|
|
67
|
+
export declare function updateMcp(input: McpServerInput, deps: McpManageDeps): Promise<McpOpResult>;
|
|
68
|
+
/** Remove a server from config and stop it if running. */
|
|
69
|
+
export declare function removeMcp(name: string, deps: McpManageDeps): Promise<McpOpResult>;
|
|
70
|
+
/** Enable a server in config and start it. */
|
|
71
|
+
export declare function enableMcp(name: string, deps: McpManageDeps): Promise<McpOpResult>;
|
|
72
|
+
/** Disable a server in config and stop it. */
|
|
73
|
+
export declare function disableMcp(name: string, deps: McpManageDeps): Promise<McpOpResult>;
|
|
74
|
+
/** Restart a running server (or start it from config if registered but stopped). */
|
|
75
|
+
export declare function restartMcp(name: string, deps: McpManageDeps): Promise<McpOpResult>;
|
|
76
|
+
/**
|
|
77
|
+
* Discover a server's tools. Tools are discovered on connect, so this ensures
|
|
78
|
+
* the server is running and returns its live tool list.
|
|
79
|
+
*/
|
|
80
|
+
export declare function discoverMcp(name: string, deps: McpManageDeps): Promise<McpOpResult>;
|
|
81
|
+
export {};
|
|
82
|
+
//# sourceMappingURL=manage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manage.d.ts","sourceRoot":"","sources":["../src/manage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { MCPTool } from './client.js';
|
|
2
|
+
/** Stable hash of the fields that define how/where we connect to a server. */
|
|
3
|
+
export declare function manifestConfigHash(cfg: {
|
|
4
|
+
transport: string;
|
|
5
|
+
command?: string | undefined;
|
|
6
|
+
args?: string[] | undefined;
|
|
7
|
+
url?: string | undefined;
|
|
8
|
+
}): string;
|
|
9
|
+
/**
|
|
10
|
+
* Read a server's cached tools. Returns null when there is no cache or when the
|
|
11
|
+
* stored `configHash` no longer matches (server config changed → stale).
|
|
12
|
+
*/
|
|
13
|
+
export declare function readManifest(cacheDir: string, name: string, configHash: string): Promise<MCPTool[] | null>;
|
|
14
|
+
/** Persist a server's discovered tools. Best-effort — IO errors are swallowed. */
|
|
15
|
+
export declare function writeManifest(cacheDir: string, name: string, configHash: string, tools: MCPTool[]): Promise<void>;
|
|
16
|
+
//# sourceMappingURL=manifest-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest-cache.d.ts","sourceRoot":"","sources":["../src/manifest-cache.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAO3C,8EAA8E;AAC9E,wBAAgB,kBAAkB,CAAC,GAAG,EAAE;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1B,GAAG,MAAM,CAQT;AAQD;;;GAGG;AACH,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAS3B;AAED,kFAAkF;AAClF,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,OAAO,EAAE,GACf,OAAO,CAAC,IAAI,CAAC,CAWf"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import type { EventBus, Logger, MCPServerConfig, ToolRegistry } from '@wrongstack/core';
|
|
2
|
+
import { type ConnectionState, MCPClient } from './client.js';
|
|
3
|
+
export interface MCPRegistryOptions {
|
|
4
|
+
toolRegistry: ToolRegistry;
|
|
5
|
+
events: EventBus;
|
|
6
|
+
log: Logger;
|
|
7
|
+
/**
|
|
8
|
+
* Directory for the on-disk tool-manifest cache (lazy-connect). Without it,
|
|
9
|
+
* `lazy` servers cannot register tools cold and fall back to eager connect.
|
|
10
|
+
* Typically `wpaths.cacheDir` (`~/.wrongstack/cache`).
|
|
11
|
+
*/
|
|
12
|
+
cacheDir?: string | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* Idle window (ms) after which a connected lazy server is auto-stopped and
|
|
15
|
+
* re-woken on the next tool call. 0 disables idle auto-sleep.
|
|
16
|
+
* Default: {@link MCP_CONSTANTS.IDLE.DEFAULT_TIMEOUT_MS}.
|
|
17
|
+
*/
|
|
18
|
+
idleTimeoutMs?: number | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Lazy mode: when true, MCP server tools are NOT registered into the
|
|
21
|
+
* tool registry on connect. They are cached internally and can be
|
|
22
|
+
* activated on demand via `activateServer(name)`. This is used in
|
|
23
|
+
* token-saving mode to avoid bloating the system prompt with 50-100+
|
|
24
|
+
* MCP tool descriptions. The model uses `mcp_control({ action: "activate", server: "..." })`
|
|
25
|
+
* to temporarily enable tools when needed.
|
|
26
|
+
* Default: false.
|
|
27
|
+
*/
|
|
28
|
+
lazyMode?: boolean | undefined;
|
|
29
|
+
}
|
|
30
|
+
export declare class MCPRegistry {
|
|
31
|
+
private readonly servers;
|
|
32
|
+
private readonly toolRegistry;
|
|
33
|
+
private readonly events;
|
|
34
|
+
private readonly log;
|
|
35
|
+
private readonly lazyMode;
|
|
36
|
+
private readonly cacheDir?;
|
|
37
|
+
private readonly idleTimeoutMs;
|
|
38
|
+
/** Single shared idle sweep timer (started lazily; unref'd; cleared on stopAll). */
|
|
39
|
+
private idleTimer?;
|
|
40
|
+
constructor(opts: MCPRegistryOptions);
|
|
41
|
+
start(cfg: MCPServerConfig): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* Boot a lazy server WITHOUT spawning it. If a tool manifest is cached (from a
|
|
44
|
+
* prior connect with matching config), register resolver-backed wrappers and
|
|
45
|
+
* go `dormant` — the process spawns on the first tool call. If there is no
|
|
46
|
+
* cache yet, do a one-time cold discovery connect to learn + cache the tools.
|
|
47
|
+
*/
|
|
48
|
+
private startLazy;
|
|
49
|
+
/**
|
|
50
|
+
* Ensure a lazy server is connected, spawning it on demand. Single-flight:
|
|
51
|
+
* concurrent first-calls share one connect. Resolver wrappers call this.
|
|
52
|
+
*/
|
|
53
|
+
ensureConnected(name: string): Promise<MCPClient>;
|
|
54
|
+
/**
|
|
55
|
+
* Register all cached tools for a given server into the tool registry.
|
|
56
|
+
* No-op if tools are already registered or the server is not connected.
|
|
57
|
+
* The server connection stays alive — this only toggles tool visibility.
|
|
58
|
+
*/
|
|
59
|
+
activateServer(name: string): void;
|
|
60
|
+
/**
|
|
61
|
+
* Unregister all tools for a given server from the tool registry.
|
|
62
|
+
* The server connection stays alive — this only toggles tool visibility.
|
|
63
|
+
* Returns the number of tools that were deactivated.
|
|
64
|
+
*/
|
|
65
|
+
deactivateServer(name: string): number;
|
|
66
|
+
/**
|
|
67
|
+
* Check whether a server's tools are currently registered.
|
|
68
|
+
*/
|
|
69
|
+
isActivated(name: string): boolean;
|
|
70
|
+
stop(name: string): Promise<void>;
|
|
71
|
+
restart(name: string): Promise<void>;
|
|
72
|
+
list(): {
|
|
73
|
+
name: string;
|
|
74
|
+
state: ConnectionState;
|
|
75
|
+
toolCount: number;
|
|
76
|
+
tools: string[];
|
|
77
|
+
}[];
|
|
78
|
+
/**
|
|
79
|
+
* Resolve the live tool names for a slot — the registered names in normal
|
|
80
|
+
* mode, or the cached lazy-tool names when running in lazy mode (where
|
|
81
|
+
* tools are connected but intentionally not registered).
|
|
82
|
+
*/
|
|
83
|
+
private toolNamesForSlot;
|
|
84
|
+
/**
|
|
85
|
+
* Wrap + register (or cache) a server's tools. Lazy servers get resolver-backed
|
|
86
|
+
* wrappers that spawn the process on first use; eager servers bind the live
|
|
87
|
+
* client directly. Honours token-saving `lazyMode` (cache, don't register) and
|
|
88
|
+
* a register-once guard for lazy resolver wrappers (so a wake/reconnect reuses
|
|
89
|
+
* the existing registrations rather than churning the tool list).
|
|
90
|
+
*/
|
|
91
|
+
private applyTools;
|
|
92
|
+
/** Start the shared idle sweep timer once (unref'd so it never holds the process). */
|
|
93
|
+
private ensureIdleSweep;
|
|
94
|
+
/** Auto-sleep connected lazy servers that have been idle past the timeout. */
|
|
95
|
+
private sweepIdle;
|
|
96
|
+
/**
|
|
97
|
+
* Soft stop: close the server process but KEEP its resolver wrappers and
|
|
98
|
+
* cached manifest registered, so the next tool call transparently re-wakes it.
|
|
99
|
+
* Distinct from {@link stop} (full teardown for disable/remove).
|
|
100
|
+
*/
|
|
101
|
+
private sleepIdle;
|
|
102
|
+
/**
|
|
103
|
+
* Catalog of every server ever registered with this registry — includes
|
|
104
|
+
* servers that are stopped, failed, or not yet started.
|
|
105
|
+
* Useful for the `mcp_control` tool to show all known servers without
|
|
106
|
+
* triggering connections.
|
|
107
|
+
*/
|
|
108
|
+
describe(): {
|
|
109
|
+
name: string;
|
|
110
|
+
state: ConnectionState;
|
|
111
|
+
toolCount: number;
|
|
112
|
+
enabled: boolean;
|
|
113
|
+
tools: string[];
|
|
114
|
+
}[];
|
|
115
|
+
stopAll(): Promise<void>;
|
|
116
|
+
/**
|
|
117
|
+
* Health check — returns 'ok' for connected servers, the current state otherwise.
|
|
118
|
+
* For HTTP-based transports this could also ping the server.
|
|
119
|
+
*/
|
|
120
|
+
health(): {
|
|
121
|
+
name: string;
|
|
122
|
+
alive: boolean;
|
|
123
|
+
latencyMs?: number | undefined;
|
|
124
|
+
}[];
|
|
125
|
+
/**
|
|
126
|
+
* L2-C: handle `notifications/tools/list_changed` from the server.
|
|
127
|
+
* Unregister the previous wrapper set, then re-register the fresh
|
|
128
|
+
* tool list. The client has already refreshed its cache before
|
|
129
|
+
* dispatching — we just need to re-wrap and re-register.
|
|
130
|
+
* In lazy mode, only update the internal cache without registering.
|
|
131
|
+
*/
|
|
132
|
+
private readonly onToolsChanged;
|
|
133
|
+
private readonly onChildExit;
|
|
134
|
+
/** Handles SSE / streamable-http disconnect — same recovery as stdio child exit. */
|
|
135
|
+
private readonly onTransportDisconnect;
|
|
136
|
+
/**
|
|
137
|
+
* L2-B: maximum number of reconnect cycles before staying `failed`.
|
|
138
|
+
* One cycle = one full `attemptConnect` (which itself may try up to 3
|
|
139
|
+
* times). Caps total reconnect storm at ~5 cycles, then the slot
|
|
140
|
+
* needs an explicit `restart()` to re-engage.
|
|
141
|
+
*/
|
|
142
|
+
private static readonly MAX_RECONNECT_CYCLES;
|
|
143
|
+
/** Base delay between cycles, in ms. Real delay adds jitter. */
|
|
144
|
+
private static readonly BASE_RECONNECT_DELAY_MS;
|
|
145
|
+
/** Hard ceiling on the inter-cycle delay so the user doesn't wait minutes. */
|
|
146
|
+
private static readonly MAX_RECONNECT_DELAY_MS;
|
|
147
|
+
private scheduleReconnect;
|
|
148
|
+
private attemptReconnect;
|
|
149
|
+
private attemptConnect;
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,eAAe,EAAQ,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAE9F,OAAO,EAAE,KAAK,eAAe,EAAE,SAAS,EAAgB,MAAM,aAAa,CAAC;AAsD5E,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,YAAY,CAAC;IAC3B,MAAM,EAAE,QAAQ,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAChC;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiC;IACzD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAW;IAClC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAqB;IAC/C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,oFAAoF;IACpF,OAAO,CAAC,SAAS,CAAC,CAA6C;IAE/D,YAAY,IAAI,EAAE,kBAAkB,EAOnC;IAEK,KAAK,CAAC,GAAG,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAiC/C;IAED;;;;;OAKG;YACW,SAAS;IAsBvB;;;OAGG;IACG,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAuBtD;IAED;;;;OAIG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAmBjC;IAED;;;;OAIG;IACH,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAgBrC;IAED;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGjC;IAEK,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA2BtC;IAEK,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOzC;IAED,IAAI,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,eAAe,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAUrF;IAED;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAIxB;;;;;;OAMG;IACH,OAAO,CAAC,UAAU;IAyBlB,sFAAsF;IACtF,OAAO,CAAC,eAAe;IASvB,8EAA8E;YAChE,SAAS;IAevB;;;;OAIG;YACW,SAAS;IAsBvB;;;;;OAKG;IACH,QAAQ,IAAI;QACV,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,eAAe,CAAC;QACvB,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,OAAO,CAAC;QACjB,KAAK,EAAE,MAAM,EAAE,CAAC;KACjB,EAAE,CAWF;IAEK,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAQ7B;IAED;;;OAGG;IACH,MAAM,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE,EAAE,CAK3E;IAED;;;;;;OAMG;IACH,OAAO,CAAC,QAAQ,CAAC,cAAc,CA0B7B;IAEF,OAAO,CAAC,QAAQ,CAAC,WAAW,CA8B1B;IAEF,oFAAoF;IACpF,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAqBpC;IAEF;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,oBAAoB,CAAsC;IAClF,gEAAgE;IAChE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAAyC;IACxF,8EAA8E;IAC9E,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CAAU;IAExD,OAAO,CAAC,iBAAiB;YAsCX,gBAAgB;YAMhB,cAAc;CA+G7B"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-side MCP. The mirror image of `MCPClient`: instead of consuming a
|
|
3
|
+
* remote MCP server, this lets WrongStack *be* an MCP server — exposing its
|
|
4
|
+
* tools to any MCP client (Claude Desktop, another agent, an IDE) over a
|
|
5
|
+
* JSON-RPC 2.0 stream.
|
|
6
|
+
*
|
|
7
|
+
* The protocol core (`MCPServer`) is transport-agnostic: feed it a raw JSON
|
|
8
|
+
* line via `handleMessage`, get back a response string (or `null` for
|
|
9
|
+
* notifications). `serveStdio` wires it to stdin/stdout for the canonical
|
|
10
|
+
* stdio transport.
|
|
11
|
+
*/
|
|
12
|
+
/** A tool descriptor advertised over `tools/list`. */
|
|
13
|
+
export interface MCPServerTool {
|
|
14
|
+
name: string;
|
|
15
|
+
description?: string | undefined;
|
|
16
|
+
inputSchema: Record<string, unknown>;
|
|
17
|
+
}
|
|
18
|
+
/** The result of a `tools/call`, as the host produces it. */
|
|
19
|
+
export interface MCPServerCallResult {
|
|
20
|
+
/** Text or pre-built MCP content blocks. Strings are wrapped as a text block. */
|
|
21
|
+
content: unknown;
|
|
22
|
+
isError: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Bridges the MCP server to a tool backend (in the CLI, the `ToolRegistry`).
|
|
26
|
+
* Kept narrow so the protocol core has no dependency on `@wrongstack/core`.
|
|
27
|
+
*/
|
|
28
|
+
export interface MCPServerToolHost {
|
|
29
|
+
listTools(): MCPServerTool[] | Promise<MCPServerTool[]>;
|
|
30
|
+
callTool(name: string, args: Record<string, unknown>): Promise<MCPServerCallResult>;
|
|
31
|
+
}
|
|
32
|
+
export interface MCPServerLogger {
|
|
33
|
+
warn?(msg: string): void;
|
|
34
|
+
info?(msg: string): void;
|
|
35
|
+
}
|
|
36
|
+
export interface MCPServerOptions {
|
|
37
|
+
host: MCPServerToolHost;
|
|
38
|
+
/** Advertised in the `initialize` handshake. Defaults to the wrongstack identity. */
|
|
39
|
+
serverInfo?: {
|
|
40
|
+
name: string;
|
|
41
|
+
version: string;
|
|
42
|
+
};
|
|
43
|
+
logger?: MCPServerLogger | undefined;
|
|
44
|
+
}
|
|
45
|
+
export declare class MCPServer {
|
|
46
|
+
private readonly host;
|
|
47
|
+
private readonly serverInfo;
|
|
48
|
+
private readonly logger?;
|
|
49
|
+
constructor(opts: MCPServerOptions);
|
|
50
|
+
/**
|
|
51
|
+
* Handle one raw JSON-RPC line. Returns the response JSON string for
|
|
52
|
+
* requests, or `null` for notifications (no `id`) and for blank input —
|
|
53
|
+
* the caller should write the string to its output stream when non-null.
|
|
54
|
+
*/
|
|
55
|
+
handleMessage(raw: string): Promise<string | null>;
|
|
56
|
+
private dispatch;
|
|
57
|
+
private encodeError;
|
|
58
|
+
}
|
|
59
|
+
/** Normalize a host result's content into MCP content blocks. */
|
|
60
|
+
export declare function toContentBlocks(content: unknown): Array<{
|
|
61
|
+
type: 'text';
|
|
62
|
+
text: string;
|
|
63
|
+
}>;
|
|
64
|
+
export interface ServeStdioHandle {
|
|
65
|
+
/** Stop reading and detach listeners. Does not exit the process. */
|
|
66
|
+
close(): void;
|
|
67
|
+
/** Resolves when the input stream ends (EOF). */
|
|
68
|
+
done: Promise<void>;
|
|
69
|
+
}
|
|
70
|
+
export interface ServeStdioOptions {
|
|
71
|
+
stdin?: NodeJS.ReadableStream | undefined;
|
|
72
|
+
stdout?: NodeJS.WritableStream | undefined;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Run an `MCPServer` over stdio: newline-delimited JSON-RPC in on stdin,
|
|
76
|
+
* responses out on stdout. CRITICAL: nothing else may write to stdout while
|
|
77
|
+
* this runs — it is the JSON-RPC channel. Route all logging to stderr.
|
|
78
|
+
*/
|
|
79
|
+
export declare function serveStdio(server: MCPServer, opts?: ServeStdioOptions): ServeStdioHandle;
|
|
80
|
+
export interface ServeHttpOptions {
|
|
81
|
+
/** TCP port. 0 picks an ephemeral port (resolved in the handle). Default 0. */
|
|
82
|
+
port?: number | undefined;
|
|
83
|
+
/** Bind address. Default '127.0.0.1' (loopback only). */
|
|
84
|
+
host?: string | undefined;
|
|
85
|
+
/**
|
|
86
|
+
* Bearer token required on every request (`Authorization: Bearer <token>`).
|
|
87
|
+
* REQUIRED when binding to a non-loopback host — `serveHttp` refuses to
|
|
88
|
+
* expose tools to the network without one.
|
|
89
|
+
*/
|
|
90
|
+
token?: string | undefined;
|
|
91
|
+
logger?: MCPServerLogger | undefined;
|
|
92
|
+
}
|
|
93
|
+
export interface ServeHttpHandle {
|
|
94
|
+
port: number;
|
|
95
|
+
host: string;
|
|
96
|
+
url: string;
|
|
97
|
+
close(): Promise<void>;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Run an `MCPServer` over HTTP: POST a single JSON-RPC request, get the JSON
|
|
101
|
+
* response (notifications → 202 with no body). Reuses `handleMessage`, so the
|
|
102
|
+
* protocol is identical to the stdio transport.
|
|
103
|
+
*
|
|
104
|
+
* Security: binds to loopback by default. Binding to any other host (e.g.
|
|
105
|
+
* `0.0.0.0`) REQUIRES a `token` — otherwise this rejects, because it would
|
|
106
|
+
* otherwise expose tool execution to the whole network unauthenticated.
|
|
107
|
+
*/
|
|
108
|
+
export declare function serveHttp(server: MCPServer, opts?: ServeHttpOptions): Promise<ServeHttpHandle>;
|
|
109
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { MCPTool } from '../client.js';
|
|
2
|
+
export interface MockToolResponse {
|
|
3
|
+
content: unknown;
|
|
4
|
+
isError?: boolean | undefined;
|
|
5
|
+
}
|
|
6
|
+
export interface MockMCPServerOptions {
|
|
7
|
+
/** Delay injected between receiving a request and sending the response (ms). */
|
|
8
|
+
responseDelayMs?: number | undefined;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Minimal in-process MCP server that speaks JSON-RPC over stdio.
|
|
12
|
+
* Writes a self-contained Node.js script to a temp file and exposes the path
|
|
13
|
+
* for spawning as a child process.
|
|
14
|
+
*/
|
|
15
|
+
export declare class MockMCPServer {
|
|
16
|
+
private readonly tools;
|
|
17
|
+
private readonly delayMs;
|
|
18
|
+
/** Responses keyed by `JSON.stringify(params)` for tools/call. */
|
|
19
|
+
private readonly responses;
|
|
20
|
+
private scriptPath?;
|
|
21
|
+
constructor(tools?: MCPTool[], opts?: MockMCPServerOptions);
|
|
22
|
+
setResponse(params: unknown, response: MockToolResponse | string): void;
|
|
23
|
+
setTools(tools: MCPTool[]): void;
|
|
24
|
+
/**
|
|
25
|
+
* Write the mock server script to a temp file and return the path.
|
|
26
|
+
* The script is self-contained and requires no external dependencies.
|
|
27
|
+
*/
|
|
28
|
+
writeScript(): Promise<string>;
|
|
29
|
+
/** Delete the temp script. Call after test completes. */
|
|
30
|
+
cleanup(): Promise<void>;
|
|
31
|
+
/** Path to the script if already written via writeScript(). */
|
|
32
|
+
get path(): string | undefined;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=mock-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock-server.d.ts","sourceRoot":"","sources":["../../src/test-helpers/mock-server.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC/B;AAED,MAAM,WAAW,oBAAoB;IACnC,gFAAgF;IAChF,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACtC;AAED;;;;GAIG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAY;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,kEAAkE;IAClE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuC;IACjE,OAAO,CAAC,UAAU,CAAC,CAAqB;IAExC,YAAY,KAAK,GAAE,OAAO,EAAO,EAAE,IAAI,GAAE,oBAAyB,EAGjE;IAED,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,gBAAgB,GAAG,MAAM,GAAG,IAAI,CAKtE;IAED,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,IAAI,CAG/B;IAED;;;OAGG;IACG,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,CAoDnC;IAED,yDAAyD;IACnD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAS7B;IAED,+DAA+D;IAC/D,IAAI,IAAI,IAAI,MAAM,GAAG,SAAS,CAE7B;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-schema.d.ts","sourceRoot":"","sources":["../src/tool-schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,EAAE,CA8B3D"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import * as https from 'node:https';
|
|
2
|
+
import type { ConnectionState, JsonRpcResponse, MCPTool, ToolCallResult } from './client.js';
|
|
3
|
+
export type JsonRpcResult = {
|
|
4
|
+
jsonrpc: string;
|
|
5
|
+
id?: number | undefined;
|
|
6
|
+
result?: unknown | undefined;
|
|
7
|
+
error?: {
|
|
8
|
+
code: number | undefined;
|
|
9
|
+
message: string;
|
|
10
|
+
data?: unknown | undefined;
|
|
11
|
+
} | undefined;
|
|
12
|
+
};
|
|
13
|
+
export interface HttpTransportOptions {
|
|
14
|
+
name: string;
|
|
15
|
+
url: string;
|
|
16
|
+
headers?: Record<string, string> | undefined;
|
|
17
|
+
startupTimeoutMs?: number | undefined;
|
|
18
|
+
requestTimeoutMs?: number | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Per-request TLS configuration. When set, an https.Agent is created
|
|
21
|
+
* and passed to fetch via the `dispatch` option. This avoids globally
|
|
22
|
+
* disabling certificate validation (NODE_TLS_REJECT_UNAUTHORIZED) which
|
|
23
|
+
* would affect all provider API calls in the same process.
|
|
24
|
+
*
|
|
25
|
+
* ⚠️ Security gate: `rejectUnauthorized: false` REQUIRES
|
|
26
|
+
* `WRONGSTACK_UNSAFE_MCP_TLS=1` as an explicit opt-in.
|
|
27
|
+
*
|
|
28
|
+
* Without this gate, an active network attacker between the client and the
|
|
29
|
+
* MCP server can read and modify tool calls and responses. Only use this
|
|
30
|
+
* for local development with self-signed certificates; production MCP
|
|
31
|
+
* servers must present a valid certificate.
|
|
32
|
+
*/
|
|
33
|
+
tls?: {
|
|
34
|
+
ca?: string | undefined;
|
|
35
|
+
rejectUnauthorized?: boolean | undefined;
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export declare class SSEReader {
|
|
39
|
+
private buffer;
|
|
40
|
+
private dataLines;
|
|
41
|
+
private listeners;
|
|
42
|
+
onMessage(cb: (data: {
|
|
43
|
+
jsonrpc?: string | undefined;
|
|
44
|
+
method?: string | undefined;
|
|
45
|
+
params?: unknown | undefined;
|
|
46
|
+
id?: number | undefined;
|
|
47
|
+
}) => void): () => void;
|
|
48
|
+
feed(chunk: string): void;
|
|
49
|
+
private processLine;
|
|
50
|
+
private flush;
|
|
51
|
+
private dispatch;
|
|
52
|
+
reset(): void;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Extract JSON-RPC envelopes from a streamable-http response body. Handles BOTH
|
|
56
|
+
* plain NDJSON (one JSON object per line) AND SSE framing
|
|
57
|
+
* (`event: message\ndata: {...}` blocks) — modern MCP servers (e.g. Context7)
|
|
58
|
+
* reply with `text/event-stream` even on a single POST, so the data must be
|
|
59
|
+
* un-prefixed before parsing. Multi-line `data:` values within one event are
|
|
60
|
+
* joined per the SSE spec.
|
|
61
|
+
*/
|
|
62
|
+
export declare function extractJsonRpcResults(text: string): JsonRpcResult[];
|
|
63
|
+
/**
|
|
64
|
+
* Fields and methods shared by all HTTP-based MCP transports.
|
|
65
|
+
* Subclasses override `connect()`, `close()`, `callTool()`, `request()`.
|
|
66
|
+
*/
|
|
67
|
+
export declare abstract class BaseHTTPTransport {
|
|
68
|
+
protected state: ConnectionState;
|
|
69
|
+
protected readonly url: string;
|
|
70
|
+
protected readonly headers: Record<string, string>;
|
|
71
|
+
protected readonly timeout: number;
|
|
72
|
+
protected readonly requestTimeout: number;
|
|
73
|
+
/** Per-request TLS agent — created once from HttpTransportOptions.tls */
|
|
74
|
+
protected readonly tlsAgent?: https.Agent | undefined;
|
|
75
|
+
protected readonly tools: MCPTool[];
|
|
76
|
+
protected abortController?: AbortController | undefined;
|
|
77
|
+
protected readonly disconnectHandlers: Array<() => void>;
|
|
78
|
+
protected readonly toolsChangedListeners: Set<(tools: MCPTool[]) => void>;
|
|
79
|
+
constructor(opts: HttpTransportOptions, transportName: string);
|
|
80
|
+
getState(): ConnectionState;
|
|
81
|
+
listTools(): MCPTool[];
|
|
82
|
+
onDisconnect(cb: () => void): () => void;
|
|
83
|
+
onToolsChanged(cb: (tools: MCPTool[]) => void): () => void;
|
|
84
|
+
/**
|
|
85
|
+
* Fire all disconnect handlers. Subclasses call this when the connection
|
|
86
|
+
* drops so the registry can schedule reconnects.
|
|
87
|
+
*/
|
|
88
|
+
protected notifyDisconnect(): void;
|
|
89
|
+
/**
|
|
90
|
+
* Apply the pinned TLS agent (if configured) to a `RequestInit` object.
|
|
91
|
+
* Uses `HttpDispatcher` from `@wrongstack/core`'s dispatcher-types shim,
|
|
92
|
+
* which declares `https.Agent` compatible with `RequestInit.dispatcher`.
|
|
93
|
+
* Verified safe: https.Agent implements the `dispatch(req, opts)` method
|
|
94
|
+
* that fetch requires at runtime.
|
|
95
|
+
*/
|
|
96
|
+
protected applyTlsAgent(fetchOpts: RequestInit): void;
|
|
97
|
+
/** Generate the next JSON-RPC request id. Subclasses provide the counter. */
|
|
98
|
+
protected abstract genId(): number;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* SSE transport for MCP over HTTP.
|
|
102
|
+
*
|
|
103
|
+
* Uses native fetch API with ReadableStream to consume SSE events.
|
|
104
|
+
* HTTP POST is used to send JSON-RPC requests.
|
|
105
|
+
*/
|
|
106
|
+
export declare class SSETransport extends BaseHTTPTransport {
|
|
107
|
+
private _nextId;
|
|
108
|
+
private readerDone;
|
|
109
|
+
private readLoopAbort?;
|
|
110
|
+
private reader?;
|
|
111
|
+
constructor(opts: HttpTransportOptions);
|
|
112
|
+
protected genId(): number;
|
|
113
|
+
/** Refresh tool list when server sends notifications/tools/list_changed. */
|
|
114
|
+
private handleToolsListChanged;
|
|
115
|
+
connect(): Promise<void>;
|
|
116
|
+
private readSSEBody;
|
|
117
|
+
private buildSSEUrl;
|
|
118
|
+
private httpPost;
|
|
119
|
+
callTool(name: string, input: unknown, opts?: {
|
|
120
|
+
signal?: AbortSignal | undefined;
|
|
121
|
+
}): Promise<ToolCallResult>;
|
|
122
|
+
/** Generic JSON-RPC request — used by MCPClient.request() for SSE transports. */
|
|
123
|
+
request(method: string, params: unknown, timeoutMs?: number): Promise<JsonRpcResponse>;
|
|
124
|
+
close(): Promise<void>;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Streamable HTTP transport for MCP.
|
|
128
|
+
*
|
|
129
|
+
* Uses session-based HTTP with NDJSON responses.
|
|
130
|
+
*/
|
|
131
|
+
export declare class StreamableHTTPTransport extends BaseHTTPTransport {
|
|
132
|
+
private _nextId;
|
|
133
|
+
private sessionId?;
|
|
134
|
+
constructor(opts: HttpTransportOptions);
|
|
135
|
+
protected genId(): number;
|
|
136
|
+
connect(): Promise<void>;
|
|
137
|
+
private postRaw;
|
|
138
|
+
/** Generic JSON-RPC request — used by MCPClient.request() for SSE/streamable-http transports. */
|
|
139
|
+
request(method: string, params: unknown, timeoutMs?: number): Promise<JsonRpcResponse>;
|
|
140
|
+
callTool(name: string, input: unknown, opts?: {
|
|
141
|
+
signal?: AbortSignal | undefined;
|
|
142
|
+
}): Promise<ToolCallResult>;
|
|
143
|
+
close(): Promise<void>;
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type Permission, type Tool } from '@wrongstack/core';
|
|
2
|
+
import type { MCPClient, MCPTool } from './client.js';
|
|
3
|
+
/**
|
|
4
|
+
* Resolves the live client for a tool call. A plain {@link MCPClient} for eager
|
|
5
|
+
* servers, or a thunk that connects-on-demand for lazy/dormant servers (the
|
|
6
|
+
* registry passes `() => this.ensureConnected(name)`).
|
|
7
|
+
*/
|
|
8
|
+
export type MCPClientResolver = MCPClient | (() => Promise<MCPClient>);
|
|
9
|
+
export declare function wrapMCPTool(serverName: string, mcpTool: MCPTool, client: MCPClientResolver, permission?: Permission): Tool;
|
|
10
|
+
//# sourceMappingURL=wrap-tool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrap-tool.d.ts","sourceRoot":"","sources":["../src/wrap-tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAoB,KAAK,UAAU,EAAE,KAAK,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAChF,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAwBtD;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,CAAC,MAAM,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;AAEvE,wBAAgB,WAAW,CACzB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,iBAAiB,EACzB,UAAU,GAAE,UAAsB,GACjC,IAAI,CAwBN"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wrongstack/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.285.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "WrongStack Model Context Protocol client and registry: stdio, SSE, and streamable HTTP transports.",
|
|
6
6
|
"repository": {
|
|
@@ -25,12 +25,11 @@
|
|
|
25
25
|
"dist"
|
|
26
26
|
],
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@wrongstack/core": "0.
|
|
28
|
+
"@wrongstack/core": "0.285.0"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/node": "^26.0.1",
|
|
32
|
-
"
|
|
33
|
-
"typescript": "^6.0.3",
|
|
32
|
+
"typescript": "^7.0.2",
|
|
34
33
|
"undici": "^8.5.0",
|
|
35
34
|
"undici-types": "^8.5.0",
|
|
36
35
|
"vitest": "^4.1.9"
|
|
@@ -39,7 +38,7 @@
|
|
|
39
38
|
"access": "public"
|
|
40
39
|
},
|
|
41
40
|
"scripts": {
|
|
42
|
-
"build": "
|
|
41
|
+
"build": "node ../../scripts/build-package.mjs",
|
|
43
42
|
"typecheck": "tsc --noEmit -p tsconfig.test.json",
|
|
44
43
|
"test": "vitest run",
|
|
45
44
|
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\""
|