@adobe/design-data-agent-mcp 1.11.0 → 1.13.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
@@ -1,6 +1,6 @@
1
1
  # `@adobe/design-data-agent-mcp`
2
2
 
3
- MCP server and Claude Code skill for the [Spectrum Design Data](../../packages/design-data/) agent surface. Read tools (`primer`, `resolve_token`, `query_tokens`, `describe_component`, `describe_guideline`, `list_guidelines`) run fully in-process via `@adobe/design-data-wasm` — no CLI binary required for those. Only `authoring_session_step_intent` still invokes the native binary (for NLP suggest ranking, not yet on the wasm surface).
3
+ MCP server and Claude Code skill for the [Spectrum Design Data](../../packages/design-data/) agent surface. Read tools (`primer`, `resolve_token`, `query_tokens`, `suggest_token`, `describe_component`, `describe_guideline`, `list_guidelines`) run fully in-process via `@adobe/design-data-wasm` — no CLI binary required for those. `suggest_token` uses the wasm `suggest` API directly; `authoring_session_step_intent` still invokes the native binary for session-state-aware ranking within an authoring flow.
4
4
 
5
5
  ## Install
6
6
 
@@ -152,6 +152,7 @@ node tools/design-data-agent-mcp/src/index.js
152
152
  | `primer` | Load full token taxonomy, component list, and field definitions |
153
153
  | `resolve_token` | Resolve a token property to its literal value |
154
154
  | `query_tokens` | Filter tokens by expression |
155
+ | `suggest_token` | Suggest tokens matching a natural-language intent |
155
156
  | `describe_component` | Fetch component schema and token bindings |
156
157
  | `describe_guideline` | Fetch guideline documentBlocks content and metadata |
157
158
  | `list_guidelines` | List guideline slugs and metadata, optionally by category |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adobe/design-data-agent-mcp",
3
- "version": "1.11.0",
3
+ "version": "1.13.0",
4
4
  "description": "MCP server and Claude Code skill for the design-data agent surface — read tools run in-process via wasm",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
@@ -30,8 +30,8 @@
30
30
  },
31
31
  "dependencies": {
32
32
  "@modelcontextprotocol/sdk": "^1.27.1",
33
- "@adobe/design-data": "3.2.0",
34
- "@adobe/design-data-wasm": "0.9.0",
33
+ "@adobe/design-data": "3.2.1",
34
+ "@adobe/design-data-wasm": "0.10.0",
35
35
  "@adobe/spectrum-design-data": "3.2.5"
36
36
  },
