@hypnosis/docker-mcp-server 1.0.3 → 1.2.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 +95 -22
- package/dist/adapters/redis.d.ts.map +1 -1
- package/dist/adapters/redis.js +18 -6
- package/dist/adapters/redis.js.map +1 -1
- package/dist/discovery/compose-parser.d.ts +4 -0
- package/dist/discovery/compose-parser.d.ts.map +1 -1
- package/dist/discovery/compose-parser.js +25 -0
- package/dist/discovery/compose-parser.js.map +1 -1
- package/dist/discovery/project-discovery.d.ts.map +1 -1
- package/dist/discovery/project-discovery.js +24 -0
- package/dist/discovery/project-discovery.js.map +1 -1
- package/dist/discovery/remote-discovery.d.ts +99 -0
- package/dist/discovery/remote-discovery.d.ts.map +1 -0
- package/dist/discovery/remote-discovery.js +410 -0
- package/dist/discovery/remote-discovery.js.map +1 -0
- package/dist/discovery/types.d.ts +4 -0
- package/dist/discovery/types.d.ts.map +1 -1
- package/dist/index.js +87 -14
- package/dist/index.js.map +1 -1
- package/dist/managers/compose-manager.d.ts +3 -1
- package/dist/managers/compose-manager.d.ts.map +1 -1
- package/dist/managers/compose-manager.js +10 -1
- package/dist/managers/compose-manager.js.map +1 -1
- package/dist/managers/container-manager.d.ts +53 -1
- package/dist/managers/container-manager.d.ts.map +1 -1
- package/dist/managers/container-manager.js +175 -71
- package/dist/managers/container-manager.js.map +1 -1
- package/dist/tools/container-tools.d.ts +9 -1
- package/dist/tools/container-tools.d.ts.map +1 -1
- package/dist/tools/container-tools.js +231 -14
- package/dist/tools/container-tools.js.map +1 -1
- package/dist/tools/database-tools.d.ts.map +1 -1
- package/dist/tools/database-tools.js +36 -4
- package/dist/tools/database-tools.js.map +1 -1
- package/dist/tools/discovery-tools.d.ts +29 -0
- package/dist/tools/discovery-tools.d.ts.map +1 -0
- package/dist/tools/discovery-tools.js +173 -0
- package/dist/tools/discovery-tools.js.map +1 -0
- package/dist/tools/env-tools.d.ts +5 -0
- package/dist/tools/env-tools.d.ts.map +1 -1
- package/dist/tools/env-tools.js +158 -15
- package/dist/tools/env-tools.js.map +1 -1
- package/dist/tools/executor-tool.d.ts +5 -0
- package/dist/tools/executor-tool.d.ts.map +1 -1
- package/dist/tools/executor-tool.js +60 -5
- package/dist/tools/executor-tool.js.map +1 -1
- package/dist/tools/mcp-health-tool.d.ts +11 -0
- package/dist/tools/mcp-health-tool.d.ts.map +1 -1
- package/dist/tools/mcp-health-tool.js +25 -4
- package/dist/tools/mcp-health-tool.js.map +1 -1
- package/dist/tools/profile-tool.d.ts +46 -0
- package/dist/tools/profile-tool.d.ts.map +1 -0
- package/dist/tools/profile-tool.js +91 -0
- package/dist/tools/profile-tool.js.map +1 -0
- package/dist/utils/compose-exec.d.ts +28 -3
- package/dist/utils/compose-exec.d.ts.map +1 -1
- package/dist/utils/compose-exec.js +100 -26
- package/dist/utils/compose-exec.js.map +1 -1
- package/dist/utils/docker-client.d.ts +73 -8
- package/dist/utils/docker-client.d.ts.map +1 -1
- package/dist/utils/docker-client.js +492 -16
- package/dist/utils/docker-client.js.map +1 -1
- package/dist/utils/profiles-file.d.ts +57 -0
- package/dist/utils/profiles-file.d.ts.map +1 -0
- package/dist/utils/profiles-file.js +167 -0
- package/dist/utils/profiles-file.js.map +1 -0
- package/dist/utils/retry.d.ts +49 -0
- package/dist/utils/retry.d.ts.map +1 -0
- package/dist/utils/retry.js +120 -0
- package/dist/utils/retry.js.map +1 -0
- package/dist/utils/ssh-config.d.ts +104 -0
- package/dist/utils/ssh-config.d.ts.map +1 -0
- package/dist/utils/ssh-config.js +346 -0
- package/dist/utils/ssh-config.js.map +1 -0
- package/dist/utils/ssh-exec.d.ts +59 -0
- package/dist/utils/ssh-exec.d.ts.map +1 -0
- package/dist/utils/ssh-exec.js +156 -0
- package/dist/utils/ssh-exec.js.map +1 -0
- package/package.json +21 -3
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Remote Project Discovery
|
|
3
|
+
* Find and parse docker-compose projects on remote servers via SSH
|
|
4
|
+
*/
|
|
5
|
+
import { logger } from '../utils/logger.js';
|
|
6
|
+
import { execSSH, readRemoteFile } from '../utils/ssh-exec.js';
|
|
7
|
+
import { ComposeParser } from './compose-parser.js';
|
|
8
|
+
/**
|
|
9
|
+
* Remote project discovery class
|
|
10
|
+
*/
|
|
11
|
+
export class RemoteProjectDiscovery {
|
|
12
|
+
dockerClientWrapper;
|
|
13
|
+
sshConfig;
|
|
14
|
+
composeParser;
|
|
15
|
+
constructor(sshConfig, dockerClientWrapper) {
|
|
16
|
+
this.sshConfig = sshConfig;
|
|
17
|
+
this.dockerClientWrapper = dockerClientWrapper;
|
|
18
|
+
this.composeParser = new ComposeParser();
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Discover all docker-compose projects on remote server
|
|
22
|
+
* Uses only Docker labels (fast mode) - no compose file reading (~2s)
|
|
23
|
+
* For detailed info about specific project, use getProjectStatus()
|
|
24
|
+
*/
|
|
25
|
+
async discoverProjects(options) {
|
|
26
|
+
const { basePath, timeout = 60000 } = options;
|
|
27
|
+
// Determine base path
|
|
28
|
+
const projectsPath = basePath || this.sshConfig.projectsPath || '/var/www';
|
|
29
|
+
logger.info(`Discovering Docker projects in ${projectsPath} on ${this.sshConfig.host}`);
|
|
30
|
+
try {
|
|
31
|
+
return await this.discoverProjectsFast(projectsPath, timeout);
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
logger.error(`Failed to discover projects: ${error.message}`);
|
|
35
|
+
throw error;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Discover projects using only Docker labels
|
|
40
|
+
* No compose file reading - fast and scalable!
|
|
41
|
+
* For detailed info about specific project, use getProjectStatus()
|
|
42
|
+
*/
|
|
43
|
+
async discoverProjectsFast(projectsPath, timeout) {
|
|
44
|
+
logger.debug('Discovering projects using Docker labels only');
|
|
45
|
+
try {
|
|
46
|
+
// Get ALL containers (running + stopped) with labels in ONE command
|
|
47
|
+
const inspectResult = await execSSH(`docker ps -a -q | xargs -r docker inspect --format '{{.Name}}\t{{.State.Status}}\t{{index .Config.Labels "com.docker.compose.project"}}\t{{index .Config.Labels "com.docker.compose.service"}}\t{{index .Config.Labels "com.docker.compose.project.working_dir"}}'`, {
|
|
48
|
+
sshConfig: this.sshConfig,
|
|
49
|
+
timeout,
|
|
50
|
+
});
|
|
51
|
+
if (inspectResult.code !== 0 || !inspectResult.stdout) {
|
|
52
|
+
logger.warn('Failed to get containers via SSH, falling back to empty result');
|
|
53
|
+
return {
|
|
54
|
+
projects: [],
|
|
55
|
+
summary: { total: 0, running: 0, partial: 0, stopped: 0 },
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
// Parse results and group by project
|
|
59
|
+
const projectsMap = new Map();
|
|
60
|
+
const lines = inspectResult.stdout.trim().split('\n').filter(l => l.trim());
|
|
61
|
+
for (const line of lines) {
|
|
62
|
+
const [name, status, project, service, path] = line.split('\t');
|
|
63
|
+
if (!name || !project || project.trim() === '') {
|
|
64
|
+
continue; // Skip containers without compose project label
|
|
65
|
+
}
|
|
66
|
+
const cleanName = name.replace(/^\//, '').trim();
|
|
67
|
+
const projectName = project.trim();
|
|
68
|
+
const projectPath = (path || '').trim() || projectsPath;
|
|
69
|
+
const containerStatus = status.trim();
|
|
70
|
+
const serviceName = (service || '').trim();
|
|
71
|
+
if (!projectsMap.has(projectName)) {
|
|
72
|
+
projectsMap.set(projectName, {
|
|
73
|
+
name: projectName,
|
|
74
|
+
path: projectPath,
|
|
75
|
+
containers: [],
|
|
76
|
+
running: 0,
|
|
77
|
+
stopped: 0,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
const projectData = projectsMap.get(projectName);
|
|
81
|
+
projectData.containers.push({
|
|
82
|
+
name: cleanName,
|
|
83
|
+
status: containerStatus,
|
|
84
|
+
service: serviceName,
|
|
85
|
+
});
|
|
86
|
+
if (containerStatus === 'running') {
|
|
87
|
+
projectData.running++;
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
projectData.stopped++;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Convert to DiscoveredProject format
|
|
94
|
+
const projects = Array.from(projectsMap.values()).map(projectData => {
|
|
95
|
+
const totalContainers = projectData.containers.length;
|
|
96
|
+
let status;
|
|
97
|
+
if (projectData.running === totalContainers && totalContainers > 0) {
|
|
98
|
+
status = 'running';
|
|
99
|
+
}
|
|
100
|
+
else if (projectData.running > 0) {
|
|
101
|
+
status = 'partial';
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
status = 'stopped';
|
|
105
|
+
}
|
|
106
|
+
// Find issues
|
|
107
|
+
const issues = [];
|
|
108
|
+
for (const container of projectData.containers) {
|
|
109
|
+
if (container.status === 'restarting') {
|
|
110
|
+
issues.push(`${container.name}: restarting`);
|
|
111
|
+
}
|
|
112
|
+
else if (container.status === 'exited') {
|
|
113
|
+
issues.push(`${container.name}: exited`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return {
|
|
117
|
+
name: projectData.name,
|
|
118
|
+
path: projectData.path,
|
|
119
|
+
composeFile: `${projectData.path}/docker-compose.yml`, // Estimated path
|
|
120
|
+
services: projectData.containers.map(c => c.service).filter(s => s), // Services from labels
|
|
121
|
+
status,
|
|
122
|
+
runningContainers: projectData.running,
|
|
123
|
+
totalServices: totalContainers, // Approximate (from containers)
|
|
124
|
+
issues,
|
|
125
|
+
};
|
|
126
|
+
});
|
|
127
|
+
const summary = this.calculateSummary(projects);
|
|
128
|
+
logger.info(`Discovered ${projects.length} projects: ${summary.running} running, ${summary.partial} partial, ${summary.stopped} stopped`);
|
|
129
|
+
return {
|
|
130
|
+
projects,
|
|
131
|
+
summary,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
catch (error) {
|
|
135
|
+
logger.error(`Discovery failed: ${error.message}`);
|
|
136
|
+
throw error;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Get running containers via SSH (more reliable than Docker API through tunnel)
|
|
141
|
+
* Optimized: single command to get all containers with labels
|
|
142
|
+
*/
|
|
143
|
+
async getRunningContainersViaSSH(timeout) {
|
|
144
|
+
const runningMap = new Map();
|
|
145
|
+
try {
|
|
146
|
+
// Get all running containers with labels in ONE command (much faster!)
|
|
147
|
+
const inspectResult = await execSSH(`docker ps -q | xargs -r docker inspect --format '{{.Name}}\t{{index .Config.Labels "com.docker.compose.project"}}\t{{index .Config.Labels "com.docker.compose.service"}}\t{{.State.Status}}'`, {
|
|
148
|
+
sshConfig: this.sshConfig,
|
|
149
|
+
timeout,
|
|
150
|
+
});
|
|
151
|
+
if (inspectResult.code === 0 && inspectResult.stdout) {
|
|
152
|
+
const lines = inspectResult.stdout.trim().split('\n').filter(l => l.trim());
|
|
153
|
+
for (const line of lines) {
|
|
154
|
+
const [name, project, service, state] = line.split('\t');
|
|
155
|
+
if (name && project) {
|
|
156
|
+
// Remove leading slash from container name
|
|
157
|
+
const cleanName = name.replace(/^\//, '');
|
|
158
|
+
runningMap.set(cleanName, {
|
|
159
|
+
name: cleanName,
|
|
160
|
+
project: project.trim(),
|
|
161
|
+
service: (service || '').trim(),
|
|
162
|
+
state: (state || 'running').trim(),
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
logger.debug(`Found ${runningMap.size} running containers via SSH`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
logger.warn(`Failed to get running containers via SSH: ${error.message}`);
|
|
171
|
+
}
|
|
172
|
+
return runningMap;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Discover a single project from compose file
|
|
176
|
+
*/
|
|
177
|
+
async discoverProject(composeFile, allContainers, runningContainersViaSSH, timeout) {
|
|
178
|
+
try {
|
|
179
|
+
// Read and parse compose file
|
|
180
|
+
const composeContent = await readRemoteFile(composeFile, {
|
|
181
|
+
sshConfig: this.sshConfig,
|
|
182
|
+
timeout,
|
|
183
|
+
});
|
|
184
|
+
const projectConfig = this.composeParser.parseFromString(composeContent, composeFile);
|
|
185
|
+
// Extract project name from directory
|
|
186
|
+
const projectDir = composeFile.replace(/\/docker-compose\.yml$/, '').replace(/\/compose\.yml$/, '');
|
|
187
|
+
const projectName = projectConfig.name || projectDir.split('/').pop() || 'unknown';
|
|
188
|
+
// Get service names from compose
|
|
189
|
+
const services = Object.keys(projectConfig.services || {});
|
|
190
|
+
// Find containers for this project from Docker API
|
|
191
|
+
const projectContainers = allContainers.filter(container => {
|
|
192
|
+
const labels = container.Labels || {};
|
|
193
|
+
return labels['com.docker.compose.project'] === projectName ||
|
|
194
|
+
labels['com.docker.compose.project.working_dir'] === projectDir;
|
|
195
|
+
});
|
|
196
|
+
// Also check running containers via SSH (more reliable)
|
|
197
|
+
const runningViaSSH = Array.from(runningContainersViaSSH.values()).filter(c => c.project === projectName);
|
|
198
|
+
// Combine: use SSH data for running status, API data for stopped containers
|
|
199
|
+
const runningContainerNames = new Set(runningViaSSH.map(c => c.name));
|
|
200
|
+
const runningCount = runningContainerNames.size;
|
|
201
|
+
// Match containers with services
|
|
202
|
+
// Count running: use SSH data (more accurate)
|
|
203
|
+
// Count stopped: use API data
|
|
204
|
+
const stoppedContainers = projectContainers.filter(c => {
|
|
205
|
+
const name = c.Names[0]?.replace(/^\//, '') || '';
|
|
206
|
+
return !runningContainerNames.has(name) && c.State !== 'running';
|
|
207
|
+
}).length;
|
|
208
|
+
// Determine status based on running containers from SSH
|
|
209
|
+
let status;
|
|
210
|
+
if (runningCount === services.length && services.length > 0) {
|
|
211
|
+
status = 'running';
|
|
212
|
+
}
|
|
213
|
+
else if (runningCount > 0) {
|
|
214
|
+
status = 'partial';
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
status = 'stopped';
|
|
218
|
+
}
|
|
219
|
+
// Find issues
|
|
220
|
+
const issues = [];
|
|
221
|
+
for (const container of projectContainers) {
|
|
222
|
+
if (container.State === 'restarting') {
|
|
223
|
+
const name = container.Names[0]?.replace(/^\//, '') || 'unknown';
|
|
224
|
+
issues.push(`${name}: restarting`);
|
|
225
|
+
}
|
|
226
|
+
else if (container.State === 'exited' && container.Status?.includes('Exited')) {
|
|
227
|
+
const name = container.Names[0]?.replace(/^\//, '') || 'unknown';
|
|
228
|
+
const exitCode = container.Status.match(/Exited \((\d+)\)/)?.[1] || '?';
|
|
229
|
+
issues.push(`${name}: exited with code ${exitCode}`);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
return {
|
|
233
|
+
name: projectName,
|
|
234
|
+
path: projectDir,
|
|
235
|
+
composeFile,
|
|
236
|
+
services,
|
|
237
|
+
status,
|
|
238
|
+
runningContainers: runningCount,
|
|
239
|
+
totalServices: services.length,
|
|
240
|
+
issues,
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
catch (error) {
|
|
244
|
+
logger.debug(`Failed to parse project from ${composeFile}: ${error.message}`);
|
|
245
|
+
return null;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Get detailed status for a specific project
|
|
250
|
+
* Optimized: Uses Docker filter + path from label, NO find!
|
|
251
|
+
*/
|
|
252
|
+
async getProjectStatus(projectName, options) {
|
|
253
|
+
const { basePath, timeout = 30000 } = options;
|
|
254
|
+
const projectsPath = basePath || this.sshConfig.projectsPath || '/var/www';
|
|
255
|
+
try {
|
|
256
|
+
// Step 1: Get containers for this project ONLY via SSH filter (fast!)
|
|
257
|
+
const inspectResult = await execSSH(`docker ps -a --filter label=com.docker.compose.project=${projectName} -q | xargs -r docker inspect --format '{{.Name}}\t{{.State.Status}}\t{{index .Config.Labels "com.docker.compose.service"}}\t{{index .Config.Labels "com.docker.compose.project.working_dir"}}'`, {
|
|
258
|
+
sshConfig: this.sshConfig,
|
|
259
|
+
timeout,
|
|
260
|
+
});
|
|
261
|
+
if (inspectResult.code !== 0 || !inspectResult.stdout || inspectResult.stdout.trim() === '') {
|
|
262
|
+
logger.debug(`No containers found for project: ${projectName}`);
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
// Step 2: Parse first container to get project path
|
|
266
|
+
const lines = inspectResult.stdout.trim().split('\n').filter(l => l.trim());
|
|
267
|
+
if (lines.length === 0) {
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
const firstLine = lines[0].split('\t');
|
|
271
|
+
const projectPath = (firstLine[3] || '').trim() || projectsPath;
|
|
272
|
+
// Step 3: Read compose file ONLY for this project (no find!)
|
|
273
|
+
let composeFile = `${projectPath}/docker-compose.yml`;
|
|
274
|
+
let composeContent;
|
|
275
|
+
try {
|
|
276
|
+
composeContent = await readRemoteFile(composeFile, {
|
|
277
|
+
sshConfig: this.sshConfig,
|
|
278
|
+
timeout,
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
catch (error) {
|
|
282
|
+
// Try alternative name
|
|
283
|
+
composeFile = `${projectPath}/compose.yml`;
|
|
284
|
+
try {
|
|
285
|
+
composeContent = await readRemoteFile(composeFile, {
|
|
286
|
+
sshConfig: this.sshConfig,
|
|
287
|
+
timeout,
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
catch (error2) {
|
|
291
|
+
logger.warn(`Compose file not found for ${projectName} at ${projectPath}`);
|
|
292
|
+
// Return basic info from labels only
|
|
293
|
+
return this.getProjectStatusFromLabels(projectName, projectPath, lines);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
// Step 4: Parse compose and get full details
|
|
297
|
+
const projectConfig = this.composeParser.parseFromString(composeContent, composeFile);
|
|
298
|
+
const services = Object.keys(projectConfig.services || {});
|
|
299
|
+
// Step 5: Get all containers for matching
|
|
300
|
+
const allContainers = await this.dockerClientWrapper.listContainers({ all: true });
|
|
301
|
+
const runningContainersViaSSH = await this.getRunningContainersViaSSH(timeout);
|
|
302
|
+
// Step 6: Match containers with services
|
|
303
|
+
const projectContainers = allContainers.filter(container => {
|
|
304
|
+
const labels = container.Labels || {};
|
|
305
|
+
return labels['com.docker.compose.project'] === projectName;
|
|
306
|
+
});
|
|
307
|
+
const runningViaSSH = Array.from(runningContainersViaSSH.values()).filter(c => c.project === projectName);
|
|
308
|
+
const runningContainerNames = new Set(runningViaSSH.map(c => c.name));
|
|
309
|
+
const runningCount = runningContainerNames.size;
|
|
310
|
+
// Determine status
|
|
311
|
+
let status;
|
|
312
|
+
if (runningCount === services.length && services.length > 0) {
|
|
313
|
+
status = 'running';
|
|
314
|
+
}
|
|
315
|
+
else if (runningCount > 0) {
|
|
316
|
+
status = 'partial';
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
status = 'stopped';
|
|
320
|
+
}
|
|
321
|
+
// Find issues
|
|
322
|
+
const issues = [];
|
|
323
|
+
for (const container of projectContainers) {
|
|
324
|
+
if (container.State === 'restarting') {
|
|
325
|
+
const name = container.Names[0]?.replace(/^\//, '') || 'unknown';
|
|
326
|
+
issues.push(`${name}: restarting`);
|
|
327
|
+
}
|
|
328
|
+
else if (container.State === 'exited' && container.Status?.includes('Exited')) {
|
|
329
|
+
const name = container.Names[0]?.replace(/^\//, '') || 'unknown';
|
|
330
|
+
const exitCode = container.Status.match(/Exited \((\d+)\)/)?.[1] || '?';
|
|
331
|
+
issues.push(`${name}: exited with code ${exitCode}`);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
return {
|
|
335
|
+
name: projectName,
|
|
336
|
+
path: projectPath,
|
|
337
|
+
composeFile,
|
|
338
|
+
services,
|
|
339
|
+
status,
|
|
340
|
+
runningContainers: runningCount,
|
|
341
|
+
totalServices: services.length,
|
|
342
|
+
issues,
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
catch (error) {
|
|
346
|
+
logger.error(`Failed to get project status for ${projectName}: ${error.message}`);
|
|
347
|
+
return null;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Get basic project status from labels only (fallback when compose file not found)
|
|
352
|
+
*/
|
|
353
|
+
getProjectStatusFromLabels(projectName, projectPath, containerLines) {
|
|
354
|
+
let running = 0;
|
|
355
|
+
let stopped = 0;
|
|
356
|
+
const services = [];
|
|
357
|
+
const issues = [];
|
|
358
|
+
for (const line of containerLines) {
|
|
359
|
+
const [name, status, service] = line.split('\t');
|
|
360
|
+
if (service && service.trim()) {
|
|
361
|
+
services.push(service.trim());
|
|
362
|
+
}
|
|
363
|
+
if (status.trim() === 'running') {
|
|
364
|
+
running++;
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
stopped++;
|
|
368
|
+
if (status.trim() === 'restarting') {
|
|
369
|
+
issues.push(`${name.replace(/^\//, '')}: restarting`);
|
|
370
|
+
}
|
|
371
|
+
else if (status.trim() === 'exited') {
|
|
372
|
+
issues.push(`${name.replace(/^\//, '')}: exited`);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
let status;
|
|
377
|
+
const total = running + stopped;
|
|
378
|
+
if (running === total && total > 0) {
|
|
379
|
+
status = 'running';
|
|
380
|
+
}
|
|
381
|
+
else if (running > 0) {
|
|
382
|
+
status = 'partial';
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
status = 'stopped';
|
|
386
|
+
}
|
|
387
|
+
return {
|
|
388
|
+
name: projectName,
|
|
389
|
+
path: projectPath,
|
|
390
|
+
composeFile: `${projectPath}/docker-compose.yml`,
|
|
391
|
+
services: [...new Set(services)], // Unique services
|
|
392
|
+
status,
|
|
393
|
+
runningContainers: running,
|
|
394
|
+
totalServices: total,
|
|
395
|
+
issues,
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Calculate summary statistics
|
|
400
|
+
*/
|
|
401
|
+
calculateSummary(projects) {
|
|
402
|
+
return {
|
|
403
|
+
total: projects.length,
|
|
404
|
+
running: projects.filter(p => p.status === 'running').length,
|
|
405
|
+
partial: projects.filter(p => p.status === 'partial').length,
|
|
406
|
+
stopped: projects.filter(p => p.status === 'stopped').length,
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
//# sourceMappingURL=remote-discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remote-discovery.js","sourceRoot":"","sources":["../../src/discovery/remote-discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -32,6 +32,8 @@ export interface ServiceConfig {
|
|
|
32
32
|
ports?: string[];
|
|
33
33
|
/** Environment variables */
|
|
34
34
|
environment?: Record<string, string>;
|
|
35
|
+
/** Working directory */
|
|
36
|
+
working_dir?: string;
|
|
35
37
|
/** Тип сервиса (для database adapters в Sprint 2) */
|
|
36
38
|
type: 'generic' | 'postgresql' | 'redis' | 'sqlite' | 'mysql' | 'mongodb';
|
|
37
39
|
}
|
|
@@ -43,5 +45,7 @@ export interface DiscoveryOptions {
|
|
|
43
45
|
cwd?: string;
|
|
44
46
|
/** Explicit path к compose file */
|
|
45
47
|
explicitPath?: string;
|
|
48
|
+
/** Explicit project name (for remote Docker without local compose file) */
|
|
49
|
+
explicitProjectName?: string;
|
|
46
50
|
}
|
|
47
51
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/discovery/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAC;IAEb,gCAAgC;IAChC,WAAW,EAAE,MAAM,CAAC;IAEpB,yBAAyB;IACzB,UAAU,EAAE,MAAM,CAAC;IAEnB,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IAEb,mBAAmB;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,mBAAmB;IACnB,KAAK,CAAC,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IAEF,YAAY;IACZ,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAEjB,4BAA4B;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAErC,qDAAqD;IACrD,IAAI,EAAE,SAAS,GAAG,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;CAC3E;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,iDAAiD;IACjD,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,mCAAmC;IACnC,YAAY,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/discovery/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAC;IAEb,gCAAgC;IAChC,WAAW,EAAE,MAAM,CAAC;IAEpB,yBAAyB;IACzB,UAAU,EAAE,MAAM,CAAC;IAEnB,8BAA8B;IAC9B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;CACzC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IAEb,mBAAmB;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,mBAAmB;IACnB,KAAK,CAAC,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;IAEF,YAAY;IACZ,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAEjB,4BAA4B;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAErC,wBAAwB;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,qDAAqD;IACrD,IAAI,EAAE,SAAS,GAAG,YAAY,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;CAC3E;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,iDAAiD;IACjD,GAAG,CAAC,EAAE,MAAM,CAAC;IAEb,mCAAmC;IACnC,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,2EAA2E;IAC3E,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B"}
|
package/dist/index.js
CHANGED
|
@@ -10,13 +10,16 @@ import { readFileSync } from 'fs';
|
|
|
10
10
|
import { fileURLToPath } from 'url';
|
|
11
11
|
import { dirname, join } from 'path';
|
|
12
12
|
import { logger } from './utils/logger.js';
|
|
13
|
-
import { getDockerClient } from './utils/docker-client.js';
|
|
13
|
+
import { getDockerClient, cleanupAllDockerClients } from './utils/docker-client.js';
|
|
14
|
+
import { loadSSHConfig } from './utils/ssh-config.js';
|
|
14
15
|
import { workspaceManager } from './utils/workspace.js';
|
|
15
16
|
import { ContainerTools } from './tools/container-tools.js';
|
|
16
17
|
import { ExecutorTool } from './tools/executor-tool.js';
|
|
17
18
|
import { DatabaseTools } from './tools/database-tools.js';
|
|
18
19
|
import { EnvTools } from './tools/env-tools.js';
|
|
19
20
|
import { MCPHealthTool } from './tools/mcp-health-tool.js';
|
|
21
|
+
import { ProfileTool } from './tools/profile-tool.js';
|
|
22
|
+
import { DiscoveryTools } from './tools/discovery-tools.js';
|
|
20
23
|
import { adapterRegistry } from './adapters/adapter-registry.js';
|
|
21
24
|
import { PostgreSQLAdapter } from './adapters/postgresql.js';
|
|
22
25
|
import { RedisAdapter } from './adapters/redis.js';
|
|
@@ -35,9 +38,25 @@ async function main() {
|
|
|
35
38
|
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
36
39
|
const version = packageJson.version || '1.0.0';
|
|
37
40
|
logger.info(`Starting Docker MCP Server v${version}`);
|
|
41
|
+
// Load SSH configuration (if provided)
|
|
42
|
+
const sshConfigResult = loadSSHConfig();
|
|
43
|
+
// Log errors only if config was expected but failed (not graceful fallbacks)
|
|
44
|
+
const hasNonFallbackErrors = sshConfigResult.errors.length > 0 &&
|
|
45
|
+
!sshConfigResult.errors.some(e => e.includes('not found') ||
|
|
46
|
+
e.includes('Falling back to local Docker'));
|
|
47
|
+
if (hasNonFallbackErrors) {
|
|
48
|
+
logger.warn('SSH configuration warnings:', sshConfigResult.errors);
|
|
49
|
+
}
|
|
50
|
+
const sshConfig = sshConfigResult.config;
|
|
51
|
+
if (sshConfig) {
|
|
52
|
+
logger.info(`SSH configuration loaded for remote Docker: ${sshConfig.host}:${sshConfig.port || 22}`);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
logger.info('Using local Docker (no SSH configuration provided)');
|
|
56
|
+
}
|
|
38
57
|
// Docker check
|
|
39
58
|
try {
|
|
40
|
-
const docker = getDockerClient();
|
|
59
|
+
const docker = getDockerClient(sshConfig);
|
|
41
60
|
await docker.ping();
|
|
42
61
|
}
|
|
43
62
|
catch (error) {
|
|
@@ -52,11 +71,13 @@ async function main() {
|
|
|
52
71
|
adapterRegistry.register('sqlite3', new SQLiteAdapter()); // alias
|
|
53
72
|
logger.info('Database adapters registered: PostgreSQL, Redis, SQLite');
|
|
54
73
|
// Initialize tools
|
|
55
|
-
const containerTools = new ContainerTools();
|
|
74
|
+
const containerTools = new ContainerTools(sshConfig);
|
|
56
75
|
const executorTool = new ExecutorTool();
|
|
57
76
|
const databaseTools = new DatabaseTools();
|
|
58
77
|
const envTools = new EnvTools();
|
|
59
|
-
const mcpHealthTool = new MCPHealthTool();
|
|
78
|
+
const mcpHealthTool = new MCPHealthTool(sshConfig);
|
|
79
|
+
const profileTool = new ProfileTool(sshConfig, process.env.DOCKER_MCP_PROFILES_FILE);
|
|
80
|
+
const discoveryTools = new DiscoveryTools(sshConfig);
|
|
60
81
|
// Create MCP Server
|
|
61
82
|
const server = new Server({
|
|
62
83
|
name: 'docker-mcp-server',
|
|
@@ -97,14 +118,20 @@ async function main() {
|
|
|
97
118
|
// Register tools
|
|
98
119
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
99
120
|
logger.debug('ListTools request received');
|
|
121
|
+
const allTools = [
|
|
122
|
+
...containerTools.getTools(),
|
|
123
|
+
executorTool.getTool(),
|
|
124
|
+
...databaseTools.getTools(),
|
|
125
|
+
...envTools.getTools(),
|
|
126
|
+
mcpHealthTool.getTool(),
|
|
127
|
+
profileTool.getTool(),
|
|
128
|
+
...discoveryTools.getTools(),
|
|
129
|
+
];
|
|
130
|
+
// Log actual count for debugging
|
|
131
|
+
logger.info(`Returning ${allTools.length} tools to MCP client`);
|
|
132
|
+
logger.debug(`Tool names: ${allTools.map(t => t.name).join(', ')}`);
|
|
100
133
|
return {
|
|
101
|
-
tools:
|
|
102
|
-
...containerTools.getTools(),
|
|
103
|
-
executorTool.getTool(),
|
|
104
|
-
...databaseTools.getTools(),
|
|
105
|
-
...envTools.getTools(),
|
|
106
|
-
mcpHealthTool.getTool(),
|
|
107
|
-
],
|
|
134
|
+
tools: allTools,
|
|
108
135
|
};
|
|
109
136
|
});
|
|
110
137
|
// Handle tool calls
|
|
@@ -115,8 +142,8 @@ async function main() {
|
|
|
115
142
|
if (toolName.startsWith('docker_env_') || toolName === 'docker_compose_config' || toolName === 'docker_healthcheck') {
|
|
116
143
|
return envTools.handleCall(request);
|
|
117
144
|
}
|
|
118
|
-
// Container tools (including compose up/down commands)
|
|
119
|
-
if (toolName.startsWith('docker_container_') || toolName === 'docker_compose_up' || toolName === 'docker_compose_down') {
|
|
145
|
+
// Container tools (including compose up/down commands and resource management)
|
|
146
|
+
if (toolName.startsWith('docker_container_') || toolName === 'docker_compose_up' || toolName === 'docker_compose_down' || toolName === 'docker_resource_list') {
|
|
120
147
|
return containerTools.handleCall(request);
|
|
121
148
|
}
|
|
122
149
|
// Executor tool
|
|
@@ -131,18 +158,64 @@ async function main() {
|
|
|
131
158
|
if (toolName === 'docker_mcp_health') {
|
|
132
159
|
return mcpHealthTool.handleCall(request);
|
|
133
160
|
}
|
|
161
|
+
// Profile tool
|
|
162
|
+
if (toolName === 'docker_profile_info') {
|
|
163
|
+
return profileTool.handleCall(request);
|
|
164
|
+
}
|
|
165
|
+
// Discovery tools
|
|
166
|
+
if (toolName === 'docker_projects') {
|
|
167
|
+
return discoveryTools.handleCall(request);
|
|
168
|
+
}
|
|
134
169
|
throw new Error(`Unknown tool: ${toolName}`);
|
|
135
170
|
});
|
|
136
171
|
// Connect transport
|
|
137
172
|
const transport = new StdioServerTransport();
|
|
138
173
|
await server.connect(transport);
|
|
139
174
|
logger.info('Docker MCP Server started successfully');
|
|
140
|
-
|
|
175
|
+
// Calculate actual tool count
|
|
176
|
+
const toolCount = containerTools.getTools().length +
|
|
177
|
+
1 + // executorTool
|
|
178
|
+
databaseTools.getTools().length +
|
|
179
|
+
envTools.getTools().length +
|
|
180
|
+
1 + // mcpHealthTool
|
|
181
|
+
1 + // profileTool
|
|
182
|
+
discoveryTools.getTools().length;
|
|
183
|
+
logger.info(`Registered tools: ${toolCount} commands (${containerTools.getTools().length} container + 1 executor + ${databaseTools.getTools().length} database + ${envTools.getTools().length} environment + 1 mcp-health + 1 profile + ${discoveryTools.getTools().length} discovery)`);
|
|
141
184
|
logger.info('Listening on STDIO...');
|
|
185
|
+
// Setup graceful shutdown handlers
|
|
186
|
+
const shutdown = async (signal) => {
|
|
187
|
+
logger.info(`Received ${signal}, shutting down gracefully...`);
|
|
188
|
+
// Cleanup all Docker clients (singleton + pool, SSH tunnels, etc.)
|
|
189
|
+
try {
|
|
190
|
+
cleanupAllDockerClients();
|
|
191
|
+
logger.info('All Docker clients cleaned up');
|
|
192
|
+
}
|
|
193
|
+
catch (error) {
|
|
194
|
+
logger.error('Error during Docker cleanup:', error.message);
|
|
195
|
+
}
|
|
196
|
+
// Close server transport
|
|
197
|
+
try {
|
|
198
|
+
await server.close();
|
|
199
|
+
logger.info('MCP server closed');
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
logger.error('Error closing server:', error.message);
|
|
203
|
+
}
|
|
204
|
+
logger.info('Shutdown complete');
|
|
205
|
+
process.exit(0);
|
|
206
|
+
};
|
|
207
|
+
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
|
208
|
+
process.on('SIGINT', () => shutdown('SIGINT'));
|
|
209
|
+
process.on('SIGHUP', () => shutdown('SIGHUP'));
|
|
210
|
+
process.on('exit', () => {
|
|
211
|
+
logger.debug('Process exiting, final cleanup...');
|
|
212
|
+
cleanupAllDockerClients();
|
|
213
|
+
});
|
|
142
214
|
}
|
|
143
215
|
// Error handling
|
|
144
216
|
main().catch((error) => {
|
|
145
217
|
logger.error('Fatal error:', error);
|
|
218
|
+
cleanupAllDockerClients(); // Cleanup on fatal error
|
|
146
219
|
process.exit(1);
|
|
147
220
|
});
|
|
148
221
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|