better-design 0.15.0 → 0.15.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
@@ -8,64 +8,42 @@ Design systems, UI principles, icons, and code review for AI coding agents. [bet
8
8
  npx better-design
9
9
  ```
10
10
 
11
- Run it once. No signup needed: a free key is created automatically and written into your installed MCP clients (Claude Code, Cursor, VS Code, Windsurf, Zed, Cline, JetBrains, and more), merge-safe, with an auto-invoke rule.
11
+ Run it once. It creates a free key, writes the config into the MCP clients you already have, and merges rather than overwriting. No signup. [See a page per client](https://better-design.com/mcp/install).
12
12
 
13
- Using ZCode? Follow the [ZCode MCP setup guide](https://better-design.com/mcp/install/zcode) to add Better Design as an HTTP server.
13
+ Already have a key? Set `BETTER_DESIGN_API_KEY`. Manage keys at [better-design.com/mcp](https://better-design.com/mcp).
14
14
 
15
- The free key has a query limit; the tools link you to turn it into a free account (same key, unlimited, history kept). Already have a key? Set `BETTER_DESIGN_API_KEY`. Manage keys at [better-design.com/mcp](https://better-design.com/mcp).
16
-
17
- > After install, set `"style": "new-york"` in `components.json` before running the shadcn command (the default `base-nova` style rewrites Radix `asChild` and breaks components). The returned install instructions include this.
15
+ > Set `"style": "new-york"` in `components.json` before running the shadcn command. The default `base-nova` style rewrites Radix `asChild` and breaks components.
18
16
 
19
17
  ## Tools
20
18
 
21
- The server exposes MCP tools only; it does not register prompts.
22
-
23
19
  | Tool | Purpose |
24
20
  | --- | --- |
25
- | `find-design-system` | Start any UI build by searching the catalog for visual foundations, or browse and compare existing systems. Returns IDs and the build/review guardrails needed for the next step. |
26
- | `create-design-system` | Start a custom design system generation job. |
27
- | `get-design-system-status` | Poll a generated design system and return the install command when ready. |
28
- | `review-illustration` | Render an SVG illustration you drew, look at it, and report what is visibly wrong |
29
- | `get-design-system-kit` | Return the correct implementation kit through one entry point. Use `target: "react"` in coding hosts for shadcn install commands and real components; use `target: "html"` only in inline canvases/artifacts for the framework-free HTML/CSS kit; use `target: "shopify"` for ready-to-write Liquid theme files (CSS asset, snippets, theme editor sections) that drop into any Online Store 2.0 theme. Accepts a catalog `designSystemId`, or a generated `projectId` for the html and shopify targets. Base UI is the default React flavor; pass `library: "radix"` when the project already uses Radix. |
30
- | `preview-design-system` | Return a token-true visual preview for a catalog design system. |
31
- | `get-ui-principle` | Load or search visual UI principles. |
21
+ | `find-design-system` | Search the catalog for a look to build on. |
22
+ | `create-design-system` | Generate a custom design system. |
23
+ | `get-design-system-status` | Poll a generation job and return the install command. |
24
+ | `get-design-system-kit` | Return the implementation kit: React components, framework-free HTML, or Shopify Liquid. |
25
+ | `preview-design-system` | Return a token-true visual preview. |
26
+ | `extract-design-system` | Pull a semantic token set out of a project's existing CSS. |
27
+ | `get-ui-principle` | Load or search visual principles. |
32
28
  | `get-ux-principle` | Load or search flow and interaction principles. |
33
- | `get-react-native-guide` | Load or search implementation guidance and code recipes for React Native and Expo projects. |
34
- | `get-three-js-guide` | Load or search implementation guidance and code recipes for Three.js and React Three Fiber projects. |
35
- | `get-motion-guide` | Load or search guidance for building a product demo video in code, from composition setup to checking the render. |
36
- | `get-review-rules` | Return the Better Design self-review checklist. Supports `category`: `accessibility`, `visual-design`, `animation`, `content`, `comprehension`, or `all`. |
37
- | `check-comprehension` | Check a finished screen against the mom test, the 15 second test, and the screenshot test. Pass the copy (`headline`, `body`, `actions`) or the screen's `code`, and it returns the findings that would stop a stranger understanding it. |
38
- | `extract-design-system` | Distill an oklch-normalized semantic token set out of a project's existing CSS (paste `globals.css` / Tailwind v4 `@theme`) so new components match the app the user already built. |
39
- | `find-icon-library` | Find an icon library for an app or project style. |
29
+ | `get-react-native-guide` | React Native and Expo implementation guidance. |
30
+ | `get-three-js-guide` | Three.js and React Three Fiber implementation guidance. |
31
+ | `get-motion-guide` | Building a product demo video in code. |
32
+ | `get-review-rules` | The self-review checklist. `category`: `accessibility`, `visual-design`, `animation`, `content`, `comprehension`, `all`. |
33
+ | `check-comprehension` | Check a finished screen against the mom test, the 15 second test, and the screenshot test. |
34
+ | `review-illustration` | Render an SVG you drew, look at it, report what is visibly wrong. |
35
+ | `find-icon-library` | Find an icon library that fits the project. |
40
36
  | `find-icons` | Search icons by name, library, and variant. |
41
- | `install-icons` | Generate local icon components in the target project. |
42
- | `detect-icon-library` | Read an existing icon-library manifest and report the active library. |
43
-
44
- ## Retrieve Principles
45
-
46
- Use `topic` when you know the principle or one of its aliases. Use `query` when you want the most relevant sections for a specific design problem.
47
-
48
- ```text
49
- get-ui-principle({ topic: "blur test" })
50
- get-ui-principle({ query: "group this dense settings screen with clearer proximity" })
51
- get-ux-principle({ topic: "reward design" })
52
- get-ux-principle({ query: "confirm a high-stakes action with control rather than celebration" })
53
- get-ux-principle({ topic: "clarity audit" })
54
- get-ux-principle({ topic: "motion brief" })
55
- ```
56
-
57
- The principle tools return complete documents for topic lookups and focused document sections for natural-language searches. After implementation, call `get-review-rules({ category: "all" })` so the same hierarchy, accessibility, motion, copy, and reward guidance is applied during review.
58
-
59
- ## Setup Behavior
37
+ | `install-icons` | Write icon components into the project. |
38
+ | `detect-icon-library` | Report which icon library a project already uses. |
60
39
 
61
- `npx better-design` auto-creates a free key when none is set, then prompts for clients, scope, and auto-invoke rules. Non-interactive runs (agents, or `-y`/`--yes`) install silently. Configs are merged into your existing files (backed up first, never clobbering other MCP servers); scope falls back per client when one isn't supported.
40
+ Every load-or-search tool takes `topic` when you know the name, or `query` when you are describing a problem.
62
41
 
63
- Options:
42
+ ## Options
64
43
 
65
44
  | Option | Description |
66
45
  | --- | --- |
67
- | `-y`, `--yes` | Non-interactive: skip prompts, auto-create a key. |
68
- | `BETTER_DESIGN_API_KEY` | Use your own key instead of auto-provisioning. |
69
- | `--global` | Install at user/global scope when the client supports it. |
70
- | `--project` | Install in the current project when the client supports it. |
71
- | `--help` | Print setup usage. |
46
+ | `-y`, `--yes` | Skip prompts. Agents and CI run this way by default. |
47
+ | `--global` | Install at user scope, where the client supports it. |
48
+ | `--project` | Install in the current project, where the client supports it. |
49
+ | `--help` | Print usage. |
package/dist/index.js CHANGED
@@ -1037,7 +1037,7 @@ function truncateToTokens(text, maxTokens) {
1037
1037
 
1038
1038
  ...(truncated to ~${maxTokens} tokens)`;
1039
1039
  }
