@hypnosis/docker-mcp-server 1.0.0

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.
Files changed (103) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +242 -0
  3. package/dist/adapters/adapter-registry.d.ts +29 -0
  4. package/dist/adapters/adapter-registry.d.ts.map +1 -0
  5. package/dist/adapters/adapter-registry.js +47 -0
  6. package/dist/adapters/adapter-registry.js.map +1 -0
  7. package/dist/adapters/database-adapter.d.ts +33 -0
  8. package/dist/adapters/database-adapter.d.ts.map +1 -0
  9. package/dist/adapters/database-adapter.js +6 -0
  10. package/dist/adapters/database-adapter.js.map +1 -0
  11. package/dist/adapters/postgresql.d.ts +42 -0
  12. package/dist/adapters/postgresql.d.ts.map +1 -0
  13. package/dist/adapters/postgresql.js +202 -0
  14. package/dist/adapters/postgresql.js.map +1 -0
  15. package/dist/adapters/redis.d.ts +46 -0
  16. package/dist/adapters/redis.d.ts.map +1 -0
  17. package/dist/adapters/redis.js +202 -0
  18. package/dist/adapters/redis.js.map +1 -0
  19. package/dist/adapters/sqlite.d.ts +34 -0
  20. package/dist/adapters/sqlite.d.ts.map +1 -0
  21. package/dist/adapters/sqlite.js +126 -0
  22. package/dist/adapters/sqlite.js.map +1 -0
  23. package/dist/adapters/types.d.ts +53 -0
  24. package/dist/adapters/types.d.ts.map +1 -0
  25. package/dist/adapters/types.js +5 -0
  26. package/dist/adapters/types.js.map +1 -0
  27. package/dist/cli.d.ts +7 -0
  28. package/dist/cli.d.ts.map +1 -0
  29. package/dist/cli.js +319 -0
  30. package/dist/cli.js.map +1 -0
  31. package/dist/discovery/compose-parser.d.ts +35 -0
  32. package/dist/discovery/compose-parser.d.ts.map +1 -0
  33. package/dist/discovery/compose-parser.js +126 -0
  34. package/dist/discovery/compose-parser.js.map +1 -0
  35. package/dist/discovery/config-merger.d.ts +19 -0
  36. package/dist/discovery/config-merger.d.ts.map +1 -0
  37. package/dist/discovery/config-merger.js +60 -0
  38. package/dist/discovery/config-merger.js.map +1 -0
  39. package/dist/discovery/project-discovery.d.ts +53 -0
  40. package/dist/discovery/project-discovery.d.ts.map +1 -0
  41. package/dist/discovery/project-discovery.js +252 -0
  42. package/dist/discovery/project-discovery.js.map +1 -0
  43. package/dist/discovery/types.d.ts +47 -0
  44. package/dist/discovery/types.d.ts.map +1 -0
  45. package/dist/discovery/types.js +6 -0
  46. package/dist/discovery/types.js.map +1 -0
  47. package/dist/index.d.ts +6 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +109 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/managers/compose-manager.d.ts +30 -0
  52. package/dist/managers/compose-manager.d.ts.map +1 -0
  53. package/dist/managers/compose-manager.js +70 -0
  54. package/dist/managers/compose-manager.js.map +1 -0
  55. package/dist/managers/container-manager.d.ts +81 -0
  56. package/dist/managers/container-manager.d.ts.map +1 -0
  57. package/dist/managers/container-manager.js +278 -0
  58. package/dist/managers/container-manager.js.map +1 -0
  59. package/dist/managers/env-manager.d.ts +37 -0
  60. package/dist/managers/env-manager.d.ts.map +1 -0
  61. package/dist/managers/env-manager.js +124 -0
  62. package/dist/managers/env-manager.js.map +1 -0
  63. package/dist/security/sql-validator.d.ts +23 -0
  64. package/dist/security/sql-validator.d.ts.map +1 -0
  65. package/dist/security/sql-validator.js +44 -0
  66. package/dist/security/sql-validator.js.map +1 -0
  67. package/dist/tools/container-tools.d.ts +31 -0
  68. package/dist/tools/container-tools.d.ts.map +1 -0
  69. package/dist/tools/container-tools.js +366 -0
  70. package/dist/tools/container-tools.js.map +1 -0
  71. package/dist/tools/database-tools.d.ts +22 -0
  72. package/dist/tools/database-tools.d.ts.map +1 -0
  73. package/dist/tools/database-tools.js +264 -0
  74. package/dist/tools/database-tools.js.map +1 -0
  75. package/dist/tools/env-tools.d.ts +52 -0
  76. package/dist/tools/env-tools.d.ts.map +1 -0
  77. package/dist/tools/env-tools.js +318 -0
  78. package/dist/tools/env-tools.js.map +1 -0
  79. package/dist/tools/executor-tool.d.ts +18 -0
  80. package/dist/tools/executor-tool.d.ts.map +1 -0
  81. package/dist/tools/executor-tool.js +95 -0
  82. package/dist/tools/executor-tool.js.map +1 -0
  83. package/dist/tools/mcp-health-tool.d.ts +65 -0
  84. package/dist/tools/mcp-health-tool.d.ts.map +1 -0
  85. package/dist/tools/mcp-health-tool.js +126 -0
  86. package/dist/tools/mcp-health-tool.js.map +1 -0
  87. package/dist/utils/cache.d.ts +43 -0
  88. package/dist/utils/cache.d.ts.map +1 -0
  89. package/dist/utils/cache.js +77 -0
  90. package/dist/utils/cache.js.map +1 -0
  91. package/dist/utils/compose-exec.d.ts +13 -0
  92. package/dist/utils/compose-exec.d.ts.map +1 -0
  93. package/dist/utils/compose-exec.js +33 -0
  94. package/dist/utils/compose-exec.js.map +1 -0
  95. package/dist/utils/docker-client.d.ts +33 -0
  96. package/dist/utils/docker-client.d.ts.map +1 -0
  97. package/dist/utils/docker-client.js +59 -0
  98. package/dist/utils/docker-client.js.map +1 -0
  99. package/dist/utils/logger.d.ts +18 -0
  100. package/dist/utils/logger.d.ts.map +1 -0
  101. package/dist/utils/logger.js +38 -0
  102. package/dist/utils/logger.js.map +1 -0
  103. package/package.json +65 -0
