@fractalizer/mcp-cli 0.3.18 → 1.0.1
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 +158 -266
- package/dist/commands/connect.command.d.ts +18 -15
- package/dist/commands/connect.command.d.ts.map +1 -1
- package/dist/commands/connect.command.js +66 -40
- package/dist/commands/connect.command.js.map +1 -1
- package/dist/commands/disconnect.command.d.ts +5 -17
- package/dist/commands/disconnect.command.d.ts.map +1 -1
- package/dist/commands/disconnect.command.js +4 -15
- package/dist/commands/disconnect.command.js.map +1 -1
- package/dist/commands/doctor.command.d.ts +34 -0
- package/dist/commands/doctor.command.d.ts.map +1 -0
- package/dist/commands/doctor.command.js +321 -0
- package/dist/commands/doctor.command.js.map +1 -0
- package/dist/commands/index.d.ts +1 -0
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +2 -0
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/list.command.d.ts +4 -9
- package/dist/commands/list.command.d.ts.map +1 -1
- package/dist/commands/list.command.js +1 -5
- package/dist/commands/list.command.js.map +1 -1
- package/dist/commands/status.command.d.ts +6 -13
- package/dist/commands/status.command.d.ts.map +1 -1
- package/dist/commands/status.command.js +18 -12
- package/dist/commands/status.command.js.map +1 -1
- package/dist/commands/validate.command.d.ts +6 -11
- package/dist/commands/validate.command.d.ts.map +1 -1
- package/dist/commands/validate.command.js +15 -19
- package/dist/commands/validate.command.js.map +1 -1
- package/dist/connectors/base/base-connector.d.ts +31 -55
- package/dist/connectors/base/base-connector.d.ts.map +1 -1
- package/dist/connectors/base/base-connector.js +71 -57
- package/dist/connectors/base/base-connector.js.map +1 -1
- package/dist/connectors/base/configurable-connector.d.ts +89 -24
- package/dist/connectors/base/configurable-connector.d.ts.map +1 -1
- package/dist/connectors/base/configurable-connector.js +266 -23
- package/dist/connectors/base/configurable-connector.js.map +1 -1
- package/dist/connectors/base/connector.interface.d.ts +29 -20
- package/dist/connectors/base/connector.interface.d.ts.map +1 -1
- package/dist/connectors/base/index.d.ts +0 -1
- package/dist/connectors/base/index.d.ts.map +1 -1
- package/dist/connectors/base/index.js +0 -1
- package/dist/connectors/base/index.js.map +1 -1
- package/dist/connectors/claude-code/claude-code.connector.d.ts +171 -21
- package/dist/connectors/claude-code/claude-code.connector.d.ts.map +1 -1
- package/dist/connectors/claude-code/claude-code.connector.js +368 -43
- package/dist/connectors/claude-code/claude-code.connector.js.map +1 -1
- package/dist/connectors/connector-factory.d.ts +15 -15
- package/dist/connectors/connector-factory.d.ts.map +1 -1
- package/dist/connectors/connector-factory.js +61 -18
- package/dist/connectors/connector-factory.js.map +1 -1
- package/dist/connectors/index.d.ts +0 -4
- package/dist/connectors/index.d.ts.map +1 -1
- package/dist/connectors/index.js +2 -8
- package/dist/connectors/index.js.map +1 -1
- package/dist/connectors/registry.d.ts +20 -27
- package/dist/connectors/registry.d.ts.map +1 -1
- package/dist/connectors/registry.js +34 -34
- package/dist/connectors/registry.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/{base.types.d.ts → client.types.d.ts} +37 -30
- package/dist/types/client.types.d.ts.map +1 -0
- package/dist/types/client.types.js +6 -0
- package/dist/types/client.types.js.map +1 -0
- package/dist/types/doctor.types.d.ts +91 -0
- package/dist/types/doctor.types.d.ts.map +1 -0
- package/dist/types/doctor.types.js +12 -0
- package/dist/types/doctor.types.js.map +1 -0
- package/dist/types/launch.types.d.ts +59 -0
- package/dist/types/launch.types.d.ts.map +1 -0
- package/dist/types/launch.types.js +6 -0
- package/dist/types/launch.types.js.map +1 -0
- package/dist/types.d.ts +23 -14
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +9 -2
- package/dist/types.js.map +1 -1
- package/dist/utils/command-executor.d.ts +39 -3
- package/dist/utils/command-executor.d.ts.map +1 -1
- package/dist/utils/command-executor.js +95 -8
- package/dist/utils/command-executor.js.map +1 -1
- package/dist/utils/config-manager.d.ts +25 -42
- package/dist/utils/config-manager.d.ts.map +1 -1
- package/dist/utils/config-manager.js +21 -49
- package/dist/utils/config-manager.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/interactive-prompter.d.ts +16 -64
- package/dist/utils/interactive-prompter.d.ts.map +1 -1
- package/dist/utils/interactive-prompter.js +12 -65
- package/dist/utils/interactive-prompter.js.map +1 -1
- package/dist/utils/launch-spec-helpers.d.ts +38 -0
- package/dist/utils/launch-spec-helpers.d.ts.map +1 -0
- package/dist/utils/launch-spec-helpers.js +131 -0
- package/dist/utils/launch-spec-helpers.js.map +1 -0
- package/package.json +2 -2
- package/dist/connectors/base/file-based-connector.d.ts +0 -97
- package/dist/connectors/base/file-based-connector.d.ts.map +0 -1
- package/dist/connectors/base/file-based-connector.js +0 -185
- package/dist/connectors/base/file-based-connector.js.map +0 -1
- package/dist/connectors/claude-desktop/claude-desktop.connector.d.ts +0 -38
- package/dist/connectors/claude-desktop/claude-desktop.connector.d.ts.map +0 -1
- package/dist/connectors/claude-desktop/claude-desktop.connector.js +0 -68
- package/dist/connectors/claude-desktop/claude-desktop.connector.js.map +0 -1
- package/dist/connectors/codex/codex.connector.d.ts +0 -51
- package/dist/connectors/codex/codex.connector.d.ts.map +0 -1
- package/dist/connectors/codex/codex.connector.js +0 -76
- package/dist/connectors/codex/codex.connector.js.map +0 -1
- package/dist/connectors/gemini/gemini.connector.d.ts +0 -41
- package/dist/connectors/gemini/gemini.connector.d.ts.map +0 -1
- package/dist/connectors/gemini/gemini.connector.js +0 -61
- package/dist/connectors/gemini/gemini.connector.js.map +0 -1
- package/dist/connectors/qwen/qwen.connector.d.ts +0 -41
- package/dist/connectors/qwen/qwen.connector.d.ts.map +0 -1
- package/dist/connectors/qwen/qwen.connector.js +0 -61
- package/dist/connectors/qwen/qwen.connector.js.map +0 -1
- package/dist/types/base.types.d.ts.map +0 -1
- package/dist/types/base.types.js +0 -6
- package/dist/types/base.types.js.map +0 -1
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Конфигурируемый file-based коннектор
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Универсальная реализация для всех клиентов, хранящих MCP-конфигурацию в JSON/TOML
|
|
5
|
+
* файлах (Claude Desktop, Gemini, Qwen, Codex и т.п.). Параметризуется через
|
|
6
|
+
* {@link ConnectorClientConfig}, передаваемый в конструктор — без наследования.
|
|
6
7
|
*/
|
|
7
|
-
import {
|
|
8
|
-
import type {
|
|
8
|
+
import { BaseConnector } from './base-connector.js';
|
|
9
|
+
import type { ConnectionStatus, MCPClientInfo } from '../../types/client.types.js';
|
|
10
|
+
import type { ServerLaunchSpec } from '../../types/launch.types.js';
|
|
9
11
|
/**
|
|
10
|
-
*
|
|
12
|
+
* Формат конфигурационного файла клиента
|
|
13
|
+
*/
|
|
14
|
+
export type ConfigFormat = 'json' | 'toml';
|
|
15
|
+
/**
|
|
16
|
+
* Конфигурация клиента для {@link ConfigurableConnector}.
|
|
17
|
+
*
|
|
18
|
+
* `configPath` может быть строкой или функцией: функция позволяет ленивое
|
|
19
|
+
* platform-aware вычисление пути (например, для Claude Desktop, где путь
|
|
20
|
+
* различается на darwin/linux/win32).
|
|
11
21
|
*/
|
|
12
22
|
export interface ConnectorClientConfig {
|
|
13
23
|
/** Уникальное имя клиента (например, 'gemini', 'qwen', 'codex') */
|
|
@@ -16,8 +26,8 @@ export interface ConnectorClientConfig {
|
|
|
16
26
|
displayName: string;
|
|
17
27
|
/** Описание клиента */
|
|
18
28
|
description: string;
|
|
19
|
-
/** Путь к конфигурационному файлу */
|
|
20
|
-
configPath: string;
|
|
29
|
+
/** Путь к конфигурационному файлу или функция, возвращающая такой путь */
|
|
30
|
+
configPath: string | (() => string);
|
|
21
31
|
/** Поддерживаемые платформы */
|
|
22
32
|
platforms: Array<'darwin' | 'linux' | 'win32'>;
|
|
23
33
|
/** Команда проверки установки (опционально) */
|
|
@@ -28,41 +38,96 @@ export interface ConnectorClientConfig {
|
|
|
28
38
|
configFormat?: ConfigFormat;
|
|
29
39
|
}
|
|
30
40
|
/**
|
|
31
|
-
* Конфигурируемый file-based
|
|
41
|
+
* Конфигурируемый file-based коннектор.
|
|
32
42
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
43
|
+
* Поддерживает JSON и TOML форматы, произвольные ключи для серверов
|
|
44
|
+
* (`mcpServers`, `mcp_servers`). Запись/чтение/удаление выполняются напрямую
|
|
45
|
+
* над `{ command, args, env }` из {@link ServerLaunchSpec}; framework не
|
|
46
|
+
* знает доменных полей.
|
|
35
47
|
*
|
|
36
48
|
* @example
|
|
37
49
|
* ```typescript
|
|
38
|
-
* const
|
|
50
|
+
* const connector = new ConfigurableConnector(
|
|
39
51
|
* 'mcp-server-yandex-tracker',
|
|
40
|
-
* 'dist/yandex-tracker.bundle.cjs',
|
|
41
52
|
* {
|
|
42
53
|
* name: 'gemini',
|
|
43
54
|
* displayName: 'Gemini CLI',
|
|
44
|
-
* description: 'Gemini CLI для
|
|
55
|
+
* description: 'Gemini CLI для MCP',
|
|
45
56
|
* configPath: path.join(os.homedir(), '.gemini/settings.json'),
|
|
46
57
|
* platforms: ['darwin', 'linux', 'win32'],
|
|
47
58
|
* }
|
|
48
59
|
* );
|
|
60
|
+
* await connector.connect({ command: 'node', args: ['/abs/path.cjs'], env: {} });
|
|
49
61
|
* ```
|
|
50
62
|
*/
|
|
51
|
-
export declare class ConfigurableConnector
|
|
63
|
+
export declare class ConfigurableConnector extends BaseConnector {
|
|
52
64
|
private readonly _serverName;
|
|
53
|
-
private readonly _entryPoint;
|
|
54
65
|
private readonly _clientConfig;
|
|
55
66
|
/**
|
|
56
|
-
* @param serverName - Имя MCP сервера для записи в конфигурацию
|
|
57
|
-
* @param
|
|
58
|
-
* @param clientConfig - Конфигурация клиента
|
|
67
|
+
* @param serverName - Имя MCP сервера для записи в конфигурацию клиента
|
|
68
|
+
* @param clientConfig - Конфигурация клиента (имя, путь, формат и т.п.)
|
|
59
69
|
*/
|
|
60
|
-
constructor(serverName: string,
|
|
70
|
+
constructor(serverName: string, clientConfig: ConnectorClientConfig);
|
|
61
71
|
getClientInfo(): MCPClientInfo;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
72
|
+
/**
|
|
73
|
+
* Проверить, установлен ли клиент.
|
|
74
|
+
*
|
|
75
|
+
* Если в {@link ConnectorClientConfig.checkCommand} задана команда — пробуем
|
|
76
|
+
* выполнить её с таймаутом {@link CHECK_COMMAND_TIMEOUT_MS}. Успех (exit 0) →
|
|
77
|
+
* клиент установлен. Любая ошибка/таймаут → fallback на dir-check.
|
|
78
|
+
*
|
|
79
|
+
* Если `checkCommand` не задана — единственная проверка: наличие директории
|
|
80
|
+
* конфига.
|
|
81
|
+
*
|
|
82
|
+
* Поведение fallback мотивировано тем, что директория конфига может остаться
|
|
83
|
+
* после удаления клиента (false positive); checkCommand даёт более надёжный
|
|
84
|
+
* сигнал, но при его недоступности dir-check всё ещё лучше чем ничего.
|
|
85
|
+
*/
|
|
86
|
+
isInstalled(): Promise<boolean>;
|
|
87
|
+
/**
|
|
88
|
+
* Запустить `checkCommand` с таймаутом. Команда парсится по whitespace:
|
|
89
|
+
* первый токен — бинарь, остальное — аргументы. Выполняется через
|
|
90
|
+
* {@link CommandExecutor.execFile} (без shell-интерпретации).
|
|
91
|
+
*
|
|
92
|
+
* @returns `true` если команда успешно выполнилась (exit 0); `false` иначе.
|
|
93
|
+
*/
|
|
94
|
+
private tryCheckCommand;
|
|
95
|
+
/**
|
|
96
|
+
* Получить статус подключения. Дополнительно к наличию записи в конфиге проверяет
|
|
97
|
+
* существование `command` на диске (для абсолютных путей и `node` со скриптом
|
|
98
|
+
* в args).
|
|
99
|
+
*/
|
|
100
|
+
getStatus(): Promise<ConnectionStatus>;
|
|
101
|
+
/**
|
|
102
|
+
* Подключить MCP сервер: записать spec в файл конфигурации клиента.
|
|
103
|
+
*/
|
|
104
|
+
connect(spec: ServerLaunchSpec): Promise<void>;
|
|
105
|
+
/**
|
|
106
|
+
* Отключить MCP сервер: удалить запись из конфигурации.
|
|
107
|
+
*/
|
|
108
|
+
disconnect(): Promise<void>;
|
|
109
|
+
/**
|
|
110
|
+
* Прочитать spec, записанную в конфиге клиента.
|
|
111
|
+
*
|
|
112
|
+
* @returns spec, если сервер присутствует в конфиге; `null` иначе.
|
|
113
|
+
*/
|
|
114
|
+
getLaunchSpec(): Promise<ServerLaunchSpec | null>;
|
|
115
|
+
private resolveConfigPath;
|
|
116
|
+
private getServerKey;
|
|
117
|
+
private getConfigFormat;
|
|
118
|
+
private readConfig;
|
|
119
|
+
private writeConfig;
|
|
120
|
+
private createDefaultConfig;
|
|
121
|
+
/**
|
|
122
|
+
* Проверка существования команды на диске. Логика выровнена с
|
|
123
|
+
* {@link BaseConnector.validateLaunchSpec}:
|
|
124
|
+
* - абсолютный путь команды → `fs.access`;
|
|
125
|
+
* - `node` + первый абсолютный путь в args → `fs.access`;
|
|
126
|
+
* - всё остальное (`npx`, `pipx`, относительная команда из PATH) → считаем OK,
|
|
127
|
+
* не пытаемся резолвить PATH.
|
|
128
|
+
*/
|
|
129
|
+
private commandExistsOnDisk;
|
|
130
|
+
private describeCommand;
|
|
131
|
+
private pathExists;
|
|
67
132
|
}
|
|
68
133
|
//# sourceMappingURL=configurable-connector.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configurable-connector.d.ts","sourceRoot":"","sources":["../../../src/connectors/base/configurable-connector.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"configurable-connector.d.ts","sourceRoot":"","sources":["../../../src/connectors/base/configurable-connector.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACnF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAkCpE;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,CAAC;AAE3C;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,WAAW,EAAE,MAAM,CAAC;IACpB,uBAAuB;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,0EAA0E;IAC1E,UAAU,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAC;IACpC,+BAA+B;IAC/B,SAAS,EAAE,KAAK,CAAC,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC,CAAC;IAC/C,+CAA+C;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2CAA2C;IAC3C,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AASD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,qBAAa,qBAAsB,SAAQ,aAAa;IACtD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAwB;IAEtD;;;OAGG;gBACS,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,qBAAqB;IAMnE,aAAa,IAAI,aAAa;IAc9B;;;;;;;;;;;;;OAaG;IACG,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAcrC;;;;;;OAMG;IACH,OAAO,CAAC,eAAe;IAavB;;;;OAIG;IACG,SAAS,IAAI,OAAO,CAAC,gBAAgB,CAAC;IA4C5C;;OAEG;IACG,OAAO,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IA+BpD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBjC;;;;OAIG;IACG,aAAa,IAAI,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAgCvD,OAAO,CAAC,iBAAiB;IAKzB,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,eAAe;YAIT,UAAU;YAQV,WAAW;IAUzB,OAAO,CAAC,mBAAmB;IAI3B;;;;;;;OAOG;YACW,mBAAmB;IAcjC,OAAO,CAAC,eAAe;YAST,UAAU;CAQzB"}
|
|
@@ -1,44 +1,62 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Конфигурируемый file-based коннектор
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Универсальная реализация для всех клиентов, хранящих MCP-конфигурацию в JSON/TOML
|
|
5
|
+
* файлах (Claude Desktop, Gemini, Qwen, Codex и т.п.). Параметризуется через
|
|
6
|
+
* {@link ConnectorClientConfig}, передаваемый в конструктор — без наследования.
|
|
6
7
|
*/
|
|
7
|
-
import
|
|
8
|
+
import * as fs from 'node:fs/promises';
|
|
9
|
+
import * as path from 'node:path';
|
|
10
|
+
import { BaseConnector } from './base-connector.js';
|
|
11
|
+
import { CommandExecutor } from '../../utils/command-executor.js';
|
|
12
|
+
import { FileManager } from '../../utils/file-manager.js';
|
|
13
|
+
import { resolveExecutablePath } from '../../utils/launch-spec-helpers.js';
|
|
8
14
|
/**
|
|
9
|
-
*
|
|
15
|
+
* Таймаут для проверки `checkCommand` в {@link ConfigurableConnector.isInstalled}.
|
|
16
|
+
*
|
|
17
|
+
* 2 секунды — компромисс между быстрой проверкой и допуском медленных
|
|
18
|
+
* стартующих CLI (gemini, codex могут грузиться 300-500ms на старте).
|
|
19
|
+
*/
|
|
20
|
+
const CHECK_COMMAND_TIMEOUT_MS = 2000;
|
|
21
|
+
/**
|
|
22
|
+
* Type guard для проверки Error
|
|
23
|
+
*/
|
|
24
|
+
function isError(error) {
|
|
25
|
+
return error instanceof Error;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Конфигурируемый file-based коннектор.
|
|
10
29
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
30
|
+
* Поддерживает JSON и TOML форматы, произвольные ключи для серверов
|
|
31
|
+
* (`mcpServers`, `mcp_servers`). Запись/чтение/удаление выполняются напрямую
|
|
32
|
+
* над `{ command, args, env }` из {@link ServerLaunchSpec}; framework не
|
|
33
|
+
* знает доменных полей.
|
|
13
34
|
*
|
|
14
35
|
* @example
|
|
15
36
|
* ```typescript
|
|
16
|
-
* const
|
|
37
|
+
* const connector = new ConfigurableConnector(
|
|
17
38
|
* 'mcp-server-yandex-tracker',
|
|
18
|
-
* 'dist/yandex-tracker.bundle.cjs',
|
|
19
39
|
* {
|
|
20
40
|
* name: 'gemini',
|
|
21
41
|
* displayName: 'Gemini CLI',
|
|
22
|
-
* description: 'Gemini CLI для
|
|
42
|
+
* description: 'Gemini CLI для MCP',
|
|
23
43
|
* configPath: path.join(os.homedir(), '.gemini/settings.json'),
|
|
24
44
|
* platforms: ['darwin', 'linux', 'win32'],
|
|
25
45
|
* }
|
|
26
46
|
* );
|
|
47
|
+
* await connector.connect({ command: 'node', args: ['/abs/path.cjs'], env: {} });
|
|
27
48
|
* ```
|
|
28
49
|
*/
|
|
29
|
-
export class ConfigurableConnector extends
|
|
50
|
+
export class ConfigurableConnector extends BaseConnector {
|
|
30
51
|
_serverName;
|
|
31
|
-
_entryPoint;
|
|
32
52
|
_clientConfig;
|
|
33
53
|
/**
|
|
34
|
-
* @param serverName - Имя MCP сервера для записи в конфигурацию
|
|
35
|
-
* @param
|
|
36
|
-
* @param clientConfig - Конфигурация клиента
|
|
54
|
+
* @param serverName - Имя MCP сервера для записи в конфигурацию клиента
|
|
55
|
+
* @param clientConfig - Конфигурация клиента (имя, путь, формат и т.п.)
|
|
37
56
|
*/
|
|
38
|
-
constructor(serverName,
|
|
57
|
+
constructor(serverName, clientConfig) {
|
|
39
58
|
super();
|
|
40
59
|
this._serverName = serverName;
|
|
41
|
-
this._entryPoint = entryPoint;
|
|
42
60
|
this._clientConfig = clientConfig;
|
|
43
61
|
}
|
|
44
62
|
getClientInfo() {
|
|
@@ -46,7 +64,7 @@ export class ConfigurableConnector extends FileBasedConnector {
|
|
|
46
64
|
name: this._clientConfig.name,
|
|
47
65
|
displayName: this._clientConfig.displayName,
|
|
48
66
|
description: this._clientConfig.description,
|
|
49
|
-
configPath: this.
|
|
67
|
+
configPath: this.resolveConfigPath(),
|
|
50
68
|
platforms: this._clientConfig.platforms,
|
|
51
69
|
};
|
|
52
70
|
if (this._clientConfig.checkCommand) {
|
|
@@ -54,14 +72,181 @@ export class ConfigurableConnector extends FileBasedConnector {
|
|
|
54
72
|
}
|
|
55
73
|
return info;
|
|
56
74
|
}
|
|
57
|
-
|
|
58
|
-
|
|
75
|
+
/**
|
|
76
|
+
* Проверить, установлен ли клиент.
|
|
77
|
+
*
|
|
78
|
+
* Если в {@link ConnectorClientConfig.checkCommand} задана команда — пробуем
|
|
79
|
+
* выполнить её с таймаутом {@link CHECK_COMMAND_TIMEOUT_MS}. Успех (exit 0) →
|
|
80
|
+
* клиент установлен. Любая ошибка/таймаут → fallback на dir-check.
|
|
81
|
+
*
|
|
82
|
+
* Если `checkCommand` не задана — единственная проверка: наличие директории
|
|
83
|
+
* конфига.
|
|
84
|
+
*
|
|
85
|
+
* Поведение fallback мотивировано тем, что директория конфига может остаться
|
|
86
|
+
* после удаления клиента (false positive); checkCommand даёт более надёжный
|
|
87
|
+
* сигнал, но при его недоступности dir-check всё ещё лучше чем ничего.
|
|
88
|
+
*/
|
|
89
|
+
async isInstalled() {
|
|
90
|
+
const checkCommand = this._clientConfig.checkCommand;
|
|
91
|
+
if (checkCommand && checkCommand.trim().length > 0) {
|
|
92
|
+
const installed = this.tryCheckCommand(checkCommand);
|
|
93
|
+
if (installed) {
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
// Fallback на dir-check (например, бинарь временно недоступен в PATH,
|
|
97
|
+
// но клиент явно установлен — есть конфиг).
|
|
98
|
+
}
|
|
99
|
+
const configDir = path.dirname(this.resolveConfigPath());
|
|
100
|
+
return FileManager.exists(configDir);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Запустить `checkCommand` с таймаутом. Команда парсится по whitespace:
|
|
104
|
+
* первый токен — бинарь, остальное — аргументы. Выполняется через
|
|
105
|
+
* {@link CommandExecutor.execFile} (без shell-интерпретации).
|
|
106
|
+
*
|
|
107
|
+
* @returns `true` если команда успешно выполнилась (exit 0); `false` иначе.
|
|
108
|
+
*/
|
|
109
|
+
tryCheckCommand(checkCommand) {
|
|
110
|
+
const tokens = checkCommand.split(/\s+/).filter((t) => t.length > 0);
|
|
111
|
+
const bin = tokens[0];
|
|
112
|
+
if (!bin)
|
|
113
|
+
return false;
|
|
114
|
+
const args = tokens.slice(1);
|
|
115
|
+
try {
|
|
116
|
+
CommandExecutor.execFile(bin, args, { timeout: CHECK_COMMAND_TIMEOUT_MS });
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return false;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Получить статус подключения. Дополнительно к наличию записи в конфиге проверяет
|
|
125
|
+
* существование `command` на диске (для абсолютных путей и `node` со скриптом
|
|
126
|
+
* в args).
|
|
127
|
+
*/
|
|
128
|
+
async getStatus() {
|
|
129
|
+
try {
|
|
130
|
+
const configPath = this.resolveConfigPath();
|
|
131
|
+
if (!(await FileManager.exists(configPath))) {
|
|
132
|
+
return { connected: false, error: 'Конфигурационный файл не найден' };
|
|
133
|
+
}
|
|
134
|
+
const config = await this.readConfig();
|
|
135
|
+
const servers = config[this.getServerKey()];
|
|
136
|
+
const serverEntry = servers?.[this._serverName];
|
|
137
|
+
if (!serverEntry) {
|
|
138
|
+
return { connected: false };
|
|
139
|
+
}
|
|
140
|
+
const commandOk = await this.commandExistsOnDisk(serverEntry);
|
|
141
|
+
if (!commandOk) {
|
|
142
|
+
return {
|
|
143
|
+
connected: false,
|
|
144
|
+
error: `Команда сервера не найдена на диске: ${this.describeCommand(serverEntry)}`,
|
|
145
|
+
details: {
|
|
146
|
+
configPath,
|
|
147
|
+
metadata: { serverConfig: serverEntry },
|
|
148
|
+
},
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
connected: true,
|
|
153
|
+
details: {
|
|
154
|
+
configPath,
|
|
155
|
+
metadata: { serverConfig: serverEntry },
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
const errorMessage = isError(error) ? error.message : String(error);
|
|
161
|
+
return {
|
|
162
|
+
connected: false,
|
|
163
|
+
error: `Ошибка чтения конфига: ${errorMessage}`,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Подключить MCP сервер: записать spec в файл конфигурации клиента.
|
|
169
|
+
*/
|
|
170
|
+
async connect(spec) {
|
|
171
|
+
const configPath = this.resolveConfigPath();
|
|
172
|
+
const configDir = path.dirname(configPath);
|
|
173
|
+
await FileManager.ensureDir(configDir);
|
|
174
|
+
let config;
|
|
175
|
+
if (await FileManager.exists(configPath)) {
|
|
176
|
+
config = await this.readConfig();
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
config = this.createDefaultConfig();
|
|
180
|
+
}
|
|
181
|
+
const serverKey = this.getServerKey();
|
|
182
|
+
const servers = (config[serverKey] ??= {});
|
|
183
|
+
const entry = {
|
|
184
|
+
command: spec.command,
|
|
185
|
+
args: [...spec.args],
|
|
186
|
+
env: spec.env,
|
|
187
|
+
};
|
|
188
|
+
if (spec.cwd !== undefined) {
|
|
189
|
+
entry.cwd = spec.cwd;
|
|
190
|
+
}
|
|
191
|
+
if (spec.disabled !== undefined) {
|
|
192
|
+
entry.disabled = spec.disabled;
|
|
193
|
+
}
|
|
194
|
+
servers[this._serverName] = entry;
|
|
195
|
+
await this.writeConfig(config);
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Отключить MCP сервер: удалить запись из конфигурации.
|
|
199
|
+
*/
|
|
200
|
+
async disconnect() {
|
|
201
|
+
const configPath = this.resolveConfigPath();
|
|
202
|
+
if (!(await FileManager.exists(configPath))) {
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
const config = await this.readConfig();
|
|
206
|
+
const serverKey = this.getServerKey();
|
|
207
|
+
const servers = config[serverKey];
|
|
208
|
+
if (servers?.[this._serverName]) {
|
|
209
|
+
delete servers[this._serverName];
|
|
210
|
+
await this.writeConfig(config);
|
|
211
|
+
}
|
|
59
212
|
}
|
|
60
|
-
|
|
61
|
-
|
|
213
|
+
/**
|
|
214
|
+
* Прочитать spec, записанную в конфиге клиента.
|
|
215
|
+
*
|
|
216
|
+
* @returns spec, если сервер присутствует в конфиге; `null` иначе.
|
|
217
|
+
*/
|
|
218
|
+
async getLaunchSpec() {
|
|
219
|
+
try {
|
|
220
|
+
const configPath = this.resolveConfigPath();
|
|
221
|
+
if (!(await FileManager.exists(configPath))) {
|
|
222
|
+
return null;
|
|
223
|
+
}
|
|
224
|
+
const config = await this.readConfig();
|
|
225
|
+
const entry = config[this.getServerKey()]?.[this._serverName];
|
|
226
|
+
if (!entry) {
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
const spec = {
|
|
230
|
+
command: entry.command,
|
|
231
|
+
args: entry.args,
|
|
232
|
+
env: entry.env,
|
|
233
|
+
};
|
|
234
|
+
if (entry.cwd !== undefined) {
|
|
235
|
+
spec.cwd = entry.cwd;
|
|
236
|
+
}
|
|
237
|
+
if (entry.disabled !== undefined) {
|
|
238
|
+
spec.disabled = entry.disabled;
|
|
239
|
+
}
|
|
240
|
+
return spec;
|
|
241
|
+
}
|
|
242
|
+
catch {
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
62
245
|
}
|
|
63
|
-
|
|
64
|
-
|
|
246
|
+
// ----- internal -----
|
|
247
|
+
resolveConfigPath() {
|
|
248
|
+
const value = this._clientConfig.configPath;
|
|
249
|
+
return typeof value === 'function' ? value() : value;
|
|
65
250
|
}
|
|
66
251
|
getServerKey() {
|
|
67
252
|
return this._clientConfig.serverKey ?? 'mcpServers';
|
|
@@ -69,5 +254,63 @@ export class ConfigurableConnector extends FileBasedConnector {
|
|
|
69
254
|
getConfigFormat() {
|
|
70
255
|
return this._clientConfig.configFormat ?? 'json';
|
|
71
256
|
}
|
|
257
|
+
async readConfig() {
|
|
258
|
+
const configPath = this.resolveConfigPath();
|
|
259
|
+
const format = this.getConfigFormat();
|
|
260
|
+
return format === 'json'
|
|
261
|
+
? FileManager.readJSON(configPath)
|
|
262
|
+
: FileManager.readTOML(configPath);
|
|
263
|
+
}
|
|
264
|
+
async writeConfig(config) {
|
|
265
|
+
const configPath = this.resolveConfigPath();
|
|
266
|
+
const format = this.getConfigFormat();
|
|
267
|
+
if (format === 'json') {
|
|
268
|
+
await FileManager.writeJSON(configPath, config);
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
await FileManager.writeTOML(configPath, config);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
createDefaultConfig() {
|
|
275
|
+
return { [this.getServerKey()]: {} };
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Проверка существования команды на диске. Логика выровнена с
|
|
279
|
+
* {@link BaseConnector.validateLaunchSpec}:
|
|
280
|
+
* - абсолютный путь команды → `fs.access`;
|
|
281
|
+
* - `node` + первый абсолютный путь в args → `fs.access`;
|
|
282
|
+
* - всё остальное (`npx`, `pipx`, относительная команда из PATH) → считаем OK,
|
|
283
|
+
* не пытаемся резолвить PATH.
|
|
284
|
+
*/
|
|
285
|
+
async commandExistsOnDisk(entry) {
|
|
286
|
+
const filePath = resolveExecutablePath({
|
|
287
|
+
command: entry.command,
|
|
288
|
+
args: entry.args,
|
|
289
|
+
env: entry.env,
|
|
290
|
+
});
|
|
291
|
+
if (filePath === null) {
|
|
292
|
+
// npx/pipx/relative-from-PATH или `node` без абсолютного пути в args —
|
|
293
|
+
// на диске проверить нечего, считаем OK.
|
|
294
|
+
return true;
|
|
295
|
+
}
|
|
296
|
+
return this.pathExists(filePath);
|
|
297
|
+
}
|
|
298
|
+
describeCommand(entry) {
|
|
299
|
+
const filePath = resolveExecutablePath({
|
|
300
|
+
command: entry.command,
|
|
301
|
+
args: entry.args,
|
|
302
|
+
env: entry.env,
|
|
303
|
+
});
|
|
304
|
+
return filePath ?? entry.command;
|
|
305
|
+
}
|
|
306
|
+
async pathExists(p) {
|
|
307
|
+
try {
|
|
308
|
+
await fs.access(p);
|
|
309
|
+
return true;
|
|
310
|
+
}
|
|
311
|
+
catch {
|
|
312
|
+
return false;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
72
315
|
}
|
|
73
316
|
//# sourceMappingURL=configurable-connector.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configurable-connector.js","sourceRoot":"","sources":["../../../src/connectors/base/configurable-connector.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"configurable-connector.js","sourceRoot":"","sources":["../../../src/connectors/base/configurable-connector.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,26 +2,26 @@
|
|
|
2
2
|
* Base connector interface for MCP clients
|
|
3
3
|
* @packageDocumentation
|
|
4
4
|
*/
|
|
5
|
-
import type {
|
|
5
|
+
import type { MCPClientInfo, ConnectionStatus } from '../../types/client.types.js';
|
|
6
|
+
import type { ServerLaunchSpec } from '../../types/launch.types.js';
|
|
6
7
|
/**
|
|
7
|
-
* Базовый интерфейс для всех MCP
|
|
8
|
-
* Generic по типу конфигурации сервера
|
|
8
|
+
* Базовый интерфейс для всех MCP коннекторов.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
10
|
+
* Framework-агностичен к доменной модели: коннектор оперирует «универсальной»
|
|
11
|
+
* спецификацией запуска {@link ServerLaunchSpec} (`{ command, args, env }`).
|
|
12
|
+
* Маппинг доменных полей в эту спецификацию выполняет вызывающая сторона.
|
|
11
13
|
*
|
|
12
14
|
* @example
|
|
13
15
|
* ```typescript
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* class MyConnector implements MCPConnector<MyServerConfig> {
|
|
20
|
-
* // implementation
|
|
16
|
+
* class MyConnector implements MCPConnector {
|
|
17
|
+
* async connect(spec: ServerLaunchSpec): Promise<void> {
|
|
18
|
+
* // запись spec в конфиг клиента
|
|
19
|
+
* }
|
|
20
|
+
* // ... остальные методы
|
|
21
21
|
* }
|
|
22
22
|
* ```
|
|
23
23
|
*/
|
|
24
|
-
export interface MCPConnector
|
|
24
|
+
export interface MCPConnector {
|
|
25
25
|
/**
|
|
26
26
|
* Получить информацию о MCP клиенте
|
|
27
27
|
* @returns Метаданные клиента (имя, описание, платформы и т.д.)
|
|
@@ -39,24 +39,33 @@ export interface MCPConnector<TConfig extends BaseMCPServerConfig = BaseMCPServe
|
|
|
39
39
|
getStatus(): Promise<ConnectionStatus>;
|
|
40
40
|
/**
|
|
41
41
|
* Подключить MCP сервер к клиенту
|
|
42
|
-
* Записывает
|
|
42
|
+
* Записывает спецификацию запуска в конфигурацию клиента.
|
|
43
43
|
*
|
|
44
|
-
* @param
|
|
45
|
-
* @throws Если клиент не установлен или
|
|
44
|
+
* @param spec - Спецификация запуска MCP сервера
|
|
45
|
+
* @throws Если клиент не установлен или спецификация невалидна
|
|
46
46
|
*/
|
|
47
|
-
connect(
|
|
47
|
+
connect(spec: ServerLaunchSpec): Promise<void>;
|
|
48
48
|
/**
|
|
49
49
|
* Отключить MCP сервер от клиента
|
|
50
|
-
* Удаляет конфигурацию из файла
|
|
50
|
+
* Удаляет конфигурацию из файла клиента.
|
|
51
51
|
*
|
|
52
52
|
* @throws Если клиент не установлен или сервер не подключен
|
|
53
53
|
*/
|
|
54
54
|
disconnect(): Promise<void>;
|
|
55
55
|
/**
|
|
56
|
-
* Валидировать
|
|
57
|
-
* @param
|
|
56
|
+
* Валидировать спецификацию запуска перед подключением
|
|
57
|
+
* @param spec - Спецификация для проверки
|
|
58
58
|
* @returns Массив ошибок валидации (пустой если валидация успешна)
|
|
59
59
|
*/
|
|
60
|
-
|
|
60
|
+
validateLaunchSpec(spec: ServerLaunchSpec): Promise<string[]>;
|
|
61
|
+
/**
|
|
62
|
+
* Получить текущую записанную в конфиге клиента спецификацию запуска.
|
|
63
|
+
* Используется командой `doctor` для самодиагностики (например, проверка
|
|
64
|
+
* существования `command` на диске).
|
|
65
|
+
*
|
|
66
|
+
* @returns Spec, если сервер подключен; `null` если не подключен или конфиг
|
|
67
|
+
* недоступен/повреждён.
|
|
68
|
+
*/
|
|
69
|
+
getLaunchSpec(): Promise<ServerLaunchSpec | null>;
|
|
61
70
|
}
|
|
62
71
|
//# sourceMappingURL=connector.interface.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connector.interface.d.ts","sourceRoot":"","sources":["../../../src/connectors/base/connector.interface.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"connector.interface.d.ts","sourceRoot":"","sources":["../../../src/connectors/base/connector.interface.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AACnF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAEpE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,aAAa,IAAI,aAAa,CAAC;IAE/B;;;OAGG;IACH,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAEhC;;;OAGG;IACH,SAAS,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAEvC;;;;;;OAMG;IACH,OAAO,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE/C;;;;;OAKG;IACH,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5B;;;;OAIG;IACH,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAE9D;;;;;;;OAOG;IACH,aAAa,IAAI,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;CACnD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/connectors/base/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/connectors/base/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/connectors/base/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/connectors/base/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,6BAA6B,CAAC"}
|