1040
- var MAX_OUTPUT_PREVIEW, ICONIFY_FETCH_TIMEOUT_MS, ICONIFY_API_BASE, REGISTRY_BASE_URL, APP_BASE_URL, WIDGET_RESOURCE_DOMAINS, WIDGET_FRAME_DOMAINS, WIDGET_APP_DOMAIN, REQUIREMENTS_MD, ANTI_MOCKUP_MD, BUILD_TARGET_RULE, CODING_HOST_RE, PREVIEW_OUTPUT_SCHEMA, BUILD_KIT_OUTPUT_SCHEMA, CONTEXT_ARG, SEARCH_TOOLS;
1040
+ var MAX_OUTPUT_PREVIEW, ICONIFY_FETCH_TIMEOUT_MS, ICONIFY_API_BASE, REGISTRY_BASE_URL, APP_BASE_URL, WIDGET_RESOURCE_DOMAINS, WIDGET_FRAME_DOMAINS, WIDGET_APP_DOMAIN, REQUIREMENTS_MD, ANTI_MOCKUP_MD, BUILD_TARGET_RULE, CODING_HOST_RE, PREVIEW_OUTPUT_SCHEMA, BUILD_KIT_OUTPUT_SCHEMA, CONTEXT_ARG, READ_ONLY_TOOL_ANNOTATIONS, SEARCH_TOOLS;
1041
1041
  var init_shared = __esm({
1042
1042
  "../shared/src/mcp/tools/shared.ts"() {
1043
1043
  "use strict";
@@ -1086,6 +1086,11 @@ The UI copy inside the screen follows the same restraint: short headlines (about
1086
1086
  CONTEXT_ARG = z.string().max(280).optional().describe(
1087
1087
  "Optional. One sentence on WHY you are calling this and what the user asked for (e.g. 'adding nav icons for the fintech dashboard'). Used only for usage analytics; does not change the result."
1088
1088
  );
1089
+ READ_ONLY_TOOL_ANNOTATIONS = {
1090
+ readOnlyHint: true,
1091
+ destructiveHint: false,
1092
+ openWorldHint: false
1093
+ };
1089
1094
  SEARCH_TOOLS = /* @__PURE__ */ new Set([
1090
1095
  "find-design-system",
1091
1096
  "get-ui-principle",
@@ -1278,7 +1283,7 @@ Use maxTokens to keep responses focused (recommended: 5000\u201310000).`,
1278
1283
  maxTokens: z2.number().min(500).max(5e4).optional().describe("Maximum tokens to return. Truncates content to fit. Recommended: 5000-10000."),
1279
1284
  context: CONTEXT_ARG
1280
1285
  }),
1281
- annotations: { readOnlyHint: true }
1286
+ annotations: READ_ONLY_TOOL_ANNOTATIONS
1282
1287
  },
1283
1288
  async ({ topic, query, maxTokens, context }) => {
1284
1289
  const start = Date.now();
@@ -1319,7 +1324,7 @@ Use maxTokens to keep responses focused (recommended: 5000\u201310000).`,
1319
1324
  maxTokens: z2.number().min(500).max(5e4).optional().describe("Maximum tokens to return. Truncates content to fit. Recommended: 5000-10000."),
1320
1325
  context: CONTEXT_ARG
1321
1326
  }),
1322
- annotations: { readOnlyHint: true }
1327
+ annotations: READ_ONLY_TOOL_ANNOTATIONS
1323
1328
  },
1324
1329
  async ({ topic, query, maxTokens, context }) => {
1325
1330
  const start = Date.now();
@@ -1365,7 +1370,7 @@ Prefer query search when you do not know the topic name. Use maxTokens to keep r
1365
1370
  maxTokens: z2.number().min(500).max(5e4).optional().describe("Maximum tokens to return. Truncates content to fit. Recommended: 5000-10000."),
1366
1371
  context: CONTEXT_ARG
1367
1372
  }),
1368
- annotations: { readOnlyHint: true }
1373
+ annotations: READ_ONLY_TOOL_ANNOTATIONS
1369
1374
  },
1370
1375
  async ({ topic, query, maxTokens, context }) => {
1371
1376
  const start = Date.now();
@@ -1422,7 +1427,7 @@ Prefer query search when you do not know the topic name. Use maxTokens to keep r
1422
1427
  maxTokens: z2.number().min(500).max(5e4).optional().describe("Maximum tokens to return. Truncates content to fit. Recommended: 5000-10000."),
1423
1428
  context: CONTEXT_ARG
1424
1429
  }),
