miromiro-mcp 0.7.4 → 0.8.2
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 +29 -12
- package/package.json +4 -2
- package/src/index.mjs +15 -13
package/README.md
CHANGED
|
@@ -9,18 +9,30 @@ Works with Claude (web, desktop, Claude Code), ChatGPT, Cursor, Windsurf, Codex,
|
|
|
9
9
|
|
|
10
10
|
## Claude Code plugin
|
|
11
11
|
|
|
12
|
-
Install as a plugin to get the tools plus
|
|
13
|
-
each one
|
|
12
|
+
Install as a plugin to get the tools plus five skills that teach Claude when to reach for
|
|
13
|
+
each one:
|
|
14
|
+
|
|
15
|
+
- `elementor-section` - any site's section as an Elementor template to import into WordPress
|
|
16
|
+
- `shopify-section` - any site's section as a Shopify theme section (`.liquid`)
|
|
17
|
+
- `clone-section` - a section as Tailwind, HTML+CSS, React or Vue
|
|
18
|
+
- `match-brand` - a site's colors, fonts and design tokens to build in its style
|
|
19
|
+
- `extract-assets` - images, SVG icons, videos, audio and Lottie files
|
|
14
20
|
|
|
15
21
|
```bash
|
|
16
|
-
claude plugin marketplace add
|
|
17
|
-
claude plugin install miromiro@
|
|
22
|
+
claude plugin marketplace add SoraiaBarroso/miromiro-mcp
|
|
23
|
+
claude plugin install miromiro@miromiro
|
|
18
24
|
```
|
|
19
25
|
|
|
20
26
|
The plugin uses the remote server, so there is nothing to install and no key to paste - on
|
|
21
27
|
first use it opens a one-click MiroMiro sign-in that links a free account (300 credits/month,
|
|
22
28
|
no card).
|
|
23
29
|
|
|
30
|
+
## Skills for OpenClaw and other agents
|
|
31
|
+
|
|
32
|
+
The same skills live in [`skills/`](skills). Each one uses the MiroMiro MCP tools when they
|
|
33
|
+
are connected and otherwise calls the REST API with `MIROMIRO_API_KEY` (free key, 300
|
|
34
|
+
credits a month: https://miromiro.app/api/onboarding).
|
|
35
|
+
|
|
24
36
|
## Quick start: remote server (nothing to install)
|
|
25
37
|
|
|
26
38
|
A hosted server lives at:
|
|
@@ -32,8 +44,13 @@ https://miromiro.app/mcp
|
|
|
32
44
|
Paste that URL into any client that accepts a remote MCP server. On first use it opens a one-click MiroMiro sign-in that links a free account (300 credits/month, no card).
|
|
33
45
|
|
|
34
46
|
- **Claude (web or desktop):** Settings → Connectors → Add custom connector → paste the URL. Or use the [one-click install](https://miromiro.app/api/mcp).
|
|
35
|
-
- **ChatGPT:** Settings → Security and login → enable Developer mode, then
|
|
47
|
+
- **ChatGPT:** Settings → Security and login → enable Developer mode, then Settings → Plugins → New Plugin with the URL (authentication: OAuth).
|
|
36
48
|
- **Cursor (remote):** add `{ "mcpServers": { "miromiro": { "url": "https://miromiro.app/mcp" } } }` to `~/.cursor/mcp.json`.
|
|
49
|
+
- **Claude Code:** `claude mcp add --transport http miromiro https://miromiro.app/mcp`, then `/mcp` in a session to sign in.
|
|
50
|
+
- **Codex:** add `[mcp_servers.miromiro]` with `url = "https://miromiro.app/mcp"` to `~/.codex/config.toml`, then run `codex mcp login miromiro`.
|
|
51
|
+
- **Grok Bot:** ask the bot "Add a custom MCP server called miromiro at https://miromiro.app/mcp", then press Authorize.
|
|
52
|
+
- **Muse:** Settings → Connectors → Add custom connector → paste the URL.
|
|
53
|
+
- Step-by-step pages for each agent: https://miromiro.app/api/agents/chatgpt (swap the last part for `claude`, `claude-code`, `codex`, `cursor`, `grok-bot`, `muse` or `openai-dots`).
|
|
37
54
|
- **Raw API key instead of OAuth:** append `?access_key=mm_live_...` to the URL, or send it as an `Authorization: Bearer` header.
|
|
38
55
|
|
|
39
56
|
## Local server (npm)
|
|
@@ -66,15 +83,15 @@ claude mcp add miromiro -s user \
|
|
|
66
83
|
|
|
67
84
|
| Tool | What it returns | Credits |
|
|
68
85
|
|---|---|---|
|
|
69
|
-
| `extract_code` | A section of a live page as a paste-ready component (Tailwind, HTML+CSS, JSX or Vue) plus the tokens it uses - start here to rebuild real UI | 25 |
|
|
86
|
+
| `extract_code` | A section of a live page as a paste-ready component (Tailwind, HTML+CSS, JSX or Vue) or an importable Elementor template / Shopify section, plus the tokens it uses - start here to rebuild real UI | 25 |
|
|
70
87
|
| `extract_brand` | Named color roles (primary/accent/background/text), palette, fonts split by role, logo, social profiles, a 0-1 confidence score, and `signals` explaining where the colors came from (declared tokens vs inferred) | 15 |
|
|
71
88
|
| `extract_design_tokens` | Full token system with usage counts; `format: css` or `tailwind` for paste-ready output, `dtcg` for a W3C Design Tokens file (Style Dictionary / Figma variables) | 10 |
|
|
72
89
|
| `extract_fonts` | Every font file and family the site loads, with weights, formats, and file URLs | 5 |
|
|
73
|
-
| `extract_videos` | Video files, `og:video`, and player embeds (YouTube, Vimeo, Wistia, Loom), tagged by source | 1 |
|
|
74
|
-
| `extract_audio` | Audio files, `og:audio`, and podcast enclosures, tagged by source | 1 |
|
|
90
|
+
| `extract_videos` | Video files, `og:video`, and player embeds (YouTube, Vimeo, Wistia, Loom), tagged by source; a direct video-file URL is returned as the single result, and a YouTube/Vimeo/TikTok/Dailymotion/Loom video URL returns its player embed without a fetch | 1 |
|
|
91
|
+
| `extract_audio` | Audio files, `og:audio`, and podcast enclosures, tagged by source; a direct audio-file URL is returned as the single result | 1 |
|
|
75
92
|
| `extract_lottie` | Lottie animation JSON files declared in the page | 3 |
|
|
76
93
|
| `extract_svgs` | Inline SVG code (sanitized, paste-ready) plus external SVG file URLs | 1 |
|
|
77
|
-
| `extract_assets` | Every image URL on a page, tagged by source, with alt text | 1 |
|
|
94
|
+
| `extract_assets` | Every image URL on a page, tagged by source, with alt text; a direct image-file URL is returned as the single result | 1 |
|
|
78
95
|
|
|
79
96
|
All tools are read-only and retry-safe. Identical calls within 24 hours are served from cache for free, and failed calls are never billed.
|
|
80
97
|
|
|
@@ -104,7 +121,7 @@ Generated code is never trimmed. Results stop at roughly 20k tokens (25k for `ex
|
|
|
104
121
|
|
|
105
122
|
The REST API and this local npm server always return everything untrimmed, so `limit` and
|
|
106
123
|
`full_output` apply to the remote server only. Every tool on both servers accepts
|
|
107
|
-
`render: true` (
|
|
124
|
+
`render: true` (forces a real browser, +5 credits, on every plan; usually not needed because the server re-runs JavaScript-only or refused pages in a browser by itself - see Notes), plus two more shared arguments:
|
|
108
125
|
|
|
109
126
|
- `fresh: true` - skip the 24-hour cache and re-extract the live page (charged normally); use when the site just changed
|
|
110
127
|
- `screenshot: true` (requires `render: true`) - the result gains a `screenshot` field: a public URL of a 1440x900 capture of the page, live for 7 days, at no extra credits - show it to the user to verify an extraction. Pass `'full'` instead of `true` for the entire page height.
|
|
@@ -131,8 +148,8 @@ The agent calls `extract_fonts` and returns every family with its font file URLs
|
|
|
131
148
|
|
|
132
149
|
## Notes
|
|
133
150
|
|
|
134
|
-
- The API reads static HTML and resolves the full CSS cascade
|
|
135
|
-
-
|
|
151
|
+
- The API reads static HTML and resolves the full CSS cascade first. When that comes back as a JavaScript app shell, with styles injected by scripts, or refused by the site (401, 403 or 406 - publishers commonly turn away datacenter IPs even for a public page), the server re-runs the call in a real browser by itself at no extra cost, on every plan, and the result carries `usage.autoRender` (a sentence to read to the user).
|
|
152
|
+
- Pass `render: true` to force the browser (+5 credits, any plan): for images, video or Lottie that only load on scroll, or when a result is still thin after the automatic pass. A 403 that says the browser was refused too means the site cannot be extracted. On extract_code and extract_design_tokens, `render: true` only permits the browser: the plain read still runs first, and the 5 credits are charged only if the browser was actually needed.
|
|
136
153
|
- Every result carries `usage` with the credits left this month. If the account holds a credit pack (one-off credits that never expire, bought at https://miromiro.app/api/pricing), `usage.packCredits` is the pack balance left; packs are drawn after the monthly credits, so a free account with a pack keeps working past its 300 credits.
|
|
137
154
|
- Respect the sites you extract from: check their terms before reusing assets commercially.
|
|
138
155
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "miromiro-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.2",
|
|
4
4
|
"description": "MCP server for the MiroMiro design-extraction API — give your coding agent the real code, design tokens, assets, SVGs, fonts, and Lottie of any website.",
|
|
5
5
|
"mcpName": "app.miromiro/miromiro",
|
|
6
6
|
"type": "module",
|
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
"type": "git",
|
|
11
11
|
"url": "git+https://github.com/SoraiaBarroso/miromiro-mcp.git"
|
|
12
12
|
},
|
|
13
|
-
"bugs": {
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/SoraiaBarroso/miromiro-mcp/issues"
|
|
15
|
+
},
|
|
14
16
|
"bin": {
|
|
15
17
|
"miromiro-mcp": "src/index.mjs"
|
|
16
18
|
},
|
package/src/index.mjs
CHANGED
|
@@ -45,7 +45,7 @@ const NAMED_SECTIONS = ['hero', 'header', 'footer', 'pricing', 'features', 'test
|
|
|
45
45
|
// client-rendered React/Next/SPA sites that return little statically.
|
|
46
46
|
const RENDER_ARG = {
|
|
47
47
|
type: 'boolean',
|
|
48
|
-
description: '
|
|
48
|
+
description: 'Force a real browser so the page\x27s JavaScript runs before it is read. Slower, and adds 5 credits. Usually not needed: when the plain read comes back as a JavaScript app shell or the site refuses it (401/403/406), the server already re-runs the page in a browser by itself at no extra cost, and usage.autoRender says so. Pass it for images, videos or Lottie that only load on scroll, with screenshot=true, or when a result is still thin after that automatic pass. If a 403 says the browser was refused too, the site cannot be extracted - do not retry. On extract_code and extract_design_tokens, render=true only permits the browser: the plain read still runs first, and the 5 credits are charged only if the browser was actually needed.'
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
// Shared input arg: skip the 24h cache for this one call (charged normally).
|
|
@@ -82,14 +82,14 @@ const TOOLS = [
|
|
|
82
82
|
title: 'Extract section as code',
|
|
83
83
|
endpoint: 'code',
|
|
84
84
|
description:
|
|
85
|
-
"Use when the user asks to rebuild, clone, copy, port, restyle or 'make it look like' part of a real website, or wants a site's section as Tailwind, HTML+CSS, React (JSX) or Vue. Give it the URL and, when the user named a part of the page, section (hero, header, footer, pricing, features, testimonials, faq, cta) - never invent a CSS selector. With neither, it auto-detects the hero; every call also returns `sections`, each other extractable section with a label and a ready selector for a follow-up call. Returns a self-contained component with the page's real resolved styles (true colors, fonts, spacing, copy) plus the tokens and assets it uses, so you adapt real values instead of estimating from a screenshot. For jsx/vue, repeated structures collapse into a data array rendered with .map()/v-for; ::before/::after come back as real elements; @keyframes ship in the css field. The `theme` field says which theme the code actually is - sites with a prefers-color-scheme dark variant return the light branch unless you pass theme='dark'; say which you returned. Not for: whole-page scraping, page text, or sites that need a login. Reads static HTML/CSS
|
|
85
|
+
"Use when the user asks to rebuild, clone, copy, port, restyle or 'make it look like' part of a real website, or wants a site's section as Tailwind, HTML+CSS, React (JSX) or Vue - or as a file to import into a site builder: framework=elementor for an Elementor template (WordPress), framework=shopify for a Shopify theme section. Give it the URL and, when the user named a part of the page, section (hero, header, footer, pricing, features, testimonials, faq, cta) - never invent a CSS selector. With neither, it auto-detects the hero; every call also returns `sections`, each other extractable section with a label and a ready selector for a follow-up call. Returns a self-contained component with the page's real resolved styles (true colors, fonts, spacing, copy) plus the tokens and assets it uses, so you adapt real values instead of estimating from a screenshot. For jsx/vue, repeated structures collapse into a data array rendered with .map()/v-for; ::before/::after come back as real elements; @keyframes ship in the css field. The `theme` field says which theme the code actually is - sites with a prefers-color-scheme dark variant return the light branch unless you pass theme='dark'; say which you returned. Not for: whole-page scraping, page text, or sites that need a login. Reads static HTML/CSS first and re-runs the page in a real browser by itself when that comes back as a JavaScript app shell or refused, at no extra cost (usage.autoRender says so) - no need to pass render=true.",
|
|
86
86
|
inputSchema: {
|
|
87
87
|
type: 'object',
|
|
88
88
|
properties: {
|
|
89
89
|
url: { type: 'string', description: 'The website URL, e.g. stripe.com' },
|
|
90
90
|
section: { type: 'string', enum: NAMED_SECTIONS, description: "Which part of the page, by name - use this when the user asked for the pricing, footer, header/nav, features, testimonials, FAQ or call-to-action block. Resolved on the page itself from its ids, classes, headings and, failing those, its content (prices, blockquotes, FAQ items), so it works without seeing the markup and on pages that label nothing. Omit for the hero. If the page has no such section you get the hero plus a `note` listing what is there." },
|
|
91
91
|
selector: { type: 'string', description: 'CSS selector for the section, ONLY when you have one from a previous result\'s `sections` list (e.g. "section.pricing-grid"). Do not guess selectors: a selector that matches nothing falls back to the hero with a `note`, and the guess costs a call. Prefer `section` for named parts of a page.' },
|
|
92
|
-
framework: { type: 'string', enum: ['tailwind', 'html', 'jsx', 'vue'], description:
|
|
92
|
+
framework: { type: 'string', enum: ['tailwind', 'html', 'jsx', 'vue', 'elementor', 'shopify'], description: "The code to generate (default tailwind). 'elementor' returns an importable Elementor template: tell the user to save `code` as a .json file and import it in WordPress under Templates > Saved Templates > Import. 'shopify' returns a theme section: save `code` as sections/<name>.liquid in the theme, then add it from the theme editor. Use the theme code editor's sections folder, not a Custom Liquid block (that block is capped at 50 KB and cannot hold the schema). Both arrive as one styled HTML block (edited as code, not as native widgets), with the section's responsive and hover styles included and its CSS scoped so it cannot clash with the theme. Give the user the file contents complete and unmodified." },
|
|
93
93
|
name: { type: 'string', description: 'Component name for the jsx target (default ExtractedSection). Ignored by tailwind, html and vue. Renaming never re-runs the extraction - it costs 0 credits on a cached section.' },
|
|
94
94
|
theme: { type: 'string', enum: ['light', 'dark'], description: "Which colour scheme to extract (default light). Pass 'dark' when the user is looking at the site in dark mode or asks for the dark version: the page's prefers-color-scheme: dark rules and custom properties become the component itself instead of riding along as dark: variants. Works whether the site expresses its themes as @media (prefers-color-scheme) or as a root attribute/class the CSS is scoped to ([data-theme=dark], html.dark). Sites that switch themes purely in JavaScript cannot be selected this way - you get the page default plus a hint saying so. No extra credits." },
|
|
95
95
|
render: RENDER_ARG, fresh: FRESH_ARG, screenshot: SCREENSHOT_ARG
|
|
@@ -114,18 +114,19 @@ const TOOLS = [
|
|
|
114
114
|
label: { type: 'string' },
|
|
115
115
|
elements: { type: 'number' },
|
|
116
116
|
hasHeading: { type: 'boolean' },
|
|
117
|
-
preview: { type: 'string' }
|
|
117
|
+
preview: { type: 'string' },
|
|
118
|
+
order: { type: 'number', description: 'Where the section starts on the page among the listed ones, 1 = topmost - sort by it to rebuild a whole page in sequence' }
|
|
118
119
|
}
|
|
119
120
|
}
|
|
120
121
|
},
|
|
121
|
-
framework: { type: 'string', description: 'tailwind | html | jsx | vue' },
|
|
122
|
-
code: { type: 'string', description: 'The generated, paste-ready component code. For jsx/vue, repeated structures (tiers, cards, list items) are collapsed into a data array rendered with .map()/v-for' },
|
|
123
|
-
css: { type: 'string', description: 'Companion CSS: always set for framework=html; for
|
|
122
|
+
framework: { type: 'string', description: 'tailwind | html | jsx | vue | elementor | shopify' },
|
|
123
|
+
code: { type: 'string', description: 'The generated, paste-ready component code. For jsx/vue, repeated structures (tiers, cards, list items) are collapsed into a data array rendered with .map()/v-for. For elementor this is the complete template JSON (a .json file); for shopify the complete section file (a .liquid file) - hand either over whole' },
|
|
124
|
+
css: { type: 'string', description: 'Companion CSS: always set for framework=html; for tailwind/jsx/vue it carries the @keyframes the section uses (add to the global stylesheet); null for elementor/shopify, whose file already contains its CSS' },
|
|
124
125
|
tokens: { type: 'object', description: 'Design tokens the extracted section actually uses' },
|
|
125
126
|
theme: { type: 'string', description: "light | dark: which one the code you just received actually is. Measured from the page, never echoed from your request - so if you asked for a theme the site cannot serve, this reports what you really got. Tell the user which theme they got when it may not match what they see on the site" },
|
|
126
127
|
assets: { description: 'Images/fonts the section references' },
|
|
127
128
|
summary: { description: 'What was extracted, at a glance. styledCoverage (0-100) is the quality signal: the % of elements the cascade found styles for' },
|
|
128
|
-
hint: { type: 'string', description: 'Only present when the extraction looks degraded (client-rendered page, runtime-injected styles) - says what to do
|
|
129
|
+
hint: { type: 'string', description: 'Only present when the extraction looks degraded (client-rendered page, runtime-injected styles) - says what to do (the server has already tried a browser where one would help); on a render=true call the styles could not be resolved even in a browser, do not retry' },
|
|
129
130
|
usage: OUT_USAGE,
|
|
130
131
|
truncation_note: OUT_TRUNCATION
|
|
131
132
|
},
|
|
@@ -235,7 +236,7 @@ const TOOLS = [
|
|
|
235
236
|
title: 'Extract images',
|
|
236
237
|
endpoint: 'images',
|
|
237
238
|
description:
|
|
238
|
-
"Use when the user wants the images from a page - photos, illustrations, backgrounds, favicon, social image - as resolved URLs tagged by source (img, srcset, picture, CSS background, favicon, og). Not for: icons and vector logos (use extract_svgs) or fonts (use extract_fonts). If images are mounted by JavaScript, call again with render=true (+5 credits).",
|
|
239
|
+
"Use when the user wants the images from a page - photos, illustrations, backgrounds, favicon, social image - as resolved URLs tagged by source (img, srcset, picture, CSS background, favicon, og). A direct image-file URL comes back as the single result (source file). Not for: icons and vector logos (use extract_svgs) or fonts (use extract_fonts). If images are mounted by JavaScript, call again with render=true (+5 credits).",
|
|
239
240
|
inputSchema: {
|
|
240
241
|
type: 'object',
|
|
241
242
|
properties: { url: { type: 'string', description: 'The website URL' }, render: RENDER_ARG, fresh: FRESH_ARG, screenshot: SCREENSHOT_ARG },
|
|
@@ -399,7 +400,7 @@ const TOOLS = [
|
|
|
399
400
|
title: 'Extract videos',
|
|
400
401
|
endpoint: 'videos',
|
|
401
402
|
description:
|
|
402
|
-
'Use when the user wants the videos on a page: <video>/<source> files, og:video, YouTube/Vimeo/Wistia/Loom embeds and direct video links, each tagged by source with a poster when declared. `source: "embed"` is a player page, not a downloadable file. Most players mount with JavaScript: if the result is thin or empty, call again with render=true (+5 credits).',
|
|
403
|
+
'Use when the user wants the videos on a page: <video>/<source> files, og:video, YouTube/Vimeo/Wistia/Loom embeds and direct video links, each tagged by source with a poster when declared. `source: "embed"` is a player page, not a downloadable file; a direct video-file URL comes back as the single result (source file). A YouTube, Vimeo, TikTok, Dailymotion or Loom video URL is answered from the URL alone with its player embed (source platform, no fetch, never pass render for these) - tell the user the file itself cannot be downloaded through MiroMiro. Most other players mount with JavaScript: if the result is thin or empty, call again with render=true (+5 credits).',
|
|
403
404
|
inputSchema: {
|
|
404
405
|
type: 'object',
|
|
405
406
|
properties: { url: { type: 'string', description: 'The website URL' }, render: RENDER_ARG, fresh: FRESH_ARG, screenshot: SCREENSHOT_ARG },
|
|
@@ -435,7 +436,7 @@ const TOOLS = [
|
|
|
435
436
|
title: 'Extract audio',
|
|
436
437
|
endpoint: 'audio',
|
|
437
438
|
description:
|
|
438
|
-
'Use when the user wants the audio files on a page: <audio>/<source> files, og:audio, podcast enclosures and download links, each tagged by source. If a JavaScript player mounts the audio at runtime, call again with render=true (+5 credits).',
|
|
439
|
+
'Use when the user wants the audio files on a page: <audio>/<source> files, og:audio, podcast enclosures and download links, each tagged by source; a direct audio-file URL comes back as the single result (source file). If a JavaScript player mounts the audio at runtime, call again with render=true (+5 credits).',
|
|
439
440
|
inputSchema: {
|
|
440
441
|
type: 'object',
|
|
441
442
|
properties: { url: { type: 'string', description: 'The website URL' }, render: RENDER_ARG, fresh: FRESH_ARG, screenshot: SCREENSHOT_ARG },
|
|
@@ -531,7 +532,7 @@ const PROMPTS = [
|
|
|
531
532
|
arguments: [
|
|
532
533
|
PROMPT_URL_ARG,
|
|
533
534
|
{ name: 'section', description: `Which part: ${NAMED_SECTIONS.join(', ')} (default hero)` },
|
|
534
|
-
{ name: 'framework', description: 'tailwind (default), html, jsx or
|
|
535
|
+
{ name: 'framework', description: 'tailwind (default), html, jsx, vue, elementor or shopify' }
|
|
535
536
|
],
|
|
536
537
|
render: ({ url, section, framework }) =>
|
|
537
538
|
`Rebuild the ${section || 'hero'} section of ${url} as ${framework || 'tailwind'} code I can paste into my project. ` +
|
|
@@ -580,6 +581,7 @@ const INSTRUCTIONS =
|
|
|
580
581
|
'`hint`, or a 403 target_blocked comes back, retry the SAME url with render=true (+5 credits) before telling the ' +
|
|
581
582
|
'user a site cannot be extracted. Theme: a site with a prefers-color-scheme dark variant returns its light branch ' +
|
|
582
583
|
'by default; pass theme=dark to extract_code for the dark version and report the `theme` field you actually got. ' +
|
|
584
|
+
'For WordPress/Elementor or Shopify users, extract_code framework=elementor|shopify returns an importable template (.json) or theme section (.liquid) instead of component code. ' +
|
|
583
585
|
'extract_design_tokens returns values and counts, not layout - not a substitute for extract_code on a rebuild; ' +
|
|
584
586
|
'format=dtcg gives a W3C Design Tokens file. Explain results, do not dump them: extract_brand\'s ' +
|
|
585
587
|
'signals.explanation says whether the colors were declared by the site or inferred (primarySource "usage" = a ' +
|
|
@@ -587,7 +589,7 @@ const INSTRUCTIONS =
|
|
|
587
589
|
'fresh=true bypasses the 24h cache. Every result carries `usage` (credits left; `packCredits` = never-expiring pack balance when the account holds one).'
|
|
588
590
|
|
|
589
591
|
const server = new Server(
|
|
590
|
-
{ name: 'miromiro', version: '0.
|
|
592
|
+
{ name: 'miromiro', version: '0.8.2' },
|
|
591
593
|
{ capabilities: { tools: {}, prompts: {} }, instructions: INSTRUCTIONS }
|
|
592
594
|
)
|
|
593
595
|
|