@nysds/mcp-server 1.18.0 → 1.18.3

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.
@@ -9,15 +9,6 @@
9
9
  * - Alias references become var() expressions
10
10
  * - Layer prefixes (primitive, applied) are stripped
11
11
  */
12
- /**
13
- * Legacy interface for backward compatibility
14
- */
15
- export interface DesignToken {
16
- name: string;
17
- value: string;
18
- category: string;
19
- description?: string;
20
- }
21
12
  /**
22
13
  * CSS-centric token info aligned with tokens.css output
23
14
  */
@@ -47,10 +38,6 @@ export interface TokenGraphNode {
47
38
  referencesVariable?: string;
48
39
  usedBy: string[];
49
40
  }
50
- export interface TokenGroup {
51
- category: string;
52
- tokens: DesignToken[];
53
- }
54
41
  /**
55
42
  * Get the path to tokens.json file
56
43
  * Uses ESM-compatible path resolution with fallbacks for different contexts
@@ -94,14 +81,6 @@ export declare function getCSSTokens(): CSSTokenInfo[];
94
81
  * Get CSS tokens filtered by category
95
82
  */
96
83
  export declare function getCSSTokensByCategory(category: string): CSSTokenInfo[];
97
- /**
98
- * Get CSS tokens filtered by layer
99
- */
100
- export declare function getCSSTokensByLayer(layer: string): CSSTokenInfo[];
101
- /**
102
- * Search CSS tokens by variable name, value, or description
103
- */
104
- export declare function searchCSSTokens(query: string): CSSTokenInfo[];
105
84
  /**
106
85
  * Get a single token by CSS variable name
107
86
  */