@@ -0,0 +1,278 @@
1
+ /**
2
+ * Container Manager
3
+ * Управление Docker контейнерами
4
+ */
5
+ import { logger } from '../utils/logger.js';
6
+ import { getDockerClient } from '../utils/docker-client.js';
7
+ export class ContainerManager {
8
+ docker;
9
+ constructor() {
10
+ const client = getDockerClient();
11
+ this.docker = client.getClient();
12
+ }
13
+ /**
14
+ * Список контейнеров проекта
15
+ */
16
+ async listContainers(projectName, composeFile, projectDir) {
17
+ logger.debug(`Listing containers for project: ${projectName}`);
18
+ // Вариант 1: Используем Docker Compose labels (прямой вызов Docker API)
19
+ try {
20
+ const containers = await this.docker.listContainers({
21
+ all: true,
22
+ filters: {
23
+ label: [`com.docker.compose.project=${projectName}`],
24
+ },
25
+ });
26
+ if (containers.length > 0) {
27
+ logger.debug(`Found ${containers.length} containers via Docker Compose labels`);
28
+ return containers.map((c) => this.mapContainerInfo(c, projectName));
29
+ }
30
+ logger.debug('No containers found via labels, trying fallback methods');
31
+ }
32
+ catch (error) {
33
+ logger.debug('Failed to list containers via labels:', error);
34
+ }
35
+ // Fallback 1: Используем docker-compose ps CLI (если есть composeFile)
36
+ if (composeFile && projectDir) {
37
+ try {
38
+ const { ComposeExec } = await import('../utils/compose-exec.js');
39
+ const output = ComposeExec.run(composeFile, ['ps', '--format', 'json'], {
40
+ cwd: projectDir,
41
+ });
42
+ const composeContainers = output
43
+ .split('\n')
44
+ .filter(line => line.trim())
45
+ .map(line => {
46
+ try {
47
+ return JSON.parse(line);
48
+ }
49
+ catch {
50
+ return null;
51
+ }
52
+ })
53
+ .filter(c => c && c.Name);
54
+ if (composeContainers.length > 0) {
55
+ logger.debug(`Found ${composeContainers.length} containers via docker-compose ps`);
56
+ // Получаем полную информацию о контейнерах через Docker API
57
+ const containerNames = composeContainers.map(c => c.Name);
58
+ const allContainers = await this.docker.listContainers({ all: true });
59
+ const projectContainers = allContainers.filter(c => {
60
+ const name = c.Names[0]?.replace(/^\//, '') || '';
61
+ return containerNames.some(n => name === n || name.includes(n));
62
+ });
63
+ return projectContainers.map((c) => {
64
+ const composeInfo = composeContainers.find(cc => {
65
+ const name = c.Names[0]?.replace(/^\//, '') || '';
66
+ return name === cc.Name || name.includes(cc.Name);
67
+ });
68
+ return this.mapContainerInfo(c, projectName, composeInfo?.Service);
69
+ });
70
+ }
71
+ }
72
+ catch (error) {
73
+ logger.debug('Failed to use docker-compose ps:', error);
74
+ }
75
+ }
76
+ // Fallback 2: Фильтр по имени проекта в названии контейнера
77
+ logger.debug('Using name-based filter as final fallback');
78
+ const containers = await this.docker.listContainers({
79
+ all: true,
80
+ filters: {
81
+ name: [projectName],
82
+ },
83
+ });
84
+ return containers.map((c) => this.mapContainerInfo(c, projectName));
85
+ }
86
+ /**
87
+ * Запустить контейнер
88
+ */
89
+ async startContainer(serviceName, projectName, composeFile, projectDir) {
90
+ const container = await this.findContainer(serviceName, projectName, composeFile, projectDir);
91
+ logger.info(`Starting container: ${serviceName}`);
92
+ await container.start();
93
+ logger.info(`Container ${serviceName} started successfully`);
94
+ }
95
+ /**
96
+ * Остановить контейнер
97
+ */
98
+ async stopContainer(serviceName, projectName, timeout = 10, composeFile, projectDir) {
99
+ const container = await this.findContainer(serviceName, projectName, composeFile, projectDir);
100
+ logger.info(`Stopping container: ${serviceName}`);
101
+ await container.stop({ t: timeout });
102
+ logger.info(`Container ${serviceName} stopped successfully`);
103
+ }
104
+ /**
105
+ * Перезапустить контейнер
106
+ */
107
+ async restartContainer(serviceName, projectName, timeout = 10, composeFile, projectDir) {
108
+ const container = await this.findContainer(serviceName, projectName, composeFile, projectDir);
109
+ logger.info(`Restarting container: ${serviceName}`);
110
+ await container.restart({ t: timeout });
111
+ logger.info(`Container ${serviceName} restarted successfully`);
112
+ }
113
+ /**
114
+ * Получить логи контейнера
115
+ * Возвращает string для обычного режима или stream для follow mode
116
+ */
117
+ async getLogs(serviceName, projectName, options = {}, composeFile, projectDir) {
118
+ const container = await this.findContainer(serviceName, projectName, composeFile, projectDir);
119
+ logger.debug(`Getting logs for: ${serviceName}`, options);
120
+ // Если follow mode → возвращаем stream
121
+ if (options.follow) {
122
+ logger.debug('Returning stream for follow mode');
123
+ const logs = await container.logs({
124
+ stdout: true,
125
+ stderr: true,
126
+ tail: options.lines || 100,
127
+ follow: true,
128
+ timestamps: options.timestamps || false,
129
+ since: options.since,
130
+ });
131
+ return logs;
132
+ }
133
+ // Иначе → возвращаем string
134
+ const logs = await container.logs({
135
+ stdout: true,
136
+ stderr: true,
137
+ tail: options.lines || 100,
138
+ follow: false,
139
+ timestamps: options.timestamps || false,
140
+ since: options.since,
141
+ });
142
+ // logs теперь Buffer, конвертируем в string
143
+ return Buffer.isBuffer(logs) ? logs.toString('utf-8') : logs.toString('utf-8');
144
+ }
145
+ /**
146
+ * Получить health status контейнера
147
+ */
148
+ async getHealthStatus(serviceName, projectName, composeFile, projectDir) {
149
+ const container = await this.findContainer(serviceName, projectName, composeFile, projectDir);
150
+ try {
151
+ const info = await container.inspect();
152
+ // Если контейнер не running
153
+ if (info.State.Status !== 'running') {
154
+ return {
155
+ status: 'not_running',
156
+ checks: 0,
157
+ failures: 0,
158
+ };
159
+ }
160
+ // Если healthcheck не определён
161
+ if (!info.State.Health) {
162
+ return {
163
+ status: 'none',
164
+ checks: 0,
165
+ failures: 0,
166
+ };
167
+ }
168
+ // Healthcheck определён
169
+ const health = info.State.Health;
170
+ const status = health.Status;
171
+ return {
172
+ status: status || 'none',
173
+ checks: health.Log?.length || 0,
174
+ failures: health.FailingStreak || 0,
175
+ };
176
+ }
177
+ catch (error) {
178
+ logger.error(`Failed to get health status for ${serviceName}:`, error);
179
+ throw new Error(`Failed to inspect container: ${error.message}`);
180
+ }
181
+ }
182
+ /**
183
+ * Выполнить команду в контейнере
184
+ */
185
+ async exec(serviceName, projectName, command, options = {}, composeFile, projectDir) {
186
+ const container = await this.findContainer(serviceName, projectName, composeFile, projectDir);
187
+ logger.debug(`Executing in ${serviceName}:`, command.join(' '));
188
+ if (options.interactive) {
189
+ logger.debug('Interactive mode (TTY) enabled');
190
+ }
191
+ const exec = await container.exec({
192
+ Cmd: command,
193
+ AttachStdout: true,
194
+ AttachStderr: true,
195
+ AttachStdin: options.interactive || false,
196
+ Tty: options.interactive || false,
197
+ User: options.user,
198
+ WorkingDir: options.workdir,
199
+ Env: options.env,
200
+ });
201
+ const stream = await exec.start({
202
+ hijack: options.interactive || false,
203
+ stdin: options.interactive || false,
204
+ });
205
+ return new Promise((resolve, reject) => {
206
+ const chunks = [];
207
+ stream.on('data', (chunk) => chunks.push(chunk));
208
+ stream.on('end', () => resolve(Buffer.concat(chunks).toString('utf-8')));
209
+ stream.on('error', reject);
210
+ });
211
+ }
212
+ /**
213
+ * Найти контейнер по имени сервиса
214
+ */
215
+ async findContainer(serviceName, projectName, composeFile, projectDir) {
216
+ const containers = await this.listContainers(projectName, composeFile, projectDir);
217
+ const found = containers.find((c) => c.service === serviceName);
218
+ if (!found) {
219
+ const available = containers.map((c) => c.service).join(', ');
220
+ throw new Error(`Container '${serviceName}' not found in project '${projectName}'.\n` +
221
+ `Available containers: ${available || 'none'}`);
222
+ }
223
+ return this.docker.getContainer(found.id);
224
+ }
225
+ /**
226
+ * Маппинг Docker ContainerInfo → наш формат
227
+ */
228
+ mapContainerInfo(container, projectName, serviceNameOverride) {
229
+ // Имя контейнера: /project_service_1 → извлекаем service
230
+ const fullName = container.Names[0]?.replace(/^\//, '') || '';
231
+ // Приоритет: override → label → извлечение из имени
232
+ const serviceName = serviceNameOverride
233
+ || container.Labels?.['com.docker.compose.service']
234
+ || this.extractServiceName(fullName, projectName);
235
+ return {
236
+ id: container.Id,
237
+ name: fullName,
238
+ service: serviceName,
239
+ status: container.State,
240
+ image: container.Image,
241
+ ports: this.extractPorts(container.Ports),
242
+ created: new Date(container.Created * 1000).toISOString(),
243
+ };
244
+ }
245
+ /**
246
+ * Извлекает порты из Docker container info
247
+ */
248
+ extractPorts(ports) {
249
+ if (!ports || ports.length === 0)
250
+ return [];
251
+ return ports.map((p) => {
252
+ if (p.PublicPort && p.PrivatePort) {
253
+ return `${p.PublicPort}:${p.PrivatePort}`;
254
+ }
255
+ if (p.PrivatePort) {
256
+ return `${p.PrivatePort}/${p.Type || 'tcp'}`;
257
+ }
258
+ return '';
259
+ }).filter((p) => p.length > 0);
260
+ }
261
+ /**
262
+ * Извлекает имя сервиса из имени контейнера
263
+ * project_service_1 → service
264
+ * project-service-1 → service
265
+ */
266
+ extractServiceName(containerName, projectName) {
267
+ // Убираем project name из начала
268
+ let name = containerName;
269
+ if (name.startsWith(projectName)) {
270
+ name = name.slice(projectName.length);
271
+ }
272
+ // Убираем разделители и номер в конце
273
+ // project_service_1 → _service_1 → service_1 → service
274
+ name = name.replace(/^[_-]/, '').replace(/[_-]\d+$/, '');
275
+ return name || containerName; // Fallback на полное имя
276
+ }
277
+ }
278
+ //# sourceMappingURL=container-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"container-manager.js","sourceRoot":"","sources":["../../src/managers/container-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Environment Manager
3
+ * Централизованное управление environment variables
4
+ */
5
+ import type { ServiceConfig } from '../discovery/types.js';
6
+ export declare class EnvManager {
7
+ /**
8
+ * Загрузить environment variables из всех источников
9
+ * Приоритет: .env.local > .env.{NODE_ENV} > .env > compose environment
10
+ */
11
+ loadEnv(projectDir: string, serviceName?: string, serviceConfig?: ServiceConfig): Record<string, string>;
12
+ /**
13
+ * Получить список .env файлов (в порядке приоритета)
14
+ * Приоритет: .env.local (highest) > .env.{NODE_ENV} > .env (base)
15
+ */
16
+ private getEnvFiles;
17
+ /**
18
+ * Парсит .env файл
19
+ */
20
+ private parseEnvFile;
21
+ /**
22
+ * Маскировать секреты в environment variables
23
+ */
24
+ maskSecrets(env: Record<string, string>): Record<string, string>;
25
+ /**
26
+ * Получить connection info для БД из environment
27
+ * Используется Database Adapters
28
+ */
29
+ getConnectionInfo(serviceConfig: ServiceConfig, env: Record<string, string>): {
30
+ host: string;
31
+ port: number;
32
+ user: string;
33
+ password?: string;
34
+ database: string;
35
+ };
36
+ }
37
+ //# sourceMappingURL=env-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-manager.d.ts","sourceRoot":"","sources":["../../src/managers/env-manager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE3D,qBAAa,UAAU;IACrB;;;OAGG;IACH,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAuBxG;;;OAGG;IACH,OAAO,CAAC,WAAW;IAUnB;;OAEG;IACH,OAAO,CAAC,YAAY;IAUpB;;OAEG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAwBhE;;;OAGG;IACH,iBAAiB,CACf,aAAa,EAAE,aAAa,EAC5B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC1B;QACD,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;KAClB;CA8CF"}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Environment Manager
3
+ * Централизованное управление environment variables
4
+ */
5
+ import { existsSync, readFileSync } from 'fs';
6
+ import { join } from 'path';
7
+ import { parse as parseDotenv } from 'dotenv';
8
+ import { logger } from '../utils/logger.js';
9
+ export class EnvManager {
10
+ /**
11
+ * Загрузить environment variables из всех источников
12
+ * Приоритет: .env.local > .env.{NODE_ENV} > .env > compose environment
13
+ */
14
+ loadEnv(projectDir, serviceName, serviceConfig) {
15
+ const env = {};
16
+ // 1. Загрузить .env файлы (в порядке приоритета)
17
+ const envFiles = this.getEnvFiles(projectDir);
18
+ for (const file of envFiles) {
19
+ if (existsSync(file)) {
20
+ const parsed = this.parseEnvFile(file);
21
+ Object.assign(env, parsed);
22
+ logger.debug(`Loaded env from: ${file}`);
23
+ }
24
+ }
25
+ // 2. Если serviceName и serviceConfig указаны → загрузить из compose
26
+ if (serviceName && serviceConfig?.environment) {
27
+ Object.assign(env, serviceConfig.environment);
28
+ logger.debug(`Loaded env from compose for service: ${serviceName}`);
29
+ }
30
+ return env;
31
+ }
32
+ /**
33
+ * Получить список .env файлов (в порядке приоритета)
34
+ * Приоритет: .env.local (highest) > .env.{NODE_ENV} > .env (base)
35
+ */
36
+ getEnvFiles(projectDir) {
37
+ const nodeEnv = process.env.NODE_ENV || 'development';
38
+ return [
39
+ join(projectDir, '.env'), // Base (lowest priority)
40
+ join(projectDir, `.env.${nodeEnv}`), // Environment-specific
41
+ join(projectDir, '.env.local'), // Local (highest priority)
42
+ ];
43
+ }
44
+ /**
45
+ * Парсит .env файл
46
+ */
47
+ parseEnvFile(filePath) {
48
+ try {
49
+ const content = readFileSync(filePath, 'utf-8');
50
+ return parseDotenv(content);
51
+ }
52
+ catch (error) {
53
+ logger.warn(`Failed to parse env file ${filePath}:`, error.message);
54
+ return {};
55
+ }
56
+ }
57
+ /**
58
+ * Маскировать секреты в environment variables
59
+ */
60
+ maskSecrets(env) {
61
+ const SECRET_KEYWORDS = [
62
+ 'PASSWORD',
63
+ 'TOKEN',
64
+ 'KEY',
65
+ 'SECRET',
66
+ 'API_KEY',
67
+ 'PRIVATE',
68
+ 'CREDENTIALS',
69
+ ];
70
+ const masked = {};
71
+ for (const [key, value] of Object.entries(env)) {
72
+ const isSecret = SECRET_KEYWORDS.some((keyword) => key.toUpperCase().includes(keyword));
73
+ masked[key] = isSecret ? '***MASKED***' : value;
74
+ }
75
+ return masked;
76
+ }
77
+ /**
78
+ * Получить connection info для БД из environment
79
+ * Используется Database Adapters
80
+ */
81
+ getConnectionInfo(serviceConfig, env) {
82
+ // Базовые значения
83
+ const host = 'localhost';
84
+ const port = 0;
85
+ const user = '';
86
+ const password = undefined;
87
+ const database = '';
88
+ // Тип БД определяет какие переменные искать
89
+ switch (serviceConfig.type) {
90
+ case 'postgresql':
91
+ return {
92
+ host,
93
+ port: 5432,
94
+ user: env.POSTGRES_USER || 'postgres',
95
+ password: env.POSTGRES_PASSWORD,
96
+ database: env.POSTGRES_DB || 'postgres',
97
+ };
98
+ case 'redis':
99
+ return {
100
+ host,
101
+ port: 6379,
102
+ user: '',
103
+ password: env.REDIS_PASSWORD,
104
+ database: '0',
105
+ };
106
+ case 'sqlite':
107
+ return {
108
+ host: 'localhost',
109
+ port: 0,
110
+ user: '',
111
+ database: env.SQLITE_DATABASE || '/app/db.sqlite3',
112
+ };
113
+ default:
114
+ return {
115
+ host,
116
+ port,
117
+ user,
118
+ password,
119
+ database,
120
+ };
121
+ }
122
+ }
123
+ }
124
+ //# sourceMappingURL=env-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-manager.js","sourceRoot":"","sources":["../../src/managers/env-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * SQL Validator
3
+ * Валидация опасных SQL команд для защиты от случайных удалений
4
+ */
5
+ export declare class SQLValidator {
6
+ private dangerousPatterns;
7
+ /**
8
+ * Валидировать SQL запрос
9
+ * Бросает ошибку если опасный
10
+ */
11
+ validate(sql: string): void;
12
+ /**
13
+ * Проверить включена ли валидация
14
+ * По умолчанию: ВКЛ (защита)
15
+ * Отключение: DOCKER_MCP_VALIDATE_SQL=false
16
+ */
17
+ static isEnabled(): boolean;
18
+ }
19
+ /**
20
+ * Singleton instance
21
+ */
22
+ export declare const sqlValidator: SQLValidator;
23
+ //# sourceMappingURL=sql-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-validator.d.ts","sourceRoot":"","sources":["../../src/security/sql-validator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,qBAAa,YAAY;IACvB,OAAO,CAAC,iBAAiB,CAMvB;IAEF;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAkB3B;;;;OAIG;IACH,MAAM,CAAC,SAAS,IAAI,OAAO;CAG5B;AAED;;GAEG;AACH,eAAO,MAAM,YAAY,cAAqB,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * SQL Validator
3
+ * Валидация опасных SQL команд для защиты от случайных удалений
4
+ */
5
+ export class SQLValidator {
6
+ dangerousPatterns = [
7
+ /DROP\s+DATABASE/i,
8
+ /DROP\s+TABLE/i,
9
+ /TRUNCATE\s+TABLE/i,
10
+ /DELETE\s+FROM\s+\w+\s*;/i, // DELETE без WHERE
11
+ /UPDATE\s+\w+\s+SET\s+.*\s*;/i, // UPDATE без WHERE (упрощенная проверка)
12
+ ];
13
+ /**
14
+ * Валидировать SQL запрос
15
+ * Бросает ошибку если опасный
16
+ */
17
+ validate(sql) {
18
+ // Проверяем включена ли валидация
19
+ if (!SQLValidator.isEnabled()) {
20
+ return;
21
+ }
22
+ for (const pattern of this.dangerousPatterns) {
23
+ if (pattern.test(sql)) {
24
+ throw new Error(`🚨 DANGEROUS SQL DETECTED: This query may cause data loss.\n` +
25
+ `Pattern: ${pattern.source}\n` +
26
+ `Query: ${sql}\n\n` +
27
+ `If you're sure, disable validation: DOCKER_MCP_VALIDATE_SQL=false`);
28
+ }
29
+ }
30
+ }
31
+ /**
32
+ * Проверить включена ли валидация
33
+ * По умолчанию: ВКЛ (защита)
34
+ * Отключение: DOCKER_MCP_VALIDATE_SQL=false
35
+ */
36
+ static isEnabled() {
37
+ return process.env.DOCKER_MCP_VALIDATE_SQL !== 'false';
38
+ }
39
+ }
40
+ /**
41
+ * Singleton instance
42
+ */
43
+ export const sqlValidator = new SQLValidator();
44
+ //# sourceMappingURL=sql-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-validator.js","sourceRoot":"","sources":["../../src/security/sql-validator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,OAAO,YAAY;IACf,iBAAiB,GAAG;QAC1B,kBAAkB;QAClB,eAAe;QACf,mBAAmB;QACnB,0BAA0B,EAAE,mBAAmB;QAC/C,8BAA8B,EAAE,yCAAyC;KAC1E,CAAC;IAEF;;;OAGG;IACH,QAAQ,CAAC,GAAW;QAClB,kCAAkC;QAClC,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,EAAE,CAAC;YAC9B,OAAO;QACT,CAAC;QAED,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YAC7C,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBACtB,MAAM,IAAI,KAAK,CACb,8DAA8D;oBAC9D,YAAY,OAAO,CAAC,MAAM,IAAI;oBAC9B,UAAU,GAAG,MAAM;oBACnB,mEAAmE,CACpE,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,SAAS;QACd,OAAO,OAAO,CAAC,GAAG,CAAC,uBAAuB,KAAK,OAAO,CAAC;IACzD,CAAC;CACF;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Container Tools
3
+ * MCP Tools для управления Docker контейнерами
4
+ */
5
+ import { CallToolRequest, Tool } from '@modelcontextprotocol/sdk/types.js';
6
+ export declare class ContainerTools {
7
+ private containerManager;
8
+ private composeManager;
9
+ private projectDiscovery;
10
+ constructor();
11
+ /**
12
+ * Регистрация всех container tools
13
+ */
14
+ getTools(): Tool[];
15
+ /**
16
+ * Обработка вызова tool
17
+ */
18
+ handleCall(request: CallToolRequest): Promise<any>;
19
+ private handleList;
20
+ private handleStart;
21
+ private handleStop;
22
+ private handleRestart;
23
+ private handleLogs;
24
+ private handleComposeUp;
25
+ private handleComposeDown;
26
+ /**
27
+ * Helper: получить project config (auto-detect или explicit)
28
+ */
29
+ private getProject;
30
+ }
31
+ //# sourceMappingURL=container-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"container-tools.d.ts","sourceRoot":"","sources":["../../src/tools/container-tools.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,eAAe,EACf,IAAI,EACL,MAAM,oCAAoC,CAAC;AAM5C,qBAAa,cAAc;IACzB,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,gBAAgB,CAAmB;;IAQ3C;;OAEG;IACH,QAAQ,IAAI,IAAI,EAAE;IAuKlB;;OAEG;IACG,UAAU,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC;YA2C1C,UAAU;YAcV,WAAW;YAkBX,UAAU;YAwBV,aAAa;YAwBb,UAAU;YAyDV,eAAe;YAkBf,iBAAiB;IAiB/B;;OAEG;YACW,UAAU;CAKzB"}