agent-collab-mcp 1.3.0 → 1.3.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/build/dispatch.d.ts +1 -0
- package/build/dispatch.js +29 -0
- package/build/index.js +1 -1
- package/build/templates.js +5 -3
- package/build/tools/dispatch.js +17 -1
- package/build/tools/setup.js +2 -2
- package/build/tools/status.js +10 -11
- package/package.json +1 -1
package/build/dispatch.d.ts
CHANGED
|
@@ -16,5 +16,6 @@ export interface DispatchResult {
|
|
|
16
16
|
export declare function dispatchAgent(target: "reviewer" | "builder", prompt: string): DispatchResult;
|
|
17
17
|
export declare function dispatchReview(taskIds: string[]): DispatchResult;
|
|
18
18
|
export declare function dispatchBuilder(taskIds?: string[], message?: string): DispatchResult;
|
|
19
|
+
export declare function dispatchArchitect(userRequest: string): DispatchResult;
|
|
19
20
|
declare function formatResult(r: DispatchResult): string;
|
|
20
21
|
export { formatResult };
|
package/build/dispatch.js
CHANGED
|
@@ -112,6 +112,35 @@ export function dispatchBuilder(taskIds, message) {
|
|
|
112
112
|
}
|
|
113
113
|
return dispatchAgent("builder", prompt);
|
|
114
114
|
}
|
|
115
|
+
export function dispatchArchitect(userRequest) {
|
|
116
|
+
const mode = getEngineMode();
|
|
117
|
+
if (isSingleEngine()) {
|
|
118
|
+
return { dispatched: false, reason: "Single-engine mode — you are the architect. Create the HLD and tasks yourself." };
|
|
119
|
+
}
|
|
120
|
+
if (!cliExists("claude")) {
|
|
121
|
+
return { dispatched: false, reason: "claude CLI not found on PATH. Install Claude Code CLI or create tasks manually." };
|
|
122
|
+
}
|
|
123
|
+
const prompt = `Call get_my_status from the agent-collab MCP. You are the Architect. Create an HLD with set_context("hld", ...) and then break the work into tasks with create_task. Set notify_builder=true on the LAST create_task call. The user wants: ${userRequest}`;
|
|
124
|
+
const logDir = ensureLogDir();
|
|
125
|
+
const ts = new Date().toISOString().replace(/[:.]/g, "-");
|
|
126
|
+
const logFile = path.join(logDir, `dispatch-architect-${ts}.log`);
|
|
127
|
+
const out = fs.openSync(logFile, "w");
|
|
128
|
+
const child = spawn("claude", ["-p", "--permission-mode", "auto", prompt], {
|
|
129
|
+
detached: true,
|
|
130
|
+
stdio: ["ignore", out, out],
|
|
131
|
+
cwd: process.cwd(),
|
|
132
|
+
});
|
|
133
|
+
child.unref();
|
|
134
|
+
const pid = child.pid ?? 0;
|
|
135
|
+
fs.writeSync(out, `--- Dispatched architect: claude -p ...\n--- PID: ${pid}\n--- Time: ${new Date().toISOString()}\n--- Request: ${userRequest}\n---\n`);
|
|
136
|
+
const db = getDb();
|
|
137
|
+
db.prepare("INSERT INTO activity_log (agent, action) VALUES (?, ?)").run(getRole(), `Invoked architect for: ${userRequest.slice(0, 100)} (PID ${pid})`);
|
|
138
|
+
return {
|
|
139
|
+
dispatched: true,
|
|
140
|
+
pid,
|
|
141
|
+
logFile: path.relative(process.cwd(), logFile),
|
|
142
|
+
};
|
|
143
|
+
}
|
|
115
144
|
function formatResult(r) {
|
|
116
145
|
if (r.dispatched) {
|
|
117
146
|
return `Dispatched (PID: ${r.pid}, log: ${r.logFile})`;
|
package/build/index.js
CHANGED
package/build/templates.js
CHANGED
|
@@ -121,15 +121,17 @@ alwaysApply: true
|
|
|
121
121
|
You have the agent-collab MCP configured. Follow the MCP workflow strictly:
|
|
122
122
|
|
|
123
123
|
1. Call \`get_my_status\` to check your role, available tools, and next action
|
|
124
|
-
2. If setup is needed, ask the user for strategy
|
|
125
|
-
3. If no tasks exist
|
|
124
|
+
2. If setup is needed, ask the user for BOTH strategy AND engine mode, then call \`setup_project(strategy, engine_mode)\`
|
|
125
|
+
3. If no tasks exist:
|
|
126
|
+
- In cursor-only mode: create HLD with \`set_context("hld", ...)\` then tasks with \`create_task\`
|
|
127
|
+
- In both mode: call \`invoke_architect("what the user wants built")\` to have Claude Code design and create tasks
|
|
126
128
|
4. For each assigned task: \`claim_task\` -> \`get_task\` -> implement -> \`submit_for_review\`
|
|
127
129
|
5. After submitting for review in "both" mode, call \`trigger_review()\` to auto-invoke the reviewer
|
|
128
130
|
6. Check \`get_my_status\` after reviews — if changes-requested, \`claim_task\` again, fix, resubmit
|
|
129
131
|
7. When all tasks are done, suggest \`archive_epic\` to the user to clear the board
|
|
130
132
|
8. NEVER write code without claiming a task first via \`claim_task\`
|
|
131
133
|
9. NEVER skip the MCP workflow even if the user says "just build it"
|
|
132
|
-
10. The \`get_my_status\` response
|
|
134
|
+
10. The \`get_my_status\` response lists your available tools — only call tools listed there
|
|
133
135
|
`;
|
|
134
136
|
const AGENTS_MD = `# Agent Instructions
|
|
135
137
|
|
package/build/tools/dispatch.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { isInitialized, getDb, isSingleEngine } from "../db.js";
|
|
3
|
-
import { dispatchReview, dispatchBuilder, formatResult } from "../dispatch.js";
|
|
3
|
+
import { dispatchReview, dispatchBuilder, dispatchArchitect, formatResult } from "../dispatch.js";
|
|
4
4
|
const NOT_SETUP = { content: [{ type: "text", text: "Project not set up. Call setup_project first." }] };
|
|
5
5
|
const SINGLE_MODE = { content: [{ type: "text", text: "Dispatch tools are only available in 'both' engine mode. In single-engine mode, you handle both roles directly." }] };
|
|
6
6
|
export function registerDispatchTools(server) {
|
|
@@ -58,6 +58,22 @@ export function registerDispatchTools(server) {
|
|
|
58
58
|
}
|
|
59
59
|
return { content: [{ type: "text", text }] };
|
|
60
60
|
});
|
|
61
|
+
server.tool("invoke_architect", "Invoke Claude Code (Architect) to create an HLD and tasks for the user's request. Use this when no tasks exist in 'both' mode.", {
|
|
62
|
+
request: z.string().describe("Description of what the user wants built. Pass the user's original request."),
|
|
63
|
+
}, async ({ request }) => {
|
|
64
|
+
if (!isInitialized())
|
|
65
|
+
return NOT_SETUP;
|
|
66
|
+
if (isSingleEngine()) {
|
|
67
|
+
return { content: [{ type: "text", text: "In single-engine mode, YOU are the architect. Create the HLD and tasks yourself with set_context and create_task." }] };
|
|
68
|
+
}
|
|
69
|
+
const result = dispatchArchitect(request);
|
|
70
|
+
let text = `Invoking Architect (Claude Code) to design and create tasks for: "${request.slice(0, 100)}${request.length > 100 ? "..." : ""}"\n`;
|
|
71
|
+
text += formatResult(result);
|
|
72
|
+
if (result.dispatched) {
|
|
73
|
+
text += `\n\nThe Architect is working in the background. It will create an HLD and tasks, then auto-notify you when done. Call get_my_status periodically to check for new tasks.`;
|
|
74
|
+
}
|
|
75
|
+
return { content: [{ type: "text", text }] };
|
|
76
|
+
});
|
|
61
77
|
server.tool("run_loop", "Run the full implement-review-fix loop for all tasks. Dispatches agents and polls until done or max rounds reached.", {
|
|
62
78
|
max_rounds: z.number().optional().describe("Max review rounds per task (default: 3)"),
|
|
63
79
|
max_tasks: z.number().optional().describe("Max tasks to process (default: all)"),
|
package/build/tools/setup.js
CHANGED
|
@@ -8,11 +8,11 @@ export function registerSetupTools(server) {
|
|
|
8
8
|
const role = getRole();
|
|
9
9
|
server.tool("setup_project", "Initialize agent collaboration for this project. Creates the database, config files, hooks, and rules.", {
|
|
10
10
|
strategy: z.string().optional().describe("Strategy ID (default: architect-builder). Call list_strategies to see options."),
|
|
11
|
-
engine_mode: z.enum(["both", "cursor-only", "claude-code-only"]).
|
|
11
|
+
engine_mode: z.enum(["both", "cursor-only", "claude-code-only"]).describe("REQUIRED. Engine mode: 'both' (Cursor builds, Claude Code reviews), 'cursor-only' (Cursor does everything), or 'claude-code-only'."),
|
|
12
12
|
project_name: z.string().optional().describe("Project name (default: current directory name)"),
|
|
13
13
|
}, async ({ strategy, engine_mode, project_name }) => {
|
|
14
14
|
const strategyId = strategy || getDefaultStrategyId();
|
|
15
|
-
const mode = engine_mode
|
|
15
|
+
const mode = engine_mode;
|
|
16
16
|
const projName = project_name || path.basename(process.cwd());
|
|
17
17
|
const def = getStrategyDef(strategyId);
|
|
18
18
|
if (!def) {
|
package/build/tools/status.js
CHANGED
|
@@ -15,7 +15,7 @@ function buildToolList(access, single) {
|
|
|
15
15
|
tools.push("save_plan");
|
|
16
16
|
tools.push("get_task", "get_context", "get_review_feedback", "get_project_overview", "log_activity");
|
|
17
17
|
if (!single)
|
|
18
|
-
tools.push("trigger_review", "notify_builder", "run_loop");
|
|
18
|
+
tools.push("trigger_review", "notify_builder", "invoke_architect", "run_loop");
|
|
19
19
|
tools.push("archive_epic", "list_epics", "get_epic", "get_codebase_context");
|
|
20
20
|
tools.push("list_strategies", "get_active_strategy", "set_strategy", "set_engine_mode");
|
|
21
21
|
return tools.join(", ");
|
|
@@ -28,20 +28,19 @@ export function registerStatusTools(server) {
|
|
|
28
28
|
type: "text",
|
|
29
29
|
text: [
|
|
30
30
|
"SETUP_NEEDED: This project hasn't been configured for agent collaboration yet.\n",
|
|
31
|
-
"
|
|
32
|
-
"1.
|
|
33
|
-
" -
|
|
31
|
+
"You MUST ask the user TWO questions before calling setup_project:\n",
|
|
32
|
+
"1. Engine mode (REQUIRED — ask the user explicitly):",
|
|
33
|
+
" - cursor-only: You handle everything alone (design + implement + review)",
|
|
34
|
+
" - both: Cursor implements, Claude Code designs and reviews (recommended for quality)",
|
|
35
|
+
" - claude-code-only: Claude Code handles everything alone\n",
|
|
36
|
+
"2. Strategy:",
|
|
37
|
+
" - architect-builder — One agent designs, the other builds",
|
|
34
38
|
" - tdd-red-green — One writes tests, the other makes them pass",
|
|
35
39
|
" - writer-reviewer — One writes code, the other critiques",
|
|
36
40
|
" - parallel-specialist — Domain split, cross-review",
|
|
37
41
|
" - planner-executor — Detailed specs, mechanical execution",
|
|
38
42
|
" - sequential-pipeline — Multi-stage quality review\n",
|
|
39
|
-
"
|
|
40
|
-
" - cursor-only: You handle everything (design + implement + review)",
|
|
41
|
-
" - both: Cursor implements, Claude Code reviews",
|
|
42
|
-
" - claude-code-only: Claude Code handles everything\n",
|
|
43
|
-
"After getting their choices, call setup_project(strategy, engine_mode).",
|
|
44
|
-
"If they just say 'go with defaults' or similar, use architect-builder + cursor-only.\n",
|
|
43
|
+
"Then call setup_project(strategy, engine_mode) with BOTH values.\n",
|
|
45
44
|
"Available tools before setup: get_my_status, setup_project, list_strategies, get_dashboard_info",
|
|
46
45
|
].join("\n"),
|
|
47
46
|
}],
|
|
@@ -100,7 +99,7 @@ export function registerStatusTools(server) {
|
|
|
100
99
|
if (single) {
|
|
101
100
|
return text(header, `No tasks on the board.${historyHint} You have all tools — start by creating tasks with create_task(...).`);
|
|
102
101
|
}
|
|
103
|
-
return text(header, `
|
|
102
|
+
return text(header, `No tasks exist.${historyHint} Call invoke_architect("describe what the user wants built") to have Claude Code create the HLD and tasks. Pass the user's original request as the argument.`);
|
|
104
103
|
}
|
|
105
104
|
return text(header, "All tasks are done. Consider archiving this work with archive_epic(\"<name>\") to clear the board for the next feature. Or create new tasks if there are more requirements.");
|
|
106
105
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-collab-mcp",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"description": "MCP server for multi-agent coordination between Cursor and Claude Code. Strategies, task management, review loops, and a live dashboard.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "build/index.js",
|