@adobe/design-data-mcp 1.6.0 → 1.7.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
@@ -1,8 +1,18 @@
1
- # [**@adobe/design-data-mcp**](https://github.com/adobe/design-data-mcp)
1
+ # [**@adobe/design-data-mcp**](https://github.com/adobe/spectrum-design-data/tree/main/tools/design-data-mcp)
2
2
 
3
- MCP server for [Adobe Spectrum](https://spectrum.adobe.com) design tokens and component schemas, powered by the [`@adobe/design-data`](https://www.npmjs.com/package/@adobe/design-data) CLI.
3
+ MCP server for [Adobe Spectrum](https://spectrum.adobe.com) design tokens, component schemas,
4
+ and design guidelines. Runs fully in-process via an embedded Spectrum snapshot — no network
5
+ access, no CLI binary, and no configuration required.
4
6
 
5
- ## Setup
7
+ ## Install in Claude Desktop (Extension)
8
+
9
+ Download the latest `design-data.mcpb` from the
10
+ [releases page](https://github.com/adobe/spectrum-design-data/releases) and drag it into
11
+ **Claude Desktop → Settings → Extensions**.
12
+
13
+ No API keys or configuration needed. The extension installs and runs offline.
14
+
15
+ ## Setup via npx (Cursor / Claude Desktop manual config)
6
16
 
7
17
  ### Cursor
8
18
 
@@ -19,7 +29,7 @@ Add to `.cursor/mcp-servers.json` in your project root:
19
29
  }
20
30
  ```
21
31
 
22
- ### Claude Desktop
32
+ ### Claude Desktop (manual config)
23
33
 
24
34
  Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
25
35
 
@@ -36,26 +46,15 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
36
46
 
37
47
  ## Tools
38
48
 
39
- | Tool | Description |
40
- | ----------------------- | -------------------------------------------------------------------------- |
41
- | `design-data-primer` | Session-start overview: token count, mode-sets, components, provenance |
42
- | `design-data-query` | Filter tokens by query expression (`component=button`, `property=color-*`) |
43
- | `design-data-suggest` | Natural-language token suggestions with confidence scores |
44
- | `design-data-component` | Full component schema (variants, sizes, states, props) |
45
- | `design-data-resolve` | Resolve a token's concrete value for a mode context |
46
-
47
- ## Custom dataset
48
-
49
- Add a `.design-data.toml` to your project root to use a specific Spectrum version or a custom fork:
50
-
51
- ```toml
52
- [source]
53
- type = "github"
54
- repo = "adobe/spectrum-design-data"
55
- tag = "@adobe/spectrum-tokens@14.11.0"
56
- ```
57
-
58
- Without a config file the embedded Spectrum snapshot is used automatically (offline, zero-setup).
49
+ | Tool | Description |
50
+ | ---------------------------- | ---------------------------------------------------------------------------------- |
51
+ | `design-data-primer` | Session-start overview: token count, mode-sets, components, guidelines, provenance |
52
+ | `design-data-query` | Filter tokens by query expression (`component=button`, `property=color-*`) |
53
+ | `design-data-suggest` | Natural-language token suggestions with Jaccard similarity confidence scores |
54
+ | `design-data-component` | Full component schema (variants, sizes, states, props) by kebab-case ID |
55
+ | `design-data-resolve` | Resolve a token's concrete value for a mode context (colorScheme, scale, contrast) |
56
+ | `design-data-guideline-list` | List available Spectrum design guideline pages, optionally filtered by category |
57
+ | `design-data-guideline` | Full guideline document by slug ID (purpose, rules, accessibility, examples) |
59
58
 
60
59
  ## License
61
60
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@adobe/design-data-mcp",
3
- "version": "1.6.0",
4
- "description": "MCP server for Spectrum design tokens and component schemas via the design-data CLI",
3
+ "version": "1.7.1",
4
+ "description": "MCP server for Spectrum design tokens, component schemas, and design guidelines (embedded, offline)",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
7
7
  "bin": {
@@ -32,7 +32,9 @@
32
32
  "@adobe/spectrum-design-data": "0.7.0"
33
33
  },
34
34
  "devDependencies": {
35
- "ava": "^6.0.1"
35
+ "@anthropic-ai/mcpb": "^2.1.2",
36
+ "ava": "^6.0.1",
37
+ "sharp": "^0.35.1"
36
38
  },
37
39
  "engines": {
38
40
  "node": ">=20.12.0"
@@ -40,9 +42,10 @@
40
42
  "keywords": [
41
43
  "mcp",
42
44
  "spectrum",
45
+ "adobe",
43
46
  "design-system",
44
47
  "design-tokens",
45
- "cli"
48
+ "design-data"
46
49
  ],
47
50
  "author": "Adobe",
48
51
  "license": "Apache-2.0",
package/src/index.js CHANGED
@@ -11,12 +11,10 @@
11
11
  /**
12
12
  * @adobe/design-data-mcp — MCP server for Spectrum design tokens and components.
13
13
  *
14
- * Wraps the @adobe/design-data CLI as five MCP tools, making Spectrum design
15
- * data available to any MCP-compatible agent (Cursor, Claude Desktop, etc.)
16
- * without requiring a Rust toolchain or monorepo checkout.
17
- *
18
- * The CLI resolves data automatically: it uses the embedded Spectrum snapshot
19
- * for zero-config offline use, or a `.design-data.toml` config for custom sources.
14
+ * Exposes seven read-only MCP tools backed by @adobe/design-data-wasm running
15
+ * in-process (no CLI binary or npx required). The embedded Spectrum snapshot
16
+ * powers zero-config offline use across Claude Desktop, Cursor, and any
17
+ * MCP-compatible agent.
20
18
  */
21
19
 
22
20
  import { readFileSync } from "fs";
@@ -45,10 +43,11 @@ export function createMCPServer() {
45
43
  const tools = createDesignDataTools();
46
44
 
47
45
  server.setRequestHandler(ListToolsRequestSchema, async () => ({
48
- tools: tools.map(({ name, description, inputSchema }) => ({
46
+ tools: tools.map(({ name, description, inputSchema, annotations }) => ({
49
47
  name,
50
48
  description,
51
49
  inputSchema,
50
+ annotations,
52
51
  })),
53
52
  }));
54
53
 
@@ -18,7 +18,7 @@
18
18
 
19
19
  import { createRequire } from "module";
20
20
  import { readFileSync, existsSync } from "fs";
21
- import { join, dirname } from "path";
21
+ import { join, dirname, resolve, sep } from "path";
22
22
 
23
23
  let _wasm;
24
24
  /** Lazy-load and cache the wasm module (nodejs target, no init() required). */
@@ -56,6 +56,10 @@ function resolveSpectrumDataPackage() {
56
56
  * Load a JSON file from a subdirectory of the design-data package.
57
57
  * Throws descriptive errors when the package or file is absent.
58
58
  *
59
+ * Path safety: the resolved absolute path is asserted to stay within
60
+ * `<pkgRoot>/<subdir>/` so that a crafted `id` value (e.g. `../../etc/passwd`)
61
+ * cannot read files outside the intended data directory.
62
+ *
59
63
  * @param {string} subdir - e.g. "components" or "guidelines"
60
64
  * @param {string} id - kebab-case slug, e.g. "button" or "colors"
61
65
  */
@@ -67,7 +71,12 @@ function loadDataFile(subdir, id) {
67
71
  `Install it with: pnpm add @adobe/spectrum-design-data`,
68
72
  );
69
73
  }
70
- const filePath = join(pkgRoot, subdir, `${id}.json`);
74
+ const baseDir = resolve(pkgRoot, subdir);
75
+ const filePath = resolve(baseDir, `${id}.json`);
76
+ // Containment check: reject any path that escapes the intended subdirectory.
77
+ if (!filePath.startsWith(baseDir + sep)) {
78
+ throw new Error(`Invalid ${subdir} id: "${id}"`);
79
+ }
71
80
  if (!existsSync(filePath)) {
72
81
  throw new Error(
73
82
  `Not found: "${id}" in ${subdir}/. ` +
@@ -96,6 +105,11 @@ export function createDesignDataTools() {
96
105
  // ── primer ─────────────────────────────────────────────────────────────
97
106
  {
98
107
  name: "design-data-primer",
108
+ annotations: {
109
+ title: "Design Data: Primer",
110
+ readOnlyHint: true,
111
+ openWorldHint: false,
112
+ },
99
113
  description:
100
114
  "Get a structural overview of the Spectrum design dataset: token count, " +
101
115
  "available mode-sets (color-scheme, scale, contrast), component list, " +
@@ -119,7 +133,14 @@ export function createDesignDataTools() {
119
133
  }
120
134
  : null;
121
135
 
136
+ // Provenance carries source + designDataVersion (the @adobe/spectrum-design-data
137
+ // package version baked into the wasm at build time via EMBEDDED_DATA_VERSION).
138
+ const { provenance } = ds.primer();
139
+
122
140
  return {
141
+ // top-level source is the legacy skill-contract field; provenance.source
142
+ // duplicates it intentionally — provenance is the richer metrics object
143
+ // and consumers should prefer it going forward.
123
144
  source: "embedded",
124
145
  tokenCount: ds.tokenCount(),
125
146
  modeSets: {
@@ -134,6 +155,7 @@ export function createDesignDataTools() {
134
155
  components: wasm.getFieldValues("component") ?? [],
135
156
  properties: wasm.getFieldValues("property") ?? [],
136
157
  guidelines: guidelinesSummary,
158
+ provenance,
137
159
  };
138
160
  },
139
161
  },
@@ -141,6 +163,11 @@ export function createDesignDataTools() {
141
163
  // ── query ───────────────────────────────────────────────────────────────
142
164
  {
143
165
  name: "design-data-query",
166
+ annotations: {
167
+ title: "Design Data: Query Tokens",
168
+ readOnlyHint: true,
169
+ openWorldHint: false,
170
+ },
144
171
  description:
145
172
  "Filter Spectrum tokens by a query expression. " +
146
173
  "Expression syntax: `component=button`, `component=button,state=hover`, " +
@@ -167,6 +194,11 @@ export function createDesignDataTools() {
167
194
  // ── suggest ─────────────────────────────────────────────────────────────
168
195
  {
169
196
  name: "design-data-suggest",
197
+ annotations: {
198
+ title: "Design Data: Suggest Tokens",
199
+ readOnlyHint: true,
200
+ openWorldHint: false,
201
+ },
170
202
  description:
171
203
  "Suggest Spectrum tokens matching a natural-language intent using Jaccard similarity " +
172
204
  "scoring over token name segments, name-object fields, and description text. " +
@@ -198,6 +230,11 @@ export function createDesignDataTools() {
198
230
  // ── component ───────────────────────────────────────────────────────────
199
231
  {
200
232
  name: "design-data-component",
233
+ annotations: {
234
+ title: "Design Data: Get Component",
235
+ readOnlyHint: true,
236
+ openWorldHint: false,
237
+ },
201
238
  description:
202
239
  "Get the full component declaration for a Spectrum component by ID. " +
203
240
  "Returns the component's displayName, description, and all available options " +
@@ -223,6 +260,11 @@ export function createDesignDataTools() {
223
260
  // ── resolve ─────────────────────────────────────────────────────────────
224
261
  {
225
262
  name: "design-data-resolve",
263
+ annotations: {
264
+ title: "Design Data: Resolve Token",
265
+ readOnlyHint: true,
266
+ openWorldHint: false,
267
+ },
226
268
  description:
227
269
  "Resolve the concrete value of a Spectrum token property for a given " +
228
270
  "mode-set context (color-scheme, scale, contrast). " +
@@ -270,6 +312,11 @@ export function createDesignDataTools() {
270
312
  // ── guideline-list ──────────────────────────────────────────────────────
271
313
  {
272
314
  name: "design-data-guideline-list",
315
+ annotations: {
316
+ title: "Design Data: List Guidelines",
317
+ readOnlyHint: true,
318
+ openWorldHint: false,
319
+ },
273
320
  description:
274
321
  "List available Spectrum design guideline pages. " +
275
322
  "Returns catalog entries with slug, title, category, status, and sourceUrl. " +
@@ -306,6 +353,11 @@ export function createDesignDataTools() {
306
353
  // ── guideline ───────────────────────────────────────────────────────────
307
354
  {
308
355
  name: "design-data-guideline",
356
+ annotations: {
357
+ title: "Design Data: Get Guideline",
358
+ readOnlyHint: true,
359
+ openWorldHint: false,
360
+ },
309
361
  description:
310
362
  "Get the full guideline document for a Spectrum design page by ID. " +
311
363
  "Returns the guideline's title, category, metadata, and documentBlocks body " +