@decantr/mcp-server 3.0.0-next.0 → 3.0.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
@@ -12,8 +12,8 @@ AI Frontend Governance for codebases touched by AI agents. Give Claude, Cursor,
12
12
 
13
13
  ![Decantr MCP demo](https://raw.githubusercontent.com/decantr-ai/decantr/main/packages/mcp-server/assets/decantr-demo.gif)
14
14
 
15
- - **Structured Contract context** -- gives your AI assistant patterns, layouts, component specs, typed graph context, Brownfield/Hybrid authority, local law, and task-time context instead of letting it guess
16
- - **Evidence-backed repair loops** -- gives AI agents Project Health, component reuse drift, accepted style bridge drift, stable diagnostic codes, typed repair IDs, graph-anchored Evidence Bundles, workspace health, and scoped repair prompts without uploading source
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
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
19
19
 
@@ -136,8 +136,8 @@ The server exposes Decantr vocabulary, context, benchmark, and verification tool
136
136
  | `decantr_suggest_patterns` | Given a page description plus optional route/source excerpt, get ranked pattern suggestions | `{ "description": "recipe feed with avatars and infinite scroll", "route": "/feed" }` |
137
137
  | `decantr_check_drift` | Check if generated code violates the design intent in the Essence spec | `{ "page_id": "overview", "components_used": ["Card", "LineChart"], "theme_used": "auradecantism" }` |
138
138
  | `decantr_get_execution_pack` | Read compiled scaffold, section, page, review, or mutation execution packs, with hosted fallback when local context is missing | `{ "pack_type": "page", "id": "overview", "format": "json" }` |
139
- | `decantr_get_project_state` | Read a compact typed summary of Essence, generated packs, graph artifacts, capsule source-handle bounds, source artifacts available for file impact, local snapshot history, typed diff counts, local law, style bridge, stable diagnostic catalog, and recommended next tools | `{ "project_path": "apps/web" }` |
140
- | `decantr_prepare_task_context` | Resolve compact route/task context, task-ranked typed route graph, optional graph-shaped changed-file impact, authority lane, local law, style bridge mappings, and evidence before editing a Brownfield, Hybrid, or Essence route | `{ "project_path": "apps/web", "route": "/feed", "task": "improve recipe card loading" }` |
139
+ | `decantr_get_project_state` | Read a compact typed summary of Essence, generated packs, graph artifacts, capsule source-handle bounds, source artifacts available for file impact, local snapshot history, typed diff counts, local law, behavior obligations, style bridge, stable diagnostic catalog, and recommended next tools | `{ "project_path": "apps/web" }` |
140
+ | `decantr_prepare_task_context` | Resolve compact route/task context, task-ranked typed route graph, optional graph-shaped changed-file impact, authority lane, local law, behavior obligations, style bridge mappings, and evidence before editing a Brownfield, Hybrid, or Essence route | `{ "project_path": "apps/web", "route": "/feed", "task": "improve recipe card loading" }` |
141
141
  | `decantr_get_contract_capsule` | Read the cache-friendly Contract capsule generated by `decantr graph`, including bounded SourceArtifact paths that can be reused as `file_path` handles | `{ "project_path": "apps/web" }` |
142
142
  | `decantr_get_graph_snapshot` | Read graph metadata with snapshot-history status and typed diff counts, a compact local history index, a route-scoped graph subgraph, node or source-file impact context, task-aware ranked context, a specific history snapshot, or a typed diff between local snapshots | `{ "project_path": "apps/web", "file_path": "src/app/page.tsx", "task": "edit source" }` |
143
143
  | `decantr_query_graph` | Query current or historical graph nodes, source files, payload fields, relations, and optional node-impact context without reading the full snapshot | `{ "project_path": "apps/web", "snapshot_id": "current", "file_path": "src/app/page.tsx", "include_impact": true }` |
@@ -184,8 +184,8 @@ The AI assistant calls these tools behind the scenes:
184
184
  3. `decantr_suggest_patterns` -- recommends `kpi-grid`, `chart-grid`, `data-table`, and `form-sections` for the described pages
185
185
  4. `decantr_resolve_pattern` -- fetches layout specs and component lists for each pattern
186
186
  5. `decantr_get_execution_pack` -- loads the compiled scaffold/page/review packs as the task contract, falling back to hosted compilation when local pack artifacts are missing
187
- 6. `decantr_get_project_state` -- checks Essence, packs, graph readiness, capsule source-handle bounds, source artifacts available for file impact, local snapshot history, typed diff counts, local law, stable diagnostic codes, and the next useful tool calls
188
- 7. `decantr_prepare_task_context` -- resolves route-local Brownfield/Hybrid context, task-ranked typed route graph context, graph-shaped changed-file impact when changed files resolve to SourceArtifact nodes, active authority, accepted local law, accepted style bridge mappings, visual evidence, and theme inventory before editing an existing app
187
+ 6. `decantr_get_project_state` -- checks Essence, packs, graph readiness, capsule source-handle bounds, source artifacts available for file impact, local snapshot history, typed diff counts, local law, accepted behavior obligations, stable diagnostic codes, and the next useful tool calls
188
+ 7. `decantr_prepare_task_context` -- resolves route-local Brownfield/Hybrid context, task-ranked typed route graph context, graph-shaped changed-file impact when changed files resolve to SourceArtifact nodes, active authority, accepted local law, accepted behavior obligations, accepted style bridge mappings, visual evidence, and theme inventory before editing an existing app
189
189
  8. `decantr_get_contract_capsule` -- loads the compact Contract graph capsule, including the bounded SourceArtifact path index, when `.decantr/graph` exists
190
190
  9. `decantr_get_graph_snapshot` -- reads graph metadata, snapshot-history status, optional compact history, typed diff counts, route-scoped graph nodes/edges with optional task-aware ranking, impact graph nodes/edges through `node_id` or `file_path`, specific history snapshots through `snapshot_id`, and local snapshot diffs through `compare_to`
191
191
  10. `decantr_query_graph` and `decantr_traverse_graph` -- answer typed follow-up questions against current or historical snapshots, such as which pages use a route, component, token, source file, rule, or diagnostic code; `decantr_query_graph` can include an impact subgraph for matched node IDs or a `file_path` SourceArtifact so agents can inspect blast radius before changing a component, token, rule, finding, or source artifact, and `decantr_traverse_graph` can resolve `file_path` into the SourceArtifact start node for relation walks
package/dist/bin.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import "./chunk-IB5HP7DE.js";
2
+ import "./chunk-PFLHZF35.js";
@@ -4,18 +4,18 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
4
4
  import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
5
5
 
6
6
  // src/tools.ts
7
- import { createHash } from "crypto";
8
7
  import { execFileSync } from "child_process";
8
+ import { createHash } from "crypto";
9
9
  import { existsSync, readdirSync, readFileSync } from "fs";
10
10
  import { readFile as readFile2 } from "fs/promises";
11
11
  import { basename as basename2, dirname as dirname2, isAbsolute as isAbsolute2, join as join2, relative as relative2 } from "path";
12
12
  import {
13
- GRAPH_NODE_TYPES,
14
- GRAPH_RELATIONS,
15
13
  buildGraphImpactContext,
16
14
  buildGraphRouteContext,
17
15
  createMemoryGraphStore,
18
16
  diffGraphSnapshots,
17
+ GRAPH_NODE_TYPES,
18
+ GRAPH_RELATIONS,
19
19
  graphPayloadString,
20
20
  sortGraphEdges,
21
21
  sortGraphNodes,
@@ -198,9 +198,7 @@ function readGraphSnapshotHistory(projectRoot, limit = 20) {
198
198
  parent_id: snapshot.parent_id ?? null,
199
199
  summary: snapshot.summary
200
200
  };
201
- }).filter((entry) => Boolean(entry)).sort(
202
- (a, b) => b.created_at.localeCompare(a.created_at) || a.id.localeCompare(b.id)
203
- ).slice(0, Math.max(1, Math.min(100, limit)));
201
+ }).filter((entry) => Boolean(entry)).sort((a, b) => b.created_at.localeCompare(a.created_at) || a.id.localeCompare(b.id)).slice(0, Math.max(1, Math.min(100, limit)));
204
202
  } catch {
205
203
  return [];
206
204
  }
