@wrongstack/mcp 0.1.1 → 0.1.2

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.js CHANGED
@@ -59,7 +59,7 @@ var MCPClient = class {
59
59
  this.request("initialize", {
60
60
  protocolVersion: "2024-11-05",
61
61
  capabilities: { tools: {} },
62
- clientInfo: { name: "wrongstack", version: "0.0.1" }
62
+ clientInfo: { name: "wrongstack", version: "0.1.1" }
63
63
  }),
64
64
  new Promise(
65
65
  (_, rej) => setTimeout(() => rej(new Error("MCP initialize timeout")), timeout)
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts","../src/wrap-tool.ts","../src/registry.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { spawn, type ChildProcess } from 'node:child_process';\n\nexport type Transport = 'stdio' | 'sse' | 'streamable-http';\n\nexport interface MCPClientOptions {\n name: string;\n transport: Transport;\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n url?: string;\n headers?: Record<string, string>;\n startupTimeoutMs?: number;\n}\n\nexport type ConnectionState =\n | 'idle'\n | 'connecting'\n | 'connected'\n | 'disconnected'\n | 'reconnecting'\n | 'failed';\n\nexport interface MCPTool {\n name: string;\n description?: string;\n inputSchema: Record<string, unknown>;\n}\n\nexport interface ToolCallResult {\n content: unknown;\n isError: boolean;\n}\n\ninterface JsonRpcRequest {\n jsonrpc: '2.0';\n id: number;\n method: string;\n params?: unknown;\n}\n\ninterface JsonRpcResponse {\n jsonrpc: '2.0';\n id: number;\n result?: unknown;\n error?: { code: number; message: string; data?: unknown };\n}\n\n/**\n * Lightweight stdio MCP client. Supports JSON-RPC 2.0 over newline-delimited JSON.\n * SSE / streamable-http are stubbed and throw on connect — to be filled by a real impl.\n */\nexport class MCPClient {\n private state: ConnectionState = 'idle';\n private child?: ChildProcess;\n private nextId = 1;\n private readonly pending = new Map<number, (res: JsonRpcResponse) => void>();\n private rxBuffer = '';\n private tools: MCPTool[] = [];\n /**\n * Guards against multiple concurrent drain-waits. When `stdin.write()`\n * returns false the first waiter sets this flag; any subsequent callers\n * skip the drain wait and emit a warning instead of racing.\n */\n private _drainPending = false;\n /** Set when a notify() call failed for reasons the caller should know about. */\n private _lastNotifySkipped = false;\n\n constructor(public readonly opts: MCPClientOptions) {}\n\n getState(): ConnectionState {\n return this.state;\n }\n\n listTools(): MCPTool[] {\n return [...this.tools];\n }\n\n /** Returns true if a prior notify() call was skipped due to backpressure. */\n hadNotifySkipped(): boolean {\n return this._lastNotifySkipped;\n }\n\n async connect(): Promise<void> {\n this.state = 'connecting';\n if (this.opts.transport !== 'stdio') {\n this.state = 'failed';\n throw new Error(`MCP transport \"${this.opts.transport}\" not supported in this build`);\n }\n if (!this.opts.command) {\n this.state = 'failed';\n throw new Error('MCP stdio transport requires \"command\"');\n }\n\n const child = spawn(this.opts.command, this.opts.args ?? [], {\n env: { ...process.env, ...this.opts.env },\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n this.child = child;\n\n child.stdout?.on('data', (chunk: Buffer) => this.onData(chunk.toString()));\n child.stderr?.on('data', () => {\n // intentionally discard stderr noise from server\n });\n child.on('exit', () => {\n this.state = 'disconnected';\n });\n child.on('error', () => {\n this.state = 'failed';\n });\n\n const timeout = this.opts.startupTimeoutMs ?? 10_000;\n const initialize = await Promise.race([\n this.request('initialize', {\n protocolVersion: '2024-11-05',\n capabilities: { tools: {} },\n clientInfo: { name: 'wrongstack', version: '0.0.1' },\n }),\n new Promise<JsonRpcResponse>((_, rej) =>\n setTimeout(() => rej(new Error('MCP initialize timeout')), timeout),\n ),\n ]);\n if (initialize.error) {\n this.state = 'failed';\n throw new Error(`MCP initialize failed: ${initialize.error.message}`);\n }\n try {\n await this.notify('notifications/initialized', {});\n } catch (err) {\n // some servers don't require this; failures are logged as warnings\n console.warn(\n '[MCP] notify(\"notifications/initialized\") failed for \"' + this.opts.name + '\": ' + (err instanceof Error ? err.message : String(err)),\n );\n }\n const toolsRes = await this.request('tools/list', {});\n if (toolsRes.error) {\n this.tools = [];\n } else {\n const result = toolsRes.result as { tools?: MCPTool[] } | undefined;\n this.tools = result?.tools ?? [];\n }\n this.state = 'connected';\n }\n\n async callTool(name: string, input: unknown): Promise<ToolCallResult> {\n if (this.state !== 'connected') {\n throw new Error(`MCP client \"${this.opts.name}\" not connected (state=${this.state})`);\n }\n const res = await this.request('tools/call', { name, arguments: input });\n if (res.error) {\n return { content: res.error.message, isError: true };\n }\n const result = res.result as { content?: unknown; isError?: boolean } | undefined;\n return {\n content: result?.content ?? '',\n isError: Boolean(result?.isError),\n };\n }\n\n async close(): Promise<void> {\n if (this.child) {\n try {\n this.child.kill();\n } catch {\n // ignore\n }\n }\n this.state = 'disconnected';\n }\n\n private request(method: string, params: unknown): Promise<JsonRpcResponse> {\n const id = this.nextId++;\n const req: JsonRpcRequest = { jsonrpc: '2.0', id, method, params };\n return new Promise((resolve, reject) => {\n this.pending.set(id, resolve);\n try {\n this.child?.stdin?.write(JSON.stringify(req) + '\\n');\n } catch (err) {\n this.pending.delete(id);\n reject(err);\n }\n });\n }\n\n private async notify(method: string, params: unknown): Promise<void> {\n const req = { jsonrpc: '2.0', method, params };\n const encoded = JSON.stringify(req) + '\\n';\n try {\n const ok = this.child?.stdin?.write(encoded);\n if (!ok) {\n // Only the first caller waits for drain; others just warn and return.\n // This avoids a race where two concurrent notify() calls each start\n // their own drain-wait, then both resolve and the buffer is still full.\n if (this._drainPending) {\n this._lastNotifySkipped = true;\n process.emitWarning(\n `[MCP] notify(\"${method}\") skipped: stdin buffer backpressure (already waiting for drain)`,\n );\n return;\n }\n this._drainPending = true;\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n this._drainPending = false;\n reject(new Error(`MCP notify(\"${method}\") drain timeout`));\n }, 500);\n this.child?.stdin?.once('drain', () => {\n clearTimeout(timeout);\n this._drainPending = false;\n resolve();\n });\n this.child?.stdin?.once('error', (err) => {\n clearTimeout(timeout);\n this._drainPending = false;\n reject(err);\n });\n });\n }\n } catch (err) {\n throw new Error(`[MCP] notify(\"${method}\") failed: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n private onData(s: string): void {\n this.rxBuffer += s;\n let idx = this.rxBuffer.indexOf('\\n');\n while (idx !== -1) {\n const line = this.rxBuffer.slice(0, idx).trim();\n this.rxBuffer = this.rxBuffer.slice(idx + 1);\n if (line) this.onLine(line);\n idx = this.rxBuffer.indexOf('\\n');\n }\n }\n\n private onLine(line: string): void {\n let msg: JsonRpcResponse;\n try {\n msg = JSON.parse(line) as JsonRpcResponse;\n } catch {\n return;\n }\n if (msg.id !== undefined && this.pending.has(msg.id)) {\n const resolve = this.pending.get(msg.id);\n this.pending.delete(msg.id);\n resolve?.(msg);\n }\n }\n}\n","import type { Tool, Permission } from '@wrongstack/core';\nimport type { MCPClient, MCPTool } from './client.js';\n\nconst MUTATING_RE = /create|update|delete|write|send|set|put|post|patch|remove|rename|move/i;\n\nexport function wrapMCPTool(\n serverName: string,\n mcpTool: MCPTool,\n client: MCPClient,\n permission: Permission = 'confirm',\n): Tool {\n const qualifiedName = `mcp__${serverName}__${mcpTool.name}`;\n return {\n name: qualifiedName,\n description: mcpTool.description ?? `${qualifiedName} (MCP tool)`,\n usageHint: `Tool provided by MCP server \"${serverName}\". ${mcpTool.description ?? ''}`,\n permission,\n mutating: MUTATING_RE.test(mcpTool.name),\n inputSchema: mcpTool.inputSchema ?? { type: 'object', properties: {} },\n async execute(input, ctx, opts) {\n const res = await client.callTool(mcpTool.name, input);\n if (res.isError) {\n throw new Error(stringify(res.content));\n }\n return stringify(res.content);\n },\n };\n}\n\nfunction stringify(c: unknown): string {\n if (typeof c === 'string') return c;\n if (Array.isArray(c)) {\n return c\n .map((item) => {\n if (item && typeof item === 'object') {\n const t = (item as { type?: string; text?: string }).type;\n if (t === 'text') return (item as { text?: string }).text ?? '';\n return JSON.stringify(item);\n }\n return String(item);\n })\n .join('\\n');\n }\n if (c && typeof c === 'object') {\n if ('text' in (c as Record<string, unknown>)) {\n return String((c as Record<string, unknown>).text);\n }\n return JSON.stringify(c);\n }\n return String(c ?? '');\n}\n","import type { EventBus, MCPServerConfig, ToolRegistry, Logger } from '@wrongstack/core';\nimport { MCPClient, type ConnectionState } from './client.js';\nimport { wrapMCPTool } from './wrap-tool.js';\n\ninterface ServerSlot {\n cfg: MCPServerConfig;\n client?: MCPClient;\n state: ConnectionState;\n toolNames: string[];\n attempts: number;\n}\n\nexport interface MCPRegistryOptions {\n toolRegistry: ToolRegistry;\n events: EventBus;\n log: Logger;\n}\n\nexport class MCPRegistry {\n private readonly servers = new Map<string, ServerSlot>();\n private readonly toolRegistry: ToolRegistry;\n private readonly events: EventBus;\n private readonly log: Logger;\n\n constructor(opts: MCPRegistryOptions) {\n this.toolRegistry = opts.toolRegistry;\n this.events = opts.events;\n this.log = opts.log;\n }\n\n async start(cfg: MCPServerConfig): Promise<void> {\n if (cfg.enabled === false) return;\n const slot: ServerSlot = {\n cfg,\n state: 'idle',\n toolNames: [],\n attempts: 0,\n };\n this.servers.set(cfg.name, slot);\n await this.attemptConnect(slot);\n }\n\n async stop(name: string): Promise<void> {\n const slot = this.servers.get(name);\n if (!slot) return;\n if (slot.client) await slot.client.close();\n for (const t of slot.toolNames) this.toolRegistry.unregister(t);\n slot.toolNames = [];\n slot.state = 'disconnected';\n this.events.emit('mcp.server.disconnected', { name, reason: 'stop' });\n }\n\n async restart(name: string): Promise<void> {\n const slot = this.servers.get(name);\n if (!slot) throw new Error(`MCP server \"${name}\" not registered`);\n await this.stop(name);\n slot.attempts = 0;\n await this.attemptConnect(slot);\n }\n\n list(): { name: string; state: ConnectionState; toolCount: number }[] {\n return Array.from(this.servers.values()).map((s) => ({\n name: s.cfg.name,\n state: s.state,\n toolCount: s.toolNames.length,\n }));\n }\n\n async stopAll(): Promise<void> {\n for (const name of Array.from(this.servers.keys())) {\n await this.stop(name);\n }\n }\n\n private async attemptConnect(slot: ServerSlot): Promise<void> {\n const MAX_ATTEMPTS = 3;\n let attempt = 0;\n while (attempt < MAX_ATTEMPTS) {\n attempt++;\n slot.state = attempt === 1 ? 'connecting' : 'reconnecting';\n slot.attempts = attempt;\n try {\n const client = new MCPClient({\n name: slot.cfg.name,\n transport: slot.cfg.transport,\n command: slot.cfg.command,\n args: slot.cfg.args,\n env: slot.cfg.env,\n url: slot.cfg.url,\n headers: slot.cfg.headers,\n startupTimeoutMs: slot.cfg.startupTimeoutMs,\n });\n await client.connect();\n slot.client = client;\n const isReconnect = attempt > 1;\n slot.state = 'connected';\n const allowed = slot.cfg.allowedTools;\n const wrapped = client\n .listTools()\n .filter((t) => !allowed || allowed.includes(t.name))\n .map((t) => wrapMCPTool(slot.cfg.name, t, client, slot.cfg.permission ?? 'confirm'));\n for (const tool of wrapped) {\n try {\n this.toolRegistry.register(tool, `mcp:${slot.cfg.name}`);\n slot.toolNames.push(tool.name);\n } catch (err) {\n this.log.warn(`MCP tool \"${tool.name}\" not registered`, err);\n }\n }\n this.events.emit(isReconnect ? 'mcp.server.reconnected' : 'mcp.server.connected', {\n name: slot.cfg.name,\n toolCount: slot.toolNames.length,\n });\n return; // success\n } catch (err) {\n this.log.warn(`MCP server \"${slot.cfg.name}\" connect attempt ${attempt} failed`, err);\n if (attempt >= MAX_ATTEMPTS) {\n this.log.error(`MCP server \"${slot.cfg.name}\" connect exhausted after ${MAX_ATTEMPTS} attempts`, err);\n slot.state = 'failed';\n this.events.emit('mcp.server.disconnected', {\n name: slot.cfg.name,\n reason: err instanceof Error ? err.message : 'unknown',\n });\n return;\n }\n const delay = 500 * 2 ** attempt;\n await new Promise((r) => setTimeout(r, delay));\n }\n }\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/client.ts","../src/wrap-tool.ts","../src/registry.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { spawn, type ChildProcess } from 'node:child_process';\n\nexport type Transport = 'stdio' | 'sse' | 'streamable-http';\n\nexport interface MCPClientOptions {\n name: string;\n transport: Transport;\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n url?: string;\n headers?: Record<string, string>;\n startupTimeoutMs?: number;\n}\n\nexport type ConnectionState =\n | 'idle'\n | 'connecting'\n | 'connected'\n | 'disconnected'\n | 'reconnecting'\n | 'failed';\n\nexport interface MCPTool {\n name: string;\n description?: string;\n inputSchema: Record<string, unknown>;\n}\n\nexport interface ToolCallResult {\n content: unknown;\n isError: boolean;\n}\n\ninterface JsonRpcRequest {\n jsonrpc: '2.0';\n id: number;\n method: string;\n params?: unknown;\n}\n\ninterface JsonRpcResponse {\n jsonrpc: '2.0';\n id: number;\n result?: unknown;\n error?: { code: number; message: string; data?: unknown };\n}\n\n/**\n * Lightweight stdio MCP client. Supports JSON-RPC 2.0 over newline-delimited JSON.\n * SSE / streamable-http are stubbed and throw on connect — to be filled by a real impl.\n */\nexport class MCPClient {\n private state: ConnectionState = 'idle';\n private child?: ChildProcess;\n private nextId = 1;\n private readonly pending = new Map<number, (res: JsonRpcResponse) => void>();\n private rxBuffer = '';\n private tools: MCPTool[] = [];\n /**\n * Guards against multiple concurrent drain-waits. When `stdin.write()`\n * returns false the first waiter sets this flag; any subsequent callers\n * skip the drain wait and emit a warning instead of racing.\n */\n private _drainPending = false;\n /** Set when a notify() call failed for reasons the caller should know about. */\n private _lastNotifySkipped = false;\n\n constructor(public readonly opts: MCPClientOptions) {}\n\n getState(): ConnectionState {\n return this.state;\n }\n\n listTools(): MCPTool[] {\n return [...this.tools];\n }\n\n /** Returns true if a prior notify() call was skipped due to backpressure. */\n hadNotifySkipped(): boolean {\n return this._lastNotifySkipped;\n }\n\n async connect(): Promise<void> {\n this.state = 'connecting';\n if (this.opts.transport !== 'stdio') {\n this.state = 'failed';\n throw new Error(`MCP transport \"${this.opts.transport}\" not supported in this build`);\n }\n if (!this.opts.command) {\n this.state = 'failed';\n throw new Error('MCP stdio transport requires \"command\"');\n }\n\n const child = spawn(this.opts.command, this.opts.args ?? [], {\n env: { ...process.env, ...this.opts.env },\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n this.child = child;\n\n child.stdout?.on('data', (chunk: Buffer) => this.onData(chunk.toString()));\n child.stderr?.on('data', () => {\n // intentionally discard stderr noise from server\n });\n child.on('exit', () => {\n this.state = 'disconnected';\n });\n child.on('error', () => {\n this.state = 'failed';\n });\n\n const timeout = this.opts.startupTimeoutMs ?? 10_000;\n const initialize = await Promise.race([\n this.request('initialize', {\n protocolVersion: '2024-11-05',\n capabilities: { tools: {} },\n clientInfo: { name: 'wrongstack', version: '0.1.1' },\n }),\n new Promise<JsonRpcResponse>((_, rej) =>\n setTimeout(() => rej(new Error('MCP initialize timeout')), timeout),\n ),\n ]);\n if (initialize.error) {\n this.state = 'failed';\n throw new Error(`MCP initialize failed: ${initialize.error.message}`);\n }\n try {\n await this.notify('notifications/initialized', {});\n } catch (err) {\n // some servers don't require this; failures are logged as warnings\n console.warn(\n '[MCP] notify(\"notifications/initialized\") failed for \"' + this.opts.name + '\": ' + (err instanceof Error ? err.message : String(err)),\n );\n }\n const toolsRes = await this.request('tools/list', {});\n if (toolsRes.error) {\n this.tools = [];\n } else {\n const result = toolsRes.result as { tools?: MCPTool[] } | undefined;\n this.tools = result?.tools ?? [];\n }\n this.state = 'connected';\n }\n\n async callTool(name: string, input: unknown): Promise<ToolCallResult> {\n if (this.state !== 'connected') {\n throw new Error(`MCP client \"${this.opts.name}\" not connected (state=${this.state})`);\n }\n const res = await this.request('tools/call', { name, arguments: input });\n if (res.error) {\n return { content: res.error.message, isError: true };\n }\n const result = res.result as { content?: unknown; isError?: boolean } | undefined;\n return {\n content: result?.content ?? '',\n isError: Boolean(result?.isError),\n };\n }\n\n async close(): Promise<void> {\n if (this.child) {\n try {\n this.child.kill();\n } catch {\n // ignore\n }\n }\n this.state = 'disconnected';\n }\n\n private request(method: string, params: unknown): Promise<JsonRpcResponse> {\n const id = this.nextId++;\n const req: JsonRpcRequest = { jsonrpc: '2.0', id, method, params };\n return new Promise((resolve, reject) => {\n this.pending.set(id, resolve);\n try {\n this.child?.stdin?.write(JSON.stringify(req) + '\\n');\n } catch (err) {\n this.pending.delete(id);\n reject(err);\n }\n });\n }\n\n private async notify(method: string, params: unknown): Promise<void> {\n const req = { jsonrpc: '2.0', method, params };\n const encoded = JSON.stringify(req) + '\\n';\n try {\n const ok = this.child?.stdin?.write(encoded);\n if (!ok) {\n // Only the first caller waits for drain; others just warn and return.\n // This avoids a race where two concurrent notify() calls each start\n // their own drain-wait, then both resolve and the buffer is still full.\n if (this._drainPending) {\n this._lastNotifySkipped = true;\n process.emitWarning(\n `[MCP] notify(\"${method}\") skipped: stdin buffer backpressure (already waiting for drain)`,\n );\n return;\n }\n this._drainPending = true;\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n this._drainPending = false;\n reject(new Error(`MCP notify(\"${method}\") drain timeout`));\n }, 500);\n this.child?.stdin?.once('drain', () => {\n clearTimeout(timeout);\n this._drainPending = false;\n resolve();\n });\n this.child?.stdin?.once('error', (err) => {\n clearTimeout(timeout);\n this._drainPending = false;\n reject(err);\n });\n });\n }\n } catch (err) {\n throw new Error(`[MCP] notify(\"${method}\") failed: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n private onData(s: string): void {\n this.rxBuffer += s;\n let idx = this.rxBuffer.indexOf('\\n');\n while (idx !== -1) {\n const line = this.rxBuffer.slice(0, idx).trim();\n this.rxBuffer = this.rxBuffer.slice(idx + 1);\n if (line) this.onLine(line);\n idx = this.rxBuffer.indexOf('\\n');\n }\n }\n\n private onLine(line: string): void {\n let msg: JsonRpcResponse;\n try {\n msg = JSON.parse(line) as JsonRpcResponse;\n } catch {\n return;\n }\n if (msg.id !== undefined && this.pending.has(msg.id)) {\n const resolve = this.pending.get(msg.id);\n this.pending.delete(msg.id);\n resolve?.(msg);\n }\n }\n}\n","import type { Tool, Permission } from '@wrongstack/core';\nimport type { MCPClient, MCPTool } from './client.js';\n\nconst MUTATING_RE = /create|update|delete|write|send|set|put|post|patch|remove|rename|move/i;\n\nexport function wrapMCPTool(\n serverName: string,\n mcpTool: MCPTool,\n client: MCPClient,\n permission: Permission = 'confirm',\n): Tool {\n const qualifiedName = `mcp__${serverName}__${mcpTool.name}`;\n return {\n name: qualifiedName,\n description: mcpTool.description ?? `${qualifiedName} (MCP tool)`,\n usageHint: `Tool provided by MCP server \"${serverName}\". ${mcpTool.description ?? ''}`,\n permission,\n mutating: MUTATING_RE.test(mcpTool.name),\n inputSchema: mcpTool.inputSchema ?? { type: 'object', properties: {} },\n async execute(input, ctx, opts) {\n const res = await client.callTool(mcpTool.name, input);\n if (res.isError) {\n throw new Error(stringify(res.content));\n }\n return stringify(res.content);\n },\n };\n}\n\nfunction stringify(c: unknown): string {\n if (typeof c === 'string') return c;\n if (Array.isArray(c)) {\n return c\n .map((item) => {\n if (item && typeof item === 'object') {\n const t = (item as { type?: string; text?: string }).type;\n if (t === 'text') return (item as { text?: string }).text ?? '';\n return JSON.stringify(item);\n }\n return String(item);\n })\n .join('\\n');\n }\n if (c && typeof c === 'object') {\n if ('text' in (c as Record<string, unknown>)) {\n return String((c as Record<string, unknown>).text);\n }\n return JSON.stringify(c);\n }\n return String(c ?? '');\n}\n","import type { EventBus, MCPServerConfig, ToolRegistry, Logger } from '@wrongstack/core';\nimport { MCPClient, type ConnectionState } from './client.js';\nimport { wrapMCPTool } from './wrap-tool.js';\n\ninterface ServerSlot {\n cfg: MCPServerConfig;\n client?: MCPClient;\n state: ConnectionState;\n toolNames: string[];\n attempts: number;\n}\n\nexport interface MCPRegistryOptions {\n toolRegistry: ToolRegistry;\n events: EventBus;\n log: Logger;\n}\n\nexport class MCPRegistry {\n private readonly servers = new Map<string, ServerSlot>();\n private readonly toolRegistry: ToolRegistry;\n private readonly events: EventBus;\n private readonly log: Logger;\n\n constructor(opts: MCPRegistryOptions) {\n this.toolRegistry = opts.toolRegistry;\n this.events = opts.events;\n this.log = opts.log;\n }\n\n async start(cfg: MCPServerConfig): Promise<void> {\n if (cfg.enabled === false) return;\n const slot: ServerSlot = {\n cfg,\n state: 'idle',\n toolNames: [],\n attempts: 0,\n };\n this.servers.set(cfg.name, slot);\n await this.attemptConnect(slot);\n }\n\n async stop(name: string): Promise<void> {\n const slot = this.servers.get(name);\n if (!slot) return;\n if (slot.client) await slot.client.close();\n for (const t of slot.toolNames) this.toolRegistry.unregister(t);\n slot.toolNames = [];\n slot.state = 'disconnected';\n this.events.emit('mcp.server.disconnected', { name, reason: 'stop' });\n }\n\n async restart(name: string): Promise<void> {\n const slot = this.servers.get(name);\n if (!slot) throw new Error(`MCP server \"${name}\" not registered`);\n await this.stop(name);\n slot.attempts = 0;\n await this.attemptConnect(slot);\n }\n\n list(): { name: string; state: ConnectionState; toolCount: number }[] {\n return Array.from(this.servers.values()).map((s) => ({\n name: s.cfg.name,\n state: s.state,\n toolCount: s.toolNames.length,\n }));\n }\n\n async stopAll(): Promise<void> {\n for (const name of Array.from(this.servers.keys())) {\n await this.stop(name);\n }\n }\n\n private async attemptConnect(slot: ServerSlot): Promise<void> {\n const MAX_ATTEMPTS = 3;\n let attempt = 0;\n while (attempt < MAX_ATTEMPTS) {\n attempt++;\n slot.state = attempt === 1 ? 'connecting' : 'reconnecting';\n slot.attempts = attempt;\n try {\n const client = new MCPClient({\n name: slot.cfg.name,\n transport: slot.cfg.transport,\n command: slot.cfg.command,\n args: slot.cfg.args,\n env: slot.cfg.env,\n url: slot.cfg.url,\n headers: slot.cfg.headers,\n startupTimeoutMs: slot.cfg.startupTimeoutMs,\n });\n await client.connect();\n slot.client = client;\n const isReconnect = attempt > 1;\n slot.state = 'connected';\n const allowed = slot.cfg.allowedTools;\n const wrapped = client\n .listTools()\n .filter((t) => !allowed || allowed.includes(t.name))\n .map((t) => wrapMCPTool(slot.cfg.name, t, client, slot.cfg.permission ?? 'confirm'));\n for (const tool of wrapped) {\n try {\n this.toolRegistry.register(tool, `mcp:${slot.cfg.name}`);\n slot.toolNames.push(tool.name);\n } catch (err) {\n this.log.warn(`MCP tool \"${tool.name}\" not registered`, err);\n }\n }\n this.events.emit(isReconnect ? 'mcp.server.reconnected' : 'mcp.server.connected', {\n name: slot.cfg.name,\n toolCount: slot.toolNames.length,\n });\n return; // success\n } catch (err) {\n this.log.warn(`MCP server \"${slot.cfg.name}\" connect attempt ${attempt} failed`, err);\n if (attempt >= MAX_ATTEMPTS) {\n this.log.error(`MCP server \"${slot.cfg.name}\" connect exhausted after ${MAX_ATTEMPTS} attempts`, err);\n slot.state = 'failed';\n this.events.emit('mcp.server.disconnected', {\n name: slot.cfg.name,\n reason: err instanceof Error ? err.message : 'unknown',\n });\n return;\n }\n const delay = 500 * 2 ** attempt;\n await new Promise((r) => setTimeout(r, delay));\n }\n }\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wrongstack/mcp",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -14,7 +14,7 @@
14
14
  "dist"
15
15
  ],
16
16
  "dependencies": {
17
- "@wrongstack/core": "0.1.1"
17
+ "@wrongstack/core": "0.1.2"
18
18
  },
19
19
  "devDependencies": {
20
20
  "@types/node": "^22.10.0",