@@ -118,21 +97,30 @@ export declare function getCSSTokenCategories(): {
118
97
  */
119
98
  export declare function getTokensCSS(): string | null;
120
99
  /**
121
- * Load all design tokens (legacy format)
122
- */
123
- export declare function getAllTokens(): DesignToken[];
124
- /**
125
- * Get tokens filtered by category (legacy format)
100
+ * Get recommended tokens for everyday use.
101
+ *
102
+ * Excludes color primitive tokens (the ~150 palette ramps like neutral-*, red-*,
103
+ * blue-*) which are low-level raw values. For font tokens, applied aliases
104
+ * (body-*, h*, ui-*) are sorted before primitives so the most useful tokens
105
+ * appear first.
126
106
  */
127
- export declare function getTokensByCategory(category: string): DesignToken[];
107
+ export declare function getRecommendedTokens(): CSSTokenInfo[];
128
108
  /**
129
- * Search tokens by name or value (legacy format)
109
+ * Get only primitive (raw value) tokens across all categories.
130
110
  */
131
- export declare function searchTokens(query: string): DesignToken[];
111
+ export declare function getPrimitiveTokens(): CSSTokenInfo[];
132
112
  /**
133
- * Get available token categories (legacy format)
113
+ * Get alternative tokens in the same category that share the same name prefix.
114
+ *
115
+ * First looks for child variants (tokens starting with this token's name + "-"):
116
+ * --nys-color-text → finds --nys-color-text-weak, --nys-color-text-reverse, etc.
117
+ *
118
+ * If no children exist, looks for siblings (tokens sharing the same parent prefix):
119
+ * --nys-color-text-weak → parent: --nys-color-text → finds text, text-weaker, etc.
120
+ *
121
+ * Returns an array of cssVariable strings (empty if none found).
134
122
  */
135
- export declare function getTokenCategories(): string[];
123
+ export declare function getAlternativeTokens(token: CSSTokenInfo): string[];
136
124
  /**
137
125
  * Clear all cached tokens (useful for testing)
138
126
  */
@@ -1 +1 @@
1
- {"version":3,"file":"token-parser.d.ts","sourceRoot":"","sources":["../../src/lib/token-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAcH;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,kDAAkD;IAClD,WAAW,EAAE,MAAM,CAAC;IACpB,+FAA+F;IAC/F,QAAQ,EAAE,MAAM,CAAC;IACjB,uFAAuF;IACvF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,yDAAyD;IACzD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAeD;;;GAGG;AACH,wBAAgB,aAAa,IAAI,MAAM,GAAG,IAAI,CAuB7C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAkBhD;AAMD;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAatD;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG;IACjD,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,MAAM,CAAC;CAC5B,CAUA;AA6LD;;;GAGG;AACH,wBAAgB,eAAe,IAAI,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CA6B7D;AAMD;;GAEG;AACH,wBAAgB,YAAY,IAAI,YAAY,EAAE,CAc7C;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,EAAE,CAKvE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,EAAE,CAGjE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,EAAE,CAW7D;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,MAAM,GACnB,YAAY,GAAG,SAAS,CAO1B;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CAW7E;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAW5C;AAkDD;;GAEG;AACH,wBAAgB,YAAY,IAAI,WAAW,EAAE,CAa5C;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW,EAAE,CAKnE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,EAAE,CAUzD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,EAAE,CAI7C;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAKtC"}
1
+ {"version":3,"file":"token-parser.d.ts","sourceRoot":"","sources":["../../src/lib/token-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAcH;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,kDAAkD;IAClD,WAAW,EAAE,MAAM,CAAC;IACpB,+FAA+F;IAC/F,QAAQ,EAAE,MAAM,CAAC;IACjB,uFAAuF;IACvF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,yDAAyD;IACzD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gDAAgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,oDAAoD;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAcD;;;GAGG;AACH,wBAAgB,aAAa,IAAI,MAAM,GAAG,IAAI,CAuB7C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAkBhD;AAYD;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAatD;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG;IACjD,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,MAAM,CAAC;CAC5B,CAUA;AAyLD;;;GAGG;AACH,wBAAgB,eAAe,IAAI,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CA6B7D;AAMD;;GAEG;AACH,wBAAgB,YAAY,IAAI,YAAY,EAAE,CAc7C;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,YAAY,EAAE,CAKvE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,MAAM,GACnB,YAAY,GAAG,SAAS,CAO1B;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CAW7E;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,GAAG,IAAI,CAW5C;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,IAAI,YAAY,EAAE,CAiBrD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,YAAY,EAAE,CAGnD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,EAAE,CA2BlE;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAItC"}
@@ -18,7 +18,6 @@ const __dirname = dirname(__filename);
18
18
  // ============================================================================
19
19
  // Token Data Cache
20
20
  // ============================================================================
21
- let cachedLegacyTokens = null;
22
21
  let cachedCSSTokens = null;
23
22
  let cachedTokenGraph = null;
24
23
  let cachedRawTokens = null;
@@ -72,6 +71,10 @@ export function getTokensCSSPath() {
72
71
  return null;
73
72
  }
74
73
  // ============================================================================
74
+ // Constants
75
+ // ============================================================================
76
+ const LAYER_PREFIXES = ["primitive", "applied", "appearance", "theme"];
77
+ // ============================================================================
75
78
  // CSS Variable Transformation
76
79
  // ============================================================================
77
80
  /**
@@ -87,7 +90,7 @@ export function toCSSVariable(jsonPath) {
87
90
  let name = "--nys-" +
88
91
  jsonPath
89
92
  // Strip layer prefixes
90
- .replace(/^(primitive|applied|appearance|theme)\./, "")
93
+ .replace(new RegExp(`^(${LAYER_PREFIXES.join("|")})\\.`), "")
91
94
  // Dots to hyphens
92
95
  .replace(/\./g, "-");
93
96
  // Strip trailing -default suffix
@@ -117,9 +120,7 @@ export function aliasToVarRef(aliasValue) {
117
120
  function getCategoryFromPath(jsonPath) {
118
121
  const parts = jsonPath.split(".");
119
122
  // Skip layer prefix if present
120
- const startIndex = ["primitive", "applied", "appearance", "theme"].includes(parts[0])
121
- ? 1
122
- : 0;
123
+ const startIndex = LAYER_PREFIXES.includes(parts[0]) ? 1 : 0;
123
124
  return parts[startIndex] || "unknown";
124
125
  }
125
126
  /**
@@ -134,7 +135,7 @@ function getCategoryFromPath(jsonPath) {
134
135
  function getLayerFromPath(jsonPath) {
135
136
  const parts = jsonPath.split(".");
136
137
  // Check for explicit layer prefixes
137
- if (["primitive", "applied", "appearance", "theme"].includes(parts[0])) {
138
+ if (LAYER_PREFIXES.includes(parts[0])) {
138
139
  return parts[0];
139
140
  }
140
141
  // color.theme.* tokens are applied semantic tokens (agency themes override these)
@@ -321,24 +322,6 @@ export function getCSSTokensByCategory(category) {
321
322
  const tokens = getCSSTokens();
322
323
  return tokens.filter((t) => t.category.toLowerCase() === category.toLowerCase());
323
324
  }
324
- /**
325
- * Get CSS tokens filtered by layer
326
- */
327
- export function getCSSTokensByLayer(layer) {
328
- const tokens = getCSSTokens();
329
- return tokens.filter((t) => t.layer.toLowerCase() === layer.toLowerCase());
330
- }
331
- /**
332
- * Search CSS tokens by variable name, value, or description
333
- */
334
- export function searchCSSTokens(query) {
335
- const tokens = getCSSTokens();
336
- const lowerQuery = query.toLowerCase();
337
- return tokens.filter((t) => t.cssVariable.toLowerCase().includes(lowerQuery) ||
338
- t.cssValue.toLowerCase().includes(lowerQuery) ||
339
- t.resolvedValue?.toLowerCase().includes(lowerQuery) ||
340
- t.description?.toLowerCase().includes(lowerQuery));
341
- }
342
325
  /**
343
326
  * Get a single token by CSS variable name
344
327
  */
@@ -378,83 +361,70 @@ export function getTokensCSS() {
378
361
  return null;
379
362
  }
380
363
  }
381
- // ============================================================================
382
- // Public API - Legacy (Backward Compatible)
383
- // ============================================================================
384
364
  /**
385
- * Parse DTCG format tokens recursively (legacy format)
365
+ * Get recommended tokens for everyday use.
366
+ *
367
+ * Excludes color primitive tokens (the ~150 palette ramps like neutral-*, red-*,
368
+ * blue-*) which are low-level raw values. For font tokens, applied aliases
369
+ * (body-*, h*, ui-*) are sorted before primitives so the most useful tokens
370
+ * appear first.
386
371
  */
387
- function parseDTCGTokens(obj, prefix = "", category = "") {
388
- const tokens = [];
389
- for (const [key, value] of Object.entries(obj)) {
390
- if (key.startsWith("$"))
391
- continue; // Skip meta properties
392
- const name = prefix ? `${prefix}.${key}` : key;
393
- const currentCategory = category || key;
394
- if (typeof value === "object" &&
395
- value !== null &&
396
- "$value" in value) {
397
- // This is a token
398
- const tokenObj = value;
399
- tokens.push({
400
- name,
401
- value: String(tokenObj.$value),
402
- category: currentCategory,
403
- description: tokenObj.$description,
404
- });
405
- }
406
- else if (typeof value === "object" && value !== null) {
407
- // Recurse into nested group
408
- tokens.push(...parseDTCGTokens(value, name, currentCategory));
372
+ export function getRecommendedTokens() {
373
+ const tokens = getCSSTokens();
374
+ const filtered = tokens.filter((t) => !(t.category === "color" && t.layer === "primitive"));
375
+ // For font tokens, sort applied before primitive so named aliases surface first
376
+ filtered.sort((a, b) => {
377
+ if (a.category === "font" && b.category === "font") {
378
+ if (a.layer === "applied" && b.layer !== "applied")
379
+ return -1;
380
+ if (a.layer !== "applied" && b.layer === "applied")
381
+ return 1;
409
382
  }
410
- }
411
- return tokens;
383
+ return 0;
384
+ });
385
+ return filtered;
412
386
  }
413
387
  /**
414
- * Load all design tokens (legacy format)
388
+ * Get only primitive (raw value) tokens across all categories.
415
389
  */
416
- export function getAllTokens() {
417
- if (cachedLegacyTokens) {
418
- return cachedLegacyTokens;
419
- }
420
- const rawTokens = loadRawTokens();
421
- if (!rawTokens) {
422
- cachedLegacyTokens = [];
423
- return cachedLegacyTokens;
424
- }
425
- cachedLegacyTokens = parseDTCGTokens(rawTokens);
426
- return cachedLegacyTokens;
427
- }
428
- /**
429
- * Get tokens filtered by category (legacy format)
430
- */
431
- export function getTokensByCategory(category) {
432
- const tokens = getAllTokens();
433
- return tokens.filter((t) => t.category.toLowerCase() === category.toLowerCase());
434
- }
435
- /**
436
- * Search tokens by name or value (legacy format)
437
- */
438
- export function searchTokens(query) {
439
- const tokens = getAllTokens();
440
- const lowerQuery = query.toLowerCase();
441
- return tokens.filter((t) => t.name.toLowerCase().includes(lowerQuery) ||
442
- t.value.toLowerCase().includes(lowerQuery) ||
443
- t.description?.toLowerCase().includes(lowerQuery));
390
+ export function getPrimitiveTokens() {
391
+ const tokens = getCSSTokens();
392
+ return tokens.filter((t) => t.layer === "primitive");
444
393
  }
445
394
  /**
446
- * Get available token categories (legacy format)
395
+ * Get alternative tokens in the same category that share the same name prefix.
396
+ *
397
+ * First looks for child variants (tokens starting with this token's name + "-"):
398
+ * --nys-color-text → finds --nys-color-text-weak, --nys-color-text-reverse, etc.
399
+ *
400
+ * If no children exist, looks for siblings (tokens sharing the same parent prefix):
401
+ * --nys-color-text-weak → parent: --nys-color-text → finds text, text-weaker, etc.
402
+ *
403
+ * Returns an array of cssVariable strings (empty if none found).
447
404
  */
448
- export function getTokenCategories() {
449
- const tokens = getAllTokens();
450
- const categories = new Set(tokens.map((t) => t.category));
451
- return Array.from(categories).sort();
405
+ export function getAlternativeTokens(token) {
406
+ const varName = token.cssVariable;
407
+ const tokens = getCSSTokens();
408
+ // Look for child variants: tokens starting with this token's name + "-"
409
+ const children = tokens.filter((t) => t.category === token.category && t.cssVariable.startsWith(varName + "-"));
410
+ if (children.length > 0) {
411
+ return children.map((t) => t.cssVariable);
412
+ }
413
+ // No children — look for siblings sharing the same parent prefix
414
+ const lastDash = varName.lastIndexOf("-");
415
+ if (lastDash <= 5)
416
+ return []; // "--nys-" is 6 chars minimum
417
+ const parent = varName.slice(0, lastDash);
418
+ return tokens
419
+ .filter((t) => t.category === token.category &&
420
+ t.cssVariable !== varName &&
421
+ (t.cssVariable === parent || t.cssVariable.startsWith(parent + "-")))
422
+ .map((t) => t.cssVariable);
452
423
  }
453
424
  /**
454
425
  * Clear all cached tokens (useful for testing)
455
426
  */
456
427
  export function clearTokenCache() {
457
- cachedLegacyTokens = null;
458
428
  cachedCSSTokens = null;
459
429
  cachedTokenGraph = null;
460
430
  cachedRawTokens = null;
@@ -1 +1 @@
1
- {"version":3,"file":"guide-tools.d.ts","sourceRoot":"","sources":["../../src/tools/guide-tools.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA6CzE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAyC1D"}
1
+ {"version":3,"file":"guide-tools.d.ts","sourceRoot":"","sources":["../../src/tools/guide-tools.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA8CzE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA0C1D"}
@@ -41,9 +41,10 @@ const TOPIC_TO_FILE = {
41
41
  styles: "styles.md",
42
42
  fonts: "fonts.md",
43
43
  "page-structure": "page-structure.md",
44
+ themes: "themes.md",
44
45
  };
45
46
  export function registerGuideTools(server) {
46
- server.tool("get_guide", "Get NYSDS guides for installation, forms, styles, fonts, page structure, or framework setup", {
47
+ server.tool("get_guide", "Get NYSDS guides for installation, forms, styles, fonts, page structure, themes, or framework setup", {
47
48
  topic: z
48
49
  .enum([
49
50
  "installation",
@@ -51,6 +52,7 @@ export function registerGuideTools(server) {
51
52
  "styles",
52
53
  "fonts",
53
54
  "page-structure",
55
+ "themes",
54
56
  ])
55
57
  .describe("The guide topic to retrieve"),
56
58
  framework: z
@@ -4,9 +4,8 @@
4
4
  * MCP tools for working with NYSDS design tokens.
5
5
  *
6
6
  * Tools:
7
- * - get_tokens: Get tokens, categories, or themes
8
- * - find_tokens: Search tokens by CSS variable, value, or description
9
- * - get_token_info: Get detailed token info with optional context validation
7
+ * - find_tokens: Search or browse tokens (discovery)
8
+ * - get_token: Get full details for a specific token (deep dive)
10
9
  * - get_token_graph: Get token dependency graph
11
10
  */
12
11
  import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -1 +1 @@
1
- {"version":3,"file":"token-tools.d.ts","sourceRoot":"","sources":["../../src/tools/token-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAqOzE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAwX1D"}
1
+ {"version":3,"file":"token-tools.d.ts","sourceRoot":"","sources":["../../src/tools/token-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAuCzE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA6N1D"}