@decantr/mcp-server 2.1.0 → 2.2.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 CHANGED
@@ -12,7 +12,7 @@ Design intelligence for AI-generated UI. Make Claude, Cursor, and Windsurf gener
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 design context** -- gives your AI assistant patterns, layouts, and component specs instead of letting it guess
15
+ - **Structured design context** -- gives your AI assistant patterns, layouts, component specs, and Brownfield task-time context instead of letting it guess
16
16
  - **Evidence-backed repair loops** -- gives AI agents Project Health, 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
@@ -133,9 +133,10 @@ The server exposes Decantr registry, context, benchmark, and verification tools.
133
133
  | `decantr_resolve_pattern` | Get full pattern details: layout spec, components, presets, code examples | `{ "id": "data-table", "preset": "product" }` |
134
134
  | `decantr_resolve_archetype` | Get archetype details: default pages, layouts, features, suggested theme | `{ "id": "saas-dashboard" }` |
135
135
  | `decantr_resolve_blueprint` | Get a full app composition with page structure and personality traits | `{ "id": "ecommerce" }` |
136
- | `decantr_suggest_patterns` | Given a page description, get ranked pattern suggestions | `{ "description": "dashboard with metrics and charts" }` |
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_prepare_task_context` | Resolve compact route/task context before editing a Brownfield or Essence route | `{ "route": "/feed", "task": "improve recipe card loading" }` |
139
140
  | `decantr_compile_execution_packs` | Compile a hosted execution-pack bundle from a local or inline essence document | `{ "path": "./decantr.essence.json", "namespace": "@official" }` |
140
141
  | `decantr_audit_project` | Run the schema-backed Decantr project audit against essence and compiled packs, with hosted fallback when local pack artifacts are missing | `{ "namespace": "@official" }` |
141
142
  | `decantr_critique` | Critique a file against the compiled review contract, with hosted fallback when local review packs are missing | `{ "file_path": "./src/pages/Overview.tsx", "namespace": "@official" }` |
@@ -170,12 +171,13 @@ The AI assistant calls these tools behind the scenes:
170
171
  3. `decantr_suggest_patterns` -- recommends `kpi-grid`, `chart-grid`, `data-table`, and `form-sections` for the described pages
171
172
  4. `decantr_resolve_pattern` -- fetches layout specs and component lists for each pattern
172
173
  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
173
- 6. `decantr_compile_execution_packs` -- compiles the hosted pack bundle when the task needs a fresh remote contract from the essence document
174
- 7. `decantr_check_drift` -- validates the generated code against the Essence spec before presenting it
175
- 8. `decantr_critique` -- critiques a specific file, falling back to the hosted verifier when the local review pack is missing
176
- 9. `decantr_audit_project` -- runs the stronger project-level audit once the implementation is in place
177
- 10. `decantr_get_evidence_bundle` -- returns the local evidence bundle for the AI repair loop
178
- 11. `decantr_get_repair_prompt` -- gives the assistant exact finding evidence, constraints to preserve, and commands to rerun
174
+ 6. `decantr_prepare_task_context` -- resolves route-local Brownfield context, visual evidence, and theme inventory before editing an existing app
175
+ 7. `decantr_compile_execution_packs` -- compiles the hosted pack bundle when the task needs a fresh remote contract from the essence document
176
+ 8. `decantr_check_drift` -- validates the generated code against the Essence spec before presenting it
177
+ 9. `decantr_critique` -- critiques a specific file, falling back to the hosted verifier when the local review pack is missing
178
+ 10. `decantr_audit_project` -- runs the stronger project-level audit once the implementation is in place
179
+ 11. `decantr_get_evidence_bundle` -- returns the local evidence bundle for the AI repair loop
180
+ 12. `decantr_get_repair_prompt` -- gives the assistant exact finding evidence, constraints to preserve, and commands to rerun
179
181
 
180
182
  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.
181
183
 
package/dist/bin.js CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- import "./chunk-FEXPLJKB.js";
2
+ import "./chunk-SVLMT45O.js";
@@ -8,7 +8,12 @@ import { existsSync, readdirSync, readFileSync } from "fs";
8
8
  import { readFile as readFile2 } from "fs/promises";
9
9
  import { basename as basename2, dirname as dirname2, join as join2, relative as relative2 } from "path";
10
10
  import { evaluateGuard, isV4 as isV42, validateEssence } from "@decantr/essence-spec";
11
- import { isContentIntelligenceSource, resolvePatternPreset } from "@decantr/registry";
11
+ import {
12
+ isContentIntelligenceSource,
13
+ patternToDiscoveryCandidate,
14
+ rankPatternCandidates,
15
+ resolvePatternPreset
16
+ } from "@decantr/registry";
12
17
 
13
18
  // src/helpers.ts
14
19
  import { realpathSync } from "fs";
@@ -124,6 +129,47 @@ async function writeDriftLog(entries, projectRoot) {
124
129
  }
125
130
 
126
131
  // src/tools.ts
132
+ function readJsonIfExists(path) {
133
+ if (!existsSync(path)) return null;
134
+ try {
135
+ return JSON.parse(readFileSync(path, "utf-8"));
136
+ } catch {
137
+ return null;
138
+ }
139
+ }
140
+ function extractPatternIdsFromLayoutItem(item, ids) {
141
+ if (typeof item === "string") {
142
+ ids.add(item);
143
+ return;
144
+ }
145
+ if (!item || typeof item !== "object") return;
146
+ const record = item;
147
+ if (typeof record.pattern === "string") ids.add(record.pattern);
148
+ if (Array.isArray(record.cols)) {
149
+ for (const col of record.cols) extractPatternIdsFromLayoutItem(col, ids);
150
+ }
151
+ }
152
+ function extractPagePatternIds(page) {
153
+ if (!page) return [];
154
+ const ids = /* @__PURE__ */ new Set();
155
+ for (const item of page.layout ?? []) extractPatternIdsFromLayoutItem(item, ids);
156
+ return [...ids].sort();
157
+ }
158
+ function summarizePackJson(pack) {
159
+ if (!pack || typeof pack !== "object") {
160
+ return { directives: [], patterns: [], visualTarget: null, sharedComponents: [] };
161
+ }
162
+ const record = pack;
163
+ const data = record.data && typeof record.data === "object" ? record.data : record;
164
+ const patterns = Array.isArray(data.patterns) ? data.patterns : [];
165
+ const directives = Array.isArray(data.directives) ? data.directives : [];
166
+ const sharedComponents = Array.isArray(data.sharedComponents) ? data.sharedComponents : Array.isArray(data.shared_components) ? data.shared_components : [];
167
+ const visualTarget = typeof data.visualTarget === "string" ? data.visualTarget : typeof data.visual_target === "string" ? data.visual_target : null;
168
+ return { directives, patterns, visualTarget, sharedComponents };
169
+ }
170
+ function routeSlug(route) {
171
+ return route.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "root";
172
+ }
127
173
  async function getShowcaseBenchmarkPayload(view) {
128
174
  const client = getPublicAPIClient();
129
175
  if (view === "manifest") {
@@ -490,7 +536,10 @@ function mcpStatusFromCounts(counts) {
490
536
  return "healthy";
491
537
  }
492
538
  function mcpScoreFromCounts(counts) {
493
- return Math.max(0, Math.min(100, 100 - counts.errorCount * 15 - counts.warnCount * 5 - counts.infoCount));
539
+ return Math.max(
540
+ 0,
541
+ Math.min(100, 100 - counts.errorCount * 15 - counts.warnCount * 5 - counts.infoCount)
542
+ );
494
543
  }
495
544
  function mcpCommandsForFinding(source) {
496
545
  switch (source) {
@@ -507,7 +556,11 @@ function mcpCommandsForFinding(source) {
507
556
  case "interaction":
508
557
  return ["decantr check --strict", "decantr health"];
509
558
  case "pack":
510
- return ["decantr refresh", "decantr registry get-pack review --write-context", "decantr health"];
559
+ return [
560
+ "decantr refresh",
561
+ "decantr registry get-pack review --write-context",
562
+ "decantr health"
563
+ ];
511
564
  case "runtime":
512
565
  return ["npm run build", "decantr health"];
513
566
  default:
@@ -908,6 +961,14 @@ var TOOLS = [
908
961
  description: {
909
962
  type: "string",
910
963
  description: 'Description of the page or section (e.g. "dashboard with metrics and charts", "settings form with toggles")'
964
+ },
965
+ route: {
966
+ type: "string",
967
+ description: 'Optional route context, for example "/feed" or "/settings".'
968
+ },
969
+ source_code: {
970
+ type: "string",
971
+ description: "Optional local source excerpt to rank against actual code evidence."
911
972
  }
912
973
  },
913
974
  required: ["description"]
@@ -1105,7 +1166,31 @@ var TOOLS = [
1105
1166
  },
1106
1167
  annotations: READ_ONLY
1107
1168
  },
1108
- // 16. decantr_get_execution_pack — local read
1169
+ // 16. decantr_prepare_task_context — local read
1170
+ {
1171
+ name: "decantr_prepare_task_context",
1172
+ title: "Prepare Task Context",
1173
+ 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.",
1174
+ inputSchema: {
1175
+ type: "object",
1176
+ properties: {
1177
+ route: {
1178
+ type: "string",
1179
+ description: 'Route being edited, for example "/feed". Preferred when known.'
1180
+ },
1181
+ page_id: {
1182
+ type: "string",
1183
+ description: "Page ID when route is unknown."
1184
+ },
1185
+ task: {
1186
+ type: "string",
1187
+ description: "Short task description used to rank relevant patterns and context."
1188
+ }
1189
+ }
1190
+ },
1191
+ annotations: READ_ONLY
1192
+ },
1193
+ // 17. decantr_get_execution_pack — local read
1109
1194
  {
1110
1195
  name: "decantr_get_execution_pack",
1111
1196
  title: "Get Execution Pack",
@@ -1506,78 +1591,59 @@ async function handleTool(name, args) {
1506
1591
  case "decantr_suggest_patterns": {
1507
1592
  const err = validateStringArg(args, "description");
1508
1593
  if (err) return { error: err };
1509
- const desc = args.description.toLowerCase();
1594
+ const desc = args.description;
1595
+ const route = typeof args.route === "string" ? args.route : void 0;
1596
+ const sourceCode = typeof args.source_code === "string" ? args.source_code : void 0;
1510
1597
  try {
1511
1598
  const patternsResponse = await apiClient.listContent("patterns", {
1512
1599
  namespace: "@official",
1513
- limit: 100
1600
+ limit: 250
1514
1601
  });
1515
- const prelimScores = [];
1516
- for (const p of patternsResponse.items) {
1517
- const slug = p.slug || "";
1518
- const name2 = p.name || slug;
1519
- const description = p.description || "";
1520
- const searchable = [name2, description].join(" ").toLowerCase();
1521
- let score = 0;
1522
- const words = desc.split(/\s+/);
1523
- for (const word of words) {
1524
- if (word.length < 3) continue;
1525
- if (searchable.includes(word)) score += 10;
1526
- }
1527
- if (desc.includes("dashboard") && ["kpi-grid", "chart-grid", "data-table", "filter-bar"].includes(slug))
1528
- score += 20;
1529
- if (desc.includes("metric") && slug === "kpi-grid") score += 15;
1530
- if (desc.includes("chart") && slug === "chart-grid") score += 15;
1531
- if (desc.includes("table") && slug === "data-table") score += 15;
1532
- if (desc.includes("form") && slug === "form-sections") score += 15;
1533
- if (desc.includes("setting") && slug === "form-sections") score += 15;
1534
- if (desc.includes("landing") && ["hero", "cta-section", "card-grid"].includes(slug))
1535
- score += 20;
1536
- if (desc.includes("hero") && slug === "hero") score += 20;
1537
- if (desc.includes("ecommerce") && ["card-grid", "filter-bar", "detail-header"].includes(slug))
1538
- score += 15;
1539
- if (desc.includes("product") && slug === "card-grid") score += 15;
1540
- if (desc.includes("feed") && slug === "activity-feed") score += 15;
1541
- if (desc.includes("filter") && slug === "filter-bar") score += 15;
1542
- if (desc.includes("search") && slug === "filter-bar") score += 10;
1543
- if (score > 0) {
1544
- prelimScores.push({ slug, score, name: name2, description });
1545
- }
1546
- }
1547
- prelimScores.sort((a, b) => b.score - a.score);
1548
- const top10 = prelimScores.slice(0, 10);
1549
- const suggestions = [];
1550
- for (const candidate of top10) {
1551
- let fullPattern = null;
1552
- try {
1553
- const fetched = await apiClient.getPattern("@official", candidate.slug);
1554
- fullPattern = fetched;
1555
- } catch {
1556
- }
1557
- let score = candidate.score;
1558
- if (fullPattern) {
1559
- const fullSearchable = [...fullPattern.components || [], ...fullPattern.tags || []].join(" ").toLowerCase();
1560
- const words = desc.split(/\s+/);
1561
- for (const word of words) {
1562
- if (word.length < 3) continue;
1563
- if (fullSearchable.includes(word)) score += 10;
1602
+ const preliminary = rankPatternCandidates(
1603
+ { query: desc, route, code: sourceCode, limit: 12 },
1604
+ patternsResponse.items.map(
1605
+ (item) => patternToDiscoveryCandidate({
1606
+ id: item.slug || item.name || "pattern",
1607
+ slug: item.slug,
1608
+ name: item.name,
1609
+ description: item.description
1610
+ })
1611
+ )
1612
+ );
1613
+ const fullCandidates = await Promise.all(
1614
+ preliminary.map(async (match) => {
1615
+ const slug = match.candidate.slug || match.candidate.id;
1616
+ try {
1617
+ const fetched = await apiClient.getPattern("@official", slug);
1618
+ return patternToDiscoveryCandidate(fetched, { slug, source: "hosted" });
1619
+ } catch {
1620
+ return match.candidate;
1564
1621
  }
1565
- }
1566
- const preset = fullPattern?.presets ? Object.values(fullPattern.presets)[0] : null;
1567
- suggestions.push({
1568
- id: candidate.slug,
1569
- score,
1570
- name: fullPattern?.name || candidate.name,
1571
- description: fullPattern?.description || candidate.description,
1572
- components: fullPattern?.components || [],
1573
- layout: preset?.layout ? preset.layout.layout : "grid"
1574
- });
1575
- }
1576
- suggestions.sort((a, b) => b.score - a.score);
1622
+ })
1623
+ );
1624
+ const suggestions = rankPatternCandidates(
1625
+ { query: desc, route, code: sourceCode, limit: 5 },
1626
+ fullCandidates
1627
+ ).map((match) => {
1628
+ const pattern = match.candidate.pattern;
1629
+ const preset = pattern?.presets ? Object.values(pattern.presets)[0] : null;
1630
+ return {
1631
+ id: match.candidate.slug || match.candidate.id,
1632
+ score: match.score,
1633
+ name: match.candidate.name || match.candidate.slug || match.candidate.id,
1634
+ description: match.candidate.description || "",
1635
+ components: match.candidate.components || [],
1636
+ interactions: match.candidate.interactions || [],
1637
+ layout: preset?.layout ? preset.layout.layout : "unknown",
1638
+ reasons: match.reasons,
1639
+ matched_terms: match.matchedTerms
1640
+ };
1641
+ });
1577
1642
  return {
1578
1643
  query: args.description,
1579
- suggestions: suggestions.slice(0, 5),
1580
- total: prelimScores.length
1644
+ route,
1645
+ suggestions,
1646
+ total: preliminary.length
1581
1647
  };
1582
1648
  } catch (e) {
1583
1649
  return { error: `Could not fetch patterns: ${e.message}` };
@@ -2251,6 +2317,118 @@ async function handleTool(name, args) {
2251
2317
  hosted_fallback_error: hostedFallbackError ?? void 0
2252
2318
  };
2253
2319
  }
2320
+ case "decantr_prepare_task_context": {
2321
+ const routeArg = typeof args.route === "string" ? args.route : void 0;
2322
+ const pageArg = typeof args.page_id === "string" ? args.page_id : void 0;
2323
+ const task = typeof args.task === "string" ? args.task : "";
2324
+ if (!routeArg && !pageArg) {
2325
+ return { error: "Provide route or page_id." };
2326
+ }
2327
+ let essence;
2328
+ try {
2329
+ const result = await readEssenceFile();
2330
+ essence = result.essence;
2331
+ } catch {
2332
+ return { error: "No valid essence file found. Run decantr init first." };
2333
+ }
2334
+ if (!isV42(essence)) {
2335
+ return {
2336
+ error: "Task context requires Essence v4.0.0. Run `decantr migrate --to v4` first."
2337
+ };
2338
+ }
2339
+ const routeEntry = routeArg ? essence.blueprint.routes?.[routeArg] : null;
2340
+ const sectionId = routeEntry?.section;
2341
+ const pageId = pageArg || routeEntry?.page;
2342
+ const section = sectionId ? essence.blueprint.sections.find((entry) => entry.id === sectionId) : essence.blueprint.sections.find(
2343
+ (entry) => entry.pages.some((page2) => page2.id === pageId)
2344
+ );
2345
+ const page = section?.pages.find((entry) => entry.id === pageId) ?? null;
2346
+ if (!section || !page || !pageId) {
2347
+ return {
2348
+ error: "Could not resolve route/page to an Essence section page.",
2349
+ available_routes: Object.keys(essence.blueprint.routes ?? {}).sort(),
2350
+ available_pages: essence.blueprint.sections.flatMap(
2351
+ (entry) => entry.pages.map((pageEntry) => ({ section_id: entry.id, page_id: pageEntry.id }))
2352
+ )
2353
+ };
2354
+ }
2355
+ const contextDir = join2(process.cwd(), ".decantr", "context");
2356
+ const manifest = readJsonIfExists(join2(contextDir, "pack-manifest.json"));
2357
+ const pageManifest = manifest?.pages.find((entry) => entry.id === pageId) ?? null;
2358
+ const sectionManifest = manifest?.sections.find((entry) => entry.id === section.id) ?? null;
2359
+ const pagePackJson = pageManifest ? readJsonIfExists(join2(contextDir, pageManifest.json)) : null;
2360
+ const sectionPackJson = sectionManifest ? readJsonIfExists(join2(contextDir, sectionManifest.json)) : null;
2361
+ const pagePackMarkdown = pageManifest && existsSync(join2(contextDir, pageManifest.markdown)) ? readFileSync(join2(contextDir, pageManifest.markdown), "utf-8") : null;
2362
+ const sectionContextPath = join2(contextDir, `section-${section.id}.md`);
2363
+ const sectionContext = existsSync(sectionContextPath) ? readFileSync(sectionContextPath, "utf-8") : null;
2364
+ const pagePackSummary = summarizePackJson(pagePackJson);
2365
+ const sectionPackSummary = summarizePackJson(sectionPackJson);
2366
+ const visualManifest = readJsonIfExists(join2(process.cwd(), ".decantr", "evidence", "visual-manifest.json"));
2367
+ const visualRoute = visualManifest?.routes?.find((entry) => entry.route === routeArg) ?? visualManifest?.routes?.find(
2368
+ (entry) => entry.screenshot?.includes(routeSlug(routeArg ?? pageId))
2369
+ ) ?? null;
2370
+ const health = readJsonIfExists(join2(process.cwd(), ".decantr", "health-baseline-diff.json"));
2371
+ const themeInventory = readJsonIfExists(
2372
+ join2(process.cwd(), ".decantr", "theme-inventory.json")
2373
+ );
2374
+ const patternIds = extractPagePatternIds(page);
2375
+ const ranked = rankPatternCandidates(
2376
+ {
2377
+ query: [task, routeArg, page.description, ...patternIds].filter(Boolean).join(" "),
2378
+ limit: 5
2379
+ },
2380
+ patternIds.map((id) => patternToDiscoveryCandidate({ id, name: id, description: id }))
2381
+ );
2382
+ return {
2383
+ route: routeArg ?? null,
2384
+ page_id: pageId,
2385
+ section_id: section.id,
2386
+ section_role: section.role,
2387
+ shell: section.shell,
2388
+ task,
2389
+ visual_target: pagePackSummary.visualTarget ?? sectionPackSummary.visualTarget ?? essence.dna.personality?.join(". ") ?? null,
2390
+ directives: pagePackSummary.directives,
2391
+ patterns: pagePackSummary.patterns.length > 0 ? pagePackSummary.patterns : patternIds,
2392
+ ranked_patterns: ranked.map((match) => ({
2393
+ id: match.candidate.slug || match.candidate.id,
2394
+ score: match.score,
2395
+ reasons: match.reasons
2396
+ })),
2397
+ shared_components: pagePackSummary.sharedComponents,
2398
+ section_context: sectionContext,
2399
+ page_pack_excerpt: pagePackMarkdown ? pagePackMarkdown.slice(0, 12e3) : null,
2400
+ health_evidence: health ? {
2401
+ baseline_path: health.baselinePath,
2402
+ saved_at: health.savedAt,
2403
+ status_changed: health.statusChanged,
2404
+ score_delta: health.scoreDelta,
2405
+ added_findings: health.addedFindings?.slice(0, 8) ?? [],
2406
+ resolved_findings: health.resolvedFindings?.slice(0, 8) ?? [],
2407
+ changed_routes: health.changedRoutes ?? [],
2408
+ changed_screenshots: health.changedScreenshots ?? [],
2409
+ contract_drift: health.contractDrift ?? []
2410
+ } : null,
2411
+ visual_evidence: visualRoute ? {
2412
+ screenshot: visualRoute.screenshot ?? null,
2413
+ screenshot_hash: visualRoute.screenshotHash ?? null,
2414
+ status: visualRoute.status ?? null,
2415
+ error: visualRoute.error ?? null
2416
+ } : null,
2417
+ theme_inventory: themeInventory ? {
2418
+ modes: themeInventory.modes,
2419
+ variants: themeInventory.variants,
2420
+ path: ".decantr/theme-inventory.json"
2421
+ } : null,
2422
+ local_files: {
2423
+ page_pack: pageManifest?.markdown ?? null,
2424
+ section_pack: sectionManifest?.markdown ?? null,
2425
+ section_context: existsSync(sectionContextPath) ? `.decantr/context/section-${section.id}.md` : null,
2426
+ visual_manifest: existsSync(
2427
+ join2(process.cwd(), ".decantr", "evidence", "visual-manifest.json")
2428
+ ) ? ".decantr/evidence/visual-manifest.json" : null
2429
+ }
2430
+ };
2431
+ }
2254
2432
  case "decantr_get_execution_pack": {
2255
2433
  const contextDir = join2(process.cwd(), ".decantr", "context");
2256
2434
  const manifestPath = join2(contextDir, "pack-manifest.json");
@@ -2747,7 +2925,7 @@ function describeUpdate(operation, payload) {
2747
2925
  }
2748
2926
 
2749
2927
  // src/index.ts
2750
- var VERSION = "2.0.0";
2928
+ var VERSION = "2.2.0";
2751
2929
  var server = new Server({ name: "decantr", version: VERSION }, { capabilities: { tools: {} } });
2752
2930
  server.setRequestHandler(ListToolsRequestSchema, async () => {
2753
2931
  return { tools: TOOLS };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import "./chunk-FEXPLJKB.js";
1
+ import "./chunk-SVLMT45O.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decantr/mcp-server",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "mcpName": "io.github.decantr-ai/mcp-server",
5
5
  "description": "MCP server for Decantr — exposes design intelligence, packs, and verification to AI coding assistants",
6
6
  "keywords": [
@@ -50,8 +50,8 @@
50
50
  "dependencies": {
51
51
  "@modelcontextprotocol/sdk": "^1.29.0",
52
52
  "@decantr/essence-spec": "2.0.1",
53
- "@decantr/verifier": "2.1.0",
54
- "@decantr/registry": "2.0.0"
53
+ "@decantr/verifier": "2.2.0",
54
+ "@decantr/registry": "2.2.0"
55
55
  },
56
56
  "scripts": {
57
57
  "build": "tsup",