@arcbridge/mcp-server 0.2.1 → 0.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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @arcbridge/mcp-server
2
2
 
3
- MCP server for ArcBridge — exposes 33 architecture tools to AI coding agents via the [Model Context Protocol](https://modelcontextprotocol.io).
3
+ MCP server for ArcBridge — exposes 34 architecture tools to AI coding agents via the [Model Context Protocol](https://modelcontextprotocol.io).
4
4
 
5
5
  ## Install
6
6
 
@@ -10,7 +10,7 @@ npm install -g @arcbridge/mcp-server
10
10
 
11
11
  ## Setup
12
12
 
13
- Add to your project's `.mcp.json`:
13
+ **Claude Code** — add to your project's `.mcp.json`:
14
14
 
15
15
  ```json
16
16
  {
@@ -23,7 +23,15 @@ Add to your project's `.mcp.json`:
23
23
  }
24
24
  ```
25
25
 
26
- Restart your AI agent (Claude Code, etc.) and approve the MCP server when prompted.
26
+ **Codex CLI** add to `~/.codex/config.toml`:
27
+
28
+ ```toml
29
+ [mcp_servers.arcbridge]
30
+ command = "npx"
31
+ args = ["-y", "@arcbridge/mcp-server"]
32
+ ```
33
+
34
+ Restart your AI agent and approve the MCP server when prompted.
27
35
 
28
36
  ## Tools
29
37
 
@@ -81,6 +89,7 @@ Restart your AI agent (Claude Code, etc.) and approve the MCP server when prompt
81
89
  | `arcbridge_get_open_questions` | Unresolved architectural questions and risks |
82
90
  | `arcbridge_propose_arc42_update` | Generate arc42 update proposals from code changes |
83
91
  | `arcbridge_get_practice_review` | 5-dimension review: architecture, security, testing, docs, complexity |
92
+ | `arcbridge_update_arc42_section` | Read or update any arc42 markdown section (frontmatter preserved) |
84
93
 
85
94
  ### Roles & Sync
86
95
 
package/dist/index.js CHANGED
@@ -31,7 +31,9 @@ import {
31
31
  generateDatabase,
32
32
  generateSyncFiles,
33
33
  indexProject,
34
- loadConfig
34
+ loadConfig,
35
+ QualityCategorySchema,
36
+ QUALITY_PRIORITIES_DESCRIPTION
35
37
  } from "@arcbridge/core";
36
38
  import { getAdapter } from "@arcbridge/adapters";
37
39
  function registerInitProject(server, ctx) {
@@ -44,7 +46,7 @@ function registerInitProject(server, ctx) {
44
46
  "Project template: nextjs-app-router (Next.js with App Router, SSR/SSG), react-vite (React SPA with Vite, client-only), api-service (Node.js API with Express/Fastify/Hono), dotnet-webapi (ASP.NET Core Web API, C#), unity-game (Unity game project, C#, code-heavy)"
45
47
  ),
46
48
  features: z.array(z.enum(["auth", "database", "api"])).default([]).describe("Features to scaffold"),
47
- quality_priorities: z.array(z.string()).default(["security", "performance", "accessibility", "maintainability"]).describe("Quality priorities in order"),
49
+ quality_priorities: z.array(QualityCategorySchema).default(["security", "performance", "accessibility", "maintainability"]).describe(QUALITY_PRIORITIES_DESCRIPTION),
48
50
  platforms: z.array(z.string()).default(["claude"]).describe("Target platforms for agent config generation"),
49
51
  target_dir: z.string().describe("Absolute path to the target project directory"),
50
52
  spec: z.string().optional().describe(
@@ -568,14 +570,14 @@ function registerGetBuildingBlock(server, ctx) {
568
570
 
569
571
  // src/tools/get-quality-scenarios.ts
570
572
  import { z as z5 } from "zod";
571
- import { QualityCategorySchema, QualityPrioritySchema, QualityScenarioStatusSchema } from "@arcbridge/core";
573
+ import { QualityCategorySchema as QualityCategorySchema2, QualityPrioritySchema, QualityScenarioStatusSchema } from "@arcbridge/core";
572
574
  function registerGetQualityScenarios(server, ctx) {
573
575
  server.tool(
574
576
  "arcbridge_get_quality_scenarios",
575
577
  "Get quality scenarios, optionally filtered by category. Shows scenario details, linked code/tests, and current status.",
576
578
  {
577
579
  target_dir: z5.string().describe("Absolute path to the project directory"),
578
- category: QualityCategorySchema.optional().describe("Filter by category"),
580
+ category: QualityCategorySchema2.optional().describe("Filter by category"),
579
581
  status: QualityScenarioStatusSchema.optional().describe("Filter by status"),
580
582
  priority: QualityPrioritySchema.optional().describe("Filter by priority (must/should/could)")
581
583
  },
@@ -756,7 +758,7 @@ import { refreshFromDocs as refreshFromDocs3 } from "@arcbridge/core";
756
758
  function registerGetCurrentTasks(server, ctx) {
757
759
  server.tool(
758
760
  "arcbridge_get_current_tasks",
759
- "Get tasks for the current in-progress phase, with their building blocks, quality scenarios, and acceptance criteria.",
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.",
760
762
  {
761
763
  target_dir: z7.string().describe("Absolute path to the project directory"),
762
764
  status: z7.enum(["todo", "in-progress", "done", "blocked"]).optional().describe("Filter tasks by status")
@@ -765,15 +767,20 @@ function registerGetCurrentTasks(server, ctx) {
765
767
  const db = ensureDb(ctx, params.target_dir);
766
768
  if (!db) return notInitialized();
767
769
  refreshFromDocs3(db, params.target_dir);
768
- const currentPhase = db.prepare(
770
+ let currentPhase = db.prepare(
769
771
  "SELECT id, name FROM phases WHERE status = 'in-progress' ORDER BY phase_number LIMIT 1"
770
772
  ).get();
773
+ if (!currentPhase) {
774
+ currentPhase = db.prepare(
775
+ "SELECT id, name FROM phases WHERE status = 'planned' ORDER BY phase_number LIMIT 1"
776
+ ).get();
777
+ }
771
778
  if (!currentPhase) {
772
779
  return {
773
780
  content: [
774
781
  {
775
782
  type: "text",
776
- text: "No phase is currently in-progress. Use `arcbridge_get_phase_plan` to see all phases."
783
+ text: "No active or planned phases found. Use `arcbridge_get_phase_plan` to see all phases."
777
784
  }
778
785
  ]
779
786
  };
@@ -4395,6 +4402,103 @@ You can commit this file to preserve the activity record in git.`
4395
4402
  );
4396
4403
  }
4397
4404
 
4405
+ // src/tools/update-arc42-section.ts
4406
+ import { z as z34 } from "zod";
4407
+ import { join as join4 } from "path";
4408
+ import { existsSync as existsSync4, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
4409
+ function splitFrontmatter(raw) {
4410
+ if (!raw.startsWith("---")) {
4411
+ return { frontmatterBlock: "", body: raw };
4412
+ }
4413
+ const endIndex = raw.indexOf("\n---", 3);
4414
+ if (endIndex < 0) {
4415
+ return { frontmatterBlock: "", body: raw };
4416
+ }
4417
+ const fmEnd = endIndex + 4;
4418
+ return {
4419
+ frontmatterBlock: raw.slice(0, fmEnd),
4420
+ body: raw.slice(fmEnd).replace(/^\n/, "")
4421
+ };
4422
+ }
4423
+ var VALID_SECTIONS = [
4424
+ "01-introduction",
4425
+ "02-constraints",
4426
+ "03-context",
4427
+ "04-solution-strategy",
4428
+ "06-runtime-views",
4429
+ "07-deployment",
4430
+ "08-crosscutting",
4431
+ "11-risks-debt"
4432
+ ];
4433
+ var SECTION_LABELS = {
4434
+ "01-introduction": "Introduction & Goals",
4435
+ "02-constraints": "Architecture Constraints",
4436
+ "03-context": "Context & Scope",
4437
+ "04-solution-strategy": "Solution Strategy",
4438
+ "06-runtime-views": "Runtime Views",
4439
+ "07-deployment": "Deployment View",
4440
+ "08-crosscutting": "Crosscutting Concepts",
4441
+ "11-risks-debt": "Risks & Technical Debt"
4442
+ };
4443
+ function registerUpdateArc42Section(server, ctx) {
4444
+ server.tool(
4445
+ "arcbridge_update_arc42_section",
4446
+ "Read or update an arc42 documentation section. Omit `content` to read the current section. Provide `content` to replace the markdown body (frontmatter is preserved automatically). Use this for sections without dedicated tools: introduction, constraints, context, solution strategy, runtime views, deployment, crosscutting concepts, risks & debt. For building blocks use `arcbridge_get_building_blocks`, for quality scenarios use `arcbridge_get_quality_scenarios`.",
4447
+ {
4448
+ target_dir: z34.string().describe("Absolute path to the project directory"),
4449
+ section: z34.enum(VALID_SECTIONS).describe(
4450
+ "Arc42 section to read or update: " + VALID_SECTIONS.map((s) => `${s} (${SECTION_LABELS[s]})`).join(", ")
4451
+ ),
4452
+ content: z34.string().optional().describe(
4453
+ "New markdown content for the section body. Omit to read the current content. Frontmatter is preserved automatically \u2014 only provide the markdown body."
4454
+ )
4455
+ },
4456
+ async (params) => {
4457
+ const db = ensureDb(ctx, params.target_dir);
4458
+ if (!db) return notInitialized();
4459
+ const filePath = join4(
4460
+ params.target_dir,
4461
+ ".arcbridge",
4462
+ "arc42",
4463
+ `${params.section}.md`
4464
+ );
4465
+ if (!existsSync4(filePath)) {
4466
+ return textResult(
4467
+ `Section file \`${params.section}.md\` not found. Run \`arcbridge_init_project\` first.`
4468
+ );
4469
+ }
4470
+ if (params.content === void 0) {
4471
+ const raw2 = readFileSync2(filePath, "utf-8");
4472
+ const { body } = splitFrontmatter(raw2);
4473
+ const label2 = SECTION_LABELS[params.section];
4474
+ const trimmedBody = body.trim();
4475
+ const startsWithHeading = /^#\s+/.test(trimmedBody);
4476
+ const outputLines = [];
4477
+ if (!startsWithHeading) {
4478
+ outputLines.push(`# ${label2}`, "");
4479
+ }
4480
+ outputLines.push(
4481
+ `**File:** \`.arcbridge/arc42/${params.section}.md\``,
4482
+ "",
4483
+ trimmedBody
4484
+ );
4485
+ return textResult(outputLines.join("\n"));
4486
+ }
4487
+ const raw = readFileSync2(filePath, "utf-8");
4488
+ const { frontmatterBlock } = splitFrontmatter(raw);
4489
+ const updated = frontmatterBlock ? `${frontmatterBlock}
4490
+ ${params.content}
4491
+ ` : `${params.content}
4492
+ `;
4493
+ writeFileSync2(filePath, updated, "utf-8");
4494
+ const label = SECTION_LABELS[params.section];
4495
+ return textResult(
4496
+ `Updated **${label}** (\`${params.section}.md\`). Frontmatter preserved.`
4497
+ );
4498
+ }
4499
+ );
4500
+ }
4501
+
4398
4502
  // src/server.ts
4399
4503
  var require2 = createRequire(import.meta.url);
4400
4504
  var { version } = require2("../package.json");
@@ -4434,6 +4538,7 @@ function createArcBridgeServer() {
4434
4538
  registerVerifyScenarios(server, ctx);
4435
4539
  registerUpdateScenarioStatus(server, ctx);
4436
4540
  registerRunRoleCheck(server, ctx);
4541
+ registerUpdateArc42Section(server, ctx);
4437
4542
  registerRecordActivity(server, ctx);
4438
4543
  registerGetMetrics(server, ctx);
4439
4544
  registerExportMetrics(server, ctx);