1425
- annotations: { readOnlyHint: true }
1430
+ annotations: READ_ONLY_TOOL_ANNOTATIONS
1426
1431
  },
1427
1432
  async ({ topic, query, maxTokens, context }) => {
1428
1433
  const start = Date.now();
@@ -1482,7 +1487,7 @@ Prefer query search when you do not know the topic name. Use maxTokens to keep r
1482
1487
  maxTokens: z2.number().min(500).max(5e4).optional().describe("Maximum tokens to return. Truncates content to fit. Recommended: 5000-10000."),
1483
1488
  context: CONTEXT_ARG
1484
1489
  }),
1485
- annotations: { readOnlyHint: true }
1490
+ annotations: READ_ONLY_TOOL_ANNOTATIONS
1486
1491
  },
1487
1492
  async ({ topic, query, maxTokens, context }) => {
1488
1493
  const start = Date.now();
@@ -1550,7 +1555,7 @@ Use maxTokens to keep responses focused (recommended: 5000\u201310000).`,
1550
1555
  maxTokens: z2.number().min(500).max(5e4).optional().describe("Maximum tokens to return. Truncates content to fit. Recommended: 5000\u201310000."),
1551
1556
  context: CONTEXT_ARG
1552
1557
  }),
1553
- annotations: { readOnlyHint: true }
1558
+ annotations: READ_ONLY_TOOL_ANNOTATIONS
1554
1559
  },
1555
1560
  async ({ category = "all", maxTokens, context }) => {
1556
1561
  const start = Date.now();
@@ -2107,7 +2112,7 @@ Use knownTerms for words your audience genuinely knows, so the check stops flagg
2107
2112
  knownTerms: z3.array(z3.string().trim().min(1).max(60)).max(50).optional().describe("Words this audience already knows, so they are not flagged as insider language."),
2108
2113
  context: CONTEXT_ARG
2109
2114
  }),
2110
- annotations: { readOnlyHint: true }
2115
+ annotations: READ_ONLY_TOOL_ANNOTATIONS
2111
2116
  },
2112
2117
  async ({ context, ...args }) => {
2113
2118
  const start = Date.now();
@@ -2292,7 +2297,7 @@ Examples:
2292
2297
  inputSchema: z4.object({
2293
2298
  query: z4.string().describe("Style description or personality traits to match.")
2294
2299
  }),
2295
- annotations: { readOnlyHint: true }
2300
+ annotations: READ_ONLY_TOOL_ANNOTATIONS
2296
2301
  };
2297
2302
  const makeIconLibraryHandler = (toolName) => async ({ query }) => {
2298
2303
  const start = Date.now();
@@ -2368,7 +2373,7 @@ Returns icons formatted for use with Iconify React. If you pass a variant, Bette
2368
2373
  libraryId: z4.string().describe("The icon library ID from find-icon-library"),
2369
2374
  variant: z4.string().optional().describe("Optional variant style (e.g., 'bold', 'outline', 'duotone').")
2370
2375
  }),
2371
- annotations: { readOnlyHint: true }
2376
+ annotations: READ_ONLY_TOOL_ANNOTATIONS
2372
2377
  };
2373
2378
  const makeIconSearchHandler = (toolName) => async ({ query, libraryId, variant }) => {
2374
2379
  const start = Date.now();
@@ -2452,7 +2457,7 @@ If \`components/icons/index.ts\` already exists in the project, MERGE the new ex
2452
2457
  variant: z4.string().optional().describe("Optional library variant (e.g. 'outline', 'filled')."),
2453
2458
  context: CONTEXT_ARG
2454
2459
  }),
2455
- annotations: { readOnlyHint: true }
2460
+ annotations: READ_ONLY_TOOL_ANNOTATIONS
2456
2461
  },
2457
2462
  async ({ libraryId, names, targetDir, format, variant, context }) => tracked(
2458
2463
  "install-icons",
@@ -2657,7 +2662,7 @@ Returns either:
2657
2662
  manifestContent: z4.string().optional().describe("Contents of the project's components/icons/.library.json file, if it exists. The agent should attempt to read this file from disk and pass it here. If the file doesn't exist or can't be read, omit this field."),
2658
2663
  context: CONTEXT_ARG
2659
2664
  }),
2660
- annotations: { readOnlyHint: true }
2665
+ annotations: READ_ONLY_TOOL_ANNOTATIONS
2661
2666
  },
2662
2667
  async ({ manifestContent, context }) => tracked("detect-icon-library", { hasManifest: Boolean(manifestContent), context }, async () => {
2663
2668
  if (!manifestContent || !manifestContent.trim()) {
@@ -6079,9 +6084,9 @@ function inlineBuildMd(projectId) {
6079
6084
  return `
6080
6085
  **Building inline (ChatGPT canvas / Claude artifact)?** There is no npm or Tailwind there, so the install above can't run. Call \`get-design-system-kit\` with \`target: "html"\` and projectId \`${projectId}\` to get this system's real tokens + a framework-free CSS kit you paste into one \`<style>\` and build with immediately.`;
6081
6086
  }
