mcp-coordinator 0.6.0 → 0.6.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.
|
@@ -3,6 +3,7 @@ import { getDb } from "../database.js";
|
|
|
3
3
|
import { runCommonAnnounceFlow } from "../announce-workflow.js";
|
|
4
4
|
import { canResetDb } from "../reset-guard.js";
|
|
5
5
|
import { parseBody, json } from "./utils.js";
|
|
6
|
+
import { normalizePath } from "../path-normalize.js";
|
|
6
7
|
export async function handleRest(req, res, ctx) {
|
|
7
8
|
const { services, httpLog, authEnabled, getRunConfig, setRunConfig } = ctx;
|
|
8
9
|
const url = req.url || "";
|
|
@@ -378,6 +379,15 @@ export async function handleRest(req, res, ctx) {
|
|
|
378
379
|
json(res, { error: "agent_name must be string when present" }, 400);
|
|
379
380
|
return;
|
|
380
381
|
}
|
|
382
|
+
const repoRoot = process.env.COORDINATOR_REPO_ROOT || null;
|
|
383
|
+
let filePath;
|
|
384
|
+
try {
|
|
385
|
+
filePath = normalizePath(repoRoot, body.file_path);
|
|
386
|
+
}
|
|
387
|
+
catch (err) {
|
|
388
|
+
json(res, { error: `invalid file_path: ${err.message}` }, 400);
|
|
389
|
+
return;
|
|
390
|
+
}
|
|
381
391
|
const MAX_CONTENT = 262144;
|
|
382
392
|
let symbols = null;
|
|
383
393
|
let contentHash = null;
|
|
@@ -387,14 +397,14 @@ export async function handleRest(req, res, ctx) {
|
|
|
387
397
|
return;
|
|
388
398
|
}
|
|
389
399
|
contentHash = createHash("sha256").update(body.content).digest("hex");
|
|
390
|
-
symbols = ctx.services.treeSitter.extract(
|
|
400
|
+
symbols = ctx.services.treeSitter.extract(filePath, body.content, null);
|
|
391
401
|
}
|
|
392
402
|
ctx.services.fileTracker.log({
|
|
393
403
|
session_id: body.session_id,
|
|
394
404
|
agent_id: body.agent_id,
|
|
395
405
|
agent_name: body.agent_name,
|
|
396
406
|
tool_name: body.tool_name,
|
|
397
|
-
file_path:
|
|
407
|
+
file_path: filePath,
|
|
398
408
|
content_hash: contentHash,
|
|
399
409
|
symbols_touched: symbols,
|
|
400
410
|
});
|
|
@@ -405,8 +415,17 @@ export async function handleRest(req, res, ctx) {
|
|
|
405
415
|
json(res, { error: "agent_id and file_path required" }, 400);
|
|
406
416
|
return;
|
|
407
417
|
}
|
|
418
|
+
const repoRoot = process.env.COORDINATOR_REPO_ROOT || null;
|
|
419
|
+
let filePath;
|
|
420
|
+
try {
|
|
421
|
+
filePath = normalizePath(repoRoot, body.file_path);
|
|
422
|
+
}
|
|
423
|
+
catch (err) {
|
|
424
|
+
json(res, { error: `invalid file_path: ${err.message}` }, 400);
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
408
427
|
const ttl = parseInt(process.env.COORDINATOR_WORKING_FILES_TTL_MIN || "30", 10);
|
|
409
|
-
services.workingFiles.start(body.agent_id,
|
|
428
|
+
services.workingFiles.start(body.agent_id, filePath, ttl);
|
|
410
429
|
json(res, { ok: true });
|
|
411
430
|
}
|
|
412
431
|
else if (url === "/api/working-files/stop" && req.method === "POST") {
|
|
@@ -414,7 +433,16 @@ export async function handleRest(req, res, ctx) {
|
|
|
414
433
|
json(res, { error: "agent_id and file_path required" }, 400);
|
|
415
434
|
return;
|
|
416
435
|
}
|
|
417
|
-
|
|
436
|
+
const repoRoot = process.env.COORDINATOR_REPO_ROOT || null;
|
|
437
|
+
let filePath;
|
|
438
|
+
try {
|
|
439
|
+
filePath = normalizePath(repoRoot, body.file_path);
|
|
440
|
+
}
|
|
441
|
+
catch (err) {
|
|
442
|
+
json(res, { error: `invalid file_path: ${err.message}` }, 400);
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
services.workingFiles.stop(body.agent_id, filePath);
|
|
418
446
|
json(res, { ok: true });
|
|
419
447
|
}
|
|
420
448
|
else if (url?.startsWith("/api/scoring-stats") && req.method === "GET") {
|
|
@@ -25,9 +25,9 @@ export function registerConsultationTools(server, services, mcpLog) {
|
|
|
25
25
|
subject: z.string(),
|
|
26
26
|
plan: z.string().optional(),
|
|
27
27
|
target_modules: z.array(z.string()),
|
|
28
|
-
target_files: z.array(z.string()),
|
|
29
|
-
depends_on_files: z.array(z.string()).optional(),
|
|
30
|
-
exports_affected: z.array(z.string()).optional(),
|
|
28
|
+
target_files: z.array(z.string()).describe("Repo-relative file paths (forward-slash, e.g. 'src/foo.ts'). Absolute paths are not accepted in team-mode."),
|
|
29
|
+
depends_on_files: z.array(z.string()).optional().describe("Repo-relative file paths your work depends on."),
|
|
30
|
+
exports_affected: z.array(z.string()).optional().describe("Repo-relative file paths whose exports your work modifies."),
|
|
31
31
|
keep_open: z.boolean().optional().describe("Keep thread open even if no agents are concerned (for manual coordination like games or debates)"),
|
|
32
32
|
assigned_to: z.string().optional().describe("Directed-dispatch: only this agent_id will be allowed to claim the thread. Use for lead→worker handoffs in maitre/chaine/relais presets. Implies keep_open=true."),
|
|
33
33
|
target_symbols: z.array(z.string().max(256)).max(200).optional()
|
|
@@ -162,7 +162,7 @@ export function registerConsultationTools(server, services, mcpLog) {
|
|
|
162
162
|
server.tool("log_action_summary", "Log a one-liner summary of an action", {
|
|
163
163
|
session_id: z.string(),
|
|
164
164
|
agent_id: z.string(),
|
|
165
|
-
file_path: z.string().optional(),
|
|
165
|
+
file_path: z.string().optional().describe("Repo-relative file path."),
|
|
166
166
|
summary: z.string(),
|
|
167
167
|
}, async ({ session_id, agent_id, file_path, summary }) => {
|
|
168
168
|
const result = consultation.logActionSummary({ session_id, agent_id, file_path, summary });
|
|
@@ -18,7 +18,7 @@ export function registerFilesTools(server, services, _mcpLog) {
|
|
|
18
18
|
return { content: [{ type: "text", text: JSON.stringify(files) }] };
|
|
19
19
|
});
|
|
20
20
|
server.tool("check_file_conflict", "Check if another agent is editing a file", {
|
|
21
|
-
file_path: z.string(),
|
|
21
|
+
file_path: z.string().describe("Repo-relative file path."),
|
|
22
22
|
agent_id: z.string(),
|
|
23
23
|
within_minutes: z.number().optional(),
|
|
24
24
|
}, async ({ file_path, agent_id, within_minutes }) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-coordinator",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"mcpName": "io.github.swoofer/mcp-coordinator",
|
|
5
5
|
"description": "Embedded MQTT broker + MCP server for multi-agent coordination",
|
|
6
6
|
"type": "module",
|
|
@@ -94,6 +94,9 @@
|
|
|
94
94
|
"tree-sitter-swift": "^0.6.0",
|
|
95
95
|
"tree-sitter-bash": "^0.21.0"
|
|
96
96
|
},
|
|
97
|
+
"overrides": {
|
|
98
|
+
"ip-address": "^10.2.0"
|
|
99
|
+
},
|
|
97
100
|
"engines": {
|
|
98
101
|
"node": ">=20"
|
|
99
102
|
}
|