@kinqs/brainrouter-cli 0.3.5 → 0.3.7
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/README.md +29 -52
- package/agents/architect.json +18 -0
- package/agents/explorer.json +18 -0
- package/agents/reviewer.json +18 -0
- package/agents/verifier.json +18 -0
- package/agents/worker.json +18 -0
- package/bin/cli.cjs +71 -0
- package/dist/agent/agent.d.ts +224 -3
- package/dist/agent/agent.js +561 -55
- package/dist/cli/banner.d.ts +80 -0
- package/dist/cli/banner.js +232 -0
- package/dist/cli/cliPrompt.d.ts +106 -0
- package/dist/cli/cliPrompt.js +314 -0
- package/dist/cli/commands/_context.d.ts +3 -1
- package/dist/cli/commands/_helpers.d.ts +1 -1
- package/dist/cli/commands/_helpers.js +6 -6
- package/dist/cli/commands/config.d.ts +46 -0
- package/dist/cli/commands/config.js +1042 -0
- package/dist/cli/commands/guard.js +75 -10
- package/dist/cli/commands/init.d.ts +20 -0
- package/dist/cli/commands/init.js +64 -0
- package/dist/cli/commands/login.d.ts +13 -0
- package/dist/cli/commands/login.js +179 -0
- package/dist/cli/commands/mcp.d.ts +19 -0
- package/dist/cli/commands/mcp.js +286 -0
- package/dist/cli/commands/memory.js +2 -2
- package/dist/cli/commands/obs.js +22 -22
- package/dist/cli/commands/orchestration.js +18 -0
- package/dist/cli/commands/session.js +13 -5
- package/dist/cli/commands/ui.js +202 -91
- package/dist/cli/commands/workflow.d.ts +20 -0
- package/dist/cli/commands/workflow.js +368 -51
- package/dist/cli/ink/ChatApp.d.ts +206 -0
- package/dist/cli/ink/ChatApp.js +493 -0
- package/dist/cli/ink/Frame.d.ts +26 -0
- package/dist/cli/ink/Frame.js +5 -0
- package/dist/cli/ink/Picker.d.ts +65 -0
- package/dist/cli/ink/Picker.js +133 -0
- package/dist/cli/ink/SlashPalette.d.ts +51 -0
- package/dist/cli/ink/SlashPalette.js +136 -0
- package/dist/cli/ink/TextField.d.ts +34 -0
- package/dist/cli/ink/TextField.js +47 -0
- package/dist/cli/ink/WizardApp.d.ts +7 -0
- package/dist/cli/ink/WizardApp.js +422 -0
- package/dist/cli/ink/ambientChat.d.ts +34 -0
- package/dist/cli/ink/ambientChat.js +7 -0
- package/dist/cli/ink/consoleCapture.d.ts +11 -0
- package/dist/cli/ink/consoleCapture.js +33 -0
- package/dist/cli/ink/markdownRender.d.ts +41 -0
- package/dist/cli/ink/markdownRender.js +278 -0
- package/dist/cli/ink/renderWithResizeClear.d.ts +14 -0
- package/dist/cli/ink/renderWithResizeClear.js +33 -0
- package/dist/cli/ink/runChat.d.ts +34 -0
- package/dist/cli/ink/runChat.js +571 -0
- package/dist/cli/ink/runPicker.d.ts +31 -0
- package/dist/cli/ink/runPicker.js +139 -0
- package/dist/cli/ink/runSlashPalette.d.ts +23 -0
- package/dist/cli/ink/runSlashPalette.js +33 -0
- package/dist/cli/ink/runWizard.d.ts +22 -0
- package/dist/cli/ink/runWizard.js +133 -0
- package/dist/cli/ink/stdinHandoff.d.ts +51 -0
- package/dist/cli/ink/stdinHandoff.js +78 -0
- package/dist/cli/ink/toolFormat.d.ts +73 -0
- package/dist/cli/ink/toolFormat.js +180 -0
- package/dist/cli/ink/useTerminalSize.d.ts +35 -0
- package/dist/cli/ink/useTerminalSize.js +26 -0
- package/dist/cli/repl.d.ts +25 -3
- package/dist/cli/repl.js +64 -646
- package/dist/cli/slashSuggest.d.ts +32 -0
- package/dist/cli/slashSuggest.js +146 -0
- package/dist/cli/spinner.d.ts +34 -0
- package/dist/cli/spinner.js +36 -0
- package/dist/cli/statusline.d.ts +67 -0
- package/dist/cli/statusline.js +204 -0
- package/dist/cli/theme.d.ts +79 -0
- package/dist/cli/theme.js +106 -0
- package/dist/cli/whereView.d.ts +81 -0
- package/dist/cli/whereView.js +245 -0
- package/dist/cli/wizard/modelsApi.d.ts +72 -0
- package/dist/cli/wizard/modelsApi.js +166 -0
- package/dist/cli/wizard/picker.d.ts +202 -0
- package/dist/cli/wizard/picker.js +547 -0
- package/dist/cli/wizard/providers.d.ts +86 -0
- package/dist/cli/wizard/providers.js +190 -0
- package/dist/cli/wizard/runner.d.ts +13 -0
- package/dist/cli/wizard/runner.js +488 -0
- package/dist/cli/wizard/types.d.ts +122 -0
- package/dist/cli/wizard/types.js +109 -0
- package/dist/config/config.d.ts +52 -0
- package/dist/config/config.js +89 -75
- package/dist/index.js +215 -206
- package/dist/memory/briefing.d.ts +11 -1
- package/dist/memory/briefing.js +69 -1
- package/dist/memory/consolidation.d.ts +1 -1
- package/dist/orchestration/agentRegistry.d.ts +36 -0
- package/dist/orchestration/agentRegistry.js +64 -0
- package/dist/orchestration/orchestrator.d.ts +7 -0
- package/dist/orchestration/orchestrator.js +2 -0
- package/dist/orchestration/tools.d.ts +10 -1
- package/dist/orchestration/tools.js +48 -4
- package/dist/prompt/breadthHint.d.ts +5 -0
- package/dist/prompt/breadthHint.js +44 -0
- package/dist/prompt/skillCatalog.d.ts +11 -0
- package/dist/prompt/skillCatalog.js +134 -0
- package/dist/prompt/skillRunner.d.ts +2 -2
- package/dist/prompt/skillRunner.js +2 -31
- package/dist/prompt/systemPrompt.d.ts +34 -0
- package/dist/prompt/systemPrompt.js +128 -108
- package/dist/runtime/dangerousCommand.d.ts +53 -0
- package/dist/runtime/dangerousCommand.js +105 -0
- package/dist/runtime/mcpClient.d.ts +38 -1
- package/dist/runtime/mcpClient.js +104 -13
- package/dist/runtime/mcpPool.d.ts +162 -0
- package/dist/runtime/mcpPool.js +423 -0
- package/dist/runtime/mcpUtils.d.ts +3 -1
- package/dist/state/goalStore.d.ts +98 -17
- package/dist/state/goalStore.js +132 -42
- package/dist/state/preferencesStore.d.ts +67 -3
- package/dist/state/preferencesStore.js +84 -1
- package/dist/state/workflowArtifacts.d.ts +63 -2
- package/dist/state/workflowArtifacts.js +120 -8
- package/dist/tests/_helpers.d.ts +31 -0
- package/dist/tests/_helpers.js +91 -0
- package/package.json +12 -5
- package/.env.example +0 -109
|
@@ -13,14 +13,46 @@ export class McpClientWrapper {
|
|
|
13
13
|
* blowing up, which the agent's existing try/catch wrappers already handle.
|
|
14
14
|
*/
|
|
15
15
|
connected = false;
|
|
16
|
+
/**
|
|
17
|
+
* 10a: cached identity. Set once by `detectMcpIdentity` after the first
|
|
18
|
+
* successful `listTools()` (or by `connect` if the config + URL gave us
|
|
19
|
+
* a clear signal). The value drives status surfaces and the brain-offline
|
|
20
|
+
* prompt swap — distinguishes "our brain went down" from "a random
|
|
21
|
+
* third-party MCP went down" once item 11's multi-MCP support lands.
|
|
22
|
+
*/
|
|
23
|
+
identity = 'unknown';
|
|
24
|
+
serverName;
|
|
16
25
|
constructor() {
|
|
17
|
-
this.client = new Client({ name: 'brainrouter-cli', version: '0.3.
|
|
26
|
+
this.client = new Client({ name: 'brainrouter-cli', version: '0.3.7' }, { capabilities: {} });
|
|
18
27
|
}
|
|
19
28
|
/** Whether this wrapper has an active MCP transport. */
|
|
20
29
|
isConnected() {
|
|
21
30
|
return this.connected;
|
|
22
31
|
}
|
|
23
|
-
|
|
32
|
+
/** 10a: who is this MCP? Set by `detectMcpIdentity`; 'unknown' before first list. */
|
|
33
|
+
getIdentity() {
|
|
34
|
+
return this.identity;
|
|
35
|
+
}
|
|
36
|
+
/** 10a: profile name passed at connect (`brainrouter` / `local-http` / etc.). */
|
|
37
|
+
getServerName() {
|
|
38
|
+
return this.serverName;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* 10a: connect with an optional `name` so the wrapper can render identity
|
|
42
|
+
* tags ("BrainRouter MCP offline" vs "third-party MCP offline") without
|
|
43
|
+
* the caller threading it through every error path. The pre-10a single-
|
|
44
|
+
* arg form remains supported — callers that don't pass a name fall back
|
|
45
|
+
* to URL-pattern detection.
|
|
46
|
+
*/
|
|
47
|
+
async connect(serverConfig, llmConfig, name) {
|
|
48
|
+
this.serverName = name;
|
|
49
|
+
// Resolve identity upfront from config metadata + name/URL patterns.
|
|
50
|
+
// The tool-signature fallback (memory_recall + list_skills) runs after
|
|
51
|
+
// the first successful `listTools` in `refreshIdentityFromTools`.
|
|
52
|
+
this.identity = resolveIdentityFromConfig(serverConfig, name);
|
|
53
|
+
return this._connect(serverConfig, llmConfig);
|
|
54
|
+
}
|
|
55
|
+
async _connect(serverConfig, llmConfig) {
|
|
24
56
|
if (serverConfig.type === 'stdio') {
|
|
25
57
|
if (!serverConfig.command) {
|
|
26
58
|
throw new Error('Stdio server configuration missing "command".');
|
|
@@ -107,16 +139,11 @@ export class McpClientWrapper {
|
|
|
107
139
|
if (llmConfig?.model && !mergedEnv.BRAINROUTER_LLM_MODEL) {
|
|
108
140
|
mergedEnv.BRAINROUTER_LLM_MODEL = llmConfig.model;
|
|
109
141
|
}
|
|
110
|
-
//
|
|
111
|
-
//
|
|
112
|
-
//
|
|
113
|
-
//
|
|
114
|
-
|
|
115
|
-
console.warn('\n⚠️ No LLM API key reached the MCP child. Sensory turns will be ' +
|
|
116
|
-
'captured but cognitive extraction (the thing that makes them ' +
|
|
117
|
-
'searchable) will fail silently. Set OPENAI_API_KEY or ' +
|
|
118
|
-
'BRAINROUTER_LLM_API_KEY before starting brainrouter.\n');
|
|
119
|
-
}
|
|
142
|
+
// (Previously: a loud console.warn here if no LLM API key reached the
|
|
143
|
+
// MCP child. That message landed above the Ink banner and looked like a
|
|
144
|
+
// CLI error even though it was a server-side concern. Server-side
|
|
145
|
+
// extraction failures should surface through MCP's own status channel —
|
|
146
|
+
// not by the CLI second-guessing what the server needs.)
|
|
120
147
|
// Spawn the MCP child with cwd set to the MCP package directory if we
|
|
121
148
|
// can find it from the first arg (typically
|
|
122
149
|
// `node /path/to/BrainRouter/brainrouter/dist/index.js`). The child
|
|
@@ -147,6 +174,14 @@ export class McpClientWrapper {
|
|
|
147
174
|
args: serverConfig.args ?? [],
|
|
148
175
|
env: mergedEnv,
|
|
149
176
|
cwd: childCwd,
|
|
177
|
+
// The MCP child is a separate process with its own concerns (its own
|
|
178
|
+
// dotenv, its own auth failures, its own platform warnings). Inheriting
|
|
179
|
+
// its stderr meant every `[BrainRouter] FATAL …`, every dotenv banner,
|
|
180
|
+
// every SQLite ExperimentalWarning leaked above our Ink chat banner
|
|
181
|
+
// and looked like the CLI was crashing. Pipe it so the SDK owns the
|
|
182
|
+
// stream; the CLI can surface a single graceful "MCP unreachable" line
|
|
183
|
+
// through its own offline-mode flow instead.
|
|
184
|
+
stderr: 'pipe',
|
|
150
185
|
});
|
|
151
186
|
await this.client.connect(this.transport);
|
|
152
187
|
this.connected = true;
|
|
@@ -178,7 +213,22 @@ export class McpClientWrapper {
|
|
|
178
213
|
// with only local tools instead of crashing when it tries to enumerate.
|
|
179
214
|
if (!this.connected)
|
|
180
215
|
return { tools: [] };
|
|
181
|
-
|
|
216
|
+
const res = await this.client.listTools({});
|
|
217
|
+
// 10a: tool-signature fallback for identity detection. If the config +
|
|
218
|
+
// URL didn't already pin the identity, the BrainRouter MCP exposes a
|
|
219
|
+
// distinctive pair (`memory_recall` AND `list_skills`) that no neutral
|
|
220
|
+
// third-party MCP will. Cache the result so the next list doesn't
|
|
221
|
+
// re-probe — identity is stable for the lifetime of a connection.
|
|
222
|
+
if (this.identity === 'unknown' && Array.isArray(res?.tools)) {
|
|
223
|
+
const names = new Set(res.tools.map((t) => t?.name));
|
|
224
|
+
if (names.has('memory_recall') && names.has('list_skills')) {
|
|
225
|
+
this.identity = 'brainrouter';
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
this.identity = 'third-party';
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
return res;
|
|
182
232
|
}
|
|
183
233
|
async callTool(name, args) {
|
|
184
234
|
// Offline mode: synthesize an error envelope that downstream consumers
|
|
@@ -232,3 +282,44 @@ export class McpClientWrapper {
|
|
|
232
282
|
this.connected = false;
|
|
233
283
|
}
|
|
234
284
|
}
|
|
285
|
+
/**
|
|
286
|
+
* 10a: figure out who an MCP profile belongs to from config metadata + name
|
|
287
|
+
* + URL alone, before any network call. Explicit `identity` wins; otherwise
|
|
288
|
+
* we check name prefix and URL host. Returns 'unknown' when nothing matches
|
|
289
|
+
* — the caller (currently `listTools`) falls back to tool-signature
|
|
290
|
+
* detection after the first successful enumeration.
|
|
291
|
+
*
|
|
292
|
+
* Detection cases:
|
|
293
|
+
* - explicit `identity: 'brainrouter'` or `identity: 'third-party'` → that.
|
|
294
|
+
* - profile name (case-insensitive) starts with `brainrouter` → brainrouter.
|
|
295
|
+
* - http URL hostname matches `*.brainrouter.cloud` / `*.brainrouter.dev`
|
|
296
|
+
* / `*.brainrouter.io` / `*.kinqs.brainrouter.*` → brainrouter.
|
|
297
|
+
* - stdio command basename matches `brainrouter` / `brainrouter-mcp` → brainrouter.
|
|
298
|
+
* - otherwise → unknown (let the tool-signature fallback decide).
|
|
299
|
+
*/
|
|
300
|
+
export function resolveIdentityFromConfig(serverConfig, name) {
|
|
301
|
+
if (serverConfig.identity === 'brainrouter' || serverConfig.identity === 'third-party') {
|
|
302
|
+
return serverConfig.identity;
|
|
303
|
+
}
|
|
304
|
+
if (name && /^brainrouter/i.test(name.trim())) {
|
|
305
|
+
return 'brainrouter';
|
|
306
|
+
}
|
|
307
|
+
if (serverConfig.type === 'http' && serverConfig.url) {
|
|
308
|
+
try {
|
|
309
|
+
const url = new URL(serverConfig.url);
|
|
310
|
+
if (/\.brainrouter\.(cloud|dev|io|com|app)$/i.test(url.hostname)) {
|
|
311
|
+
return 'brainrouter';
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
catch {
|
|
315
|
+
// Malformed URL; let later code surface the connection error.
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
if (serverConfig.type === 'stdio' && serverConfig.command) {
|
|
319
|
+
const base = serverConfig.command.split(/[/\\]/).pop() ?? '';
|
|
320
|
+
if (/^brainrouter(-mcp)?$/i.test(base)) {
|
|
321
|
+
return 'brainrouter';
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
return 'unknown';
|
|
325
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { McpClientWrapper } from './mcpClient.js';
|
|
2
|
+
import type { LLMConfig, ServerConfig } from '../config/config.js';
|
|
3
|
+
/**
|
|
4
|
+
* 0.3.7 — Multi-MCP support. Wraps a `Map<serverId, McpClientWrapper>`
|
|
5
|
+
* and exposes the same public API as a single wrapper (`isConnected`,
|
|
6
|
+
* `getIdentity`, `getServerName`, `listTools`, `callTool`, `close`),
|
|
7
|
+
* so existing call-sites that hold an `mcpClient` reference keep
|
|
8
|
+
* working unchanged.
|
|
9
|
+
*
|
|
10
|
+
* Pattern lifted from Claude Code's `.mcp.json` model (see
|
|
11
|
+
* `openSrc/claude-code/CHANGELOG.md` — concurrent startup at line 688,
|
|
12
|
+
* tool prefixing at line 1515, graceful degradation at line 189). Our
|
|
13
|
+
* shape:
|
|
14
|
+
*
|
|
15
|
+
* - All configured servers attempt connection concurrently on boot,
|
|
16
|
+
* each with a 5s timeout. Offline ones do NOT block others.
|
|
17
|
+
* - Tools surface to the agent with `mcp_<serverId>_<toolName>`
|
|
18
|
+
* prefix (Claude Code style).
|
|
19
|
+
* - `callTool` accepts BOTH the prefixed form (the canonical name
|
|
20
|
+
* the LLM sees in the tool inventory) AND the raw form (back-compat
|
|
21
|
+
* for the existing system prompt and skills that hardcode
|
|
22
|
+
* `memory_recall` etc.). Raw form routes to the unique server
|
|
23
|
+
* providing that tool name; collision (two servers expose the same
|
|
24
|
+
* unprefixed name) returns a helpful error pointing at the
|
|
25
|
+
* prefixed form.
|
|
26
|
+
*
|
|
27
|
+
* Future versions may drop the raw-name fallback once skills and
|
|
28
|
+
* prompts are migrated to prefixed names; the pool then becomes the
|
|
29
|
+
* pure Claude Code shape. Until then the dual-name resolution is a
|
|
30
|
+
* transition aid documented in CHANGELOG `[0.3.7]`.
|
|
31
|
+
*/
|
|
32
|
+
export type McpServerStatus = {
|
|
33
|
+
serverId: string;
|
|
34
|
+
identity: 'brainrouter' | 'third-party' | 'unknown';
|
|
35
|
+
/** 'connected' once the underlying wrapper reports isConnected. */
|
|
36
|
+
status: 'connected' | 'connecting' | 'offline' | 'failed';
|
|
37
|
+
/** Filled after the first successful listTools (used by /mcp list). */
|
|
38
|
+
toolCount?: number;
|
|
39
|
+
/** Per-server error message when status === 'failed'. */
|
|
40
|
+
error?: string;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Choose which configured MCP profiles should connect for a normal CLI run.
|
|
44
|
+
*
|
|
45
|
+
* BrainRouter profiles are special: users may store several BrainRouter MCPs
|
|
46
|
+
* (local, staging, remote, self-hosted), but only one should be active at a
|
|
47
|
+
* time because the BrainRouter MCP is the memory/brain plane. Third-party MCPs
|
|
48
|
+
* are additive tools, so they all connect concurrently.
|
|
49
|
+
*
|
|
50
|
+
* `requestedProfile` is the explicit escape hatch (`--profile <name>`): it
|
|
51
|
+
* scopes the run to exactly that profile, matching the existing single-server
|
|
52
|
+
* mode.
|
|
53
|
+
*/
|
|
54
|
+
export declare function selectMcpServerIds(servers: Record<string, ServerConfig>, activeServer?: string, requestedProfile?: string): string[];
|
|
55
|
+
export declare class McpClientPool {
|
|
56
|
+
/** serverId → connected wrapper. */
|
|
57
|
+
private clients;
|
|
58
|
+
/** serverId → status entry (kept even for failed/offline servers so /mcp can render them). */
|
|
59
|
+
private statuses;
|
|
60
|
+
/**
|
|
61
|
+
* Unprefixed tool name → owning serverId. Sentinel `__COLLISION__`
|
|
62
|
+
* marks tool names exposed by multiple servers (must be addressed
|
|
63
|
+
* via the prefixed form).
|
|
64
|
+
*/
|
|
65
|
+
private toolToServer;
|
|
66
|
+
/** Prefixed form (`mcp_<serverId>_<tool>`) → `{serverId, tool}` for fast dispatch. */
|
|
67
|
+
private prefixedToServer;
|
|
68
|
+
/** LLM config from the last connectAll — needed for reconnect calls. */
|
|
69
|
+
private currentLlmConfig?;
|
|
70
|
+
/** Raw server configs from the last connectAll — needed for /mcp reconnect <id>. */
|
|
71
|
+
private serverConfigs;
|
|
72
|
+
/** serverId → prefix used in tool names. Brainrouter servers get "brainrouter"; others keep their config key. */
|
|
73
|
+
private prefixIds;
|
|
74
|
+
/** Reverse: prefixId → serverId (needed to dispatch `mcp_brainrouter_X` back to the real key). */
|
|
75
|
+
private prefixToServerId;
|
|
76
|
+
private getPrefixId;
|
|
77
|
+
private assignPrefixId;
|
|
78
|
+
/**
|
|
79
|
+
* Connect to every entry in `servers` concurrently. Each connect
|
|
80
|
+
* gets its own timeout; offline servers don't block the others.
|
|
81
|
+
* Returns the status array after all connects settle.
|
|
82
|
+
*/
|
|
83
|
+
connectAll(servers: Record<string, ServerConfig>, llmConfig?: LLMConfig, options?: {
|
|
84
|
+
timeoutMs?: number;
|
|
85
|
+
onStatusChange?: (s: McpServerStatus) => void;
|
|
86
|
+
}): Promise<McpServerStatus[]>;
|
|
87
|
+
/**
|
|
88
|
+
* Connect a single server. Used both by `connectAll` and by
|
|
89
|
+
* `/mcp connect <id>` for late-joining servers. Idempotent — if
|
|
90
|
+
* the server is already connected, closes the previous wrapper first.
|
|
91
|
+
*/
|
|
92
|
+
connectOne(serverId: string, config: ServerConfig, llmConfig?: LLMConfig, timeoutMs?: number): Promise<void>;
|
|
93
|
+
/** Tear down a single server. Removes it from the pool and rebuilds the tool index. */
|
|
94
|
+
disconnectOne(serverId: string): Promise<void>;
|
|
95
|
+
/** Reconnect: close + connect again using the stashed config. */
|
|
96
|
+
reconnectOne(serverId: string): Promise<void>;
|
|
97
|
+
/**
|
|
98
|
+
* Walk every connected client and rebuild the tool→server indices.
|
|
99
|
+
* Called after every connect / disconnect / reconnect so the
|
|
100
|
+
* dispatch path stays correct without re-fetching tools on every
|
|
101
|
+
* `callTool`.
|
|
102
|
+
*/
|
|
103
|
+
private refreshToolIndex;
|
|
104
|
+
/**
|
|
105
|
+
* Concatenated tool list across every connected server, with names
|
|
106
|
+
* prefixed `mcp_<serverId>_<toolName>` (Claude Code style). The
|
|
107
|
+
* agent calls this once per turn and hands it to the LLM.
|
|
108
|
+
*/
|
|
109
|
+
listTools(): Promise<{
|
|
110
|
+
tools: any[];
|
|
111
|
+
}>;
|
|
112
|
+
/**
|
|
113
|
+
* Route a tool call to the right server. Accepts both name forms:
|
|
114
|
+
*
|
|
115
|
+
* - `mcp_<serverId>_<tool>` — the canonical form the LLM sees
|
|
116
|
+
* in the inventory. Stripped + dispatched directly.
|
|
117
|
+
* - `<tool>` raw form — back-compat for prompts/skills that
|
|
118
|
+
* hardcode `memory_recall`-style names. Routed to the unique
|
|
119
|
+
* server providing that tool. Returns a helpful error if two
|
|
120
|
+
* servers expose the same name (caller must use the prefix).
|
|
121
|
+
*/
|
|
122
|
+
callTool(name: string, args: Record<string, any>): Promise<any>;
|
|
123
|
+
/** Internal — map a name (prefixed OR raw) to a concrete server + tool. */
|
|
124
|
+
private resolveToolCall;
|
|
125
|
+
/** True iff at least one server is connected. */
|
|
126
|
+
isConnected(): boolean;
|
|
127
|
+
/**
|
|
128
|
+
* Identity precedence: any connected `brainrouter` > any connected
|
|
129
|
+
* `third-party` > `unknown`. The CLI banner + offline prompt swap
|
|
130
|
+
* branch on this — "BrainRouter is offline" makes sense only when
|
|
131
|
+
* we expected one and didn't get one.
|
|
132
|
+
*/
|
|
133
|
+
getIdentity(): 'brainrouter' | 'third-party' | 'unknown';
|
|
134
|
+
/**
|
|
135
|
+
* Human-readable summary for the banner/statusline. Single-server
|
|
136
|
+
* pools render just the server name; multi-server pools render
|
|
137
|
+
* a count + the first few names.
|
|
138
|
+
*/
|
|
139
|
+
getServerName(): string | undefined;
|
|
140
|
+
/**
|
|
141
|
+
* Look up a wrapper by serverId. Used by `/mcp tools <server>` and
|
|
142
|
+
* similar commands that want to talk to one specific server.
|
|
143
|
+
*/
|
|
144
|
+
getClient(serverId: string): McpClientWrapper | undefined;
|
|
145
|
+
/**
|
|
146
|
+
* Find the connected wrapper whose identity is 'brainrouter'. Some
|
|
147
|
+
* code paths (memory capture, working-memory offload) specifically
|
|
148
|
+
* need the canonical brain regardless of how many third-party MCPs
|
|
149
|
+
* the user added.
|
|
150
|
+
*/
|
|
151
|
+
getBrainrouterClient(): McpClientWrapper | undefined;
|
|
152
|
+
/** Server id for the currently connected BrainRouter MCP, if one is active. */
|
|
153
|
+
getActiveBrainrouterServerId(): string | undefined;
|
|
154
|
+
/** Status snapshot for every server the pool has tried to connect to. */
|
|
155
|
+
getStatuses(): McpServerStatus[];
|
|
156
|
+
/** Status for one server (returns undefined if the pool has never seen it). */
|
|
157
|
+
getStatus(serverId: string): McpServerStatus | undefined;
|
|
158
|
+
/** List of serverIds currently held by the pool (connected or not). */
|
|
159
|
+
getServerIds(): string[];
|
|
160
|
+
/** Close every wrapper. Used on CLI exit. */
|
|
161
|
+
close(): Promise<void>;
|
|
162
|
+
}
|