@arcbridge/mcp-server 0.2.1 → 0.3.0
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 +12 -3
- package/dist/index.js +106 -3
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @arcbridge/mcp-server
|
|
2
2
|
|
|
3
|
-
MCP server for ArcBridge — exposes
|
|
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
|
-
|
|
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
|
-
|
|
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
|
@@ -756,7 +756,7 @@ import { refreshFromDocs as refreshFromDocs3 } from "@arcbridge/core";
|
|
|
756
756
|
function registerGetCurrentTasks(server, ctx) {
|
|
757
757
|
server.tool(
|
|
758
758
|
"arcbridge_get_current_tasks",
|
|
759
|
-
"Get tasks for the current in-progress
|
|
759
|
+
"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
760
|
{
|
|
761
761
|
target_dir: z7.string().describe("Absolute path to the project directory"),
|
|
762
762
|
status: z7.enum(["todo", "in-progress", "done", "blocked"]).optional().describe("Filter tasks by status")
|
|
@@ -765,15 +765,20 @@ function registerGetCurrentTasks(server, ctx) {
|
|
|
765
765
|
const db = ensureDb(ctx, params.target_dir);
|
|
766
766
|
if (!db) return notInitialized();
|
|
767
767
|
refreshFromDocs3(db, params.target_dir);
|
|
768
|
-
|
|
768
|
+
let currentPhase = db.prepare(
|
|
769
769
|
"SELECT id, name FROM phases WHERE status = 'in-progress' ORDER BY phase_number LIMIT 1"
|
|
770
770
|
).get();
|
|
771
|
+
if (!currentPhase) {
|
|
772
|
+
currentPhase = db.prepare(
|
|
773
|
+
"SELECT id, name FROM phases WHERE status = 'planned' ORDER BY phase_number LIMIT 1"
|
|
774
|
+
).get();
|
|
775
|
+
}
|
|
771
776
|
if (!currentPhase) {
|
|
772
777
|
return {
|
|
773
778
|
content: [
|
|
774
779
|
{
|
|
775
780
|
type: "text",
|
|
776
|
-
text: "No
|
|
781
|
+
text: "No active or planned phases found. Use `arcbridge_get_phase_plan` to see all phases."
|
|
777
782
|
}
|
|
778
783
|
]
|
|
779
784
|
};
|
|
@@ -4395,6 +4400,103 @@ You can commit this file to preserve the activity record in git.`
|
|
|
4395
4400
|
);
|
|
4396
4401
|
}
|
|
4397
4402
|
|
|
4403
|
+
// src/tools/update-arc42-section.ts
|
|
4404
|
+
import { z as z34 } from "zod";
|
|
4405
|
+
import { join as join4 } from "path";
|
|
4406
|
+
import { existsSync as existsSync4, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
4407
|
+
function splitFrontmatter(raw) {
|
|
4408
|
+
if (!raw.startsWith("---")) {
|
|
4409
|
+
return { frontmatterBlock: "", body: raw };
|
|
4410
|
+
}
|
|
4411
|
+
const endIndex = raw.indexOf("\n---", 3);
|
|
4412
|
+
if (endIndex < 0) {
|
|
4413
|
+
return { frontmatterBlock: "", body: raw };
|
|
4414
|
+
}
|
|
4415
|
+
const fmEnd = endIndex + 4;
|
|
4416
|
+
return {
|
|
4417
|
+
frontmatterBlock: raw.slice(0, fmEnd),
|
|
4418
|
+
body: raw.slice(fmEnd).replace(/^\n/, "")
|
|
4419
|
+
};
|
|
4420
|
+
}
|
|
4421
|
+
var VALID_SECTIONS = [
|
|
4422
|
+
"01-introduction",
|
|
4423
|
+
"02-constraints",
|
|
4424
|
+
"03-context",
|
|
4425
|
+
"04-solution-strategy",
|
|
4426
|
+
"06-runtime-views",
|
|
4427
|
+
"07-deployment",
|
|
4428
|
+
"08-crosscutting",
|
|
4429
|
+
"11-risks-debt"
|
|
4430
|
+
];
|
|
4431
|
+
var SECTION_LABELS = {
|
|
4432
|
+
"01-introduction": "Introduction & Goals",
|
|
4433
|
+
"02-constraints": "Architecture Constraints",
|
|
4434
|
+
"03-context": "Context & Scope",
|
|
4435
|
+
"04-solution-strategy": "Solution Strategy",
|
|
4436
|
+
"06-runtime-views": "Runtime Views",
|
|
4437
|
+
"07-deployment": "Deployment View",
|
|
4438
|
+
"08-crosscutting": "Crosscutting Concepts",
|
|
4439
|
+
"11-risks-debt": "Risks & Technical Debt"
|
|
4440
|
+
};
|
|
4441
|
+
function registerUpdateArc42Section(server, ctx) {
|
|
4442
|
+
server.tool(
|
|
4443
|
+
"arcbridge_update_arc42_section",
|
|
4444
|
+
"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`.",
|
|
4445
|
+
{
|
|
4446
|
+
target_dir: z34.string().describe("Absolute path to the project directory"),
|
|
4447
|
+
section: z34.enum(VALID_SECTIONS).describe(
|
|
4448
|
+
"Arc42 section to read or update: " + VALID_SECTIONS.map((s) => `${s} (${SECTION_LABELS[s]})`).join(", ")
|
|
4449
|
+
),
|
|
4450
|
+
content: z34.string().optional().describe(
|
|
4451
|
+
"New markdown content for the section body. Omit to read the current content. Frontmatter is preserved automatically \u2014 only provide the markdown body."
|
|
4452
|
+
)
|
|
4453
|
+
},
|
|
4454
|
+
async (params) => {
|
|
4455
|
+
const db = ensureDb(ctx, params.target_dir);
|
|
4456
|
+
if (!db) return notInitialized();
|
|
4457
|
+
const filePath = join4(
|
|
4458
|
+
params.target_dir,
|
|
4459
|
+
".arcbridge",
|
|
4460
|
+
"arc42",
|
|
4461
|
+
`${params.section}.md`
|
|
4462
|
+
);
|
|
4463
|
+
if (!existsSync4(filePath)) {
|
|
4464
|
+
return textResult(
|
|
4465
|
+
`Section file \`${params.section}.md\` not found. Run \`arcbridge_init_project\` first.`
|
|
4466
|
+
);
|
|
4467
|
+
}
|
|
4468
|
+
if (params.content === void 0) {
|
|
4469
|
+
const raw2 = readFileSync2(filePath, "utf-8");
|
|
4470
|
+
const { body } = splitFrontmatter(raw2);
|
|
4471
|
+
const label2 = SECTION_LABELS[params.section];
|
|
4472
|
+
const trimmedBody = body.trim();
|
|
4473
|
+
const startsWithHeading = /^#\s+/.test(trimmedBody);
|
|
4474
|
+
const outputLines = [];
|
|
4475
|
+
if (!startsWithHeading) {
|
|
4476
|
+
outputLines.push(`# ${label2}`, "");
|
|
4477
|
+
}
|
|
4478
|
+
outputLines.push(
|
|
4479
|
+
`**File:** \`.arcbridge/arc42/${params.section}.md\``,
|
|
4480
|
+
"",
|
|
4481
|
+
trimmedBody
|
|
4482
|
+
);
|
|
4483
|
+
return textResult(outputLines.join("\n"));
|
|
4484
|
+
}
|
|
4485
|
+
const raw = readFileSync2(filePath, "utf-8");
|
|
4486
|
+
const { frontmatterBlock } = splitFrontmatter(raw);
|
|
4487
|
+
const updated = frontmatterBlock ? `${frontmatterBlock}
|
|
4488
|
+
${params.content}
|
|
4489
|
+
` : `${params.content}
|
|
4490
|
+
`;
|
|
4491
|
+
writeFileSync2(filePath, updated, "utf-8");
|
|
4492
|
+
const label = SECTION_LABELS[params.section];
|
|
4493
|
+
return textResult(
|
|
4494
|
+
`Updated **${label}** (\`${params.section}.md\`). Frontmatter preserved.`
|
|
4495
|
+
);
|
|
4496
|
+
}
|
|
4497
|
+
);
|
|
4498
|
+
}
|
|
4499
|
+
|
|
4398
4500
|
// src/server.ts
|
|
4399
4501
|
var require2 = createRequire(import.meta.url);
|
|
4400
4502
|
var { version } = require2("../package.json");
|
|
@@ -4434,6 +4536,7 @@ function createArcBridgeServer() {
|
|
|
4434
4536
|
registerVerifyScenarios(server, ctx);
|
|
4435
4537
|
registerUpdateScenarioStatus(server, ctx);
|
|
4436
4538
|
registerRunRoleCheck(server, ctx);
|
|
4539
|
+
registerUpdateArc42Section(server, ctx);
|
|
4437
4540
|
registerRecordActivity(server, ctx);
|
|
4438
4541
|
registerGetMetrics(server, ctx);
|
|
4439
4542
|
registerExportMetrics(server, ctx);
|