@decantr/mcp-server 3.7.0 → 3.8.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
@@ -142,7 +142,7 @@ The server exposes a hard 8-tool MCP surface. Pass an `action` to select the rou
142
142
  | `decantr_contract` | Read Essence, validate, check drift, generate a skeleton, or read the Contract capsule | `{ "action": "validate", "path": "./decantr.essence.json" }` |
143
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` | Search and resolve hosted registry content, benchmarks, and execution packs | `{ "action": "resolve_pattern", "id": "data-table", "preset": "product" }` |
145
+ | `decantr_registry` | Compatibility content-corpus tool for official vocabulary, benchmarks, and execution packs | `{ "action": "resolve_pattern", "id": "data-table", "preset": "product" }` |
146
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" } }` |
@@ -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
- Registry and pack-resolution tools may call the configured Decantr API. Source upload fallbacks for hosted critique/audit are disabled unless the tool call explicitly passes `allow_hosted_upload: true`. The MCP server does not emit Decantr telemetry. See [security permissions](https://decantr.ai/reference/security-permissions.md).
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.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" }`.
170
+ Decantr 3.4 consolidated legacy MCP tool names into the eight action-based tools above. Decantr 3.8.1 keeps that surface, preserves v2 task/evidence/workspace-health/health-loop contracts, and routes official corpus compatibility through `decantr_registry` rather than adding a ninth tool. 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 registry 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 design system, and drift detection that catches deviations before they ship.
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; hosted upload remains opt-in with `allow_hosted_upload: true`
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-S3XFNHZ5.js";
2
+ import "./chunk-ZZ6NMQ5Y.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 { basename as basename2, dirname as dirname2, isAbsolute as isAbsolute2, join as join2, relative as relative2, resolve as resolve2 } from "path";
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,
@@ -1010,111 +1010,6 @@ async function getHostedExecutionPackManifestPayload(args) {
1010
1010
  typeof args.namespace === "string" ? { namespace: args.namespace } : void 0
1011
1011
  );
1012
1012
  }