6082
- async function fetchProjectTokensCss(projectId, authContext) {
6087
+ async function fetchProjectTokensCss(projectId, apiFetch, authContext) {
6083
6088
  try {
6084
- const res = await fetch(`${APP_BASE_URL}/api/projects/${projectId}/registry/all.json`, {
6089
+ const res = await apiFetch(`${APP_BASE_URL}/api/projects/${projectId}/registry/all.json`, {
6085
6090
  headers: authHeaders(authContext)
6086
6091
  });
6087
6092
  if (!res.ok) return null;
@@ -6171,7 +6176,8 @@ function registerDesignSystemTools({
6171
6176
  provider,
6172
6177
  tracked,
6173
6178
  track,
6174
- authContext
6179
+ authContext,
6180
+ apiFetch = globalThis.fetch
6175
6181
  }, { enableShopifyKit = true } = {}) {
6176
6182
  const searchInputSchema = z5.object({
6177
6183
  query: z5.string().describe(
@@ -6269,7 +6275,7 @@ ${BUILD_TARGET_RULE}` : ""}`
6269
6275
  title: "Find a Design System for a UI Build",
6270
6276
  description: searchDescription(),
6271
6277
  inputSchema: searchInputSchema,
6272
- annotations: { readOnlyHint: true }
6278
+ annotations: READ_ONLY_TOOL_ANNOTATIONS
6273
6279
  },
6274
6280
  makeSearchHandler("find-design-system", true)
6275
6281
  );
@@ -6290,7 +6296,7 @@ ${BUILD_TARGET_RULE}` : ""}`
6290
6296
  structuredContent: { status: "error", name: `Project ${projectId.slice(0, 8)}`, viewUrl: viewUrl2, tokensCss: "" }
6291
6297
  };
6292
6298
  }
6293
- const result = await fetchProjectTokensCss(projectId, authContext);
6299
+ const result = await fetchProjectTokensCss(projectId, apiFetch, authContext);
6294
6300
  if (!result?.tokensCss) {
6295
6301
  return {
6296
6302
  content: [{ type: "text", text: `Could not load tokens for project "${projectId}". It may still be generating, or the id is wrong. Check ${viewUrl2}.` }],
@@ -6393,7 +6399,7 @@ ${fence3}` }],
6393
6399
  }) => tracked("get-design-system-kit", { target: "shopify", designSystemId, projectId, context }, async () => {
6394
6400
  if (projectId) {
6395
6401
  const viewUrl2 = `${APP_BASE_URL}/projects/${projectId}`;
6396
- const result = await fetchProjectTokensCss(projectId, authContext);
6402
+ const result = await fetchProjectTokensCss(projectId, apiFetch, authContext);
6397
6403
  if (!result?.tokensCss) {
6398
6404
  return {
6399
6405
  content: [{ type: "text", text: `Could not load tokens for project "${projectId}". It may still be generating, or the id is wrong. Check ${viewUrl2}.` }],
@@ -6500,7 +6506,7 @@ ${BUILD_TARGET_RULE}`,
6500
6506
  context: CONTEXT_ARG
6501
6507
  }),
6502
6508
  outputSchema: buildKitOutputSchema(enableShopifyKit),
6503
- annotations: { readOnlyHint: true }
6509
+ annotations: READ_ONLY_TOOL_ANNOTATIONS
6504
6510
  // This tool returns build instructions, not a visual preview. Attaching
6505
6511
  // the preview template makes ChatGPT render a nested showcase iframe;
6506
6512
  // when that iframe is unavailable the user sees a large blank card even
@@ -6742,7 +6748,7 @@ Share the project URL with the user right away so they can watch the generation
6742
6748
  requestHeaders.Authorization = `Bearer ${bearer2}`;
6743
6749
  }
6744
6750
  try {
6745
- const startRes = await fetch(startUrl, {
6751
+ const startRes = await apiFetch(startUrl, {
6746
6752
  method: "POST",
6747
6753
  headers: requestHeaders,
6748
6754
  body: JSON.stringify({
@@ -6786,7 +6792,7 @@ Share the project URL with the user right away so they can watch the generation
6786
6792
  const statusUrl = `${APP_BASE_URL}/api/projects/${projectId}`;
6787
6793
  let project;
6788
6794
  try {
6789
- const res = await fetch(statusUrl, { headers });
6795
+ const res = await apiFetch(statusUrl, { headers });
6790
6796
  if (!res.ok) {
6791
6797
  return { content: [{ type: "text", text: `Could not read project ${projectId} (HTTP ${res.status}). Check the id, or view it at ${APP_BASE_URL}/projects/${projectId}.` }] };
6792
6798
  }
@@ -6803,7 +6809,7 @@ npx shadcn@latest add ${registryUrl}
6803
6809
  let tokensCss = "";
6804
6810
  let dsName = `Project ${projectId.slice(0, 8)}`;
6805
6811
  try {
6806
- const res = await fetch(registryUrl);
6812
+ const res = await apiFetch(registryUrl);
6807
6813
  if (res.ok) {
6808
6814
  const json = await res.json();
6809
6815
  if (json.meta?.installInstructions) body = json.meta.installInstructions;
@@ -7525,7 +7531,7 @@ Returns: the semantic palette (primary, background, foreground, accent, border,
7525
7531
  name: z6.string().trim().min(1).max(120).optional().describe("Optional label for the extracted system, e.g. the app or repo name."),
7526
7532
  maxTokens: z6.number().min(500).max(5e4).optional().describe("Maximum tokens to return. Truncates the token sheet to fit.")
7527
7533
  }),
7528
- annotations: { readOnlyHint: true }
7534
+ annotations: READ_ONLY_TOOL_ANNOTATIONS
7529
7535
  },
7530
7536
  async ({ css, name, maxTokens }) => tracked("extract-design-system", { name: name ?? null }, async () => {
7531
7537
  const result = extractDesignSystem(css, name);
@@ -7558,7 +7564,13 @@ function fail(message) {
7558
7564
  }
7559
7565
  };
7560
7566
  }
7561
- function registerIllustrationTools({ server, track, tracked, authContext }) {
7567
+ function registerIllustrationTools({
7568
+ server,
7569
+ track,
7570
+ tracked,
7571
+ authContext,
7572
+ apiFetch = globalThis.fetch
7573
+ }) {
7562
7574
  const authHeaders2 = () => {
7563
7575
  const headers = { "Content-Type": "application/json" };
7564
7576
  if (authContext) {
@@ -7591,7 +7603,7 @@ Markup carrying script, event handlers, remote references, or styles that reach
7591
7603
  reviewToken: z7.string().optional().describe("The token from a previous review of this drawing. Reviews it again free.")
7592
7604
  }),
7593
7605
  outputSchema: REVIEW_OUTPUT_SCHEMA,
7594
- annotations: { readOnlyHint: true }
7606
+ annotations: READ_ONLY_TOOL_ANNOTATIONS
7595
7607
  },
7596
7608
  async ({
7597
7609
  svg,
@@ -7603,7 +7615,7 @@ Markup carrying script, event handlers, remote references, or styles that reach
7603
7615
  { query: intent, animated, repeat: Boolean(reviewToken) },
7604
7616
  async () => {
7605
7617
  try {
7606
- const res = await fetch(`${APP_BASE_URL}/api/illustrations/review`, {
7618
+ const res = await apiFetch(`${APP_BASE_URL}/api/illustrations/review`, {
7607
7619
  method: "POST",
7608
7620
  headers: authHeaders2(),
7609
7621
  signal: AbortSignal.timeout(6e4),
@@ -7719,9 +7731,9 @@ var init_preview_resource = __esm({
7719
7731
  });
7720
7732
 
7721
7733
  // ../shared/src/mcp/tools.ts
7722
- function registerAllTools(server, provider, onToolUsage, authContext, options = {}) {
7734
+ function registerAllTools(server, provider, onToolUsage, authContext, options = {}, apiFetch = globalThis.fetch) {
7723
7735
  const { track, tracked } = createTracking(server, onToolUsage);
7724
- const deps = { server, provider, track, tracked, authContext };
7736
+ const deps = { server, provider, track, tracked, authContext, apiFetch };
7725
7737
  registerPrincipleTools(deps, options);
7726
7738
  registerComprehensionTools(deps);
7727
7739
  registerIconTools(deps);
@@ -7763,17 +7775,25 @@ function createMcpServer(options) {
7763
7775
  authContext,
7764
7776
  enableReactNativeGuide = true,
7765
7777
  enableThreeJsGuide = true,
7766
- enableShopifyKit = true
7778
+ enableShopifyKit = true,
7779
+ apiFetch = globalThis.fetch
7767
7780
  } = options;
7768
7781
  const server = new McpServer(
7769
7782
  { name, version },
7770
7783
  { instructions: getMcpInstructions({ enableReactNativeGuide, enableThreeJsGuide }) }
7771
7784
  );
7772
- registerAllTools(server, provider, onToolUsage, authContext, {
7773
- enableReactNativeGuide,
7774
- enableThreeJsGuide,
7775
- enableShopifyKit
7776
- });
7785
+ registerAllTools(
7786
+ server,
7787
+ provider,
7788
+ onToolUsage,
7789
+ authContext,
7790
+ {
7791
+ enableReactNativeGuide,
7792
+ enableThreeJsGuide,
7793
+ enableShopifyKit
7794
+ },
7795
+ apiFetch
7796
+ );
7777
7797
  return server;
7778
7798
  }
7779
7799
  var init_mcp = __esm({