cliskill 1.0.3 → 1.0.5
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 +66 -0
- package/dist/bootstrap/cli.js +1 -1
- package/dist/{chunk-PBLJ6557.js → chunk-ETGUAK34.js} +372 -8
- package/dist/chunk-ETGUAK34.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.js +3 -203
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-PBLJ6557.js.map +0 -1
package/README.md
CHANGED
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
- [Использование](#-использование)
|
|
25
25
|
- [Конфигурация](#-конфигурация)
|
|
26
26
|
- [Инструменты](#-инструменты)
|
|
27
|
+
- [MCP серверы](#-mcp-серверы)
|
|
27
28
|
- [Агентская система](#-агентская-система)
|
|
28
29
|
- [Архитектура](#-архитектура)
|
|
29
30
|
- [API провайдеры](#-api-провайдеры)
|
|
@@ -345,6 +346,71 @@ cliskill включает 15 встроенных инструментов дл
|
|
|
345
346
|
|
|
346
347
|
---
|
|
347
348
|
|
|
349
|
+
## 🔌 MCP серверы
|
|
350
|
+
|
|
351
|
+
**MCP (Model Context Protocol)** — открытый протокол для подключения внешних инструментов к AI-ассистентам. cliskill автоматически запускает MCP-серверы при старте и регистрирует их инструменты как доступные для модели.
|
|
352
|
+
|
|
353
|
+
### Как это работает
|
|
354
|
+
|
|
355
|
+
1. cliskill читает `mcpServers` из конфига
|
|
356
|
+
2. Запускает каждый сервер как дочерний процесс (stdio transport)
|
|
357
|
+
3. Получает список инструментов через `tools/list`
|
|
358
|
+
4. Регистрирует их в ToolRegistry с префиксом `mcp_{serverName}_`
|
|
359
|
+
5. Модель может вызывать MCP-инструменты наравне со встроенными
|
|
360
|
+
|
|
361
|
+
### Настройка
|
|
362
|
+
|
|
363
|
+
Добавьте массив `mcpServers` в конфиг (`~/.cliskill/config.json` или `.cliskillrc.json`):
|
|
364
|
+
|
|
365
|
+
```json
|
|
366
|
+
{
|
|
367
|
+
"mcpServers": [
|
|
368
|
+
{
|
|
369
|
+
"name": "filesystem",
|
|
370
|
+
"command": "npx",
|
|
371
|
+
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/projects"],
|
|
372
|
+
"transport": "stdio"
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
"name": "github",
|
|
376
|
+
"command": "npx",
|
|
377
|
+
"args": ["-y", "@modelcontextprotocol/server-github"],
|
|
378
|
+
"env": {
|
|
379
|
+
"GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_your_token"
|
|
380
|
+
},
|
|
381
|
+
"transport": "stdio"
|
|
382
|
+
}
|
|
383
|
+
]
|
|
384
|
+
}
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### Поля конфигурации MCP-сервера
|
|
388
|
+
|
|
389
|
+
| Поле | Тип | Обязательное | Описание |
|
|
390
|
+
|------|-----|:---:|----------|
|
|
391
|
+
| `name` | string | ✅ | Уникальное имя сервера |
|
|
392
|
+
| `command` | string | ✅ | Команда запуска процесса |
|
|
393
|
+
| `args` | string[] | — | Аргументы команды (по умолчанию `[]`) |
|
|
394
|
+
| `env` | object | — | Переменные окружения для процесса |
|
|
395
|
+
| `transport` | string | — | Транспорт: `"stdio"` (по умолчанию) |
|
|
396
|
+
|
|
397
|
+
### Популярные MCP-серверы
|
|
398
|
+
|
|
399
|
+
| Сервер | Пакет | Назначение |
|
|
400
|
+
|--------|-------|------------|
|
|
401
|
+
| Filesystem | `@modelcontextprotocol/server-filesystem` | Доступ к файловой системе |
|
|
402
|
+
| GitHub | `@modelcontextprotocol/server-github` | Работа с GitHub API |
|
|
403
|
+
| PostgreSQL | `@modelcontextprotocol/server-postgres` | Запросы к PostgreSQL |
|
|
404
|
+
| Brave Search | `@modelcontextprotocol/server-brave-search` | Веб-поиск через Brave |
|
|
405
|
+
| Memory | `@modelcontextprotocol/server-memory` | Память между сессиями |
|
|
406
|
+
| Puppeteer | `@modelcontextprotocol/server-puppeteer` | Управление браузером |
|
|
407
|
+
|
|
408
|
+
### Безопасность
|
|
409
|
+
|
|
410
|
+
- MCP-инструменты наследуют `riskLevel = 'safe'` — требуют разрешения в режиме `ask`
|
|
411
|
+
- Серверы запускаются с переменными окружения из конфига (не из системы)
|
|
412
|
+
- При ошибке подключения сервер пропускается, остальные продолжают работу
|
|
413
|
+
|
|
348
414
|
## 🤖 Агентская система
|
|
349
415
|
|
|
350
416
|
### Auto Mode
|
package/dist/bootstrap/cli.js
CHANGED
|
@@ -90,6 +90,18 @@ var modelsSchema = z.object({
|
|
|
90
90
|
fallbackModel: z.string().default("glm-5.1"),
|
|
91
91
|
maxContextTokens: z.number().default(5e5)
|
|
92
92
|
});
|
|
93
|
+
var mcpServerSchema = z.object({
|
|
94
|
+
/** Unique name for this MCP server */
|
|
95
|
+
name: z.string().min(1),
|
|
96
|
+
/** Command to start the MCP server process */
|
|
97
|
+
command: z.string().min(1),
|
|
98
|
+
/** Arguments passed to the command */
|
|
99
|
+
args: z.array(z.string()).default([]),
|
|
100
|
+
/** Environment variables for the server process */
|
|
101
|
+
env: z.record(z.string()).optional(),
|
|
102
|
+
/** Transport type (currently only stdio supported) */
|
|
103
|
+
transport: z.enum(["stdio"]).default("stdio")
|
|
104
|
+
});
|
|
93
105
|
var appConfigSchema = z.object({
|
|
94
106
|
/** Default provider name to use */
|
|
95
107
|
defaultProvider: z.string().optional(),
|
|
@@ -136,7 +148,9 @@ var appConfigSchema = z.object({
|
|
|
136
148
|
maxHistoryAge: z.number().default(60),
|
|
137
149
|
maxMemorySize: z.number().default(50),
|
|
138
150
|
idleThreshold: z.number().default(3e5)
|
|
139
|
-
}).default({})
|
|
151
|
+
}).default({}),
|
|
152
|
+
/** MCP servers — external tool providers via Model Context Protocol */
|
|
153
|
+
mcpServers: z.array(mcpServerSchema).default([])
|
|
140
154
|
});
|
|
141
155
|
|
|
142
156
|
// src/config/constants.ts
|
|
@@ -1189,12 +1203,22 @@ function zodToJsonSchema(schema) {
|
|
|
1189
1203
|
return result2;
|
|
1190
1204
|
}
|
|
1191
1205
|
if (schema instanceof z2.ZodTuple) {
|
|
1192
|
-
const
|
|
1206
|
+
const itemSchemas = schema.items.map((item) => zodToJsonSchema(item));
|
|
1207
|
+
const allTypes = itemSchemas.map((s) => s.type).filter(Boolean);
|
|
1208
|
+
const uniqueTypes = [...new Set(allTypes)];
|
|
1209
|
+
let mergedItems;
|
|
1210
|
+
if (uniqueTypes.length === 1) {
|
|
1211
|
+
mergedItems = { type: uniqueTypes[0] };
|
|
1212
|
+
} else if (uniqueTypes.length > 1) {
|
|
1213
|
+
mergedItems = { anyOf: uniqueTypes.map((t) => ({ type: t })) };
|
|
1214
|
+
} else {
|
|
1215
|
+
mergedItems = {};
|
|
1216
|
+
}
|
|
1193
1217
|
const result2 = {
|
|
1194
1218
|
type: "array",
|
|
1195
|
-
items,
|
|
1196
|
-
minItems:
|
|
1197
|
-
maxItems:
|
|
1219
|
+
items: mergedItems,
|
|
1220
|
+
minItems: itemSchemas.length,
|
|
1221
|
+
maxItems: itemSchemas.length
|
|
1198
1222
|
};
|
|
1199
1223
|
if (schema.description) result2.description = schema.description;
|
|
1200
1224
|
return result2;
|
|
@@ -6801,6 +6825,312 @@ function buildSystemPrompt() {
|
|
|
6801
6825
|
].join("\n\n");
|
|
6802
6826
|
}
|
|
6803
6827
|
|
|
6828
|
+
// src/mcp/client.ts
|
|
6829
|
+
import { spawn } from "child_process";
|
|
6830
|
+
import { createInterface } from "readline";
|
|
6831
|
+
var REQUEST_TIMEOUT = 3e4;
|
|
6832
|
+
var MCPClient = class {
|
|
6833
|
+
config;
|
|
6834
|
+
process = null;
|
|
6835
|
+
rl = null;
|
|
6836
|
+
connected = false;
|
|
6837
|
+
nextId = 1;
|
|
6838
|
+
pendingRequests = /* @__PURE__ */ new Map();
|
|
6839
|
+
buffer = "";
|
|
6840
|
+
constructor(config) {
|
|
6841
|
+
this.config = config;
|
|
6842
|
+
}
|
|
6843
|
+
async connect() {
|
|
6844
|
+
if (this.connected) return;
|
|
6845
|
+
const env = {
|
|
6846
|
+
...process.env,
|
|
6847
|
+
...this.config.env
|
|
6848
|
+
};
|
|
6849
|
+
this.process = spawn(this.config.command, this.config.args, {
|
|
6850
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
6851
|
+
env
|
|
6852
|
+
});
|
|
6853
|
+
this.process.on("error", (err) => {
|
|
6854
|
+
this.cleanup();
|
|
6855
|
+
throw err;
|
|
6856
|
+
});
|
|
6857
|
+
this.process.on("exit", () => {
|
|
6858
|
+
this.cleanup();
|
|
6859
|
+
});
|
|
6860
|
+
if (!this.process.stdout) {
|
|
6861
|
+
throw new Error("MCP server stdout is not available");
|
|
6862
|
+
}
|
|
6863
|
+
this.rl = createInterface({ input: this.process.stdout });
|
|
6864
|
+
this.rl.on("line", (line) => {
|
|
6865
|
+
this.handleLine(line);
|
|
6866
|
+
});
|
|
6867
|
+
if (this.process.stderr) {
|
|
6868
|
+
this.process.stderr.on("data", () => {
|
|
6869
|
+
});
|
|
6870
|
+
}
|
|
6871
|
+
await this.sendRequest("initialize", {
|
|
6872
|
+
protocolVersion: "2024-11-05",
|
|
6873
|
+
capabilities: {},
|
|
6874
|
+
clientInfo: { name: "cliskill", version: "1.0.0" }
|
|
6875
|
+
});
|
|
6876
|
+
this.sendNotification("notifications/initialized", {});
|
|
6877
|
+
this.connected = true;
|
|
6878
|
+
}
|
|
6879
|
+
async disconnect() {
|
|
6880
|
+
if (!this.process) return;
|
|
6881
|
+
for (const [, pending] of this.pendingRequests) {
|
|
6882
|
+
clearTimeout(pending.timer);
|
|
6883
|
+
pending.reject(new Error("Connection closed"));
|
|
6884
|
+
}
|
|
6885
|
+
this.pendingRequests.clear();
|
|
6886
|
+
this.process.kill("SIGTERM");
|
|
6887
|
+
this.cleanup();
|
|
6888
|
+
}
|
|
6889
|
+
async listTools() {
|
|
6890
|
+
const response = await this.sendRequest("tools/list", {});
|
|
6891
|
+
const result = response.result;
|
|
6892
|
+
return result?.tools ?? [];
|
|
6893
|
+
}
|
|
6894
|
+
async callTool(name, args) {
|
|
6895
|
+
const response = await this.sendRequest("tools/call", { name, arguments: args });
|
|
6896
|
+
return response.result;
|
|
6897
|
+
}
|
|
6898
|
+
async listResources() {
|
|
6899
|
+
const response = await this.sendRequest("resources/list", {});
|
|
6900
|
+
const result = response.result;
|
|
6901
|
+
return result?.resources ?? [];
|
|
6902
|
+
}
|
|
6903
|
+
async readResource(uri) {
|
|
6904
|
+
const response = await this.sendRequest("resources/read", { uri });
|
|
6905
|
+
return response.result;
|
|
6906
|
+
}
|
|
6907
|
+
async listPrompts() {
|
|
6908
|
+
const response = await this.sendRequest("prompts/list", {});
|
|
6909
|
+
const result = response.result;
|
|
6910
|
+
return result?.prompts ?? [];
|
|
6911
|
+
}
|
|
6912
|
+
isConnected() {
|
|
6913
|
+
return this.connected;
|
|
6914
|
+
}
|
|
6915
|
+
sendRequest(method, params) {
|
|
6916
|
+
return new Promise((resolve9, reject) => {
|
|
6917
|
+
if (!this.process?.stdin) {
|
|
6918
|
+
reject(new Error("MCP server not connected"));
|
|
6919
|
+
return;
|
|
6920
|
+
}
|
|
6921
|
+
const id = this.nextId++;
|
|
6922
|
+
const request = { jsonrpc: "2.0", id, method, params };
|
|
6923
|
+
const timer = setTimeout(() => {
|
|
6924
|
+
this.pendingRequests.delete(id);
|
|
6925
|
+
reject(new Error(`Request timeout: ${method} (id=${id})`));
|
|
6926
|
+
}, REQUEST_TIMEOUT);
|
|
6927
|
+
this.pendingRequests.set(id, { resolve: resolve9, reject, timer });
|
|
6928
|
+
const data = JSON.stringify(request) + "\n";
|
|
6929
|
+
this.process.stdin.write(data, (err) => {
|
|
6930
|
+
if (err) {
|
|
6931
|
+
clearTimeout(timer);
|
|
6932
|
+
this.pendingRequests.delete(id);
|
|
6933
|
+
reject(err);
|
|
6934
|
+
}
|
|
6935
|
+
});
|
|
6936
|
+
});
|
|
6937
|
+
}
|
|
6938
|
+
sendNotification(method, params) {
|
|
6939
|
+
if (!this.process?.stdin) return;
|
|
6940
|
+
const notification = { jsonrpc: "2.0", method, params };
|
|
6941
|
+
const data = JSON.stringify(notification) + "\n";
|
|
6942
|
+
this.process.stdin.write(data);
|
|
6943
|
+
}
|
|
6944
|
+
handleLine(line) {
|
|
6945
|
+
this.buffer += line;
|
|
6946
|
+
let response;
|
|
6947
|
+
try {
|
|
6948
|
+
response = JSON.parse(this.buffer);
|
|
6949
|
+
} catch {
|
|
6950
|
+
return;
|
|
6951
|
+
} finally {
|
|
6952
|
+
this.buffer = "";
|
|
6953
|
+
}
|
|
6954
|
+
if (response.id !== void 0 && response.id !== null) {
|
|
6955
|
+
const pending = this.pendingRequests.get(response.id);
|
|
6956
|
+
if (pending) {
|
|
6957
|
+
clearTimeout(pending.timer);
|
|
6958
|
+
this.pendingRequests.delete(response.id);
|
|
6959
|
+
pending.resolve(response);
|
|
6960
|
+
}
|
|
6961
|
+
}
|
|
6962
|
+
}
|
|
6963
|
+
cleanup() {
|
|
6964
|
+
this.connected = false;
|
|
6965
|
+
this.rl?.close();
|
|
6966
|
+
this.rl = null;
|
|
6967
|
+
this.process = null;
|
|
6968
|
+
this.buffer = "";
|
|
6969
|
+
}
|
|
6970
|
+
};
|
|
6971
|
+
|
|
6972
|
+
// src/mcp/manager.ts
|
|
6973
|
+
var MCPConnectionManager = class {
|
|
6974
|
+
clients = /* @__PURE__ */ new Map();
|
|
6975
|
+
async addServer(config) {
|
|
6976
|
+
const client = new MCPClient(config);
|
|
6977
|
+
await client.connect();
|
|
6978
|
+
this.clients.set(config.name, client);
|
|
6979
|
+
}
|
|
6980
|
+
async removeServer(name) {
|
|
6981
|
+
const client = this.clients.get(name);
|
|
6982
|
+
if (client) {
|
|
6983
|
+
await client.disconnect();
|
|
6984
|
+
this.clients.delete(name);
|
|
6985
|
+
}
|
|
6986
|
+
}
|
|
6987
|
+
getConnectedServers() {
|
|
6988
|
+
return Array.from(this.clients.entries()).filter(([, client]) => client.isConnected()).map(([name]) => name);
|
|
6989
|
+
}
|
|
6990
|
+
async getAllTools() {
|
|
6991
|
+
const allTools = [];
|
|
6992
|
+
for (const [, client] of this.clients) {
|
|
6993
|
+
if (!client.isConnected()) continue;
|
|
6994
|
+
try {
|
|
6995
|
+
const tools = await client.listTools();
|
|
6996
|
+
allTools.push(...tools);
|
|
6997
|
+
} catch {
|
|
6998
|
+
}
|
|
6999
|
+
}
|
|
7000
|
+
return allTools;
|
|
7001
|
+
}
|
|
7002
|
+
async callTool(serverName, toolName, args) {
|
|
7003
|
+
const client = this.clients.get(serverName);
|
|
7004
|
+
if (!client) {
|
|
7005
|
+
throw new Error(`MCP server "${serverName}" not found`);
|
|
7006
|
+
}
|
|
7007
|
+
if (!client.isConnected()) {
|
|
7008
|
+
throw new Error(`MCP server "${serverName}" is not connected`);
|
|
7009
|
+
}
|
|
7010
|
+
return client.callTool(toolName, args);
|
|
7011
|
+
}
|
|
7012
|
+
async getToolsForServer(serverName) {
|
|
7013
|
+
const client = this.clients.get(serverName);
|
|
7014
|
+
if (!client || !client.isConnected()) {
|
|
7015
|
+
return [];
|
|
7016
|
+
}
|
|
7017
|
+
return client.listTools();
|
|
7018
|
+
}
|
|
7019
|
+
async disconnectAll() {
|
|
7020
|
+
for (const [, client] of this.clients) {
|
|
7021
|
+
try {
|
|
7022
|
+
await client.disconnect();
|
|
7023
|
+
} catch {
|
|
7024
|
+
}
|
|
7025
|
+
}
|
|
7026
|
+
this.clients.clear();
|
|
7027
|
+
}
|
|
7028
|
+
};
|
|
7029
|
+
|
|
7030
|
+
// src/mcp/mcp-tool-adapter.ts
|
|
7031
|
+
import { z as z20 } from "zod";
|
|
7032
|
+
var MCPToolAdapter = class {
|
|
7033
|
+
name;
|
|
7034
|
+
description;
|
|
7035
|
+
inputSchema;
|
|
7036
|
+
riskLevel = "safe";
|
|
7037
|
+
concurrencySafe = true;
|
|
7038
|
+
readOnly = true;
|
|
7039
|
+
serverName;
|
|
7040
|
+
mcpManager;
|
|
7041
|
+
rawInputSchema;
|
|
7042
|
+
constructor(serverName, toolName, description, inputSchema, mcpManager) {
|
|
7043
|
+
this.name = `mcp_${serverName}_${toolName}`;
|
|
7044
|
+
this.description = description;
|
|
7045
|
+
this.serverName = serverName;
|
|
7046
|
+
this.mcpManager = mcpManager;
|
|
7047
|
+
this.rawInputSchema = inputSchema;
|
|
7048
|
+
this.inputSchema = this.buildZodSchema(inputSchema);
|
|
7049
|
+
}
|
|
7050
|
+
async execute(input, context) {
|
|
7051
|
+
const allowed = await context.checkPermission(this.name, JSON.stringify(input));
|
|
7052
|
+
if (!allowed) {
|
|
7053
|
+
return `Error: Permission denied for MCP tool: ${this.name}`;
|
|
7054
|
+
}
|
|
7055
|
+
try {
|
|
7056
|
+
const result = await this.mcpManager.callTool(this.serverName, this.getOriginalName(), input);
|
|
7057
|
+
return typeof result === "string" ? result : JSON.stringify(result, null, 2);
|
|
7058
|
+
} catch (err) {
|
|
7059
|
+
return `Error calling MCP tool ${this.name}: ${err.message}`;
|
|
7060
|
+
}
|
|
7061
|
+
}
|
|
7062
|
+
toToolDefinition() {
|
|
7063
|
+
return {
|
|
7064
|
+
name: this.name,
|
|
7065
|
+
description: this.description,
|
|
7066
|
+
inputSchema: this.rawInputSchema
|
|
7067
|
+
};
|
|
7068
|
+
}
|
|
7069
|
+
getOriginalName() {
|
|
7070
|
+
const parts = this.name.split("_");
|
|
7071
|
+
return parts.slice(2).join("_");
|
|
7072
|
+
}
|
|
7073
|
+
getServerName() {
|
|
7074
|
+
return this.serverName;
|
|
7075
|
+
}
|
|
7076
|
+
buildZodSchema(jsonSchema) {
|
|
7077
|
+
const properties = jsonSchema.properties ?? {};
|
|
7078
|
+
const required = new Set(jsonSchema.required ?? []);
|
|
7079
|
+
const shape = {};
|
|
7080
|
+
for (const [key, propSchema] of Object.entries(properties)) {
|
|
7081
|
+
const zodType = this.jsonSchemaPropertyToZod(propSchema);
|
|
7082
|
+
shape[key] = required.has(key) ? zodType : zodType.optional();
|
|
7083
|
+
}
|
|
7084
|
+
return z20.object(shape);
|
|
7085
|
+
}
|
|
7086
|
+
jsonSchemaPropertyToZod(prop) {
|
|
7087
|
+
const type = prop.type;
|
|
7088
|
+
switch (type) {
|
|
7089
|
+
case "string":
|
|
7090
|
+
if (prop.enum) return z20.enum(prop.enum);
|
|
7091
|
+
return z20.string();
|
|
7092
|
+
case "number":
|
|
7093
|
+
case "integer":
|
|
7094
|
+
return z20.number();
|
|
7095
|
+
case "boolean":
|
|
7096
|
+
return z20.boolean();
|
|
7097
|
+
case "array":
|
|
7098
|
+
if (prop.items && typeof prop.items === "object") {
|
|
7099
|
+
return z20.array(this.jsonSchemaPropertyToZod(prop.items));
|
|
7100
|
+
}
|
|
7101
|
+
return z20.array(z20.unknown());
|
|
7102
|
+
case "object":
|
|
7103
|
+
if (prop.properties && typeof prop.properties === "object") {
|
|
7104
|
+
return this.buildZodSchema(prop);
|
|
7105
|
+
}
|
|
7106
|
+
return z20.record(z20.unknown());
|
|
7107
|
+
default:
|
|
7108
|
+
return z20.unknown();
|
|
7109
|
+
}
|
|
7110
|
+
}
|
|
7111
|
+
};
|
|
7112
|
+
async function registerMCPTools(mcpManager, registerFn) {
|
|
7113
|
+
const registered = [];
|
|
7114
|
+
for (const serverName of mcpManager.getConnectedServers()) {
|
|
7115
|
+
try {
|
|
7116
|
+
const tools = await mcpManager.getToolsForServer(serverName);
|
|
7117
|
+
for (const tool of tools) {
|
|
7118
|
+
const adapter = new MCPToolAdapter(
|
|
7119
|
+
serverName,
|
|
7120
|
+
tool.name,
|
|
7121
|
+
tool.description ?? `MCP tool: ${tool.name}`,
|
|
7122
|
+
tool.inputSchema,
|
|
7123
|
+
mcpManager
|
|
7124
|
+
);
|
|
7125
|
+
registerFn(adapter);
|
|
7126
|
+
registered.push(adapter.name);
|
|
7127
|
+
}
|
|
7128
|
+
} catch {
|
|
7129
|
+
}
|
|
7130
|
+
}
|
|
7131
|
+
return registered;
|
|
7132
|
+
}
|
|
7133
|
+
|
|
6804
7134
|
// src/ui/repl.ts
|
|
6805
7135
|
var SessionSaver = class {
|
|
6806
7136
|
filePath;
|
|
@@ -6847,6 +7177,36 @@ function buildModelRouter(adapterRegistry, config) {
|
|
|
6847
7177
|
defaultModel: config.models.defaultModel
|
|
6848
7178
|
});
|
|
6849
7179
|
}
|
|
7180
|
+
async function connectMcpServers(config, toolRegistry) {
|
|
7181
|
+
if (config.mcpServers.length === 0) return null;
|
|
7182
|
+
const mcpManager = new MCPConnectionManager();
|
|
7183
|
+
let connectedCount = 0;
|
|
7184
|
+
for (const serverConfig of config.mcpServers) {
|
|
7185
|
+
try {
|
|
7186
|
+
await mcpManager.addServer({
|
|
7187
|
+
name: serverConfig.name,
|
|
7188
|
+
command: serverConfig.command,
|
|
7189
|
+
args: serverConfig.args,
|
|
7190
|
+
env: serverConfig.env,
|
|
7191
|
+
transport: serverConfig.transport
|
|
7192
|
+
});
|
|
7193
|
+
connectedCount++;
|
|
7194
|
+
} catch (err) {
|
|
7195
|
+
console.error(`MCP server "${serverConfig.name}" connection failed: ${err.message}`);
|
|
7196
|
+
}
|
|
7197
|
+
}
|
|
7198
|
+
if (connectedCount === 0) return mcpManager;
|
|
7199
|
+
const registeredTools = await registerMCPTools(mcpManager, (tool) => {
|
|
7200
|
+
try {
|
|
7201
|
+
toolRegistry.register(tool);
|
|
7202
|
+
} catch {
|
|
7203
|
+
}
|
|
7204
|
+
});
|
|
7205
|
+
if (registeredTools.length > 0) {
|
|
7206
|
+
console.log(` MCP: ${connectedCount} server(s) connected, ${registeredTools.length} tool(s) loaded`);
|
|
7207
|
+
}
|
|
7208
|
+
return mcpManager;
|
|
7209
|
+
}
|
|
6850
7210
|
async function runTuiRepl(config) {
|
|
6851
7211
|
const adapterRegistry = new AdapterRegistry();
|
|
6852
7212
|
for (const provider of config.providers) {
|
|
@@ -6859,6 +7219,7 @@ async function runTuiRepl(config) {
|
|
|
6859
7219
|
const adapter = config.defaultProvider ? adapterRegistry.get(config.defaultProvider) : adapterRegistry.getAll()[0];
|
|
6860
7220
|
const modelRouter = buildModelRouter(adapterRegistry, config);
|
|
6861
7221
|
const toolRegistry = createDefaultToolRegistry(modelRouter);
|
|
7222
|
+
const mcpManager = await connectMcpServers(config, toolRegistry);
|
|
6862
7223
|
ensureDataDir();
|
|
6863
7224
|
const sessionSaver = new SessionSaver();
|
|
6864
7225
|
await sessionSaver.init();
|
|
@@ -6953,13 +7314,14 @@ async function runBasicRepl(config) {
|
|
|
6953
7314
|
`);
|
|
6954
7315
|
}
|
|
6955
7316
|
const toolRegistry = createDefaultToolRegistry(modelRouter);
|
|
7317
|
+
await connectMcpServers(config, toolRegistry);
|
|
6956
7318
|
const abortController = new AbortController();
|
|
6957
7319
|
ensureDataDir();
|
|
6958
7320
|
const sessionSaver = new SessionSaver();
|
|
6959
7321
|
await sessionSaver.init();
|
|
6960
7322
|
let sessionMessages = [];
|
|
6961
|
-
const { createInterface } = await import("readline");
|
|
6962
|
-
const rl =
|
|
7323
|
+
const { createInterface: createInterface2 } = await import("readline");
|
|
7324
|
+
const rl = createInterface2({
|
|
6963
7325
|
input: process.stdin,
|
|
6964
7326
|
output: process.stdout,
|
|
6965
7327
|
prompt: "> "
|
|
@@ -10028,6 +10390,8 @@ export {
|
|
|
10028
10390
|
renderInkApp,
|
|
10029
10391
|
formatAnsiMessage,
|
|
10030
10392
|
MessageList,
|
|
10393
|
+
MCPClient,
|
|
10394
|
+
MCPConnectionManager,
|
|
10031
10395
|
runCli
|
|
10032
10396
|
};
|
|
10033
|
-
//# sourceMappingURL=chunk-
|
|
10397
|
+
//# sourceMappingURL=chunk-ETGUAK34.js.map
|