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.
@@ -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
@@ -31,7 +31,7 @@ else {
31
31
  }
32
32
  const server = new McpServer({
33
33
  name: "agent-collab",
34
- version: "1.3.0",
34
+ version: "1.3.1",
35
35
  }, { instructions });
36
36
  registerStatusTools(server);
37
37
  registerSetupTools(server);
@@ -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/engine preferences, then call \`setup_project\`
125
- 3. If no tasks exist and you can create them, create an HLD with \`set_context\` then create tasks with \`create_task\`
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 includes your available tools — only call tools listed there
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
 
@@ -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)"),
@@ -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"]).optional().describe("Engine mode (default: cursor-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 || "cursor-only";
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) {
@@ -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
- "Ask the user which setup they'd like:\n",
32
- "1. Strategy (default: architect-builder):",
33
- " - architect-builder One designs, the other builds",
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
- "2. Engine mode (default: cursor-only):",
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, `STOP: No tasks exist.${historyHint} Do NOT write code directly. The architect agent must create tasks first.`);
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.0",
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",