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 +25 -47
- package/dist/index.js +54 -34
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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.
|
|
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
|
-
|
|
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
|
-
|
|
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` |
|
|
26
|
-
| `create-design-system` |
|
|
27
|
-
| `get-design-system-status` | Poll a
|
|
28
|
-
| `
|
|
29
|
-
| `
|
|
30
|
-
| `
|
|
31
|
-
| `get-ui-principle` | Load or search visual
|
|
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` |
|
|
34
|
-
| `get-three-js-guide` |
|
|
35
|
-
| `get-motion-guide` |
|
|
36
|
-
| `get-review-rules` |
|
|
37
|
-
| `check-comprehension` | Check a finished screen against the mom test, the 15 second test, and the screenshot test.
|
|
38
|
-
| `
|
|
39
|
-
| `find-icon-library` | Find an icon library
|
|
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` |
|
|
42
|
-
| `detect-icon-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
|
-
|
|
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` |
|
|
68
|
-
| `
|
|
69
|
-
| `--
|
|
70
|
-
| `--
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
|
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:
|
|
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:
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
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({
|
|
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:
|
|
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
|
|
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(
|
|
7773
|
-
|
|
7774
|
-
|
|
7775
|
-
|
|
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({
|