@decantr/mcp-server 3.6.2 → 3.8.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 +10 -10
- package/dist/bin.js +1 -1
- package/dist/{chunk-XCTAGWHI.js → chunk-M45XVAPP.js} +77 -157
- package/dist/index.js +1 -1
- package/package.json +7 -6
- package/server.json +20 -0
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ AI Frontend Governance for codebases touched by AI agents. Give Claude, Cursor,
|
|
|
12
12
|
|
|
13
13
|

|
|
14
14
|
|
|
15
|
-
- **Structured Contract context** -- gives your AI assistant patterns, layouts, component specs, typed graph context, Brownfield/Hybrid authority, local law, behavior obligations, and task-time context instead of letting it guess
|
|
15
|
+
- **Structured Contract context** -- gives your AI assistant patterns, layouts, component specs, shared Brownfield discovery metadata, typed graph context, Brownfield/Hybrid authority, local law, behavior obligations, and task-time context instead of letting it guess
|
|
16
16
|
- **Evidence-backed repair loops** -- gives AI agents Project Health, component reuse drift, accepted behavior-obligation drift, accepted style bridge drift, stable diagnostic codes, typed repair IDs, graph-anchored Evidence Bundles, workspace health, and scoped repair prompts without uploading source
|
|
17
17
|
- **Drift detection** -- catches when generated code deviates from your design intent
|
|
18
18
|
- **Zero config** -- run with `npx`, no API keys or accounts required
|
|
@@ -138,12 +138,12 @@ The server exposes a hard 8-tool MCP surface. Pass an `action` to select the rou
|
|
|
138
138
|
|
|
139
139
|
| Tool | Description | Example Input |
|
|
140
140
|
|------|-------------|---------------|
|
|
141
|
-
| `decantr_project` | Read local project state and workspace health | `{ "action": "state", "project_path": "apps/web" }` |
|
|
141
|
+
| `decantr_project` | Read local project state, shared discovery summary, and workspace health | `{ "action": "state", "project_path": "apps/web" }` |
|
|
142
142
|
| `decantr_contract` | Read Essence, validate, check drift, generate a skeleton, or read the Contract capsule | `{ "action": "validate", "path": "./decantr.essence.json" }` |
|
|
143
|
-
| `decantr_context` | Read scaffold, section, page, task, and execution-pack context | `{ "action": "task", "project_path": "apps/web", "route": "/feed", "task": "improve recipe card loading" }` |
|
|
143
|
+
| `decantr_context` | Read scaffold, section, page, task, shared discovery summary, and execution-pack context | `{ "action": "task", "project_path": "apps/web", "route": "/feed", "task": "improve recipe card loading" }` |
|
|
144
144
|
| `decantr_graph` | Read graph snapshots, query graph nodes/edges, or traverse graph relations | `{ "action": "query", "project_path": "apps/web", "file_path": "src/app/page.tsx", "include_impact": true }` |
|
|
145
|
-
| `decantr_registry` |
|
|
146
|
-
| `decantr_verify` | Run audit, critique, findings, v2 evidence bundles, or health-loop reads | `{ "action": "evidence_bundle", "project_path": "apps/web" }` |
|
|
145
|
+
| `decantr_registry` | Compatibility content-corpus tool for official vocabulary, benchmarks, and execution packs | `{ "action": "resolve_pattern", "id": "data-table", "preset": "product" }` |
|
|
146
|
+
| `decantr_verify` | Run audit, critique, findings, v2 evidence bundles with discovery metadata, or health-loop reads | `{ "action": "evidence_bundle", "project_path": "apps/web" }` |
|
|
147
147
|
| `decantr_repair` | Return typed findings, repair plans, repair prompts, and v2 health-loop guidance | `{ "action": "health_loop", "project_path": "apps/web" }` |
|
|
148
148
|
| `decantr_contract_write` | Explicit write surface for accepting drift, deferring drift to the drift log, or mutating Essence v4 | `{ "action": "update_essence", "operation": "add_feature", "payload": { "feature": "billing" } }` |
|
|
149
149
|
|
|
@@ -155,7 +155,7 @@ For Decantr 3 assistant prompt migration, see the MCP migration guide: https://d
|
|
|
155
155
|
|
|
156
156
|
The MCP server reads Decantr files, including `.decantr/graph` typed graph artifacts, and selected project files from the active workspace. Write access is limited to the explicit `decantr_contract_write` tool with `accept_drift` and `update_essence` actions. `accept_drift` may defer a finding to `.decantr/drift-log.json` when the caller explicitly requests that resolution. Paths are contained to the active workspace root.
|
|
157
157
|
|
|
158
|
-
|
|
158
|
+
Content-corpus and pack-resolution tools may call the configured Decantr API. Source upload fallbacks for hosted critique/audit are retired; verification tools run local reads unless a future major version introduces a new upload contract. The MCP server does not emit Decantr telemetry. See [security permissions](https://decantr.ai/reference/security-permissions.md).
|
|
159
159
|
|
|
160
160
|
## Compatibility
|
|
161
161
|
|
|
@@ -167,11 +167,11 @@ Registry and pack-resolution tools may call the configured Decantr API. Source u
|
|
|
167
167
|
|
|
168
168
|
### 3.4 Tool Surface Migration
|
|
169
169
|
|
|
170
|
-
Decantr 3.4 consolidated legacy MCP tool names into the eight action-based tools above. Decantr 3.
|
|
170
|
+
Decantr 3.4 consolidated legacy MCP tool names into the eight action-based tools above. Decantr 3.7 keeps that surface, preserves v2 task/evidence/workspace-health/health-loop contracts, and adds compatible discovery metadata only through the consolidated tools. For example, `decantr_get_project_state` becomes `decantr_project` with `{ "action": "state" }`, `decantr_get_graph_snapshot` becomes `decantr_graph` with `{ "action": "snapshot" }`, and the legacy write tools become `decantr_contract_write` with `{ "action": "accept_drift" }` or `{ "action": "update_essence" }`.
|
|
171
171
|
|
|
172
172
|
## How It Works
|
|
173
173
|
|
|
174
|
-
An Essence spec (`decantr.essence.json`) captures your design intent -- archetype, theme, page structure, patterns, and guard rules -- in a single declarative file. The MCP server exposes this spec and the Decantr
|
|
174
|
+
An Essence spec (`decantr.essence.json`) captures your design intent -- archetype, theme, page structure, patterns, and guard rules -- in a single declarative file. The MCP server exposes this spec and the official Decantr content corpus to your AI assistant, giving it concrete layout specs, component lists, and visual treatments instead of relying on the model's generic training data. The result is generated code that follows a coherent contract, and drift detection that catches deviations before they ship.
|
|
175
175
|
|
|
176
176
|
## Example Workflow
|
|
177
177
|
|
|
@@ -180,11 +180,11 @@ An Essence spec (`decantr.essence.json`) captures your design intent -- archetyp
|
|
|
180
180
|
The AI assistant calls these tools behind the scenes:
|
|
181
181
|
|
|
182
182
|
1. `decantr_contract` with `create_essence`, `validate`, or `check_drift` actions to generate and verify the contract
|
|
183
|
-
2. `decantr_registry` with `resolve_archetype`, `suggest_patterns`, `resolve_pattern`, or `compile_execution_packs` actions to fetch vocabulary and packs
|
|
183
|
+
2. `decantr_registry` with `resolve_archetype`, `suggest_patterns`, `resolve_pattern`, or `compile_execution_packs` actions to fetch official content-corpus vocabulary and packs
|
|
184
184
|
3. `decantr_context` with `execution_pack` or `task` actions to load the compact task contract before editing
|
|
185
185
|
4. `decantr_project` with `state` to check Essence, packs, graph readiness, local law, diagnostics, and next useful action calls
|
|
186
186
|
5. `decantr_contract` with `capsule` and `decantr_graph` with `snapshot`, `query`, or `traverse` to read typed graph context
|
|
187
|
-
6. `decantr_verify` with `critique`, `audit_project`, or `evidence_bundle` to produce local v2 evidence
|
|
187
|
+
6. `decantr_verify` with `critique`, `audit_project`, or `evidence_bundle` to produce local v2 evidence
|
|
188
188
|
7. `decantr_repair` with `findings`, `repair_plan`, `repair_prompt`, or `health_loop` to enter a scoped evidence-backed repair loop
|
|
189
189
|
|
|
190
190
|
The AI now generates code with the right layout structure, correct components, and consistent styling, then gets a scoped evidence-backed repair loop instead of a generic guess.
|
package/dist/bin.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import "./chunk-
|
|
2
|
+
import "./chunk-M45XVAPP.js";
|
|
@@ -8,7 +8,7 @@ import { execFileSync } from "child_process";
|
|
|
8
8
|
import { createHash } from "crypto";
|
|
9
9
|
import { existsSync, readdirSync, readFileSync } from "fs";
|
|
10
10
|
import { readFile as readFile2 } from "fs/promises";
|
|
11
|
-
import {
|
|
11
|
+
import { dirname as dirname2, isAbsolute as isAbsolute2, join as join2, relative as relative2, resolve as resolve2 } from "path";
|
|
12
12
|
import {
|
|
13
13
|
buildGraphImpactContext,
|
|
14
14
|
buildGraphRouteContext,
|
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
createEvidenceTier,
|
|
36
36
|
createLoopReadiness,
|
|
37
37
|
deriveVerificationDiagnostic,
|
|
38
|
+
discoverProject,
|
|
38
39
|
KNOWN_VERIFICATION_DIAGNOSTICS,
|
|
39
40
|
LOOP_READINESS_V2_SCHEMA_URL,
|
|
40
41
|
PROJECT_HEALTH_REPORT_V2_SCHEMA_URL,
|
|
@@ -234,6 +235,65 @@ function displayProjectFile(projectRoot, path) {
|
|
|
234
235
|
if (isAbsolute2(path)) return displayWorkspacePath(path);
|
|
235
236
|
return displayWorkspacePath(join2(projectRoot, path));
|
|
236
237
|
}
|
|
238
|
+
function mcpDiscoverySummary(projectRoot) {
|
|
239
|
+
const discovery = discoverProject(projectRoot);
|
|
240
|
+
return {
|
|
241
|
+
schema_version: "discovery.v1",
|
|
242
|
+
project_path: discovery.workspace.projectPath,
|
|
243
|
+
workspace_scope: discovery.workspace.scope,
|
|
244
|
+
project: {
|
|
245
|
+
framework: discovery.project.framework,
|
|
246
|
+
framework_version: discovery.project.frameworkVersion,
|
|
247
|
+
package_manager: discovery.project.packageManager,
|
|
248
|
+
primary_language: discovery.project.primaryLanguage,
|
|
249
|
+
has_typescript: discovery.project.hasTypeScript,
|
|
250
|
+
has_tailwind: discovery.project.hasTailwind,
|
|
251
|
+
has_decantr: discovery.project.hasDecantr,
|
|
252
|
+
package_name: discovery.project.packageName,
|
|
253
|
+
evidence: discovery.project.evidence
|
|
254
|
+
},
|
|
255
|
+
routes: {
|
|
256
|
+
strategy: discovery.routes.strategy,
|
|
257
|
+
route_signal_count: discovery.routes.routeSignalCount,
|
|
258
|
+
taskable_route_count: discovery.routes.taskableRouteCount,
|
|
259
|
+
confidence: discovery.routes.confidence,
|
|
260
|
+
taskable_routes: discovery.routes.taskableRoutes.slice(0, 20).map((route) => ({
|
|
261
|
+
path: route.path,
|
|
262
|
+
file: route.file,
|
|
263
|
+
source: route.source,
|
|
264
|
+
confidence: route.confidence
|
|
265
|
+
})),
|
|
266
|
+
signals: discovery.routes.routeSignals.slice(0, 20).map((signal) => ({
|
|
267
|
+
path: signal.path,
|
|
268
|
+
file: signal.file,
|
|
269
|
+
kind: signal.kind,
|
|
270
|
+
taskable: signal.taskable,
|
|
271
|
+
confidence: signal.confidence
|
|
272
|
+
}))
|
|
273
|
+
},
|
|
274
|
+
components: {
|
|
275
|
+
component_count: discovery.components.componentCount,
|
|
276
|
+
page_count: discovery.components.pageCount,
|
|
277
|
+
confidence: discovery.components.confidence,
|
|
278
|
+
directories: discovery.components.directories,
|
|
279
|
+
evidence: discovery.components.evidence,
|
|
280
|
+
limitations: discovery.components.limitations
|
|
281
|
+
},
|
|
282
|
+
styling: {
|
|
283
|
+
approach: discovery.styling.approach,
|
|
284
|
+
config_file: discovery.styling.configFile,
|
|
285
|
+
css_variable_count: discovery.styling.cssVariableCount,
|
|
286
|
+
color_token_count: discovery.styling.colorTokenCount,
|
|
287
|
+
dark_mode: discovery.styling.darkMode,
|
|
288
|
+
theme_signals: discovery.styling.themeSignals
|
|
289
|
+
},
|
|
290
|
+
assistant: {
|
|
291
|
+
rule_files: discovery.assistant.ruleFiles
|
|
292
|
+
},
|
|
293
|
+
confidence: discovery.confidence,
|
|
294
|
+
limitations: discovery.limitations
|
|
295
|
+
};
|
|
296
|
+
}
|
|
237
297
|
function graphAvailableRoutes(snapshot) {
|
|
238
298
|
return snapshot.nodes.filter((node) => node.type === "Route").map((node) => graphPayloadString(node.payload, "path") ?? node.id.replace(/^rt:/, "")).sort();
|
|
239
299
|
}
|
|
@@ -950,111 +1010,6 @@ async function getHostedExecutionPackManifestPayload(args) {
|
|
|
950
1010
|
typeof args.namespace === "string" ? { namespace: args.namespace } : void 0
|
|
951
1011
|
);
|
|
952
1012
|
}
|
|
953
|
-
async function getHostedFileCritiquePayload(args) {
|
|
954
|
-
const client = getAPIClient();
|
|
955
|
-
const filePath = args.file_path;
|
|
956
|
-
const resolvedFilePath = resolveWorkspacePath(filePath);
|
|
957
|
-
const snapshotFilePath = relative2(process.cwd(), resolvedFilePath).replace(/\\/g, "/") || basename2(resolvedFilePath);
|
|
958
|
-
const code = await readFile2(resolvedFilePath, "utf-8");
|
|
959
|
-
const { essence } = await readEssenceFile(args.path);
|
|
960
|
-
const treatmentsPath = typeof args.treatments_path === "string" ? resolveWorkspacePath(args.treatments_path) : join2(process.cwd(), "src", "styles", "treatments.css");
|
|
961
|
-
const treatmentsCss = existsSync(treatmentsPath) ? readFileSync(treatmentsPath, "utf-8") : void 0;
|
|
962
|
-
return client.critiqueFile(
|
|
963
|
-
{
|
|
964
|
-
essence,
|
|
965
|
-
filePath: snapshotFilePath,
|
|
966
|
-
code,
|
|
967
|
-
treatmentsCss
|
|
968
|
-
},
|
|
969
|
-
typeof args.namespace === "string" ? { namespace: args.namespace } : void 0
|
|
970
|
-
);
|
|
971
|
-
}
|
|
972
|
-
function extractHostedAssetPaths(indexHtml) {
|
|
973
|
-
const assetPaths = /* @__PURE__ */ new Set();
|
|
974
|
-
for (const match of indexHtml.matchAll(/<(?:script|link)[^>]+(?:src|href)="([^"]+)"/g)) {
|
|
975
|
-
const assetPath = match[1];
|
|
976
|
-
const assetsIndex = assetPath.indexOf("/assets/");
|
|
977
|
-
if (assetsIndex === -1) continue;
|
|
978
|
-
assetPaths.add(assetPath.slice(assetsIndex));
|
|
979
|
-
}
|
|
980
|
-
return [...assetPaths];
|
|
981
|
-
}
|
|
982
|
-
async function captureHostedDistSnapshot(projectRoot, distPathArg) {
|
|
983
|
-
const distRoot = distPathArg ? resolveWorkspacePath(distPathArg, projectRoot) : join2(projectRoot, "dist");
|
|
984
|
-
const indexPath = join2(distRoot, "index.html");
|
|
985
|
-
if (!existsSync(indexPath)) {
|
|
986
|
-
return void 0;
|
|
987
|
-
}
|
|
988
|
-
const indexHtml = readFileSync(indexPath, "utf-8");
|
|
989
|
-
const assets = {};
|
|
990
|
-
for (const assetPath of extractHostedAssetPaths(indexHtml)) {
|
|
991
|
-
const snapshotAssetPath = assetPath.replace(/^[/\\]+/, "");
|
|
992
|
-
const assetFilePath = resolveWorkspacePath(snapshotAssetPath, distRoot);
|
|
993
|
-
if (existsSync(assetFilePath)) {
|
|
994
|
-
assets[snapshotAssetPath] = readFileSync(assetFilePath, "utf-8");
|
|
995
|
-
}
|
|
996
|
-
}
|
|
997
|
-
return {
|
|
998
|
-
indexHtml,
|
|
999
|
-
assets
|
|
1000
|
-
};
|
|
1001
|
-
}
|
|
1002
|
-
function isHostedSourceSnapshotFile(path) {
|
|
1003
|
-
if (/\.d\.ts$/i.test(path)) return false;
|
|
1004
|
-
return /\.(?:[cm]?[jt]sx?)$/i.test(path);
|
|
1005
|
-
}
|
|
1006
|
-
async function captureHostedSourceSnapshot(projectRoot, sourcesPathArg) {
|
|
1007
|
-
if (!sourcesPathArg) {
|
|
1008
|
-
return void 0;
|
|
1009
|
-
}
|
|
1010
|
-
const sourcesRoot = resolveWorkspacePath(sourcesPathArg, projectRoot);
|
|
1011
|
-
if (!existsSync(sourcesRoot)) {
|
|
1012
|
-
return void 0;
|
|
1013
|
-
}
|
|
1014
|
-
const files = {};
|
|
1015
|
-
const ignoredDirNames = /* @__PURE__ */ new Set([
|
|
1016
|
-
"node_modules",
|
|
1017
|
-
".git",
|
|
1018
|
-
".decantr",
|
|
1019
|
-
"dist",
|
|
1020
|
-
"build",
|
|
1021
|
-
"coverage"
|
|
1022
|
-
]);
|
|
1023
|
-
const rootPrefix = basename2(sourcesRoot);
|
|
1024
|
-
const walk = (absoluteDir, relativeDir) => {
|
|
1025
|
-
for (const entry of readdirSync(absoluteDir, { withFileTypes: true })) {
|
|
1026
|
-
if (ignoredDirNames.has(entry.name)) continue;
|
|
1027
|
-
const absolutePath = join2(absoluteDir, entry.name);
|
|
1028
|
-
const relativePath = join2(relativeDir, entry.name).replace(/\\/g, "/");
|
|
1029
|
-
if (entry.isDirectory()) {
|
|
1030
|
-
walk(absolutePath, relativePath);
|
|
1031
|
-
continue;
|
|
1032
|
-
}
|
|
1033
|
-
if (!entry.isFile()) continue;
|
|
1034
|
-
if (!isHostedSourceSnapshotFile(relativePath)) continue;
|
|
1035
|
-
files[relativePath] = readFileSync(absolutePath, "utf-8");
|
|
1036
|
-
}
|
|
1037
|
-
};
|
|
1038
|
-
walk(sourcesRoot, rootPrefix);
|
|
1039
|
-
return Object.keys(files).length > 0 ? { files } : void 0;
|
|
1040
|
-
}
|
|
1041
|
-
async function getHostedProjectAuditPayload(args) {
|
|
1042
|
-
const client = getAPIClient();
|
|
1043
|
-
const { essence } = await readEssenceFile(args.path);
|
|
1044
|
-
const dist = await captureHostedDistSnapshot(process.cwd(), args.dist_path);
|
|
1045
|
-
const sources = await captureHostedSourceSnapshot(
|
|
1046
|
-
process.cwd(),
|
|
1047
|
-
args.sources_path
|
|
1048
|
-
);
|
|
1049
|
-
return client.auditProject(
|
|
1050
|
-
{
|
|
1051
|
-
essence,
|
|
1052
|
-
dist,
|
|
1053
|
-
sources
|
|
1054
|
-
},
|
|
1055
|
-
typeof args.namespace === "string" ? { namespace: args.namespace } : void 0
|
|
1056
|
-
);
|
|
1057
|
-
}
|
|
1058
1013
|
async function loadHostedExecutionPackBundleFallback(args) {
|
|
1059
1014
|
try {
|
|
1060
1015
|
return {
|
|
@@ -1094,38 +1049,9 @@ async function loadHostedSelectedExecutionPackFallback(args) {
|
|
|
1094
1049
|
};
|
|
1095
1050
|
}
|
|
1096
1051
|
}
|
|
1097
|
-
async function loadHostedFileCritiqueFallback(args) {
|
|
1098
|
-
try {
|
|
1099
|
-
return {
|
|
1100
|
-
report: await getHostedFileCritiquePayload(args),
|
|
1101
|
-
error: null
|
|
1102
|
-
};
|
|
1103
|
-
} catch (error) {
|
|
1104
|
-
return {
|
|
1105
|
-
report: null,
|
|
1106
|
-
error: error.message
|
|
1107
|
-
};
|
|
1108
|
-
}
|
|
1109
|
-
}
|
|
1110
|
-
async function loadHostedProjectAuditFallback(args) {
|
|
1111
|
-
try {
|
|
1112
|
-
return {
|
|
1113
|
-
report: await getHostedProjectAuditPayload(args),
|
|
1114
|
-
error: null
|
|
1115
|
-
};
|
|
1116
|
-
} catch (error) {
|
|
1117
|
-
return {
|
|
1118
|
-
report: null,
|
|
1119
|
-
error: error.message
|
|
1120
|
-
};
|
|
1121
|
-
}
|
|
1122
|
-
}
|
|
1123
1052
|
function hasExecutionPackPayload(payload) {
|
|
1124
1053
|
return payload.markdown !== null || payload.json !== null;
|
|
1125
1054
|
}
|
|
1126
|
-
function allowsHostedUpload(args) {
|
|
1127
|
-
return args.allow_hosted_upload === true;
|
|
1128
|
-
}
|
|
1129
1055
|
function toHostedExecutionPackPayload(pack) {
|
|
1130
1056
|
return {
|
|
1131
1057
|
markdown: pack && typeof pack.renderedMarkdown === "string" ? pack.renderedMarkdown : null,
|
|
@@ -1285,7 +1211,7 @@ function mcpCommandsForFinding(source) {
|
|
|
1285
1211
|
case "pack":
|
|
1286
1212
|
return [
|
|
1287
1213
|
"decantr refresh",
|
|
1288
|
-
"decantr
|
|
1214
|
+
"decantr content get-pack review --write-context",
|
|
1289
1215
|
"decantr health"
|
|
1290
1216
|
];
|
|
1291
1217
|
case "runtime":
|
|
@@ -1974,7 +1900,7 @@ var TOOLS = [
|
|
|
1974
1900
|
consolidatedTool(
|
|
1975
1901
|
"decantr_registry",
|
|
1976
1902
|
"Decantr Registry",
|
|
1977
|
-
"
|
|
1903
|
+
"Compatibility tool for searching the official Decantr content corpus, benchmark metadata, and execution packs.",
|
|
1978
1904
|
READ_ONLY_NETWORK
|
|
1979
1905
|
),
|
|
1980
1906
|
consolidatedTool(
|
|
@@ -2292,7 +2218,7 @@ async function handleLegacyTool(name, args) {
|
|
|
2292
2218
|
if (args.components_used && Array.isArray(args.components_used) && args.page_id && typeof args.page_id === "string") {
|
|
2293
2219
|
const pages = listEssencePages(essence);
|
|
2294
2220
|
const page = pages.find((p) => p.id === args.page_id);
|
|
2295
|
-
if (page
|
|
2221
|
+
if (page?.layout) {
|
|
2296
2222
|
const expectedPatterns = /* @__PURE__ */ new Set();
|
|
2297
2223
|
for (const item of page.layout) {
|
|
2298
2224
|
if (typeof item === "string") {
|
|
@@ -2621,6 +2547,7 @@ async function handleLegacyTool(name, args) {
|
|
|
2621
2547
|
return {
|
|
2622
2548
|
source: "local_workspace",
|
|
2623
2549
|
project_root: displayWorkspacePath(projectRoot),
|
|
2550
|
+
discovery: mcpDiscoverySummary(projectRoot),
|
|
2624
2551
|
essence: essence ? {
|
|
2625
2552
|
present: true,
|
|
2626
2553
|
version: typeof essence.version === "string" ? essence.version : null,
|
|
@@ -3222,7 +3149,7 @@ async function handleLegacyTool(name, args) {
|
|
|
3222
3149
|
const hosted = await loadHostedExecutionPackBundleFallback(args);
|
|
3223
3150
|
if (!hosted.bundle) {
|
|
3224
3151
|
return {
|
|
3225
|
-
error: "Scaffold context not found. Run `decantr refresh` or `decantr
|
|
3152
|
+
error: "Scaffold context not found. Run `decantr refresh` or `decantr content compile-packs --write-context` to materialize scaffold context and execution packs.",
|
|
3226
3153
|
hosted_fallback_error: hosted.error ?? hostedScaffold.error ?? hostedReview.error
|
|
3227
3154
|
};
|
|
3228
3155
|
}
|
|
@@ -3353,7 +3280,7 @@ async function handleLegacyTool(name, args) {
|
|
|
3353
3280
|
context: derivedContext,
|
|
3354
3281
|
execution_pack_source: executionPackSource,
|
|
3355
3282
|
execution_pack: executionPack,
|
|
3356
|
-
note: executionPackSource === "hosted_fallback" ? "Section context file not found. Using hosted compiled execution pack fallback as the readable section context." : `Section context file not found. Run \`decantr refresh\` or \`decantr
|
|
3283
|
+
note: executionPackSource === "hosted_fallback" ? "Section context file not found. Using hosted compiled execution pack fallback as the readable section context." : `Section context file not found. Run \`decantr refresh\` or \`decantr content get-pack section ${sectionId} --write-context\` to generate it.`,
|
|
3357
3284
|
hosted_fallback_error: executionPackSource ? void 0 : hostedFallbackError
|
|
3358
3285
|
};
|
|
3359
3286
|
}
|
|
@@ -3406,7 +3333,7 @@ async function handleLegacyTool(name, args) {
|
|
|
3406
3333
|
const hosted = await loadHostedPageSelection();
|
|
3407
3334
|
if (!hosted) {
|
|
3408
3335
|
return {
|
|
3409
|
-
error: "Execution pack manifest not found. Run `decantr refresh` or `decantr
|
|
3336
|
+
error: "Execution pack manifest not found. Run `decantr refresh` or `decantr content get-pack manifest --write-context` to generate compiled packs.",
|
|
3410
3337
|
hosted_fallback_error: hostedFallbackError
|
|
3411
3338
|
};
|
|
3412
3339
|
}
|
|
@@ -3651,6 +3578,7 @@ async function handleLegacyTool(name, args) {
|
|
|
3651
3578
|
verifyCommand
|
|
3652
3579
|
};
|
|
3653
3580
|
return {
|
|
3581
|
+
discovery: mcpDiscoverySummary(projectRoot),
|
|
3654
3582
|
route: resolvedRoute,
|
|
3655
3583
|
page_id: pageId,
|
|
3656
3584
|
section_id: section.id,
|
|
@@ -3755,7 +3683,7 @@ async function handleLegacyTool(name, args) {
|
|
|
3755
3683
|
hostedFallbackError = hosted.error;
|
|
3756
3684
|
if (!hosted.bundle) {
|
|
3757
3685
|
return {
|
|
3758
|
-
error: "Execution pack manifest not found. Run `decantr refresh` or `decantr
|
|
3686
|
+
error: "Execution pack manifest not found. Run `decantr refresh` or `decantr content get-pack manifest --write-context` to generate compiled packs.",
|
|
3759
3687
|
hosted_fallback_error: hosted.error
|
|
3760
3688
|
};
|
|
3761
3689
|
}
|
|
@@ -3775,7 +3703,7 @@ async function handleLegacyTool(name, args) {
|
|
|
3775
3703
|
hostedFallbackError = hosted.error;
|
|
3776
3704
|
if (!hosted.selected) {
|
|
3777
3705
|
return {
|
|
3778
|
-
error: "Execution pack manifest not found. Run `decantr refresh` or `decantr
|
|
3706
|
+
error: "Execution pack manifest not found. Run `decantr refresh` or `decantr content get-pack manifest --write-context` to generate compiled packs.",
|
|
3779
3707
|
hosted_fallback_error: hosted.error
|
|
3780
3708
|
};
|
|
3781
3709
|
}
|
|
@@ -3930,12 +3858,6 @@ async function handleLegacyTool(name, args) {
|
|
|
3930
3858
|
if (existsSync(localReviewPackPath)) {
|
|
3931
3859
|
return critiqueFile(args.file_path, process.cwd());
|
|
3932
3860
|
}
|
|
3933
|
-
if (allowsHostedUpload(args)) {
|
|
3934
|
-
const hosted = await loadHostedFileCritiqueFallback(args);
|
|
3935
|
-
if (hosted.report) {
|
|
3936
|
-
return hosted.report;
|
|
3937
|
-
}
|
|
3938
|
-
}
|
|
3939
3861
|
return critiqueFile(args.file_path, process.cwd());
|
|
3940
3862
|
}
|
|
3941
3863
|
case "decantr_audit_project": {
|
|
@@ -3965,12 +3887,6 @@ async function handleLegacyTool(name, args) {
|
|
|
3965
3887
|
if (hasReviewPack && hasPackManifest) {
|
|
3966
3888
|
return auditProject(projectRoot);
|
|
3967
3889
|
}
|
|
3968
|
-
if (allowsHostedUpload(args)) {
|
|
3969
|
-
const hosted = await loadHostedProjectAuditFallback(args);
|
|
3970
|
-
if (hosted.report) {
|
|
3971
|
-
return hosted.report;
|
|
3972
|
-
}
|
|
3973
|
-
}
|
|
3974
3890
|
return auditProject(projectRoot);
|
|
3975
3891
|
}
|
|
3976
3892
|
case "decantr_get_findings": {
|
|
@@ -4072,7 +3988,10 @@ async function handleLegacyTool(name, args) {
|
|
|
4072
3988
|
try {
|
|
4073
3989
|
const projectRoot = resolveMcpProjectRoot(args.project_path);
|
|
4074
3990
|
const state = await getMcpHealthState(projectRoot);
|
|
4075
|
-
return
|
|
3991
|
+
return {
|
|
3992
|
+
...state.evidence,
|
|
3993
|
+
discovery: mcpDiscoverySummary(projectRoot)
|
|
3994
|
+
};
|
|
4076
3995
|
} catch (error) {
|
|
4077
3996
|
return { error: error.message };
|
|
4078
3997
|
}
|
|
@@ -4111,6 +4030,7 @@ async function handleLegacyTool(name, args) {
|
|
|
4111
4030
|
}
|
|
4112
4031
|
return {
|
|
4113
4032
|
project: state.evidence.project,
|
|
4033
|
+
discovery: mcpDiscoverySummary(projectRoot),
|
|
4114
4034
|
health: state.evidence.health,
|
|
4115
4035
|
finding: {
|
|
4116
4036
|
id: finding.id,
|
|
@@ -4329,7 +4249,7 @@ function describeUpdate(operation, payload) {
|
|
|
4329
4249
|
}
|
|
4330
4250
|
|
|
4331
4251
|
// src/index.ts
|
|
4332
|
-
var VERSION = "3.
|
|
4252
|
+
var VERSION = "3.8.0";
|
|
4333
4253
|
var server = new Server({ name: "decantr", version: VERSION }, { capabilities: { tools: {} } });
|
|
4334
4254
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
4335
4255
|
return { tools: TOOLS };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import "./chunk-
|
|
1
|
+
import "./chunk-M45XVAPP.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@decantr/mcp-server",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.8.0",
|
|
4
4
|
"mcpName": "io.github.decantr-ai/mcp-server",
|
|
5
5
|
"description": "MCP server for Decantr — exposes Contract context, typed graph artifacts, and verification evidence to AI coding assistants",
|
|
6
6
|
"keywords": [
|
|
@@ -41,7 +41,8 @@
|
|
|
41
41
|
"main": "dist/index.js",
|
|
42
42
|
"types": "dist/index.d.ts",
|
|
43
43
|
"files": [
|
|
44
|
-
"dist"
|
|
44
|
+
"dist",
|
|
45
|
+
"server.json"
|
|
45
46
|
],
|
|
46
47
|
"engines": {
|
|
47
48
|
"node": ">=20.19.0"
|
|
@@ -51,10 +52,10 @@
|
|
|
51
52
|
},
|
|
52
53
|
"dependencies": {
|
|
53
54
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
54
|
-
"@decantr/core": "3.
|
|
55
|
-
"@decantr/verifier": "3.
|
|
56
|
-
"@decantr/essence-spec": "3.
|
|
57
|
-
"@decantr/registry": "3.
|
|
55
|
+
"@decantr/core": "3.8.0",
|
|
56
|
+
"@decantr/verifier": "3.8.0",
|
|
57
|
+
"@decantr/essence-spec": "3.8.0",
|
|
58
|
+
"@decantr/registry": "3.8.0"
|
|
58
59
|
},
|
|
59
60
|
"scripts": {
|
|
60
61
|
"build": "tsup",
|
package/server.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
|
+
"name": "io.github.decantr-ai/mcp-server",
|
|
4
|
+
"description": "AI Frontend Governance for codebases touched by AI agents. Serves Contract context, typed graph artifacts, drift evidence, and repair prompts.",
|
|
5
|
+
"repository": {
|
|
6
|
+
"url": "https://github.com/decantr-ai/decantr",
|
|
7
|
+
"source": "github"
|
|
8
|
+
},
|
|
9
|
+
"version": "3.8.0",
|
|
10
|
+
"packages": [
|
|
11
|
+
{
|
|
12
|
+
"registryType": "npm",
|
|
13
|
+
"identifier": "@decantr/mcp-server",
|
|
14
|
+
"version": "3.8.0",
|
|
15
|
+
"transport": {
|
|
16
|
+
"type": "stdio"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|