1013
- async function getHostedFileCritiquePayload(args) {
1014
- const client = getAPIClient();
1015
- const filePath = args.file_path;
1016
- const resolvedFilePath = resolveWorkspacePath(filePath);
1017
- const snapshotFilePath = relative2(process.cwd(), resolvedFilePath).replace(/\\/g, "/") || basename2(resolvedFilePath);
1018
- const code = await readFile2(resolvedFilePath, "utf-8");
1019
- const { essence } = await readEssenceFile(args.path);
1020
- const treatmentsPath = typeof args.treatments_path === "string" ? resolveWorkspacePath(args.treatments_path) : join2(process.cwd(), "src", "styles", "treatments.css");
1021
- const treatmentsCss = existsSync(treatmentsPath) ? readFileSync(treatmentsPath, "utf-8") : void 0;
1022
- return client.critiqueFile(
1023
- {
1024
- essence,
1025
- filePath: snapshotFilePath,
1026
- code,
1027
- treatmentsCss
1028
- },
1029
- typeof args.namespace === "string" ? { namespace: args.namespace } : void 0
1030
- );
1031
- }
1032
- function extractHostedAssetPaths(indexHtml) {
1033
- const assetPaths = /* @__PURE__ */ new Set();
1034
- for (const match of indexHtml.matchAll(/<(?:script|link)[^>]+(?:src|href)="([^"]+)"/g)) {
1035
- const assetPath = match[1];
1036
- const assetsIndex = assetPath.indexOf("/assets/");
1037
- if (assetsIndex === -1) continue;
1038
- assetPaths.add(assetPath.slice(assetsIndex));
1039
- }
1040
- return [...assetPaths];
1041
- }
1042
- async function captureHostedDistSnapshot(projectRoot, distPathArg) {
1043
- const distRoot = distPathArg ? resolveWorkspacePath(distPathArg, projectRoot) : join2(projectRoot, "dist");
1044
- const indexPath = join2(distRoot, "index.html");
1045
- if (!existsSync(indexPath)) {
1046
- return void 0;
1047
- }
1048
- const indexHtml = readFileSync(indexPath, "utf-8");
1049
- const assets = {};
1050
- for (const assetPath of extractHostedAssetPaths(indexHtml)) {
1051
- const snapshotAssetPath = assetPath.replace(/^[/\\]+/, "");
1052
- const assetFilePath = resolveWorkspacePath(snapshotAssetPath, distRoot);
1053
- if (existsSync(assetFilePath)) {
1054
- assets[snapshotAssetPath] = readFileSync(assetFilePath, "utf-8");
1055
- }
1056
- }
1057
- return {
1058
- indexHtml,
1059
- assets
1060
- };
1061
- }
1062
- function isHostedSourceSnapshotFile(path) {
1063
- if (/\.d\.ts$/i.test(path)) return false;
1064
- return /\.(?:[cm]?[jt]sx?)$/i.test(path);
1065
- }
1066
- async function captureHostedSourceSnapshot(projectRoot, sourcesPathArg) {
1067
- if (!sourcesPathArg) {
1068
- return void 0;
1069
- }
1070
- const sourcesRoot = resolveWorkspacePath(sourcesPathArg, projectRoot);
1071
- if (!existsSync(sourcesRoot)) {
1072
- return void 0;
1073
- }
1074
- const files = {};
1075
- const ignoredDirNames = /* @__PURE__ */ new Set([
1076
- "node_modules",
1077
- ".git",
1078
- ".decantr",
1079
- "dist",
1080
- "build",
1081
- "coverage"
1082
- ]);
1083
- const rootPrefix = basename2(sourcesRoot);
1084
- const walk = (absoluteDir, relativeDir) => {
1085
- for (const entry of readdirSync(absoluteDir, { withFileTypes: true })) {
1086
- if (ignoredDirNames.has(entry.name)) continue;
1087
- const absolutePath = join2(absoluteDir, entry.name);
1088
- const relativePath = join2(relativeDir, entry.name).replace(/\\/g, "/");
1089
- if (entry.isDirectory()) {
1090
- walk(absolutePath, relativePath);
1091
- continue;
1092
- }
1093
- if (!entry.isFile()) continue;
1094
- if (!isHostedSourceSnapshotFile(relativePath)) continue;
1095
- files[relativePath] = readFileSync(absolutePath, "utf-8");
1096
- }
1097
- };
1098
- walk(sourcesRoot, rootPrefix);
1099
- return Object.keys(files).length > 0 ? { files } : void 0;
1100
- }
1101
- async function getHostedProjectAuditPayload(args) {
1102
- const client = getAPIClient();
1103
- const { essence } = await readEssenceFile(args.path);
1104
- const dist = await captureHostedDistSnapshot(process.cwd(), args.dist_path);
1105
- const sources = await captureHostedSourceSnapshot(
1106
- process.cwd(),
1107
- args.sources_path
1108
- );
1109
- return client.auditProject(
1110
- {
1111
- essence,
1112
- dist,
1113
- sources
1114
- },
1115
- typeof args.namespace === "string" ? { namespace: args.namespace } : void 0
1116
- );
1117
- }
1118
1013
  async function loadHostedExecutionPackBundleFallback(args) {
1119
1014
  try {
1120
1015
  return {
@@ -1154,38 +1049,9 @@ async function loadHostedSelectedExecutionPackFallback(args) {
1154
1049
  };
1155
1050
  }
1156
1051
  }
1157
- async function loadHostedFileCritiqueFallback(args) {
1158
- try {
1159
- return {
1160
- report: await getHostedFileCritiquePayload(args),
1161
- error: null
1162
- };
1163
- } catch (error) {
1164
- return {
1165
- report: null,
1166
- error: error.message
1167
- };
1168
- }
1169
- }
1170
- async function loadHostedProjectAuditFallback(args) {
1171
- try {
1172
- return {
1173
- report: await getHostedProjectAuditPayload(args),
1174
- error: null
1175
- };
1176
- } catch (error) {
1177
- return {
1178
- report: null,
1179
- error: error.message
1180
- };
1181
- }
1182
- }
1183
1052
  function hasExecutionPackPayload(payload) {
1184
1053
  return payload.markdown !== null || payload.json !== null;
1185
1054
  }
1186
- function allowsHostedUpload(args) {
1187
- return args.allow_hosted_upload === true;
1188
- }
1189
1055
  function toHostedExecutionPackPayload(pack) {
1190
1056
  return {
1191
1057
  markdown: pack && typeof pack.renderedMarkdown === "string" ? pack.renderedMarkdown : null,
@@ -1345,7 +1211,7 @@ function mcpCommandsForFinding(source) {
1345
1211
  case "pack":
1346
1212
  return [
1347
1213
  "decantr refresh",
1348
- "decantr registry get-pack review --write-context",
1214
+ "decantr content get-pack review --write-context",
1349
1215
  "decantr health"
1350
1216
  ];
1351
1217
  case "runtime":
@@ -2034,7 +1900,7 @@ var TOOLS = [
2034
1900
  consolidatedTool(
2035
1901
  "decantr_registry",
2036
1902
  "Decantr Registry",
2037
- "Search and resolve hosted registry content, benchmark metadata, and execution packs.",
1903
+ "Compatibility tool for searching the official Decantr content corpus, benchmark metadata, and execution packs.",
2038
1904
  READ_ONLY_NETWORK
2039
1905
  ),
2040
1906
  consolidatedTool(
@@ -3283,7 +3149,7 @@ async function handleLegacyTool(name, args) {
3283
3149
  const hosted = await loadHostedExecutionPackBundleFallback(args);
3284
3150
  if (!hosted.bundle) {
3285
3151
  return {
3286
- error: "Scaffold context not found. Run `decantr refresh` or `decantr registry compile-packs --write-context` to materialize scaffold context and execution packs.",
3152
+ error: "Scaffold context not found. Run `decantr refresh` or `decantr content compile-packs --write-context` to materialize scaffold context and execution packs.",
3287
3153
  hosted_fallback_error: hosted.error ?? hostedScaffold.error ?? hostedReview.error
3288
3154
  };
3289
3155
  }
@@ -3414,7 +3280,7 @@ async function handleLegacyTool(name, args) {
3414
3280
  context: derivedContext,
3415
3281
  execution_pack_source: executionPackSource,
3416
3282
  execution_pack: executionPack,
3417
- 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 registry get-pack section ${sectionId} --write-context\` to generate it.`,
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.`,
3418
3284
  hosted_fallback_error: executionPackSource ? void 0 : hostedFallbackError
3419
3285
  };
3420
3286
  }
@@ -3467,7 +3333,7 @@ async function handleLegacyTool(name, args) {
3467
3333
  const hosted = await loadHostedPageSelection();
3468
3334
  if (!hosted) {
3469
3335
  return {
3470
- error: "Execution pack manifest not found. Run `decantr refresh` or `decantr registry get-pack manifest --write-context` to generate compiled packs.",
3336
+ error: "Execution pack manifest not found. Run `decantr refresh` or `decantr content get-pack manifest --write-context` to generate compiled packs.",
3471
3337
  hosted_fallback_error: hostedFallbackError
3472
3338
  };
3473
3339
  }
@@ -3817,7 +3683,7 @@ async function handleLegacyTool(name, args) {
3817
3683
  hostedFallbackError = hosted.error;
3818
3684
  if (!hosted.bundle) {
3819
3685
  return {
3820
- error: "Execution pack manifest not found. Run `decantr refresh` or `decantr registry get-pack manifest --write-context` to generate compiled packs.",
3686
+ error: "Execution pack manifest not found. Run `decantr refresh` or `decantr content get-pack manifest --write-context` to generate compiled packs.",
3821
3687
  hosted_fallback_error: hosted.error
3822
3688
  };
3823
3689
  }
@@ -3837,7 +3703,7 @@ async function handleLegacyTool(name, args) {
3837
3703
  hostedFallbackError = hosted.error;
3838
3704
  if (!hosted.selected) {
3839
3705
  return {
3840
- error: "Execution pack manifest not found. Run `decantr refresh` or `decantr registry get-pack manifest --write-context` to generate compiled packs.",
3706
+ error: "Execution pack manifest not found. Run `decantr refresh` or `decantr content get-pack manifest --write-context` to generate compiled packs.",
3841
3707
  hosted_fallback_error: hosted.error
3842
3708
  };
3843
3709
  }
@@ -3992,12 +3858,6 @@ async function handleLegacyTool(name, args) {
3992
3858
  if (existsSync(localReviewPackPath)) {
3993
3859
  return critiqueFile(args.file_path, process.cwd());
3994
3860
  }
3995
- if (allowsHostedUpload(args)) {
3996
- const hosted = await loadHostedFileCritiqueFallback(args);
3997
- if (hosted.report) {
3998
- return hosted.report;
3999
- }
4000
- }
4001
3861
  return critiqueFile(args.file_path, process.cwd());
4002
3862
  }
4003
3863
  case "decantr_audit_project": {
@@ -4027,12 +3887,6 @@ async function handleLegacyTool(name, args) {
4027
3887
  if (hasReviewPack && hasPackManifest) {
4028
3888
  return auditProject(projectRoot);
4029
3889
  }
4030
- if (allowsHostedUpload(args)) {
4031
- const hosted = await loadHostedProjectAuditFallback(args);
4032
- if (hosted.report) {
4033
- return hosted.report;
4034
- }
4035
- }
4036
3890
  return auditProject(projectRoot);
4037
3891
  }
4038
3892
  case "decantr_get_findings": {
@@ -4395,7 +4249,7 @@ function describeUpdate(operation, payload) {
4395
4249
  }
4396
4250
 
4397
4251
  // src/index.ts
4398
- var VERSION = "3.7.0";
4252
+ var VERSION = "3.8.1";
4399
4253
  var server = new Server({ name: "decantr", version: VERSION }, { capabilities: { tools: {} } });
4400
4254
  server.setRequestHandler(ListToolsRequestSchema, async () => {
4401
4255
  return { tools: TOOLS };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import "./chunk-S3XFNHZ5.js";
1
+ import "./chunk-ZZ6NMQ5Y.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decantr/mcp-server",
3
- "version": "3.7.0",
3
+ "version": "3.8.1",
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/essence-spec": "3.4.0",
55
- "@decantr/core": "3.6.0",
56
- "@decantr/registry": "3.4.0",
57
- "@decantr/verifier": "3.7.0"
55
+ "@decantr/core": "3.8.1",
56
+ "@decantr/essence-spec": "3.8.1",
57
+ "@decantr/registry": "3.8.1",
58
+ "@decantr/verifier": "3.8.1"
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.1",
10
+ "packages": [
11
+ {
12
+ "registryType": "npm",
13
+ "identifier": "@decantr/mcp-server",
14
+ "version": "3.8.1",
15
+ "transport": {
16
+ "type": "stdio"
17
+ }
18
+ }
19
+ ]
20
+ }