@kinqs/brainrouter-cli 0.3.6 → 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/dist/agent/agent.d.ts +12 -1
- package/dist/agent/agent.js +134 -18
- package/dist/cli/banner.d.ts +20 -0
- package/dist/cli/banner.js +47 -14
- package/dist/cli/cliPrompt.d.ts +40 -3
- package/dist/cli/cliPrompt.js +52 -25
- package/dist/cli/commands/_context.d.ts +3 -1
- package/dist/cli/commands/_helpers.d.ts +1 -1
- package/dist/cli/commands/config.d.ts +46 -0
- package/dist/cli/commands/config.js +1042 -0
- 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 +13 -11
- package/dist/cli/commands/mcp.js +239 -74
- package/dist/cli/commands/orchestration.js +18 -0
- package/dist/cli/commands/ui.js +117 -58
- package/dist/cli/commands/workflow.d.ts +2 -0
- package/dist/cli/commands/workflow.js +54 -8
- 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 +43 -712
- package/dist/cli/slashSuggest.d.ts +32 -0
- package/dist/cli/slashSuggest.js +146 -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 +12 -0
- package/dist/config/config.js +45 -3
- package/dist/index.js +148 -206
- package/dist/memory/briefing.d.ts +1 -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/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.js +5 -1
- package/dist/runtime/mcpClient.js +14 -11
- package/dist/runtime/mcpPool.d.ts +162 -0
- package/dist/runtime/mcpPool.js +423 -0
- package/dist/runtime/mcpUtils.d.ts +3 -1
- package/package.json +8 -2
- package/.env.example +0 -116
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { CommandContext } from './_context.js';
|
|
2
|
+
/**
|
|
3
|
+
* `/init` slash command — 0.3.7 redesign.
|
|
4
|
+
*
|
|
5
|
+
* Two behaviours under one verb, picked by the first argument:
|
|
6
|
+
*
|
|
7
|
+
* - `/init` (bare) — re-run the onboarding wizard inside the REPL.
|
|
8
|
+
* The REPL already owns the readline, so the wizard reuses it
|
|
9
|
+
* (`ownsReadline: false`). Aborting at any step leaves disk
|
|
10
|
+
* untouched.
|
|
11
|
+
* - `/init agentmd` — back-compat alias for the 0.3.6 behaviour
|
|
12
|
+
* that only scaffolded AGENT.md (the wizard now folds this in as
|
|
13
|
+
* its final step, but users with muscle memory keep the lever).
|
|
14
|
+
*
|
|
15
|
+
* The auto-trigger on REPL start (when no `~/.config/brainrouter/config.json`
|
|
16
|
+
* exists) calls `runWizard` directly from `index.ts` with
|
|
17
|
+
* `ownsReadline: true`. That's a separate entry point — this slash
|
|
18
|
+
* handler is only for the in-REPL invocation.
|
|
19
|
+
*/
|
|
20
|
+
export declare function tryHandleInitCommand(ctx: CommandContext): Promise<boolean>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { initAgentMd } from '../../prompt/initAgentMd.js';
|
|
3
|
+
import { runWizard } from '../ink/runWizard.js';
|
|
4
|
+
/**
|
|
5
|
+
* `/init` slash command — 0.3.7 redesign.
|
|
6
|
+
*
|
|
7
|
+
* Two behaviours under one verb, picked by the first argument:
|
|
8
|
+
*
|
|
9
|
+
* - `/init` (bare) — re-run the onboarding wizard inside the REPL.
|
|
10
|
+
* The REPL already owns the readline, so the wizard reuses it
|
|
11
|
+
* (`ownsReadline: false`). Aborting at any step leaves disk
|
|
12
|
+
* untouched.
|
|
13
|
+
* - `/init agentmd` — back-compat alias for the 0.3.6 behaviour
|
|
14
|
+
* that only scaffolded AGENT.md (the wizard now folds this in as
|
|
15
|
+
* its final step, but users with muscle memory keep the lever).
|
|
16
|
+
*
|
|
17
|
+
* The auto-trigger on REPL start (when no `~/.config/brainrouter/config.json`
|
|
18
|
+
* exists) calls `runWizard` directly from `index.ts` with
|
|
19
|
+
* `ownsReadline: true`. That's a separate entry point — this slash
|
|
20
|
+
* handler is only for the in-REPL invocation.
|
|
21
|
+
*/
|
|
22
|
+
export async function tryHandleInitCommand(ctx) {
|
|
23
|
+
const { command, args, agent, repl } = ctx;
|
|
24
|
+
if (command !== '/init')
|
|
25
|
+
return false;
|
|
26
|
+
// Back-compat: explicit subcommand keeps the 0.3.6 one-shot behaviour.
|
|
27
|
+
if (args[0]?.toLowerCase() === 'agentmd' || args[0]?.toLowerCase() === 'agent') {
|
|
28
|
+
const result = initAgentMd(agent.workspaceRoot);
|
|
29
|
+
if (result.status === 'created') {
|
|
30
|
+
console.log(chalk.green(`\n✓ Created ${result.path}`));
|
|
31
|
+
console.log(chalk.gray(' Edit it to describe your project — any AGENT.md-aware agent will read it.\n'));
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
console.log(chalk.yellow(`\nFile already exists: ${result.path}`));
|
|
35
|
+
console.log(chalk.gray(' Run `/init agentmd --overwrite` if you really want to start fresh (TODO).\n'));
|
|
36
|
+
}
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
// Wizard mode. Ink owns stdin while the wizard is mounted; once it
|
|
40
|
+
// unmounts the REPL's readline resumes naturally because we kept the
|
|
41
|
+
// process.stdin handle around (Ink restores raw mode on exit).
|
|
42
|
+
try {
|
|
43
|
+
const result = await runWizard({
|
|
44
|
+
workspaceRoot: agent.workspaceRoot,
|
|
45
|
+
});
|
|
46
|
+
if (result.config?.llm) {
|
|
47
|
+
// Live-update the in-flight agent so the next turn uses the new
|
|
48
|
+
// model / endpoint without forcing a restart. Keep the wrapper's
|
|
49
|
+
// existing MCP connection — switching MCP needs a restart for
|
|
50
|
+
// now (next item on the polish list).
|
|
51
|
+
const llm = result.config.llm;
|
|
52
|
+
agent.setModel(llm.model);
|
|
53
|
+
// The agent's internal openai client cached the endpoint at
|
|
54
|
+
// construction time — repl users may need a fresh CLI process
|
|
55
|
+
// for endpoint changes to fully take effect.
|
|
56
|
+
console.log(chalk.gray(' (note: endpoint / API-key changes apply on the next CLI restart)\n'));
|
|
57
|
+
}
|
|
58
|
+
repl.refreshPromptForMode();
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
console.error(chalk.red(`\n/init failed: ${err?.message ?? err}\n`));
|
|
62
|
+
}
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { CommandContext } from './_context.js';
|
|
2
|
+
/**
|
|
3
|
+
* `/login` slash command — 0.3.7 redesign on the new internal picker.
|
|
4
|
+
*
|
|
5
|
+
* Opens a small modal that picks a transport (stdio / local-http /
|
|
6
|
+
* remote-http), gathers fields via the framed text prompt, runs a
|
|
7
|
+
* single 5s reachability probe, and saves the profile. Probe failure
|
|
8
|
+
* offers "save anyway / try a different transport / cancel".
|
|
9
|
+
*
|
|
10
|
+
* The legacy `brainrouter login` subcommand stays for users who
|
|
11
|
+
* scripted it.
|
|
12
|
+
*/
|
|
13
|
+
export declare function tryHandleLoginCommand(ctx: CommandContext): Promise<boolean>;
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { saveConfig } from '../../config/config.js';
|
|
3
|
+
import { McpClientWrapper } from '../../runtime/mcpClient.js';
|
|
4
|
+
import { maskApiKey } from '../wizard/providers.js';
|
|
5
|
+
// 0.3.7 — picker / prompt moved to Ink (see commands/config.ts for the
|
|
6
|
+
// full rationale on why the raw-stdout primitives were retired).
|
|
7
|
+
import { runPicker, runTextField } from '../ink/runPicker.js';
|
|
8
|
+
const pickFromList = runPicker;
|
|
9
|
+
const promptText = runTextField;
|
|
10
|
+
import { buildTheme } from '../theme.js';
|
|
11
|
+
import { readPreferences } from '../../state/preferencesStore.js';
|
|
12
|
+
import { editLlm, promptBrainrouterApiKey } from './config.js';
|
|
13
|
+
/**
|
|
14
|
+
* `/login` slash command — 0.3.7 redesign on the new internal picker.
|
|
15
|
+
*
|
|
16
|
+
* Opens a small modal that picks a transport (stdio / local-http /
|
|
17
|
+
* remote-http), gathers fields via the framed text prompt, runs a
|
|
18
|
+
* single 5s reachability probe, and saves the profile. Probe failure
|
|
19
|
+
* offers "save anyway / try a different transport / cancel".
|
|
20
|
+
*
|
|
21
|
+
* The legacy `brainrouter login` subcommand stays for users who
|
|
22
|
+
* scripted it.
|
|
23
|
+
*/
|
|
24
|
+
export async function tryHandleLoginCommand(ctx) {
|
|
25
|
+
if (ctx.command !== '/login')
|
|
26
|
+
return false;
|
|
27
|
+
const theme = buildTheme(readPreferences(ctx.agent.workspaceRoot).theme === 'mono' ? 'mono' : readPreferences(ctx.agent.workspaceRoot).theme === 'light' ? 'light' : 'dark');
|
|
28
|
+
while (true) {
|
|
29
|
+
const transport = await pickFromList({
|
|
30
|
+
theme,
|
|
31
|
+
title: '/login — MCP profile',
|
|
32
|
+
subtitle: 'Pick how this CLI reaches the BrainRouter MCP.',
|
|
33
|
+
rows: [
|
|
34
|
+
{ id: 'local-stdio', label: 'Local stdio', value: 'brainrouter-mcp', description: 'No HTTP server needed' },
|
|
35
|
+
{ id: 'local-http', label: 'Local HTTP', value: 'localhost:3747', description: 'Connect to a brainrouter-mcp HTTP server running locally' },
|
|
36
|
+
{ id: 'remote-http', label: 'Remote HTTP', value: 'custom URL', description: 'Hosted MCP server (URL + optional key)' },
|
|
37
|
+
],
|
|
38
|
+
});
|
|
39
|
+
if (transport.kind !== 'pick') {
|
|
40
|
+
console.log(chalk.yellow('\n /login cancelled.\n'));
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
let serverConfig;
|
|
44
|
+
let profileName = '';
|
|
45
|
+
if (transport.id === 'local-stdio') {
|
|
46
|
+
serverConfig = { type: 'stdio', command: 'brainrouter-mcp', args: [], identity: 'brainrouter' };
|
|
47
|
+
profileName = 'local-stdio';
|
|
48
|
+
}
|
|
49
|
+
else if (transport.id === 'local-http') {
|
|
50
|
+
// 0.3.7 — collect the BrainRouter API key even for local-http.
|
|
51
|
+
// brainrouter-mcp HTTP servers can require auth (BRAINROUTER_API_KEY
|
|
52
|
+
// set in their server.env). Pre-fill from the env var; blank is OK
|
|
53
|
+
// for unauthenticated dev servers.
|
|
54
|
+
const apiKey = await promptBrainrouterApiKey(theme, 'local', ctx.config.servers['local-http']?.apiKey);
|
|
55
|
+
if (apiKey === undefined) {
|
|
56
|
+
console.log(chalk.yellow('\n /login cancelled.\n'));
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
serverConfig = {
|
|
60
|
+
type: 'http',
|
|
61
|
+
url: 'http://localhost:3747/mcp',
|
|
62
|
+
apiKey: apiKey || undefined,
|
|
63
|
+
identity: 'brainrouter',
|
|
64
|
+
};
|
|
65
|
+
profileName = 'local-http';
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
const urlResult = await promptText({
|
|
69
|
+
theme,
|
|
70
|
+
title: 'Remote MCP URL',
|
|
71
|
+
subtitle: 'Paste the full URL (e.g. https://brainrouter.example.com/mcp).',
|
|
72
|
+
prefilled: ctx.config.servers['remote']?.url ?? '',
|
|
73
|
+
placeholder: 'https://...',
|
|
74
|
+
validate: (raw) => {
|
|
75
|
+
const v = raw.trim();
|
|
76
|
+
if (!v)
|
|
77
|
+
return 'URL required';
|
|
78
|
+
try {
|
|
79
|
+
new URL(v);
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return 'not a valid URL';
|
|
83
|
+
}
|
|
84
|
+
return undefined;
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
if (urlResult.kind !== 'accept') {
|
|
88
|
+
console.log(chalk.yellow('\n /login cancelled.\n'));
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
const url = urlResult.text.trim();
|
|
92
|
+
const apiKey = await promptBrainrouterApiKey(theme, 'remote', ctx.config.servers['remote']?.apiKey);
|
|
93
|
+
if (apiKey === undefined) {
|
|
94
|
+
console.log(chalk.yellow('\n /login cancelled.\n'));
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
serverConfig = { type: 'http', url, apiKey: apiKey || undefined, identity: 'brainrouter' };
|
|
98
|
+
profileName = 'remote';
|
|
99
|
+
}
|
|
100
|
+
const probe = await probeMcpProfile(serverConfig, profileName);
|
|
101
|
+
if (!probe.ok) {
|
|
102
|
+
const choice = await pickFromList({
|
|
103
|
+
theme,
|
|
104
|
+
title: 'MCP probe failed',
|
|
105
|
+
subtitle: probe.error,
|
|
106
|
+
rows: [
|
|
107
|
+
{ id: 'save', label: 'Save anyway', description: 'Persist the profile; run /mcp reconnect once the server is up' },
|
|
108
|
+
{ id: 'retry', label: 'Try a different transport', description: 'Re-open the picker' },
|
|
109
|
+
{ id: 'cancel', label: 'Cancel', description: 'Discard — nothing written' },
|
|
110
|
+
],
|
|
111
|
+
});
|
|
112
|
+
if (choice.kind !== 'pick' || choice.id === 'cancel') {
|
|
113
|
+
console.log(chalk.yellow('\n /login cancelled.\n'));
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
if (choice.id === 'retry')
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
console.log(chalk.green(`\n ✓ Probe succeeded (${probe.latencyMs}ms).`));
|
|
121
|
+
}
|
|
122
|
+
ctx.config.servers[profileName] = serverConfig;
|
|
123
|
+
ctx.config.activeServer = profileName;
|
|
124
|
+
saveConfig(ctx.config);
|
|
125
|
+
const apiKeyDisplay = serverConfig.apiKey ? maskApiKey(serverConfig.apiKey) : '(no key)';
|
|
126
|
+
console.log(chalk.green(` ✓ MCP profile "${profileName}" saved as active. ${apiKeyDisplay}`));
|
|
127
|
+
console.log(chalk.gray(' Run /mcp reconnect to pick up the new transport without restarting.\n'));
|
|
128
|
+
// 0.3.7 — follow-on LLM credential step. Pre-0.3.7 `/login`
|
|
129
|
+
// *only* handled the MCP profile; users who wanted to refresh
|
|
130
|
+
// their LLM API key in the same flow had to bounce out to
|
|
131
|
+
// `/config` or `/init`. Now we offer it inline.
|
|
132
|
+
//
|
|
133
|
+
// Always offer (per user direction); default-No when LLM
|
|
134
|
+
// creds are already populated, default-Yes when missing.
|
|
135
|
+
const hasLlm = Boolean(ctx.config.llm?.apiKey?.trim()) && Boolean(ctx.config.llm?.endpoint);
|
|
136
|
+
const promptSubtitle = hasLlm
|
|
137
|
+
? `Current: ${ctx.config.llm?.model ?? '(unset)'} @ ${ctx.config.llm?.endpoint ?? '(no endpoint)'} · key ${maskApiKey(ctx.config.llm?.apiKey ?? '')}`
|
|
138
|
+
: 'No LLM credentials saved yet — set them now so the next turn works.';
|
|
139
|
+
const llmChoice = await pickFromList({
|
|
140
|
+
theme,
|
|
141
|
+
title: 'Update LLM credentials?',
|
|
142
|
+
subtitle: promptSubtitle,
|
|
143
|
+
rows: hasLlm ? [
|
|
144
|
+
{ id: 'skip', label: 'Skip — keep current LLM config', description: 'Press ENTER to exit /login' },
|
|
145
|
+
{ id: 'update', label: 'Update LLM', description: 'Switch provider / paste a new key / change model' },
|
|
146
|
+
] : [
|
|
147
|
+
{ id: 'update', label: 'Set LLM now', description: 'Provider → API key → Model' },
|
|
148
|
+
{ id: 'skip', label: 'Skip — set up later via /config', description: 'Exit /login without LLM config' },
|
|
149
|
+
],
|
|
150
|
+
initialCursor: 0,
|
|
151
|
+
});
|
|
152
|
+
if (llmChoice.kind === 'pick' && llmChoice.id === 'update') {
|
|
153
|
+
const ok = await editLlm(ctx);
|
|
154
|
+
if (!ok) {
|
|
155
|
+
console.log(chalk.yellow(' /login — LLM step cancelled; MCP profile saved.\n'));
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
async function probeMcpProfile(serverConfig, name) {
|
|
162
|
+
const wrapper = new McpClientWrapper();
|
|
163
|
+
const start = Date.now();
|
|
164
|
+
try {
|
|
165
|
+
await Promise.race([
|
|
166
|
+
wrapper.connect(serverConfig, undefined, name),
|
|
167
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('timed out after 5s')), 5_000)),
|
|
168
|
+
]);
|
|
169
|
+
await wrapper.close();
|
|
170
|
+
return { ok: true, latencyMs: Date.now() - start };
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
try {
|
|
174
|
+
await wrapper.close();
|
|
175
|
+
}
|
|
176
|
+
catch { /* ignore */ }
|
|
177
|
+
return { ok: false, error: String(err?.message ?? err) };
|
|
178
|
+
}
|
|
179
|
+
}
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* `/mcp` slash-command surface. 0.3.7 multi-MCP rewrite — third-party
|
|
3
|
+
* MCPs connect concurrently while BrainRouter MCP profiles are mutually
|
|
4
|
+
* exclusive so exactly one brain is active at a time.
|
|
5
5
|
*
|
|
6
|
-
* /mcp
|
|
7
|
-
* /mcp list
|
|
8
|
-
* /mcp
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
* /mcp — alias for /mcp list
|
|
7
|
+
* /mcp list — every configured profile + per-server status
|
|
8
|
+
* /mcp tools [server] — MCP tools grouped by `mcp__<server>__*`
|
|
9
|
+
* namespace; pass a server id to scope
|
|
10
|
+
* /mcp connect <name> — connect a configured server that's idle/offline
|
|
11
|
+
* /mcp disconnect <name> — close one server's transport (config preserved)
|
|
12
|
+
* /mcp reconnect [name] — reconnect ONE (when name given) or the selected pool
|
|
11
13
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
14
|
+
* Backwards-compat: `/mcp reconnect` with no arg reconnects the same
|
|
15
|
+
* selected set used at boot: all third-party MCPs plus the active
|
|
16
|
+
* BrainRouter MCP. Pass an explicit name to target one.
|
|
15
17
|
*/
|
|
16
18
|
import type { CommandContext } from './_context.js';
|
|
17
19
|
export declare function tryHandleMcpCommand(ctx: CommandContext): Promise<boolean>;
|