@arcbridge/mcp-server 0.3.1 → 0.3.3

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 CHANGED
@@ -55,8 +55,8 @@ Restart your AI agent and approve the MCP server when prompted.
55
55
 
56
56
  | Tool | Description |
57
57
  |------|-------------|
58
- | `arcbridge_get_phase_plan` | All phases with tasks and acceptance criteria |
59
- | `arcbridge_get_current_tasks` | Tasks for the active phase |
58
+ | `arcbridge_get_phase_plan` | Phase plan with tasks filterable by phase_id, status, include_completed |
59
+ | `arcbridge_get_current_tasks` | Tasks for the current or a specific phase (via phase_id) |
60
60
  | `arcbridge_update_task` | Mark tasks in-progress, done, blocked, or cancelled |
61
61
  | `arcbridge_create_task` | Add a task to any phase |
62
62
  | `arcbridge_delete_task` | Remove one or more tasks permanently (batch via task_ids array) |
package/dist/index.js CHANGED
@@ -47,7 +47,7 @@ function registerInitProject(server, ctx) {
47
47
  ),
48
48
  features: z.array(z.enum(["auth", "database", "api"])).default([]).describe("Features to scaffold"),
49
49
  quality_priorities: z.array(QualityCategorySchema).default(["security", "performance", "accessibility", "maintainability"]).describe(QUALITY_PRIORITIES_DESCRIPTION),
50
- platforms: z.array(z.string()).default(["claude"]).describe("Target platforms for agent config generation"),
50
+ platforms: z.array(z.enum(["claude", "copilot", "codex", "gemini"])).default(["claude"]).describe("Target platforms. Generates platform-specific instruction files and agent configs."),
51
51
  target_dir: z.string().describe("Absolute path to the target project directory"),
52
52
  spec: z.string().optional().describe(
53
53
  "Project specification or requirements text. Saved to .arcbridge/spec.md and referenced by agents for context. Can be a description, user stories, or any text that defines what the project should do."
@@ -275,9 +275,13 @@ function registerGetProjectStatus(server, ctx) {
275
275
  return notInitialized();
276
276
  }
277
277
  refreshFromDocs(db, params.target_dir);
278
- const projectName = db.prepare(
279
- "SELECT value FROM arcbridge_meta WHERE key = 'project_name'"
280
- ).get()?.value ?? "Unknown";
278
+ const metaRows = db.prepare(
279
+ "SELECT key, value FROM arcbridge_meta WHERE key IN ('project_name', 'project_type', 'platforms')"
280
+ ).all();
281
+ const meta = Object.fromEntries(metaRows.map((r) => [r.key, r.value]));
282
+ const projectName = meta.project_name ?? "Unknown";
283
+ const projectType = meta.project_type;
284
+ const platforms = meta.platforms;
281
285
  const phases = db.prepare(
282
286
  "SELECT id, name, phase_number, status FROM phases ORDER BY phase_number"
283
287
  ).all();
@@ -304,7 +308,18 @@ function registerGetProjectStatus(server, ctx) {
304
308
  ).get().count;
305
309
  const lines = [
306
310
  `# Project Status: ${projectName}`,
307
- "",
311
+ ""
312
+ ];
313
+ if (projectType) {
314
+ lines.push(`**Template:** ${projectType}`);
315
+ }
316
+ if (platforms) {
317
+ lines.push(`**Platforms:** ${platforms}`);
318
+ }
319
+ if (projectType || platforms) {
320
+ lines.push("");
321
+ }
322
+ lines.push(
308
323
  "## Current Phase",
309
324
  "",
310
325
  currentPhase ? `**${currentPhase.name}** (${currentPhase.status})` : "*No phases defined*",
@@ -331,7 +346,7 @@ function registerGetProjectStatus(server, ctx) {
331
346
  (s) => `- ${s.status === "passing" ? "pass" : s.status === "failing" ? "FAIL" : s.status === "partial" ? "partial" : "untested"} ${s.id}: ${s.name} [${s.category}] (${s.priority})`
332
347
  ),
333
348
  ""
334
- ];
349
+ );
335
350
  lines.push("## Code Intelligence", "");