@@ -703,17 +701,51 @@ function impactedRoutesForFiles(projectRoot, files) {
703
701
  }
704
702
  return [...impacted].sort();
705
703
  }
704
+ function stringArray(value) {
705
+ return Array.isArray(value) ? value.filter((entry) => typeof entry === "string" && entry.trim().length > 0) : [];
706
+ }
707
+ function behaviorObligationSummary(pattern) {
708
+ const contract = pattern.behavior_obligations;
709
+ if (!contract || !Array.isArray(contract.obligations)) return null;
710
+ const obligations = contract.obligations.map((entry, index) => {
711
+ if (!entry || typeof entry !== "object" || Array.isArray(entry)) return null;
712
+ const record = entry;
713
+ const id = typeof record.id === "string" && record.id.trim() ? record.id.trim() : `obligation-${index + 1}`;
714
+ const label = typeof record.label === "string" && record.label.trim() ? record.label.trim() : id;
715
+ return {
716
+ id,
717
+ label,
718
+ severity: typeof record.severity === "string" ? record.severity : null,
719
+ evidence: typeof record.evidence === "string" ? record.evidence : null
720
+ };
721
+ }).filter((entry) => Boolean(entry));
722
+ if (obligations.length === 0) return null;
723
+ return {
724
+ pattern_id: pattern.id ?? "unknown",
725
+ pattern_role: contract.pattern_role ?? pattern.role ?? null,
726
+ intent: contract.intent ?? null,
727
+ modalities: stringArray(contract.modalities),
728
+ states: stringArray(contract.states),
729
+ risk_profile: stringArray(contract.risk_profile),
730
+ obligations,
731
+ test_hints: stringArray(contract.test_hints),
732
+ component_paths: pattern.componentPaths ?? []
733
+ };
734
+ }
706
735
  function localLawSummary(projectRoot) {
707
736
  const patterns = readJsonIfExists(join2(projectRoot, ".decantr", "local-patterns.json"));
708
737
  const rules = readJsonIfExists(join2(projectRoot, ".decantr", "rules.json"));
738
+ const behaviorObligations = patterns?.patterns?.map((pattern) => behaviorObligationSummary(pattern)).filter((entry) => Boolean(entry)) ?? [];
709
739
  return {
710
740
  patterns_path: patterns ? ".decantr/local-patterns.json" : null,
711
741
  rules_path: rules ? ".decantr/rules.json" : null,
712
742
  patterns: patterns?.patterns?.map((pattern) => ({
713
743
  id: pattern.id ?? "unknown",
714
744
  role: pattern.role ?? null,
715
- component_paths: pattern.componentPaths ?? []
745
+ component_paths: pattern.componentPaths ?? [],
746
+ behavior_obligations: behaviorObligationSummary(pattern)
716
747
  })) ?? [],
748
+ behavior_obligations: behaviorObligations,
717
749
  rules: rules?.rules?.map((rule) => ({
718
750
  id: rule.id ?? "unknown",
719
751
  enabled: rule.enabled ?? false,
@@ -2099,7 +2131,7 @@ var TOOLS = [
2099
2131
  {
2100
2132
  name: "decantr_prepare_task_context",
2101
2133
  title: "Prepare Task Context",
2102
- description: "Resolve compact Brownfield/Essence task-time context for a route or page before editing. Returns route, section, page pack, directives, patterns, shared components, visual target, health evidence, and local screenshot references when available.",
2134
+ description: "Resolve compact Brownfield/Essence task-time context for a route or page before editing. Returns route, section, page pack, directives, local law, behavior obligations, style bridge mappings, typed graph context, health evidence, and local screenshot references when available.",
2103
2135
  inputSchema: {
2104
2136
  type: "object",
2105
2137
  properties: {
@@ -3237,7 +3269,9 @@ async function handleTool(name, args) {
3237
3269
  const capsule = readJsonIfExists(capsulePath);
3238
3270
  const graphFreshness = inspectMcpGraphFreshness(projectRoot);
3239
3271
  const projectConfig = readJsonIfExists(join2(projectRoot, ".decantr", "project.json"));
3240
- const localPatternsPresent = existsSync(join2(projectRoot, ".decantr", "local-patterns.json"));
3272
+ const localPatternsPresent = existsSync(
3273
+ join2(projectRoot, ".decantr", "local-patterns.json")
3274
+ );
3241
3275
  const localRulesPresent = existsSync(join2(projectRoot, ".decantr", "rules.json"));
3242
3276
  const styleBridgePresent = existsSync(join2(projectRoot, ".decantr", "style-bridge.json"));
3243
3277
  const hasGraphArtifacts = existsSync(snapshotPath) && snapshotHistoryPresent && existsSync(manifestPath) && existsSync(diffPath) && existsSync(capsulePath);
@@ -4864,7 +4898,7 @@ function describeUpdate(operation, payload) {
4864
4898
  }
4865
4899
 
4866
4900
  // src/index.ts
4867
- var VERSION = "3.0.0-next.0";
4901
+ var VERSION = "3.0.1";
4868
4902
  var server = new Server({ name: "decantr", version: VERSION }, { capabilities: { tools: {} } });
4869
4903
  server.setRequestHandler(ListToolsRequestSchema, async () => {
4870
4904
  return { tools: TOOLS };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import "./chunk-IB5HP7DE.js";
1
+ import "./chunk-PFLHZF35.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decantr/mcp-server",
3
- "version": "3.0.0-next.0",
3
+ "version": "3.0.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": [
@@ -44,17 +44,17 @@
44
44
  "dist"
45
45
  ],
46
46
  "engines": {
47
- "node": ">=20"
47
+ "node": ">=20.19.0"
48
48
  },
49
49
  "publishConfig": {
50
50
  "access": "public"
51
51
  },
52
52
  "dependencies": {
53
53
  "@modelcontextprotocol/sdk": "^1.29.0",
54
- "@decantr/core": "3.0.0-next.0",
55
- "@decantr/verifier": "3.0.0-next.0",
56
- "@decantr/registry": "3.0.0-next.0",
57
- "@decantr/essence-spec": "3.0.0-next.0"
54
+ "@decantr/core": "3.0.1",
55
+ "@decantr/verifier": "3.0.1",
56
+ "@decantr/essence-spec": "3.0.1",
57
+ "@decantr/registry": "3.0.1"
58
58
  },
59
59
  "scripts": {
60
60
  "build": "tsup",