miromiro-mcp 0.8.0 → 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 +19 -7
- package/package.json +4 -2
- package/src/index.mjs +6 -5
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:
|
|
@@ -109,7 +121,7 @@ Generated code is never trimmed. Results stop at roughly 20k tokens (25k for `ex
|
|
|
109
121
|
|
|
110
122
|
The REST API and this local npm server always return everything untrimmed, so `limit` and
|
|
111
123
|
`full_output` apply to the remote server only. Every tool on both servers accepts
|
|
112
|
-
`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:
|
|
113
125
|
|
|
114
126
|
- `fresh: true` - skip the 24-hour cache and re-extract the live page (charged normally); use when the site just changed
|
|
115
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.
|
|
@@ -136,8 +148,8 @@ The agent calls `extract_fonts` and returns every family with its font file URLs
|
|
|
136
148
|
|
|
137
149
|
## Notes
|
|
138
150
|
|
|
139
|
-
- The API reads static HTML and resolves the full CSS cascade
|
|
140
|
-
-
|
|
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.
|
|
141
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.
|
|
142
154
|
- Respect the sites you extract from: check their terms before reusing assets commercially.
|
|
143
155
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "miromiro-mcp",
|
|
3
|
-
"version": "0.8.
|
|
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,7 +82,7 @@ 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 - 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
|
|
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: {
|
|
@@ -114,7 +114,8 @@ 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
|
},
|
|
@@ -125,7 +126,7 @@ const TOOLS = [
|
|
|
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
|
},
|
|
@@ -588,7 +589,7 @@ const INSTRUCTIONS =
|
|
|
588
589
|
'fresh=true bypasses the 24h cache. Every result carries `usage` (credits left; `packCredits` = never-expiring pack balance when the account holds one).'
|
|
589
590
|
|
|
590
591
|
const server = new Server(
|
|
591
|
-
{ name: 'miromiro', version: '0.8.
|
|
592
|
+
{ name: 'miromiro', version: '0.8.2' },
|
|
592
593
|
{ capabilities: { tools: {}, prompts: {} }, instructions: INSTRUCTIONS }
|
|
593
594
|
)
|
|
594
595
|
|