336
351
  if (symbolCount > 0) {
337
352
  lines.push(
@@ -679,25 +694,49 @@ import { refreshFromDocs as refreshFromDocs2 } from "@arcbridge/core";
679
694
  function registerGetPhasePlan(server, ctx) {
680
695
  server.tool(
681
696
  "arcbridge_get_phase_plan",
682
- "Get the complete phase plan with all phases, their tasks, status, and gate requirements.",
697
+ "Get the phase plan with phases, tasks, status, and gate requirements. Use filters to reduce output for large projects.",
683
698
  {
684
- target_dir: z6.string().describe("Absolute path to the project directory")
699
+ target_dir: z6.string().describe("Absolute path to the project directory"),
700
+ phase_id: z6.string().optional().describe("Show only a specific phase by ID"),
701
+ status: z6.enum(["planned", "in-progress", "complete", "blocked"]).optional().describe("Filter phases by status"),
702
+ include_completed: z6.boolean().default(true).describe("Include completed phases (default: true). Set to false to hide completed phases and reduce output.")
685
703
  },
686
704
  async (params) => {
687
705
  const db = ensureDb(ctx, params.target_dir);
688
706
  if (!db) return notInitialized();
689
707
  refreshFromDocs2(db, params.target_dir);
690
- const phases = db.prepare(
691
- "SELECT id, name, phase_number, status, description, gate_status, started_at, completed_at FROM phases ORDER BY phase_number"
692
- ).all();
708
+ let query = "SELECT id, name, phase_number, status, description, gate_status, started_at, completed_at FROM phases";
709
+ const conditions = [];
710
+ const queryParams = [];
711
+ if (params.phase_id) {
712
+ conditions.push("id = ?");
713
+ queryParams.push(params.phase_id);
714
+ }
715
+ if (params.status) {
716
+ conditions.push("status = ?");
717
+ queryParams.push(params.status);
718
+ }
719
+ if (!params.include_completed && !params.status && !params.phase_id) {
720
+ conditions.push("status != 'complete'");
721
+ }
722
+ if (conditions.length > 0) {
723
+ query += " WHERE " + conditions.join(" AND ");
724
+ }
725
+ query += " ORDER BY phase_number";
726
+ const phases = db.prepare(query).all(...queryParams);
693
727
  if (phases.length === 0) {
728
+ const hint = params.phase_id ? `Phase '${params.phase_id}' not found.` : params.status ? `No phases with status '${params.status}'.` : "No phases defined yet.";
694
729
  return {
695
- content: [
696
- { type: "text", text: "No phases defined yet." }
697
- ]
730
+ content: [{ type: "text", text: hint }]
698
731
  };
699
732
  }
700
- const lines = ["# Phase Plan", ""];
733
+ const lines = [];
734
+ if (conditions.length > 0) {
735
+ const totalPhases = db.prepare("SELECT COUNT(*) as count FROM phases").get().count;
736
+ lines.push(`# Phase Plan (${phases.length} of ${totalPhases} phases)`, "");
737
+ } else {
738
+ lines.push("# Phase Plan", "");
739
+ }
701
740
  for (const phase of phases) {
702
741
  const icon = phase.status === "complete" ? "[x]" : phase.status === "in-progress" ? "[>]" : phase.status === "blocked" ? "[!]" : "[ ]";
703
742
  lines.push(
@@ -758,32 +797,48 @@ import { refreshFromDocs as refreshFromDocs3 } from "@arcbridge/core";
758
797
  function registerGetCurrentTasks(server, ctx) {
759
798
  server.tool(
760
799
  "arcbridge_get_current_tasks",
761
- "Get tasks for the current phase (in-progress, or first planned if none is in-progress), with their building blocks, quality scenarios, and acceptance criteria.",
800
+ "Get tasks for a phase. Defaults to the current phase (in-progress, or first planned). Pass phase_id to get tasks for a specific phase.",
762
801
  {
763
802
  target_dir: z7.string().describe("Absolute path to the project directory"),
803
+ phase_id: z7.string().optional().describe("Get tasks for a specific phase by ID (default: current/first planned phase)"),
764
804
  status: z7.enum(["todo", "in-progress", "done", "blocked"]).optional().describe("Filter tasks by status")
765
805
  },
766
806
  async (params) => {
767
807
  const db = ensureDb(ctx, params.target_dir);
768
808
  if (!db) return notInitialized();
769
809
  refreshFromDocs3(db, params.target_dir);
770
- let currentPhase = db.prepare(
771
- "SELECT id, name FROM phases WHERE status = 'in-progress' ORDER BY phase_number LIMIT 1"
772
- ).get();
773
- if (!currentPhase) {
810
+ let currentPhase;
811
+ if (params.phase_id) {
812
+ currentPhase = db.prepare("SELECT id, name FROM phases WHERE id = ?").get(params.phase_id);
813
+ if (!currentPhase) {
814
+ return {
815
+ content: [
816
+ {
817
+ type: "text",
818
+ text: `Phase '${params.phase_id}' not found. Use \`arcbridge_get_phase_plan\` to see all phases.`
819
+ }
820
+ ]
821
+ };
822
+ }
823
+ } else {
774
824
  currentPhase = db.prepare(
775
- "SELECT id, name FROM phases WHERE status = 'planned' ORDER BY phase_number LIMIT 1"
825
+ "SELECT id, name FROM phases WHERE status = 'in-progress' ORDER BY phase_number LIMIT 1"
776
826
  ).get();
777
- }
778
- if (!currentPhase) {
779
- return {
780
- content: [
781
- {
782
- type: "text",
783
- text: "No active or planned phases found. Use `arcbridge_get_phase_plan` to see all phases."
784
- }
785
- ]
786
- };
827
+ if (!currentPhase) {
828
+ currentPhase = db.prepare(
829
+ "SELECT id, name FROM phases WHERE status = 'planned' ORDER BY phase_number LIMIT 1"
830
+ ).get();
831
+ }
832
+ if (!currentPhase) {
833
+ return {
834
+ content: [
835
+ {
836
+ type: "text",
837
+ text: "No active or planned phases found. Use `arcbridge_get_phase_plan` to see all phases."
838
+ }
839
+ ]
840
+ };
841
+ }
787
842
  }
788
843
  let query = "SELECT id, phase_id, title, description, status, building_block, quality_scenarios, acceptance_criteria FROM tasks WHERE phase_id = ?";
789
844
  const queryParams = [currentPhase.id];