37
37
  "devDependencies": {
@@ -6,12 +6,12 @@ description: >
6
6
  system, token lookup, spec-conformance, drift detection, or token authoring on custom data.
7
7
  metadata:
8
8
  author: adobe
9
- version: "1.11.0"
9
+ version: "1.13.0"
10
10
  when_to_use: >
11
11
  Trigger on: design system, design tokens, spec-conformant, drift, validate tokens, token
12
12
  authoring, custom dataset, DESIGN_DATA_PATH, design-data validate, design-data diff,
13
13
  design-data write, product-context.json.
14
- allowed-tools: mcp__design-data-agent__primer, mcp__design-data-agent__query_tokens, mcp__design-data-agent__resolve_token, mcp__design-data-agent__describe_component, mcp__design-data-agent__validate_usage, mcp__design-data-agent__diff_datasets, mcp__design-data-agent__write, mcp__design-data-agent__start_authoring_session, mcp__design-data-agent__authoring_session_step_intent, mcp__design-data-agent__authoring_session_step_classification, mcp__design-data-agent__authoring_session_step_values, mcp__design-data-agent__authoring_session_commit, mcp__design-data-agent__authoring_session_cancel, mcp__design-data-agent__authoring_session_get, mcp__design-data-agent__authoring_session_list
14
+ allowed-tools: mcp__design-data-agent__primer, mcp__design-data-agent__query_tokens, mcp__design-data-agent__suggest_token, mcp__design-data-agent__resolve_token, mcp__design-data-agent__describe_component, mcp__design-data-agent__validate_usage, mcp__design-data-agent__diff_datasets, mcp__design-data-agent__write, mcp__design-data-agent__start_authoring_session, mcp__design-data-agent__authoring_session_step_intent, mcp__design-data-agent__authoring_session_step_classification, mcp__design-data-agent__authoring_session_step_values, mcp__design-data-agent__authoring_session_commit, mcp__design-data-agent__authoring_session_cancel, mcp__design-data-agent__authoring_session_get, mcp__design-data-agent__authoring_session_list
15
15
  ---
16
16
 
17
17
  # design-data agent skill
@@ -67,9 +67,18 @@ all subsequent lookups. No inputs required.
67
67
 
68
68
  ### Resolve a token to its literal value — `resolve_token`
69
69
 
70
- Required: `property` (string) — e.g. `"accent-background-color-default"`
71
- Optional: `colorScheme` (`"light"` or `"dark"`), `scale` (`"desktop"` or `"mobile"`),
72
- `contrast` (`"regular"` or `"high"`)
70
+ Required: `property` (string) — the bare `name.property` segment, e.g. `"background-color"`
71
+ or `"corner-radius"` (see `primer().properties` for the full list). **Not** a flattened
72
+ legacyKey like `"accent-background-color-default"` — that form never resolves.
73
+ Optional context: `colorScheme` (`"light"` or `"dark"`), `scale` (`"desktop"` or `"mobile"`),
74
+ `contrast` (`"regular"` or `"high"`). Optional narrowing: `component`, `variant`, `state`, and
75
+ `colorRole`. Set `excludeDeprecated` to omit tokens with `lifecycle.deprecatedIn`.
76
+
77
+ > **Gotcha:** when several tokens share a property, use `variant`, `state`, or `colorRole` to
78
+ > narrow the match, then check `ambiguous` and `deprecated` on the result. `component` is
79
+ > sparsely populated in the current dataset, so prefer the other fields when available.
80
+ > `resolve_token` still uses cascade ranking when multiple candidates remain; use `query_tokens`
81
+ > to inspect the full candidate set.
73
82
 
74
83
  ### Query tokens by filter expression — `query_tokens`
75
84
 
@@ -83,14 +92,25 @@ Filter syntax examples:
83
92
  ```
84
93
  property=background-color
85
94
  property=*background*
86
- component=button
87
- component=button,state=hover
88
95
  property=background-color|property=border-color
89
96
  $schema=https://spectrum.adobe.com/page/design-token/
90
97
  ```
91
98
 
99
+ > **Gotcha:** `component=<id>` currently always returns `[]` — tokens aren't
100
+ > component-indexed in this dataset. Use `describe_component` to see a component's known
101
+ > token bindings instead.
102
+
92
103
  > **Exit codes:** `0` = matches found; empty array = no matches (not an error).
93
104
 
105
+ ### Suggest a token from a description — `suggest_token`
106
+
107
+ Required: `intent` (string) — a natural-language description of the design need,
108
+ such as `"primary CTA button background color"`.
109
+
110
+ Optional: `limit` (number, default `5`) — the maximum number of suggestions to return.
111
+ Results are ranked by confidence using token names, name-object fields, and description
112
+ text. Use this when the user describes what they need rather than knowing a token name.
113
+
94
114
  ***
95
115
 
96
116
  ## Component info — `describe_component`
@@ -152,8 +172,9 @@ Helper tools: `authoring_session_get` (inspect state), `authoring_session_list`
152
172
  `authoring_session_commit` accepts an optional `schema_path` to override the schemas directory
153
173
  for Layer-1 JSON-Schema validation before writing.
154
174
 
155
- > **Note:** `authoring_session_step_intent` (NLP suggestion ranking) still delegates to the
156
- > `design-data` CLI because the NLP `suggest` API is not yet on the wasm surface.
175
+ > **Note:** The standalone `suggest_token` tool calls the wasm `suggest` API directly.
176
+ > `authoring_session_step_intent` still delegates to the `design-data` CLI for
177
+ > session-state-aware ranking within an authoring flow.
157
178
 
158
179
  ***
159
180
 
package/src/tools/read.js CHANGED
@@ -20,8 +20,9 @@
20
20
  * @adobe/design-data-mcp package's `design-data-guideline` tool via the
21
21
  * `@adobe/design-data/guideline` module, rather than duplicated here.
22
22
  *
23
- * Note: authoring_session_step_intent in authoring.js still uses the CLI because
24
- * the NLP suggest ranking is not yet on the wasm surface.
23
+ * suggest_token uses the wasm suggest surface directly. The separate
24
+ * authoring_session_step_intent flow still uses the CLI for session-state-aware
25
+ * ranking within an authoring session.
25
26
  *
26
27
  * Cascade scope (see cascade-bootstrap.js / spectrum-design-data-h890.14): once a
27
28
  * `.design-data.toml` cascade is resolved, primer/resolve_token/query_tokens/
@@ -121,16 +122,16 @@ export function createReadTools() {
121
122
  async handler() {
122
123
  // Shape note: this response intentionally diverges from the CLI PrimerData
123
124
  // struct (sdk/core/src/primer.rs). The CLI emits modeSets as an array of
124
- // {name, values} objects and taxonomyFields as a flat array. This in-process
125
- // shape uses keyed objects (matching the sibling design-data-mcp), which agents
126
- // and the SKILL.md skill prompt consume by key name. Skill contract:
127
- // tokenCount, modeSets.{colorScheme,scale,contrast}, components[],
125
+ // {name, modes, defaultMode} objects and taxonomyFields as a flat array. This
126
+ // in-process shape uses keyed objects (matching the sibling design-data-mcp),
127
+ // which agents and the SKILL.md skill prompt consume by key name. Skill
128
+ // contract: tokenCount, modeSets.{colorScheme,scale,contrast}, components[],
128
129
  // taxonomyFields.{indexed,advisory}. provenance is included for metrics:
129
130
  // for the embedded dataset it carries designDataVersion (@adobe/spectrum-design-data
130
131
  // version baked in at wasm build time); for custom datasets the source differs.
131
132
  const wasm = await getWasm();
132
133
  const ds = await getDataset();
133
- const { provenance } = ds.primer();
134
+ const { provenance, modeSets: rawModeSets } = ds.primer();
134
135
  // Best-effort staleness check (spectrum-design-data-9fe.5) — silent on
135
136
  // failure, never blocks the primer response.
136
137
  const datasetStatus = await checkDatasetFreshness(
@@ -142,11 +143,13 @@ export function createReadTools() {
142
143
  // and consumers should prefer it going forward.
143
144
  source: config.cascadeActive ? "cascade" : "embedded",
144
145
  tokenCount: ds.tokenCount(),
145
- modeSets: {
146
- colorScheme: wasm.getFieldValues("colorScheme") ?? [],
147
- scale: wasm.getFieldValues("scale") ?? [],
148
- contrast: wasm.getFieldValues("contrast") ?? [],
149
- },
146
+ // Mode-set dimensions (colorScheme, scale, contrast) live in
147
+ // graph.mode_sets, not the field-catalog registry, so they're read from
148
+ // ds.primer()'s modeSets array rather than wasm.getFieldValues()
149
+ // (spectrum-design-data-v9bb).
150
+ modeSets: Object.fromEntries(
151
+ rawModeSets.map((ms) => [ms.name, ms.modes]),
152
+ ),
150
153
  taxonomyFields: {
151
154
  indexed: wasm.getIndexedFields(),
152
155
  advisory: wasm.getAdvisoryFields() ?? [],
@@ -163,7 +166,9 @@ export function createReadTools() {
163
166
  {
164
167
  name: "resolve_token",
165
168
  description:
166
- "Resolve a design token property to its final value for a given color scheme, scale, and contrast level.",
169
+ "Resolve a design token property to its final value for a given context. " +
170
+ "Use component, variant, state, or colorRole to disambiguate shared properties; " +
171
+ "inspect ambiguous and deprecated in the result.",
167
172
  inputSchema: {
168
173
  type: "object",
169
174
  required: ["property"],
@@ -171,7 +176,9 @@ export function createReadTools() {
171
176
  property: {
172
177
  type: "string",
173
178
  description:
174
- "Token property name, e.g. accent-background-color-default",
179
+ "Bare token property name (the name.property segment, e.g. " +
180
+ '"background-color", "corner-radius" — see primer().properties for ' +
181
+ "the full list). Not a flattened legacyKey.",
175
182
  },
176
183
  colorScheme: {
177
184
  type: "string",
@@ -187,10 +194,46 @@ export function createReadTools() {
187
194
  enum: ["regular", "high"],
188
195
  description: "Contrast: regular or high",
189
196
  },
197
+ component: {
198
+ type: "string",
199
+ description:
200
+ "Optional component name-object field. It is sparsely populated; " +
201
+ "prefer variant, state, or colorRole when available.",
202
+ },
203
+ variant: {
204
+ type: "string",
205
+ description:
206
+ "Optional token variant used to narrow shared properties.",
207
+ },
208
+ state: {
209
+ type: "string",
210
+ description:
211
+ "Optional token state used to narrow shared properties (including array-valued state).",
212
+ },
213
+ colorRole: {
214
+ type: "string",
215
+ description:
216
+ "Optional color role such as accent, negative, or positive.",
217
+ },
218
+ excludeDeprecated: {
219
+ type: "boolean",
220
+ description:
221
+ "Exclude tokens with lifecycle.deprecatedIn from candidate resolution.",
222
+ },
190
223
  },
191
224
  additionalProperties: false,
192
225
  },
193
- async handler({ property, colorScheme, scale, contrast }) {
226
+ async handler({
227
+ property,
228
+ colorScheme,
229
+ scale,
230
+ contrast,
231
+ component,
232
+ variant,
233
+ state,
234
+ colorRole,
235
+ excludeDeprecated,
236
+ }) {
194
237
  const ds = await loadDataset(
195
238
  config.cascadeActive ? config.cascadeDataPath : config.dataPath,
196
239
  );
@@ -198,10 +241,19 @@ export function createReadTools() {
198
241
  if (colorScheme) context.colorScheme = colorScheme;
199
242
  if (scale) context.scale = scale;
200
243
  if (contrast) context.contrast = contrast;
201
- const result = ds.resolve(property, context);
244
+ const result = ds.resolve(property, context, {
245
+ component,
246
+ variant,
247
+ state,
248
+ colorRole,
249
+ excludeDeprecated: excludeDeprecated ?? false,
250
+ });
202
251
  if (!result) {
252
+ const deprecatedHint = excludeDeprecated
253
+ ? " Only deprecated matches may exist; retry without excludeDeprecated to inspect them."
254
+ : "";
203
255
  throw new Error(
204
- `No token found for property "${property}" in context ${JSON.stringify(context)}`,
256
+ `No token found for property "${property}" in context ${JSON.stringify(context)}.${deprecatedHint}`,
205
257
  );
206
258
  }
207
259
  return result;
@@ -218,7 +270,11 @@ export function createReadTools() {
218
270
  properties: {
219
271
  filter: {
220
272
  type: "string",
221
- description: 'Filter expression, e.g. "category=color"',
273
+ description:
274
+ 'Filter expression, e.g. "property=background-color". Valid keys: ' +
275
+ "property, component, variant, state, colorScheme, scale, contrast, " +
276
+ 'uuid, $schema. Note: "component" is not currently populated on ' +
277
+ "tokens — component=<id> always returns []; use describe_component instead.",
222
278
  },
223
279
  },
224
280
  additionalProperties: false,
@@ -231,6 +287,36 @@ export function createReadTools() {
231
287
  },
232
288
  },
233
289
 
290
+ {
291
+ name: "suggest_token",
292
+ description:
293
+ "Suggest Spectrum tokens matching a natural-language intent using Jaccard similarity " +
294
+ "scoring over token name segments, name-object fields, and description text. " +
295
+ "Returns matches ranked by confidence with token name, layer, value, and name object. " +
296
+ "Use when the user describes what they need rather than knowing the token name.",
297
+ inputSchema: {
298
+ type: "object",
299
+ required: ["intent"],
300
+ properties: {
301
+ intent: {
302
+ type: "string",
303
+ description:
304
+ 'Natural-language description of the design need, e.g. "primary CTA button background color"',
305
+ },
306
+ limit: {
307
+ type: "number",
308
+ description: "Maximum number of suggestions to return (default: 5)",
309
+ default: 5,
310
+ },
311
+ },
312
+ additionalProperties: false,
313
+ },
314
+ async handler({ intent, limit = 5 }) {
315
+ const ds = await getDataset();
316
+ return ds.suggest(intent, undefined, limit);
317
+ },
318
+ },
319
+
234
320
  {
235
321
  name: "describe_component",
236
322
  description: