@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,126 @@
1
+ /**
2
+ * MCP Health Tool
3
+ * Самодиагностика MCP сервера
4
+ */
5
+ import { getDockerClient } from '../utils/docker-client.js';
6
+ import { ProjectDiscovery } from '../discovery/project-discovery.js';
7
+ import { adapterRegistry } from '../adapters/adapter-registry.js';
8
+ import { projectConfigCache } from '../utils/cache.js';
9
+ import { logger } from '../utils/logger.js';
10
+ export class MCPHealthTool {
11
+ /**
12
+ * Регистрация health tool
13
+ */
14
+ getTool() {
15
+ return {
16
+ name: 'docker_mcp_health',
17
+ description: 'Check health status of the MCP server (self-diagnostics)',
18
+ inputSchema: {
19
+ type: 'object',
20
+ properties: {},
21
+ },
22
+ };
23
+ }
24
+ /**
25
+ * Обработка вызова tool
26
+ */
27
+ async handleCall(request) {
28
+ try {
29
+ const healthStatus = await this.check();
30
+ return {
31
+ content: [
32
+ {
33
+ type: 'text',
34
+ text: JSON.stringify(healthStatus, null, 2),
35
+ },
36
+ ],
37
+ };
38
+ }
39
+ catch (error) {
40
+ logger.error('MCP health check failed:', error);
41
+ return {
42
+ content: [
43
+ {
44
+ type: 'text',
45
+ text: `Error: ${error.message}`,
46
+ },
47
+ ],
48
+ isError: true,
49
+ };
50
+ }
51
+ }
52
+ /**
53
+ * Выполнить проверки здоровья
54
+ */
55
+ async check() {
56
+ const checks = {};
57
+ // 1. Docker Connection
58
+ try {
59
+ const start = Date.now();
60
+ const docker = getDockerClient();
61
+ await docker.ping();
62
+ const latency = Date.now() - start;
63
+ checks.docker = {
64
+ status: 'ok',
65
+ latency,
66
+ };
67
+ }
68
+ catch (error) {
69
+ checks.docker = {
70
+ status: 'failed',
71
+ message: error.message || 'Docker connection failed',
72
+ };
73
+ }
74
+ // 2. Project Discovery
75
+ try {
76
+ const projectDiscovery = new ProjectDiscovery();
77
+ const project = await projectDiscovery.findProject();
78
+ checks.discovery = {
79
+ status: 'ok',
80
+ projectFound: true,
81
+ projectName: project.name,
82
+ };
83
+ }
84
+ catch (error) {
85
+ checks.discovery = {
86
+ status: 'failed',
87
+ message: error.message || 'Project discovery failed',
88
+ projectFound: false,
89
+ };
90
+ }
91
+ // 3. Adapters Registry
92
+ const registeredTypes = adapterRegistry.getRegisteredTypes();
93
+ checks.adapters = {
94
+ status: 'ok',
95
+ registered: registeredTypes,
96
+ count: registeredTypes.length,
97
+ };
98
+ // 4. Cache Status
99
+ checks.cache = {
100
+ status: 'ok',
101
+ size: projectConfigCache.size(),
102
+ ttl: 60, // seconds (hardcoded, так как в Cache не экспортирован)
103
+ };
104
+ // 5. Memory Usage
105
+ const mem = process.memoryUsage();
106
+ const heapUsedMB = Math.round(mem.heapUsed / 1024 / 1024);
107
+ const heapTotalMB = Math.round(mem.heapTotal / 1024 / 1024);
108
+ const rssMB = Math.round(mem.rss / 1024 / 1024);
109
+ checks.memory = {
110
+ status: heapUsedMB > 500 ? 'warning' : 'ok',
111
+ heapUsed: heapUsedMB,
112
+ heapTotal: heapTotalMB,
113
+ rss: rssMB,
114
+ };
115
+ // Overall status
116
+ const hasFailures = Object.values(checks).some((check) => check.status === 'failed');
117
+ const hasWarnings = Object.values(checks).some((check) => check.status === 'warning');
118
+ return {
119
+ status: hasFailures ? 'unhealthy' : hasWarnings ? 'degraded' : 'healthy',
120
+ timestamp: new Date().toISOString(),
121
+ uptime: Math.round(process.uptime()), // seconds
122
+ checks,
123
+ };
124
+ }
125
+ }
126
+ //# sourceMappingURL=mcp-health-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-health-tool.js","sourceRoot":"","sources":["../../src/tools/mcp-health-tool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Cache utility
3
+ * Кеширование с TTL (Time To Live)
4
+ */
5
+ import type { ProjectConfig } from '../discovery/types.js';
6
+ /**
7
+ * Generic cache с TTL
8
+ */
9
+ export declare class Cache<T> {
10
+ private cache;
11
+ private ttl;
12
+ constructor(ttlSeconds?: number);
13
+ /**
14
+ * Установить значение в кеш
15
+ */
16
+ set(key: string, value: T): void;
17
+ /**
18
+ * Получить значение из кеша
19
+ * Возвращает undefined если ключ не найден или истек TTL
20
+ */
21
+ get(key: string): T | undefined;
22
+ /**
23
+ * Инвалидировать ключ
24
+ */
25
+ invalidate(key: string): void;
26
+ /**
27
+ * Очистить весь кеш
28
+ */
29
+ clear(): void;
30
+ /**
31
+ * Проверить наличие ключа (без проверки TTL)
32
+ */
33
+ has(key: string): boolean;
34
+ /**
35
+ * Получить размер кеша
36
+ */
37
+ size(): number;
38
+ }
39
+ /**
40
+ * Singleton для ProjectConfig кеша (TTL: 60 секунд)
41
+ */
42
+ export declare const projectConfigCache: Cache<ProjectConfig>;
43
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/utils/cache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAQ3D;;GAEG;AACH,qBAAa,KAAK,CAAC,CAAC;IAClB,OAAO,CAAC,KAAK,CAAoC;IACjD,OAAO,CAAC,GAAG,CAAS;gBAER,UAAU,GAAE,MAAW;IAInC;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAQhC;;;OAGG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAmB/B;;OAEG;IACH,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAM7B;;OAEG;IACH,KAAK,IAAI,IAAI;IAMb;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB;;OAEG;IACH,IAAI,IAAI,MAAM;CAGf;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,sBAA+B,CAAC"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Cache utility
3
+ * Кеширование с TTL (Time To Live)
4
+ */
5
+ import { logger } from './logger.js';
6
+ /**
7
+ * Generic cache с TTL
8
+ */
9
+ export class Cache {
10
+ cache = new Map();
11
+ ttl; // milliseconds
12
+ constructor(ttlSeconds = 60) {
13
+ this.ttl = ttlSeconds * 1000;
14
+ }
15
+ /**
16
+ * Установить значение в кеш
17
+ */
18
+ set(key, value) {
19
+ this.cache.set(key, {
20
+ value,
21
+ expiresAt: Date.now() + this.ttl,
22
+ });
23
+ logger.debug(`Cache set: ${key} (TTL: ${this.ttl / 1000}s)`);
24
+ }
25
+ /**
26
+ * Получить значение из кеша
27
+ * Возвращает undefined если ключ не найден или истек TTL
28
+ */
29
+ get(key) {
30
+ const entry = this.cache.get(key);
31
+ if (!entry) {
32
+ logger.debug(`Cache miss: ${key}`);
33
+ return undefined;
34
+ }
35
+ // Проверка TTL
36
+ if (Date.now() > entry.expiresAt) {
37
+ this.cache.delete(key);
38
+ logger.debug(`Cache expired: ${key}`);
39
+ return undefined;
40
+ }
41
+ logger.debug(`Cache hit: ${key}`);
42
+ return entry.value;
43
+ }
44
+ /**
45
+ * Инвалидировать ключ
46
+ */
47
+ invalidate(key) {
48
+ if (this.cache.delete(key)) {
49
+ logger.debug(`Cache invalidated: ${key}`);
50
+ }
51
+ }
52
+ /**
53
+ * Очистить весь кеш
54
+ */
55
+ clear() {
56
+ const size = this.cache.size;
57
+ this.cache.clear();
58
+ logger.debug(`Cache cleared (${size} entries)`);
59
+ }
60
+ /**
61
+ * Проверить наличие ключа (без проверки TTL)
62
+ */
63
+ has(key) {
64
+ return this.cache.has(key);
65
+ }
66
+ /**
67
+ * Получить размер кеша
68
+ */
69
+ size() {
70
+ return this.cache.size;
71
+ }
72
+ }
73
+ /**
74
+ * Singleton для ProjectConfig кеша (TTL: 60 секунд)
75
+ */
76
+ export const projectConfigCache = new Cache(60);
77
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/utils/cache.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAOrC;;GAEG;AACH,MAAM,OAAO,KAAK;IACR,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAC;IACzC,GAAG,CAAS,CAAC,eAAe;IAEpC,YAAY,aAAqB,EAAE;QACjC,IAAI,CAAC,GAAG,GAAG,UAAU,GAAG,IAAI,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,GAAW,EAAE,KAAQ;QACvB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE;YAClB,KAAK;YACL,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG;SACjC,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,cAAc,GAAG,UAAU,IAAI,CAAC,GAAG,GAAG,IAAI,IAAI,CAAC,CAAC;IAC/D,CAAC;IAED;;;OAGG;IACH,GAAG,CAAC,GAAW;QACb,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QAElC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,CAAC,KAAK,CAAC,eAAe,GAAG,EAAE,CAAC,CAAC;YACnC,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,eAAe;QACf,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACvB,MAAM,CAAC,KAAK,CAAC,kBAAkB,GAAG,EAAE,CAAC,CAAC;YACtC,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,CAAC,KAAK,CAAC,cAAc,GAAG,EAAE,CAAC,CAAC;QAClC,OAAO,KAAK,CAAC,KAAK,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,GAAW;QACpB,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3B,MAAM,CAAC,KAAK,CAAC,sBAAsB,GAAG,EAAE,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;QAC7B,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,MAAM,CAAC,KAAK,CAAC,kBAAkB,IAAI,WAAW,CAAC,CAAC;IAClD,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,GAAW;QACb,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,IAAI;QACF,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,KAAK,CAAgB,EAAE,CAAC,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Compose Exec
3
+ * CLI wrapper для docker-compose команд
4
+ */
5
+ export declare class ComposeExec {
6
+ /**
7
+ * Выполнить docker-compose команду
8
+ */
9
+ static run(composeFile: string, args: string[], options?: {
10
+ cwd?: string;
11
+ }): string;
12
+ }
13
+ //# sourceMappingURL=compose-exec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compose-exec.d.ts","sourceRoot":"","sources":["../../src/utils/compose-exec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,qBAAa,WAAW;IACtB;;OAEG;IACH,MAAM,CAAC,GAAG,CACR,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAO,GAC7B,MAAM;CAuBV"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Compose Exec
3
+ * CLI wrapper для docker-compose команд
4
+ */
5
+ import { execSync } from 'child_process';
6
+ import { logger } from './logger.js';
7
+ export class ComposeExec {
8
+ /**
9
+ * Выполнить docker-compose команду
10
+ */
11
+ static run(composeFile, args, options = {}) {
12
+ // Строим команду: docker-compose -f <file> <args>
13
+ const cmd = `docker-compose -f ${composeFile} ${args.join(' ')}`;
14
+ logger.debug(`Executing docker-compose: ${cmd}`);
15
+ if (options.cwd) {
16
+ logger.debug(`Working directory: ${options.cwd}`);
17
+ }
18
+ try {
19
+ const output = execSync(cmd, {
20
+ cwd: options.cwd,
21
+ encoding: 'utf-8',
22
+ stdio: ['pipe', 'pipe', 'pipe'],
23
+ });
24
+ return output;
25
+ }
26
+ catch (error) {
27
+ logger.error('docker-compose command failed:', error);
28
+ const errorMessage = error.message || String(error);
29
+ throw new Error(`docker-compose failed: ${errorMessage}`);
30
+ }
31
+ }
32
+ }
33
+ //# sourceMappingURL=compose-exec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compose-exec.js","sourceRoot":"","sources":["../../src/utils/compose-exec.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,OAAO,WAAW;IACtB;;OAEG;IACH,MAAM,CAAC,GAAG,CACR,WAAmB,EACnB,IAAc,EACd,UAA4B,EAAE;QAE9B,kDAAkD;QAClD,MAAM,GAAG,GAAG,qBAAqB,WAAW,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAEjE,MAAM,CAAC,KAAK,CAAC,6BAA6B,GAAG,EAAE,CAAC,CAAC;QACjD,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;YAChB,MAAM,CAAC,KAAK,CAAC,sBAAsB,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QACpD,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,EAAE;gBAC3B,GAAG,EAAE,OAAO,CAAC,GAAG;gBAChB,QAAQ,EAAE,OAAO;gBACjB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;aAChC,CAAC,CAAC;YAEH,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,MAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE,KAAK,CAAC,CAAC;YACtD,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC;YACpD,MAAM,IAAI,KAAK,CAAC,0BAA0B,YAAY,EAAE,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Docker Client Wrapper
3
+ * Обёртка над Dockerode для централизованного управления
4
+ */
5
+ import Docker from 'dockerode';
6
+ /**
7
+ * Wrapper над Dockerode для централизованного управления
8
+ */
9
+ export declare class DockerClient {
10
+ private docker;
11
+ constructor();
12
+ /**
13
+ * Проверка подключения к Docker
14
+ */
15
+ ping(): Promise<void>;
16
+ /**
17
+ * Получить native Dockerode instance
18
+ */
19
+ getClient(): Docker;
20
+ /**
21
+ * Список контейнеров
22
+ */
23
+ listContainers(options?: Docker.ContainerListOptions): Promise<Docker.ContainerInfo[]>;
24
+ /**
25
+ * Получить контейнер по ID или имени
26
+ */
27
+ getContainer(id: string): Docker.Container;
28
+ }
29
+ /**
30
+ * Получить singleton instance DockerClient
31
+ */
32
+ export declare function getDockerClient(): DockerClient;
33
+ //# sourceMappingURL=docker-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker-client.d.ts","sourceRoot":"","sources":["../../src/utils/docker-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,MAAM,MAAM,WAAW,CAAC;AAG/B;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAS;;IAOvB;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAY3B;;OAEG;IACH,SAAS,IAAI,MAAM;IAInB;;OAEG;IACG,cAAc,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,oBAAoB;IAI1D;;OAEG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC,SAAS;CAG3C;AAKD;;GAEG;AACH,wBAAgB,eAAe,IAAI,YAAY,CAK9C"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Docker Client Wrapper
3
+ * Обёртка над Dockerode для централизованного управления
4
+ */
5
+ import Docker from 'dockerode';
6
+ import { logger } from './logger.js';
7
+ /**
8
+ * Wrapper над Dockerode для централизованного управления
9
+ */
10
+ export class DockerClient {
11
+ docker;
12
+ constructor() {
13
+ this.docker = new Docker();
14
+ logger.debug('Dockerode client initialized');
15
+ }
16
+ /**
17
+ * Проверка подключения к Docker
18
+ */
19
+ async ping() {
20
+ try {
21
+ await this.docker.ping();
22
+ logger.info('Docker connection verified');
23
+ }
24
+ catch (error) {
25
+ logger.error('Docker connection failed:', error);
26
+ throw new Error('Docker is not running. Please start Docker Desktop and try again.');
27
+ }
28
+ }
29
+ /**
30
+ * Получить native Dockerode instance
31
+ */
32
+ getClient() {
33
+ return this.docker;
34
+ }
35
+ /**
36
+ * Список контейнеров
37
+ */
38
+ async listContainers(options) {
39
+ return this.docker.listContainers(options);
40
+ }
41
+ /**
42
+ * Получить контейнер по ID или имени
43
+ */
44
+ getContainer(id) {
45
+ return this.docker.getContainer(id);
46
+ }
47
+ }
48
+ // Singleton instance
49
+ let dockerClientInstance = null;
50
+ /**
51
+ * Получить singleton instance DockerClient
52
+ */
53
+ export function getDockerClient() {
54
+ if (!dockerClientInstance) {
55
+ dockerClientInstance = new DockerClient();
56
+ }
57
+ return dockerClientInstance;
58
+ }
59
+ //# sourceMappingURL=docker-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker-client.js","sourceRoot":"","sources":["../../src/utils/docker-client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,MAAM,MAAM,WAAW,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC;;GAEG;AACH,MAAM,OAAO,YAAY;IACf,MAAM,CAAS;IAEvB;QACE,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;IAC/C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI;QACR,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACzB,MAAM,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QAC5C,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,MAAM,CAAC,KAAK,CAAC,2BAA2B,EAAE,KAAK,CAAC,CAAC;YACjD,MAAM,IAAI,KAAK,CACb,mEAAmE,CACpE,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACH,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,OAAqC;QACxD,OAAO,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;IAC7C,CAAC;IAED;;OAEG;IACH,YAAY,CAAC,EAAU;QACrB,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IACtC,CAAC;CACF;AAED,qBAAqB;AACrB,IAAI,oBAAoB,GAAwB,IAAI,CAAC;AAErD;;GAEG;AACH,MAAM,UAAU,eAAe;IAC7B,IAAI,CAAC,oBAAoB,EAAE,CAAC;QAC1B,oBAAoB,GAAG,IAAI,YAAY,EAAE,CAAC;IAC5C,CAAC;IACD,OAAO,oBAAoB,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Logger для MCP Server
3
+ * Выводит в stderr (stdout занят MCP протоколом)
4
+ */
5
+ type LogLevel = 'debug' | 'info' | 'warn' | 'error';
6
+ declare class Logger {
7
+ private level;
8
+ constructor(level?: LogLevel);
9
+ private shouldLog;
10
+ private log;
11
+ debug(message: string, ...args: any[]): void;
12
+ info(message: string, ...args: any[]): void;
13
+ warn(message: string, ...args: any[]): void;
14
+ error(message: string, ...args: any[]): void;
15
+ }
16
+ export declare const logger: Logger;
17
+ export {};
18
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,KAAK,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAEpD,cAAM,MAAM;IACV,OAAO,CAAC,KAAK,CAAoB;gBAErB,KAAK,CAAC,EAAE,QAAQ;IAI5B,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,GAAG;IAUX,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAI5C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAI3C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAI3C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;CAG7C;AAGD,eAAO,MAAM,MAAM,QAElB,CAAC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Logger для MCP Server
3
+ * Выводит в stderr (stdout занят MCP протоколом)
4
+ */
5
+ class Logger {
6
+ level = 'info';
7
+ constructor(level) {
8
+ if (level)
9
+ this.level = level;
10
+ }
11
+ shouldLog(level) {
12
+ const levels = ['debug', 'info', 'warn', 'error'];
13
+ return levels.indexOf(level) >= levels.indexOf(this.level);
14
+ }
15
+ log(level, message, ...args) {
16
+ if (!this.shouldLog(level))
17
+ return;
18
+ const timestamp = new Date().toISOString();
19
+ const prefix = `[${timestamp}] [${level.toUpperCase()}]`;
20
+ // MCP: stdout для протокола, stderr для логов
21
+ console.error(prefix, message, ...args);
22
+ }
23
+ debug(message, ...args) {
24
+ this.log('debug', message, ...args);
25
+ }
26
+ info(message, ...args) {
27
+ this.log('info', message, ...args);
28
+ }
29
+ warn(message, ...args) {
30
+ this.log('warn', message, ...args);
31
+ }
32
+ error(message, ...args) {
33
+ this.log('error', message, ...args);
34
+ }
35
+ }
36
+ // Singleton instance
37
+ export const logger = new Logger(process.env.LOG_LEVEL || 'info');
38
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,MAAM;IACF,KAAK,GAAa,MAAM,CAAC;IAEjC,YAAY,KAAgB;QAC1B,IAAI,KAAK;YAAE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IAChC,CAAC;IAEO,SAAS,CAAC,KAAe;QAC/B,MAAM,MAAM,GAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QAC9D,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7D,CAAC;IAEO,GAAG,CAAC,KAAe,EAAE,OAAe,EAAE,GAAG,IAAW;QAC1D,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;YAAE,OAAO;QAEnC,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC3C,MAAM,MAAM,GAAG,IAAI,SAAS,MAAM,KAAK,CAAC,WAAW,EAAE,GAAG,CAAC;QAEzD,8CAA8C;QAC9C,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAG,IAAW;QACnC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACtC,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAG,IAAW;QAClC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACrC,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAG,IAAW;QAClC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACrC,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAG,IAAW;QACnC,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IACtC,CAAC;CACF;AAED,qBAAqB;AACrB,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,MAAM,CAC7B,OAAO,CAAC,GAAG,CAAC,SAAsB,IAAI,MAAM,CAC9C,CAAC"}
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "@hypnosis/docker-mcp-server",
3
+ "version": "1.0.0",
4
+ "description": "Universal Docker MCP server for AI assistants (Cursor, Claude Desktop)",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "bin": {
9
+ "docker-mcp-server": "dist/index.js",
10
+ "docker-mcp-server-cli": "dist/cli.js"
11
+ },
12
+ "files": [
13
+ "dist",
14
+ "README.md",
15
+ "LICENSE"
16
+ ],
17
+ "scripts": {
18
+ "build": "tsc",
19
+ "prepare": "npm run build",
20
+ "start": "node dist/index.js",
21
+ "dev": "tsx src/index.ts",
22
+ "clean": "rm -rf dist",
23
+ "test": "vitest run",
24
+ "test:watch": "vitest",
25
+ "test:ui": "vitest --ui",
26
+ "test:coverage": "vitest run --coverage",
27
+ "prepublishOnly": "npm run build && npm test",
28
+ "publish:dry": "npm pack --dry-run",
29
+ "publish:check": "npm pack && tar -tzf *.tgz | head -20 && rm -f *.tgz",
30
+ "publish:npm": "npm publish --access public"
31
+ },
32
+ "dependencies": {
33
+ "@modelcontextprotocol/sdk": "^0.6.0",
34
+ "dockerode": "^4.0.2",
35
+ "dotenv": "^16.4.5",
36
+ "yaml": "^2.3.4"
37
+ },
38
+ "devDependencies": {
39
+ "@types/dockerode": "^3.3.31",
40
+ "@types/node": "^20.11.0",
41
+ "@vitest/coverage-v8": "^4.0.16",
42
+ "@vitest/ui": "^4.0.16",
43
+ "tsx": "^4.7.0",
44
+ "typescript": "^5.3.0",
45
+ "vitest": "^4.0.16"
46
+ },
47
+ "engines": {
48
+ "node": ">=18.0.0"
49
+ },
50
+ "keywords": [
51
+ "mcp",
52
+ "docker",
53
+ "docker-compose",
54
+ "cursor",
55
+ "claude",
56
+ "ai",
57
+ "model-context-protocol"
58
+ ],
59
+ "author": "Danila Susak <danilasusak@gmail.com>",
60
+ "license": "MIT",
61
+ "repository": {
62
+ "type": "git",
63
+ "url": "git+https://github.com/hypnosis/docker-mcp-server.git"
64
+ }
65
+ }