@mcp-z/client 1.0.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/AGENTS.md +159 -0
- package/LICENSE +21 -0
- package/README.md +90 -0
- package/dist/cjs/auth/capability-discovery.d.cts +25 -0
- package/dist/cjs/auth/capability-discovery.d.ts +25 -0
- package/dist/cjs/auth/capability-discovery.js +280 -0
- package/dist/cjs/auth/capability-discovery.js.map +1 -0
- package/dist/cjs/auth/index.d.cts +9 -0
- package/dist/cjs/auth/index.d.ts +9 -0
- package/dist/cjs/auth/index.js +28 -0
- package/dist/cjs/auth/index.js.map +1 -0
- package/dist/cjs/auth/interactive-oauth-flow.d.cts +58 -0
- package/dist/cjs/auth/interactive-oauth-flow.d.ts +58 -0
- package/dist/cjs/auth/interactive-oauth-flow.js +537 -0
- package/dist/cjs/auth/interactive-oauth-flow.js.map +1 -0
- package/dist/cjs/auth/oauth-callback-listener.d.cts +56 -0
- package/dist/cjs/auth/oauth-callback-listener.d.ts +56 -0
- package/dist/cjs/auth/oauth-callback-listener.js +333 -0
- package/dist/cjs/auth/oauth-callback-listener.js.map +1 -0
- package/dist/cjs/auth/pkce.d.cts +17 -0
- package/dist/cjs/auth/pkce.d.ts +17 -0
- package/dist/cjs/auth/pkce.js +192 -0
- package/dist/cjs/auth/pkce.js.map +1 -0
- package/dist/cjs/auth/rfc9728-discovery.d.cts +34 -0
- package/dist/cjs/auth/rfc9728-discovery.d.ts +34 -0
- package/dist/cjs/auth/rfc9728-discovery.js +436 -0
- package/dist/cjs/auth/rfc9728-discovery.js.map +1 -0
- package/dist/cjs/auth/types.d.cts +137 -0
- package/dist/cjs/auth/types.d.ts +137 -0
- package/dist/cjs/auth/types.js +9 -0
- package/dist/cjs/auth/types.js.map +1 -0
- package/dist/cjs/client-helpers.d.cts +55 -0
- package/dist/cjs/client-helpers.d.ts +55 -0
- package/dist/cjs/client-helpers.js +128 -0
- package/dist/cjs/client-helpers.js.map +1 -0
- package/dist/cjs/config/server-loader.d.cts +27 -0
- package/dist/cjs/config/server-loader.d.ts +27 -0
- package/dist/cjs/config/server-loader.js +111 -0
- package/dist/cjs/config/server-loader.js.map +1 -0
- package/dist/cjs/config/validate-config.d.cts +15 -0
- package/dist/cjs/config/validate-config.d.ts +15 -0
- package/dist/cjs/config/validate-config.js +128 -0
- package/dist/cjs/config/validate-config.js.map +1 -0
- package/dist/cjs/connection/connect-client.d.cts +59 -0
- package/dist/cjs/connection/connect-client.d.ts +59 -0
- package/dist/cjs/connection/connect-client.js +536 -0
- package/dist/cjs/connection/connect-client.js.map +1 -0
- package/dist/cjs/connection/existing-process-transport.d.cts +40 -0
- package/dist/cjs/connection/existing-process-transport.d.ts +40 -0
- package/dist/cjs/connection/existing-process-transport.js +274 -0
- package/dist/cjs/connection/existing-process-transport.js.map +1 -0
- package/dist/cjs/connection/types.d.cts +61 -0
- package/dist/cjs/connection/types.d.ts +61 -0
- package/dist/cjs/connection/types.js +53 -0
- package/dist/cjs/connection/types.js.map +1 -0
- package/dist/cjs/connection/wait-for-http-ready.d.cts +15 -0
- package/dist/cjs/connection/wait-for-http-ready.d.ts +15 -0
- package/dist/cjs/connection/wait-for-http-ready.js +232 -0
- package/dist/cjs/connection/wait-for-http-ready.js.map +1 -0
- package/dist/cjs/dcr/dcr-authenticator.d.cts +73 -0
- package/dist/cjs/dcr/dcr-authenticator.d.ts +73 -0
- package/dist/cjs/dcr/dcr-authenticator.js +655 -0
- package/dist/cjs/dcr/dcr-authenticator.js.map +1 -0
- package/dist/cjs/dcr/dynamic-client-registrar.d.cts +28 -0
- package/dist/cjs/dcr/dynamic-client-registrar.d.ts +28 -0
- package/dist/cjs/dcr/dynamic-client-registrar.js +245 -0
- package/dist/cjs/dcr/dynamic-client-registrar.js.map +1 -0
- package/dist/cjs/dcr/index.d.cts +8 -0
- package/dist/cjs/dcr/index.d.ts +8 -0
- package/dist/cjs/dcr/index.js +24 -0
- package/dist/cjs/dcr/index.js.map +1 -0
- package/dist/cjs/index.d.cts +21 -0
- package/dist/cjs/index.d.ts +21 -0
- package/dist/cjs/index.js +94 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/monkey-patches.d.cts +6 -0
- package/dist/cjs/monkey-patches.d.ts +6 -0
- package/dist/cjs/monkey-patches.js +236 -0
- package/dist/cjs/monkey-patches.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/response-wrappers.d.cts +41 -0
- package/dist/cjs/response-wrappers.d.ts +41 -0
- package/dist/cjs/response-wrappers.js +443 -0
- package/dist/cjs/response-wrappers.js.map +1 -0
- package/dist/cjs/search/index.d.cts +6 -0
- package/dist/cjs/search/index.d.ts +6 -0
- package/dist/cjs/search/index.js +25 -0
- package/dist/cjs/search/index.js.map +1 -0
- package/dist/cjs/search/search.d.cts +22 -0
- package/dist/cjs/search/search.d.ts +22 -0
- package/dist/cjs/search/search.js +630 -0
- package/dist/cjs/search/search.js.map +1 -0
- package/dist/cjs/search/types.d.cts +122 -0
- package/dist/cjs/search/types.d.ts +122 -0
- package/dist/cjs/search/types.js +10 -0
- package/dist/cjs/search/types.js.map +1 -0
- package/dist/cjs/spawn/spawn-server.d.cts +83 -0
- package/dist/cjs/spawn/spawn-server.d.ts +83 -0
- package/dist/cjs/spawn/spawn-server.js +410 -0
- package/dist/cjs/spawn/spawn-server.js.map +1 -0
- package/dist/cjs/spawn/spawn-servers.d.cts +151 -0
- package/dist/cjs/spawn/spawn-servers.d.ts +151 -0
- package/dist/cjs/spawn/spawn-servers.js +911 -0
- package/dist/cjs/spawn/spawn-servers.js.map +1 -0
- package/dist/cjs/types.d.cts +11 -0
- package/dist/cjs/types.d.ts +11 -0
- package/dist/cjs/types.js +10 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/cjs/utils/logger.d.cts +24 -0
- package/dist/cjs/utils/logger.d.ts +24 -0
- package/dist/cjs/utils/logger.js +80 -0
- package/dist/cjs/utils/logger.js.map +1 -0
- package/dist/cjs/utils/path-utils.d.cts +45 -0
- package/dist/cjs/utils/path-utils.d.ts +45 -0
- package/dist/cjs/utils/path-utils.js +158 -0
- package/dist/cjs/utils/path-utils.js.map +1 -0
- package/dist/cjs/utils/sanitizer.d.cts +30 -0
- package/dist/cjs/utils/sanitizer.d.ts +30 -0
- package/dist/cjs/utils/sanitizer.js +124 -0
- package/dist/cjs/utils/sanitizer.js.map +1 -0
- package/dist/esm/auth/capability-discovery.d.ts +25 -0
- package/dist/esm/auth/capability-discovery.js +110 -0
- package/dist/esm/auth/capability-discovery.js.map +1 -0
- package/dist/esm/auth/index.d.ts +9 -0
- package/dist/esm/auth/index.js +6 -0
- package/dist/esm/auth/index.js.map +1 -0
- package/dist/esm/auth/interactive-oauth-flow.d.ts +58 -0
- package/dist/esm/auth/interactive-oauth-flow.js +217 -0
- package/dist/esm/auth/interactive-oauth-flow.js.map +1 -0
- package/dist/esm/auth/oauth-callback-listener.d.ts +56 -0
- package/dist/esm/auth/oauth-callback-listener.js +166 -0
- package/dist/esm/auth/oauth-callback-listener.js.map +1 -0
- package/dist/esm/auth/pkce.d.ts +17 -0
- package/dist/esm/auth/pkce.js +41 -0
- package/dist/esm/auth/pkce.js.map +1 -0
- package/dist/esm/auth/rfc9728-discovery.d.ts +34 -0
- package/dist/esm/auth/rfc9728-discovery.js +157 -0
- package/dist/esm/auth/rfc9728-discovery.js.map +1 -0
- package/dist/esm/auth/types.d.ts +137 -0
- package/dist/esm/auth/types.js +7 -0
- package/dist/esm/auth/types.js.map +1 -0
- package/dist/esm/client-helpers.d.ts +55 -0
- package/dist/esm/client-helpers.js +81 -0
- package/dist/esm/client-helpers.js.map +1 -0
- package/dist/esm/config/server-loader.d.ts +27 -0
- package/dist/esm/config/server-loader.js +49 -0
- package/dist/esm/config/server-loader.js.map +1 -0
- package/dist/esm/config/validate-config.d.ts +15 -0
- package/dist/esm/config/validate-config.js +76 -0
- package/dist/esm/config/validate-config.js.map +1 -0
- package/dist/esm/connection/connect-client.d.ts +59 -0
- package/dist/esm/connection/connect-client.js +272 -0
- package/dist/esm/connection/connect-client.js.map +1 -0
- package/dist/esm/connection/existing-process-transport.d.ts +40 -0
- package/dist/esm/connection/existing-process-transport.js +103 -0
- package/dist/esm/connection/existing-process-transport.js.map +1 -0
- package/dist/esm/connection/types.d.ts +61 -0
- package/dist/esm/connection/types.js +34 -0
- package/dist/esm/connection/types.js.map +1 -0
- package/dist/esm/connection/wait-for-http-ready.d.ts +15 -0
- package/dist/esm/connection/wait-for-http-ready.js +43 -0
- package/dist/esm/connection/wait-for-http-ready.js.map +1 -0
- package/dist/esm/dcr/dcr-authenticator.d.ts +73 -0
- package/dist/esm/dcr/dcr-authenticator.js +235 -0
- package/dist/esm/dcr/dcr-authenticator.js.map +1 -0
- package/dist/esm/dcr/dynamic-client-registrar.d.ts +28 -0
- package/dist/esm/dcr/dynamic-client-registrar.js +66 -0
- package/dist/esm/dcr/dynamic-client-registrar.js.map +1 -0
- package/dist/esm/dcr/index.d.ts +8 -0
- package/dist/esm/dcr/index.js +5 -0
- package/dist/esm/dcr/index.js.map +1 -0
- package/dist/esm/index.d.ts +21 -0
- package/dist/esm/index.js +22 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/monkey-patches.d.ts +6 -0
- package/dist/esm/monkey-patches.js +32 -0
- package/dist/esm/monkey-patches.js.map +1 -0
- package/dist/esm/package.json +1 -0
- package/dist/esm/response-wrappers.d.ts +41 -0
- package/dist/esm/response-wrappers.js +201 -0
- package/dist/esm/response-wrappers.js.map +1 -0
- package/dist/esm/search/index.d.ts +6 -0
- package/dist/esm/search/index.js +3 -0
- package/dist/esm/search/index.js.map +1 -0
- package/dist/esm/search/search.d.ts +22 -0
- package/dist/esm/search/search.js +236 -0
- package/dist/esm/search/search.js.map +1 -0
- package/dist/esm/search/types.d.ts +122 -0
- package/dist/esm/search/types.js +8 -0
- package/dist/esm/search/types.js.map +1 -0
- package/dist/esm/spawn/spawn-server.d.ts +83 -0
- package/dist/esm/spawn/spawn-server.js +145 -0
- package/dist/esm/spawn/spawn-server.js.map +1 -0
- package/dist/esm/spawn/spawn-servers.d.ts +151 -0
- package/dist/esm/spawn/spawn-servers.js +406 -0
- package/dist/esm/spawn/spawn-servers.js.map +1 -0
- package/dist/esm/types.d.ts +11 -0
- package/dist/esm/types.js +9 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/esm/utils/logger.d.ts +24 -0
- package/dist/esm/utils/logger.js +59 -0
- package/dist/esm/utils/logger.js.map +1 -0
- package/dist/esm/utils/path-utils.d.ts +45 -0
- package/dist/esm/utils/path-utils.js +89 -0
- package/dist/esm/utils/path-utils.js.map +1 -0
- package/dist/esm/utils/sanitizer.d.ts +30 -0
- package/dist/esm/utils/sanitizer.js +43 -0
- package/dist/esm/utils/sanitizer.js.map +1 -0
- package/package.json +92 -0
- package/schemas/servers.d.ts +90 -0
- package/schemas/servers.schema.json +104 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/libs/client/src/search/types.ts"],"sourcesContent":["/**\n * Search types for MCP capability discovery\n *\n * Enables agents to discover tools, prompts, and resources without\n * loading full schemas into context.\n */\n\nimport type { PromptArgument } from '../connection/types.ts';\n\n/**\n * Types of MCP capabilities that can be searched\n */\nexport type CapabilityType = 'tool' | 'prompt' | 'resource';\n\n/**\n * Fields that can be searched within capabilities\n */\nexport type SearchField = 'name' | 'description' | 'schema' | 'server';\n\n/**\n * Options for configuring search behavior\n */\nexport interface SearchOptions {\n /**\n * Filter to specific capability types\n * @default ['tool', 'prompt', 'resource']\n */\n types?: CapabilityType[];\n\n /**\n * Filter to specific servers by name\n * @default all servers in config\n */\n servers?: string[];\n\n /**\n * Which fields to search within\n * @default ['name', 'description', 'schema']\n */\n searchFields?: SearchField[];\n\n /**\n * Maximum number of results to return\n * @default 20\n */\n limit?: number;\n\n /**\n * Minimum relevance score (0-1) for results\n * @default 0\n */\n threshold?: number;\n}\n\n/**\n * A single search result representing a matched capability\n */\nexport interface SearchResult {\n /** The type of capability */\n type: CapabilityType;\n\n /** The server that provides this capability */\n server: string;\n\n /** The name of the capability */\n name: string;\n\n /** Human-readable description (may be truncated) */\n description: string | undefined;\n\n /** Which fields matched the search query */\n matchedOn: string[];\n\n /** Relevance score from 0 (low) to 1 (high) */\n score: number;\n}\n\n/**\n * Complete search response\n */\nexport interface SearchResponse {\n /** The original search query */\n query: string;\n\n /** Matching results, sorted by relevance */\n results: SearchResult[];\n\n /** Total number of matches before limit was applied */\n total: number;\n}\n\n/**\n * Internal representation of a tool for indexing\n */\nexport interface IndexedTool {\n type: 'tool';\n server: string;\n name: string;\n description: string | undefined;\n /** Flattened searchable text from inputSchema property descriptions */\n schemaText: string;\n}\n\n/**\n * Internal representation of a prompt for indexing\n */\nexport interface IndexedPrompt {\n type: 'prompt';\n server: string;\n name: string;\n description: string | undefined;\n /** Flattened searchable text from arguments */\n argumentsText: string;\n arguments: PromptArgument[] | undefined;\n}\n\n/**\n * Internal representation of a resource for indexing\n */\nexport interface IndexedResource {\n type: 'resource';\n server: string;\n name: string;\n description: string | undefined;\n uri: string;\n mimeType: string | undefined;\n}\n\n/**\n * Union of all indexed capability types\n */\nexport type IndexedCapability = IndexedTool | IndexedPrompt | IndexedResource;\n\n/**\n * Index containing all capabilities from connected servers\n */\nexport interface CapabilityIndex {\n /** All indexed capabilities */\n capabilities: IndexedCapability[];\n\n /** Servers that were indexed */\n servers: string[];\n\n /** When the index was created */\n indexedAt: Date;\n}\n"],"names":[],"mappings":"AAAA;;;;;CAKC,GAgID;;CAEC,GACD,WASC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Low-level single server spawning utilities.
|
|
3
|
+
* Provides core process spawning with path resolution, environment management, and lifecycle control.
|
|
4
|
+
*/
|
|
5
|
+
import { type ChildProcess, type StdioOptions } from 'child_process';
|
|
6
|
+
/**
|
|
7
|
+
* Options for spawning a single server process.
|
|
8
|
+
* @internal
|
|
9
|
+
*/
|
|
10
|
+
export interface SpawnProcessOptions {
|
|
11
|
+
/** Server name for logging */
|
|
12
|
+
name: string;
|
|
13
|
+
/** Command to execute (e.g., 'node', 'npx') */
|
|
14
|
+
command: string;
|
|
15
|
+
/** Command arguments (paths will be resolved relative to cwd) */
|
|
16
|
+
args?: string[];
|
|
17
|
+
/** Working directory (must be absolute path) */
|
|
18
|
+
cwd?: string;
|
|
19
|
+
/** Additional environment variables (merged with process.env) */
|
|
20
|
+
env?: Record<string, string>;
|
|
21
|
+
/** Standard I/O configuration */
|
|
22
|
+
stdio?: StdioOptions;
|
|
23
|
+
/** Use shell for command execution (default: false, true on Windows) */
|
|
24
|
+
shell?: boolean;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Handle to a spawned server process.
|
|
28
|
+
* Provides access to the process, resolved config, and lifecycle control.
|
|
29
|
+
* @hidden
|
|
30
|
+
*/
|
|
31
|
+
export interface ServerProcess {
|
|
32
|
+
/**
|
|
33
|
+
* The resolved server configuration that was actually used.
|
|
34
|
+
* Useful for debugging and understanding what was spawned.
|
|
35
|
+
*/
|
|
36
|
+
config: {
|
|
37
|
+
name: string;
|
|
38
|
+
command: string;
|
|
39
|
+
args: string[];
|
|
40
|
+
cwd: string;
|
|
41
|
+
env: Record<string, string>;
|
|
42
|
+
stdio: StdioOptions;
|
|
43
|
+
shell: boolean;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* The spawned child process.
|
|
47
|
+
*/
|
|
48
|
+
process: ChildProcess;
|
|
49
|
+
/**
|
|
50
|
+
* Close the server gracefully.
|
|
51
|
+
* Sends the specified signal (default: SIGINT), then SIGKILL after timeout.
|
|
52
|
+
*
|
|
53
|
+
* @param signal - Signal to send (default: SIGINT)
|
|
54
|
+
* @param opts - Options including timeout
|
|
55
|
+
* @returns Promise resolving to whether the process timed out and was force-killed
|
|
56
|
+
*/
|
|
57
|
+
close: (signal?: NodeJS.Signals, opts?: {
|
|
58
|
+
timeoutMs?: number;
|
|
59
|
+
}) => Promise<{
|
|
60
|
+
timedOut: boolean;
|
|
61
|
+
killed: boolean;
|
|
62
|
+
}>;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Spawn a single server process with path resolution and environment management.
|
|
66
|
+
*
|
|
67
|
+
* @internal
|
|
68
|
+
* @param opts - Server spawn options
|
|
69
|
+
* @returns ServerProcess handle with resolved config, process, and stop function
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* const handle = spawnProcess({
|
|
73
|
+
* name: 'echo',
|
|
74
|
+
* command: 'node',
|
|
75
|
+
* args: ['./bin/server.js', '--port', '3000'],
|
|
76
|
+
* cwd: '/home/user/project/test/lib/servers/echo',
|
|
77
|
+
* env: { LOG_LEVEL: 'error' }
|
|
78
|
+
* });
|
|
79
|
+
*
|
|
80
|
+
* // Later...
|
|
81
|
+
* await handle.close();
|
|
82
|
+
*/
|
|
83
|
+
export declare function spawnProcess(opts: SpawnProcessOptions): ServerProcess;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Low-level single server spawning utilities.
|
|
3
|
+
* Provides core process spawning with path resolution, environment management, and lifecycle control.
|
|
4
|
+
*/ import { spawn } from 'child_process';
|
|
5
|
+
import * as process from 'process';
|
|
6
|
+
import { logger } from '../utils/logger.js';
|
|
7
|
+
import { resolveArgsPaths } from '../utils/path-utils.js';
|
|
8
|
+
/**
|
|
9
|
+
* Normalize environment variables by merging with process.env and filtering undefined values.
|
|
10
|
+
*/ function normalizeEnv(env) {
|
|
11
|
+
const merged = {
|
|
12
|
+
...process.env,
|
|
13
|
+
...env || {}
|
|
14
|
+
};
|
|
15
|
+
const result = {};
|
|
16
|
+
for (const [key, value] of Object.entries(merged)){
|
|
17
|
+
if (value !== undefined) {
|
|
18
|
+
result[key] = value;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Spawn a single server process with path resolution and environment management.
|
|
25
|
+
*
|
|
26
|
+
* @internal
|
|
27
|
+
* @param opts - Server spawn options
|
|
28
|
+
* @returns ServerProcess handle with resolved config, process, and stop function
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* const handle = spawnProcess({
|
|
32
|
+
* name: 'echo',
|
|
33
|
+
* command: 'node',
|
|
34
|
+
* args: ['./bin/server.js', '--port', '3000'],
|
|
35
|
+
* cwd: '/home/user/project/test/lib/servers/echo',
|
|
36
|
+
* env: { LOG_LEVEL: 'error' }
|
|
37
|
+
* });
|
|
38
|
+
*
|
|
39
|
+
* // Later...
|
|
40
|
+
* await handle.close();
|
|
41
|
+
*/ export function spawnProcess(opts) {
|
|
42
|
+
var _opts_cwd, _opts_stdio, _opts_shell;
|
|
43
|
+
const name = opts.name;
|
|
44
|
+
const command = opts.command;
|
|
45
|
+
const cwd = (_opts_cwd = opts.cwd) !== null && _opts_cwd !== void 0 ? _opts_cwd : process.cwd();
|
|
46
|
+
const stdio = (_opts_stdio = opts.stdio) !== null && _opts_stdio !== void 0 ? _opts_stdio : 'inherit';
|
|
47
|
+
const shell = (_opts_shell = opts.shell) !== null && _opts_shell !== void 0 ? _opts_shell : process.platform === 'win32';
|
|
48
|
+
// Resolve paths in args relative to the working directory
|
|
49
|
+
const args = opts.args ? resolveArgsPaths(opts.args, cwd) : [];
|
|
50
|
+
// Merge environment variables
|
|
51
|
+
const env = normalizeEnv(opts.env);
|
|
52
|
+
// Create resolved config for return value
|
|
53
|
+
const resolvedConfig = {
|
|
54
|
+
name,
|
|
55
|
+
command,
|
|
56
|
+
args,
|
|
57
|
+
cwd,
|
|
58
|
+
env,
|
|
59
|
+
stdio,
|
|
60
|
+
shell
|
|
61
|
+
};
|
|
62
|
+
// Log spawn operation
|
|
63
|
+
logger.info(`[${name}] → ${command} ${args.join(' ')}`);
|
|
64
|
+
// Spawn the process
|
|
65
|
+
const spawnOpts = {
|
|
66
|
+
cwd,
|
|
67
|
+
env,
|
|
68
|
+
stdio,
|
|
69
|
+
shell
|
|
70
|
+
};
|
|
71
|
+
const child = spawn(command, args, spawnOpts);
|
|
72
|
+
// Attach lifecycle logging
|
|
73
|
+
child.on('exit', (code, sig)=>logger.info(`[${name}] exited (code=${code}, signal=${sig || 'none'})`));
|
|
74
|
+
child.on('error', (err)=>logger.info(`[${name}] process error: ${err.message}`));
|
|
75
|
+
// Create stop function with graceful shutdown
|
|
76
|
+
const stop = async (signal = 'SIGINT', opts = {})=>{
|
|
77
|
+
var _opts_timeoutMs;
|
|
78
|
+
// If already exited, return immediately
|
|
79
|
+
if (child.exitCode !== null || child.signalCode !== null) {
|
|
80
|
+
return {
|
|
81
|
+
timedOut: false,
|
|
82
|
+
killed: false
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
const timeoutMs = (_opts_timeoutMs = opts.timeoutMs) !== null && _opts_timeoutMs !== void 0 ? _opts_timeoutMs : 500;
|
|
86
|
+
// Wait for 'close' event (process exit + stdio streams closed)
|
|
87
|
+
// This is better than 'exit' because it ensures stdio is fully cleaned up
|
|
88
|
+
const closePromise = new Promise((resolve)=>{
|
|
89
|
+
let isResolved = false;
|
|
90
|
+
let wasKilled = false;
|
|
91
|
+
const resolveOnce = (timedOut)=>{
|
|
92
|
+
if (isResolved) return;
|
|
93
|
+
isResolved = true;
|
|
94
|
+
clearTimeout(timeout);
|
|
95
|
+
resolve({
|
|
96
|
+
timedOut,
|
|
97
|
+
killed: wasKilled
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
// Set timeout for forceful kill
|
|
101
|
+
const timeout = setTimeout(()=>{
|
|
102
|
+
try {
|
|
103
|
+
// Check again before SIGKILL
|
|
104
|
+
if (child.exitCode === null && !child.killed) {
|
|
105
|
+
child.kill('SIGKILL');
|
|
106
|
+
wasKilled = true;
|
|
107
|
+
}
|
|
108
|
+
} catch (_) {}
|
|
109
|
+
// Even if kill fails, resolve
|
|
110
|
+
resolveOnce(true);
|
|
111
|
+
}, timeoutMs);
|
|
112
|
+
// Listen for 'close' event (not 'exit') to wait for stdio close
|
|
113
|
+
child.once('close', ()=>{
|
|
114
|
+
resolveOnce(false);
|
|
115
|
+
});
|
|
116
|
+
// Also listen for 'error' event in case spawn failed
|
|
117
|
+
// This prevents promise from hanging forever if process never started
|
|
118
|
+
child.once('error', ()=>{
|
|
119
|
+
resolveOnce(false);
|
|
120
|
+
});
|
|
121
|
+
// Send graceful shutdown signal
|
|
122
|
+
try {
|
|
123
|
+
// Check one more time before killing
|
|
124
|
+
if (child.exitCode !== null) {
|
|
125
|
+
resolveOnce(false);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const killed = child.kill(signal);
|
|
129
|
+
// If kill returned false, process already exited
|
|
130
|
+
if (!killed) {
|
|
131
|
+
resolveOnce(false);
|
|
132
|
+
}
|
|
133
|
+
} catch (_err) {
|
|
134
|
+
// If kill throws, process is gone or unreachable
|
|
135
|
+
resolveOnce(false);
|
|
136
|
+
}
|
|
137
|
+
});
|
|
138
|
+
return closePromise;
|
|
139
|
+
};
|
|
140
|
+
return {
|
|
141
|
+
config: resolvedConfig,
|
|
142
|
+
process: child,
|
|
143
|
+
close: stop
|
|
144
|
+
};
|
|
145
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/Projects/ai/mcp-z/libs/client/src/spawn/spawn-server.ts"],"sourcesContent":["/**\n * Low-level single server spawning utilities.\n * Provides core process spawning with path resolution, environment management, and lifecycle control.\n */\n\nimport { type ChildProcess, type SpawnOptions, type StdioOptions, spawn } from 'child_process';\nimport * as process from 'process';\nimport { logger } from '../utils/logger.ts';\nimport { resolveArgsPaths } from '../utils/path-utils.ts';\n\n/**\n * Options for spawning a single server process.\n * @internal\n */\nexport interface SpawnProcessOptions {\n /** Server name for logging */\n name: string;\n /** Command to execute (e.g., 'node', 'npx') */\n command: string;\n /** Command arguments (paths will be resolved relative to cwd) */\n args?: string[];\n /** Working directory (must be absolute path) */\n cwd?: string;\n /** Additional environment variables (merged with process.env) */\n env?: Record<string, string>;\n /** Standard I/O configuration */\n stdio?: StdioOptions;\n /** Use shell for command execution (default: false, true on Windows) */\n shell?: boolean;\n}\n\n/**\n * Handle to a spawned server process.\n * Provides access to the process, resolved config, and lifecycle control.\n * @hidden\n */\nexport interface ServerProcess {\n /**\n * The resolved server configuration that was actually used.\n * Useful for debugging and understanding what was spawned.\n */\n config: {\n name: string;\n command: string;\n args: string[];\n cwd: string;\n env: Record<string, string>;\n stdio: StdioOptions;\n shell: boolean;\n };\n\n /**\n * The spawned child process.\n */\n process: ChildProcess;\n\n /**\n * Close the server gracefully.\n * Sends the specified signal (default: SIGINT), then SIGKILL after timeout.\n *\n * @param signal - Signal to send (default: SIGINT)\n * @param opts - Options including timeout\n * @returns Promise resolving to whether the process timed out and was force-killed\n */\n close: (signal?: NodeJS.Signals, opts?: { timeoutMs?: number }) => Promise<{ timedOut: boolean; killed: boolean }>;\n}\n\n/**\n * Normalize environment variables by merging with process.env and filtering undefined values.\n */\nfunction normalizeEnv(env?: Record<string, string>): Record<string, string> {\n const merged = { ...process.env, ...(env || {}) };\n const result: Record<string, string> = {};\n for (const [key, value] of Object.entries(merged)) {\n if (value !== undefined) {\n result[key] = value;\n }\n }\n return result;\n}\n\n/**\n * Spawn a single server process with path resolution and environment management.\n *\n * @internal\n * @param opts - Server spawn options\n * @returns ServerProcess handle with resolved config, process, and stop function\n *\n * @example\n * const handle = spawnProcess({\n * name: 'echo',\n * command: 'node',\n * args: ['./bin/server.js', '--port', '3000'],\n * cwd: '/home/user/project/test/lib/servers/echo',\n * env: { LOG_LEVEL: 'error' }\n * });\n *\n * // Later...\n * await handle.close();\n */\nexport function spawnProcess(opts: SpawnProcessOptions): ServerProcess {\n const name = opts.name;\n const command = opts.command;\n const cwd = opts.cwd ?? process.cwd();\n const stdio = opts.stdio ?? 'inherit';\n const shell = opts.shell ?? process.platform === 'win32';\n\n // Resolve paths in args relative to the working directory\n const args = opts.args ? resolveArgsPaths(opts.args, cwd) : [];\n\n // Merge environment variables\n const env = normalizeEnv(opts.env);\n\n // Create resolved config for return value\n const resolvedConfig = {\n name,\n command,\n args,\n cwd,\n env,\n stdio,\n shell,\n };\n\n // Log spawn operation\n logger.info(`[${name}] → ${command} ${args.join(' ')}`);\n\n // Spawn the process\n const spawnOpts: SpawnOptions = { cwd, env, stdio, shell };\n const child = spawn(command, args, spawnOpts);\n\n // Attach lifecycle logging\n child.on('exit', (code, sig) => logger.info(`[${name}] exited (code=${code}, signal=${sig || 'none'})`));\n child.on('error', (err) => logger.info(`[${name}] process error: ${err.message}`));\n\n // Create stop function with graceful shutdown\n const stop = async (signal: NodeJS.Signals = 'SIGINT', opts: { timeoutMs?: number } = {}): Promise<{ timedOut: boolean; killed: boolean }> => {\n // If already exited, return immediately\n if (child.exitCode !== null || child.signalCode !== null) {\n return { timedOut: false, killed: false };\n }\n\n const timeoutMs = opts.timeoutMs ?? 500;\n\n // Wait for 'close' event (process exit + stdio streams closed)\n // This is better than 'exit' because it ensures stdio is fully cleaned up\n const closePromise = new Promise<{ timedOut: boolean; killed: boolean }>((resolve) => {\n let isResolved = false;\n let wasKilled = false;\n\n const resolveOnce = (timedOut: boolean) => {\n if (isResolved) return;\n isResolved = true;\n clearTimeout(timeout);\n resolve({ timedOut, killed: wasKilled });\n };\n\n // Set timeout for forceful kill\n const timeout = setTimeout(() => {\n try {\n // Check again before SIGKILL\n if (child.exitCode === null && !child.killed) {\n child.kill('SIGKILL');\n wasKilled = true;\n }\n } catch (_) {}\n // Even if kill fails, resolve\n resolveOnce(true);\n }, timeoutMs);\n\n // Listen for 'close' event (not 'exit') to wait for stdio close\n child.once('close', () => {\n resolveOnce(false);\n });\n\n // Also listen for 'error' event in case spawn failed\n // This prevents promise from hanging forever if process never started\n child.once('error', () => {\n resolveOnce(false);\n });\n\n // Send graceful shutdown signal\n try {\n // Check one more time before killing\n if (child.exitCode !== null) {\n resolveOnce(false);\n return;\n }\n\n const killed = child.kill(signal);\n // If kill returned false, process already exited\n if (!killed) {\n resolveOnce(false);\n }\n } catch (_err) {\n // If kill throws, process is gone or unreachable\n resolveOnce(false);\n }\n });\n\n return closePromise;\n };\n\n return {\n config: resolvedConfig,\n process: child,\n close: stop,\n };\n}\n"],"names":["spawn","process","logger","resolveArgsPaths","normalizeEnv","env","merged","result","key","value","Object","entries","undefined","spawnProcess","opts","name","command","cwd","stdio","shell","platform","args","resolvedConfig","info","join","spawnOpts","child","on","code","sig","err","message","stop","signal","exitCode","signalCode","timedOut","killed","timeoutMs","closePromise","Promise","resolve","isResolved","wasKilled","resolveOnce","clearTimeout","timeout","setTimeout","kill","_","once","_err","config","close"],"mappings":"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"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* High-level multi-server registry management.
|
|
3
|
+
* Starts multiple servers from a servers configuration object.
|
|
4
|
+
* Supports stdio, http, and ws transports.
|
|
5
|
+
* Implements Claude Code-compatible configuration with start extension support.
|
|
6
|
+
*/
|
|
7
|
+
import { type ManagedClient } from '../client-helpers.js';
|
|
8
|
+
import { connectMcpClient } from '../connection/connect-client.js';
|
|
9
|
+
import { type SearchOptions, type SearchResponse } from '../search/index.js';
|
|
10
|
+
import type { McpServerEntry } from '../types.js';
|
|
11
|
+
import { type ServerProcess } from './spawn-server.js';
|
|
12
|
+
/**
|
|
13
|
+
* Servers configuration type - a map of server names to their configurations.
|
|
14
|
+
*/
|
|
15
|
+
export type ServersConfig = Record<string, McpServerEntry>;
|
|
16
|
+
/**
|
|
17
|
+
* Dialect for server spawning.
|
|
18
|
+
*
|
|
19
|
+
* - 'servers': Spawn stdio servers (Claude Code compatible)
|
|
20
|
+
* - 'start': Spawn HTTP servers with start blocks
|
|
21
|
+
*/
|
|
22
|
+
export type Dialect = 'servers' | 'start';
|
|
23
|
+
/**
|
|
24
|
+
* Options for creating a server registry.
|
|
25
|
+
*/
|
|
26
|
+
export interface CreateServerRegistryOptions {
|
|
27
|
+
/** Working directory for spawned processes (default: process.cwd()) */
|
|
28
|
+
cwd?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Base environment for all servers.
|
|
31
|
+
* If provided, process.env is NOT included (caller has full control).
|
|
32
|
+
* If omitted, process.env is used as the base (default behavior).
|
|
33
|
+
*/
|
|
34
|
+
env?: Record<string, string>;
|
|
35
|
+
/**
|
|
36
|
+
* Dialects controlling which servers to spawn.
|
|
37
|
+
* - ['servers']: Spawn stdio servers only (default, Claude Code compatible)
|
|
38
|
+
* - ['start']: Only spawn servers with start blocks (HTTP servers)
|
|
39
|
+
* - ['servers', 'start']: Spawn both stdio servers and start blocks
|
|
40
|
+
* @default ['servers']
|
|
41
|
+
*/
|
|
42
|
+
dialects?: Dialect[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Result of closing the registry.
|
|
46
|
+
*/
|
|
47
|
+
export interface CloseResult {
|
|
48
|
+
/** Whether any process timed out during shutdown */
|
|
49
|
+
timedOut: boolean;
|
|
50
|
+
/** Number of processes that were force-killed */
|
|
51
|
+
killedCount: number;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* A registry of spawned MCP servers with connection management.
|
|
55
|
+
* Provides access to individual server handles, connection management, and collection-wide close.
|
|
56
|
+
*/
|
|
57
|
+
type RegistryConnectOptions = Parameters<typeof connectMcpClient>[2];
|
|
58
|
+
export interface ServerRegistry {
|
|
59
|
+
/**
|
|
60
|
+
* The resolved servers configuration that was used.
|
|
61
|
+
* Useful for debugging and understanding what was started.
|
|
62
|
+
*/
|
|
63
|
+
config: ServersConfig;
|
|
64
|
+
/**
|
|
65
|
+
* Map of server name to server process handle.
|
|
66
|
+
* @hidden
|
|
67
|
+
*/
|
|
68
|
+
servers: Map<string, ServerProcess>;
|
|
69
|
+
/**
|
|
70
|
+
* Set of connected clients tracked by this registry.
|
|
71
|
+
* Automatically populated when using registry.connect().
|
|
72
|
+
*/
|
|
73
|
+
clients: Set<ManagedClient>;
|
|
74
|
+
/**
|
|
75
|
+
* Connect to a server by name.
|
|
76
|
+
* The connected client is automatically tracked for close.
|
|
77
|
+
*
|
|
78
|
+
* @param name - Server name from configuration
|
|
79
|
+
* @returns Connected MCP SDK Client
|
|
80
|
+
*/
|
|
81
|
+
connect: (name: string, options?: RegistryConnectOptions) => Promise<ManagedClient>;
|
|
82
|
+
/**
|
|
83
|
+
* Close all clients and servers gracefully.
|
|
84
|
+
* First closes all tracked clients, then sends the specified signal to all server processes.
|
|
85
|
+
*
|
|
86
|
+
* @param signal - Signal to send to processes (default: SIGINT)
|
|
87
|
+
* @param opts - Options including timeout
|
|
88
|
+
* @returns Promise resolving to whether any process timed out and how many were force-killed
|
|
89
|
+
*/
|
|
90
|
+
close: (signal?: NodeJS.Signals, opts?: {
|
|
91
|
+
timeoutMs?: number;
|
|
92
|
+
}) => Promise<CloseResult>;
|
|
93
|
+
/**
|
|
94
|
+
* Search indexed capabilities across all currently connected clients.
|
|
95
|
+
* Requires at least one connected client; respects SearchOptions filters.
|
|
96
|
+
*/
|
|
97
|
+
searchCapabilities: (query: string, options?: SearchOptions) => Promise<SearchResponse>;
|
|
98
|
+
/**
|
|
99
|
+
* Support for `await using` pattern (automatic close).
|
|
100
|
+
*/
|
|
101
|
+
[Symbol.asyncDispose]: () => Promise<void>;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Create a registry of MCP servers from configuration.
|
|
105
|
+
*
|
|
106
|
+
* **Fast start**: Returns immediately after processes are created.
|
|
107
|
+
* Use `registry.connect()` for lazy MCP connection.
|
|
108
|
+
*
|
|
109
|
+
* @param serversConfig - Map of server names to their configurations
|
|
110
|
+
* @param options - Options for registry creation
|
|
111
|
+
* @param options.cwd - Working directory for spawned processes (default: process.cwd())
|
|
112
|
+
* @param options.env - Base environment for all servers. If provided, process.env is NOT included.
|
|
113
|
+
* If omitted, process.env is used as the base (default behavior).
|
|
114
|
+
* @param options.dialects - Dialects controlling which servers to spawn (default: ['servers'])
|
|
115
|
+
* - ['servers']: Spawn stdio servers only (Claude Code compatible)
|
|
116
|
+
* - ['start']: Only spawn servers with start blocks (HTTP servers)
|
|
117
|
+
* - ['servers', 'start']: Spawn both stdio servers and start blocks
|
|
118
|
+
* @returns ServerRegistry instance with config, server map, connect method, and close function
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* // Fast server start (does NOT wait for readiness)
|
|
122
|
+
* const registry = createServerRegistry({
|
|
123
|
+
* 'echo': { command: 'node', args: ['server.ts'] },
|
|
124
|
+
* });
|
|
125
|
+
*
|
|
126
|
+
* // Connect when needed (waits for MCP handshake)
|
|
127
|
+
* const client = await registry.connect('echo');
|
|
128
|
+
*
|
|
129
|
+
* // Cleanup (closes all clients AND processes)
|
|
130
|
+
* await registry.close();
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* // Start HTTP servers with start blocks
|
|
134
|
+
* const registry = createServerRegistry(
|
|
135
|
+
* {
|
|
136
|
+
* 'http-server': {
|
|
137
|
+
* url: 'http://localhost:8080/mcp',
|
|
138
|
+
* start: { command: 'node', args: ['http.ts', '--port', '8080'] }
|
|
139
|
+
* },
|
|
140
|
+
* },
|
|
141
|
+
* { dialects: ['start'] }
|
|
142
|
+
* );
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* // Using await using for automatic close
|
|
146
|
+
* await using registry = createServerRegistry(config);
|
|
147
|
+
* const client = await registry.connect('server');
|
|
148
|
+
* // Auto-disposed when scope exits
|
|
149
|
+
*/
|
|
150
|
+
export declare function createServerRegistry(serversConfig: ServersConfig, options?: CreateServerRegistryOptions): ServerRegistry;
|
|
151
|
+
export {};
|