[{"data":1,"prerenderedAt":2667},["ShallowReactive",2],{"api-blog-make-ai-agent-match-a-real-website-design":3,"api-blog-related-make-ai-agent-match-a-real-website-design":922},{"id":4,"title":5,"author":6,"body":7,"category":890,"date":891,"dateModified":891,"description":892,"extension":520,"faqs":893,"image":902,"meta":903,"navigation":227,"path":904,"readingTime":309,"relatedSlugs":905,"seo":910,"seoTitle":911,"stem":912,"tags":913,"__hash__":921},"apiBlog/api-blog/make-ai-agent-match-a-real-website-design.md","How to Make Claude, Cursor or ChatGPT Match a Real Website Instead of Guessing","Soraia",{"type":8,"value":9,"toc":873},"minimark",[10,14,17,22,34,37,40,44,47,492,498,506,509,513,516,577,580,584,587,590,594,597,600,606,609,613,713,716,720,727,733,739,745,749,757,797,800,826,829,833,836,840,845,848,852,855,859,862,866,869],[11,12,13],"p",{},"Your agent gets a real website wrong because you gave it a picture. Give it values instead: the hex codes, the font names, the spacing scale and, when you need a whole section, the actual markup. A model that has the numbers does not have to guess them.",[11,15,16],{},"There are four ways to do that. They go from five minutes by hand to nothing at all.",[18,19,21],"h2",{"id":20},"why-the-screenshot-fails","Why the screenshot fails",[11,23,24,25,29,30,33],{},"A screenshot is pixels. The model looks at a heading and estimates 48px. It was 56px. It sees a purple and writes ",[26,27,28],"code",{},"#6366f1",". The brand color was ",[26,31,32],{},"#635bff",". It cannot tell that the page uses a 4px spacing grid, or that the font is a custom typeface and not the system one.",[11,35,36],{},"Asking harder does not help. \"Match the spacing exactly\" is an instruction about information the model was never given.",[11,38,39],{},"Screenshots are still good for one thing: layout. Keep using them for where things go. Stop using them for what the values are.",[18,41,43],{"id":42},"_1-copy-the-computed-styles-from-devtools","1. Copy the computed styles from devtools",[11,45,46],{},"This works on any site, today, with nothing installed. Open the page, open the console, and run:",[48,49,54],"pre",{"className":50,"code":51,"language":52,"meta":53,"style":53},"language-js shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","const el = document.querySelector('main section') // the section you want\nconst pick = ['color', 'backgroundColor', 'fontFamily', 'fontSize', 'fontWeight',\n  'lineHeight', 'letterSpacing', 'padding', 'gap', 'borderRadius', 'boxShadow']\n\nconst rows = [el, ...el.querySelectorAll('h1, h2, p, a, button')].slice(0, 12).map((n) => {\n  const s = getComputedStyle(n)\n  return {\n    tag: n.tagName.toLowerCase(),\n    text: n.textContent.trim().slice(0, 40),\n    ...Object.fromEntries(pick.map(p => [p, s[p]]))\n  }\n})\ncopy(JSON.stringify(rows, null, 2))\n","js","",[26,55,56,102,163,222,229,307,330,339,366,405,450,456,464],{"__ignoreMap":53},[57,58,61,65,69,73,76,79,83,86,89,93,95,98],"span",{"class":59,"line":60},"line",1,[57,62,64],{"class":63},"spNyl","const",[57,66,68],{"class":67},"sTEyZ"," el ",[57,70,72],{"class":71},"sMK4o","=",[57,74,75],{"class":67}," document",[57,77,78],{"class":71},".",[57,80,82],{"class":81},"s2Zo4","querySelector",[57,84,85],{"class":67},"(",[57,87,88],{"class":71},"'",[57,90,92],{"class":91},"sfazB","main section",[57,94,88],{"class":71},[57,96,97],{"class":67},") ",[57,99,101],{"class":100},"sHwdD","// the section you want\n",[57,103,105,107,110,112,115,117,120,122,125,128,131,133,135,137,140,142,144,146,149,151,153,155,158,160],{"class":59,"line":104},2,[57,106,64],{"class":63},[57,108,109],{"class":67}," pick ",[57,111,72],{"class":71},[57,113,114],{"class":67}," [",[57,116,88],{"class":71},[57,118,119],{"class":91},"color",[57,121,88],{"class":71},[57,123,124],{"class":71},",",[57,126,127],{"class":71}," '",[57,129,130],{"class":91},"backgroundColor",[57,132,88],{"class":71},[57,134,124],{"class":71},[57,136,127],{"class":71},[57,138,139],{"class":91},"fontFamily",[57,141,88],{"class":71},[57,143,124],{"class":71},[57,145,127],{"class":71},[57,147,148],{"class":91},"fontSize",[57,150,88],{"class":71},[57,152,124],{"class":71},[57,154,127],{"class":71},[57,156,157],{"class":91},"fontWeight",[57,159,88],{"class":71},[57,161,162],{"class":71},",\n",[57,164,166,169,172,174,176,178,181,183,185,187,190,192,194,196,199,201,203,205,208,210,212,214,217,219],{"class":59,"line":165},3,[57,167,168],{"class":71},"  '",[57,170,171],{"class":91},"lineHeight",[57,173,88],{"class":71},[57,175,124],{"class":71},[57,177,127],{"class":71},[57,179,180],{"class":91},"letterSpacing",[57,182,88],{"class":71},[57,184,124],{"class":71},[57,186,127],{"class":71},[57,188,189],{"class":91},"padding",[57,191,88],{"class":71},[57,193,124],{"class":71},[57,195,127],{"class":71},[57,197,198],{"class":91},"gap",[57,200,88],{"class":71},[57,202,124],{"class":71},[57,204,127],{"class":71},[57,206,207],{"class":91},"borderRadius",[57,209,88],{"class":71},[57,211,124],{"class":71},[57,213,127],{"class":71},[57,215,216],{"class":91},"boxShadow",[57,218,88],{"class":71},[57,220,221],{"class":67},"]\n",[57,223,225],{"class":59,"line":224},4,[57,226,228],{"emptyLinePlaceholder":227},true,"\n",[57,230,232,234,237,239,242,244,247,250,252,255,257,259,262,264,267,269,272,274,278,280,283,286,288,291,293,295,299,301,304],{"class":59,"line":231},5,[57,233,64],{"class":63},[57,235,236],{"class":67}," rows ",[57,238,72],{"class":71},[57,240,241],{"class":67}," [el",[57,243,124],{"class":71},[57,245,246],{"class":71}," ...",[57,248,249],{"class":67},"el",[57,251,78],{"class":71},[57,253,254],{"class":81},"querySelectorAll",[57,256,85],{"class":67},[57,258,88],{"class":71},[57,260,261],{"class":91},"h1, h2, p, a, button",[57,263,88],{"class":71},[57,265,266],{"class":67},")]",[57,268,78],{"class":71},[57,270,271],{"class":81},"slice",[57,273,85],{"class":67},[57,275,277],{"class":276},"sbssI","0",[57,279,124],{"class":71},[57,281,282],{"class":276}," 12",[57,284,285],{"class":67},")",[57,287,78],{"class":71},[57,289,290],{"class":81},"map",[57,292,85],{"class":67},[57,294,85],{"class":71},[57,296,298],{"class":297},"sHdIc","n",[57,300,285],{"class":71},[57,302,303],{"class":63}," =>",[57,305,306],{"class":71}," {\n",[57,308,310,313,316,319,322,325,327],{"class":59,"line":309},6,[57,311,312],{"class":63},"  const",[57,314,315],{"class":67}," s",[57,317,318],{"class":71}," =",[57,320,321],{"class":81}," getComputedStyle",[57,323,85],{"class":324},"swJcz",[57,326,298],{"class":67},[57,328,329],{"class":324},")\n",[57,331,333,337],{"class":59,"line":332},7,[57,334,336],{"class":335},"s7zQu","  return",[57,338,306],{"class":71},[57,340,342,345,348,351,353,356,358,361,364],{"class":59,"line":341},8,[57,343,344],{"class":324},"    tag",[57,346,347],{"class":71},":",[57,349,350],{"class":67}," n",[57,352,78],{"class":71},[57,354,355],{"class":67},"tagName",[57,357,78],{"class":71},[57,359,360],{"class":81},"toLowerCase",[57,362,363],{"class":324},"()",[57,365,162],{"class":71},[57,367,369,372,374,376,378,381,383,386,388,390,392,394,396,398,401,403],{"class":59,"line":368},9,[57,370,371],{"class":324},"    text",[57,373,347],{"class":71},[57,375,350],{"class":67},[57,377,78],{"class":71},[57,379,380],{"class":67},"textContent",[57,382,78],{"class":71},[57,384,385],{"class":81},"trim",[57,387,363],{"class":324},[57,389,78],{"class":71},[57,391,271],{"class":81},[57,393,85],{"class":324},[57,395,277],{"class":276},[57,397,124],{"class":71},[57,399,400],{"class":276}," 40",[57,402,285],{"class":324},[57,404,162],{"class":71},[57,406,408,411,414,416,419,421,424,426,428,430,432,434,436,438,440,442,445,447],{"class":59,"line":407},10,[57,409,410],{"class":71},"    ...",[57,412,413],{"class":67},"Object",[57,415,78],{"class":71},[57,417,418],{"class":81},"fromEntries",[57,420,85],{"class":324},[57,422,423],{"class":67},"pick",[57,425,78],{"class":71},[57,427,290],{"class":81},[57,429,85],{"class":324},[57,431,11],{"class":297},[57,433,303],{"class":63},[57,435,114],{"class":324},[57,437,11],{"class":67},[57,439,124],{"class":71},[57,441,315],{"class":67},[57,443,444],{"class":324},"[",[57,446,11],{"class":67},[57,448,449],{"class":324},"]]))\n",[57,451,453],{"class":59,"line":452},11,[57,454,455],{"class":71},"  }\n",[57,457,459,462],{"class":59,"line":458},12,[57,460,461],{"class":71},"}",[57,463,329],{"class":67},[57,465,467,470,473,475,478,481,483,486,489],{"class":59,"line":466},13,[57,468,469],{"class":81},"copy",[57,471,472],{"class":67},"(JSON",[57,474,78],{"class":71},[57,476,477],{"class":81},"stringify",[57,479,480],{"class":67},"(rows",[57,482,124],{"class":71},[57,484,485],{"class":71}," null,",[57,487,488],{"class":276}," 2",[57,490,491],{"class":67},"))\n",[11,493,494,497],{},[26,495,496],{},"copy()"," is a console helper in Chrome, Edge and Firefox. The JSON is now on your clipboard. Paste it into the chat with:",[48,499,504],{"className":500,"code":502,"language":503,"meta":53},[501],"language-text","Build this section in my project. Use exactly these computed values.\nDo not invent colors, sizes or fonts that are not in the list.\n","text",[26,505,502],{"__ignoreMap":53},[11,507,508],{},"Computed styles are what the browser actually rendered, after every stylesheet and media query, so they are the truth for your screen size. The limit is that they are for one viewport and no hover states. Resize the window and run it again if you need the mobile values.",[18,510,512],{"id":511},"_2-keep-a-tokens-file-in-the-repo","2. Keep a tokens file in the repo",[11,514,515],{},"If you match the same reference more than once, stop pasting. Put the values where the agent reads them on every task:",[48,517,521],{"className":518,"code":519,"language":520,"meta":53,"style":53},"language-md shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003C!-- CLAUDE.md, .cursor/rules, or AGENTS.md -->\n## Design reference: acme.com\n\n- Primary #635bff, text #0a2540, background #ffffff, muted #425466\n- Font: \"Sohne\", system-ui. Weights 400 and 600.\n- Type scale: 14, 16, 20, 32, 56 px\n- Spacing: 4, 8, 16, 24, 48 px. Radius 8 px.\n- Use only these values. Ask before adding a new one.\n","md",[26,522,523,528,537,541,549,556,563,570],{"__ignoreMap":53},[57,524,525],{"class":59,"line":60},[57,526,527],{"class":100},"\u003C!-- CLAUDE.md, .cursor/rules, or AGENTS.md -->\n",[57,529,530,533],{"class":59,"line":104},[57,531,532],{"class":71},"## ",[57,534,536],{"class":535},"sBMFI","Design reference: acme.com\n",[57,538,539],{"class":59,"line":165},[57,540,228],{"emptyLinePlaceholder":227},[57,542,543,546],{"class":59,"line":224},[57,544,545],{"class":71},"-",[57,547,548],{"class":67}," Primary #635bff, text #0a2540, background #ffffff, muted #425466\n",[57,550,551,553],{"class":59,"line":231},[57,552,545],{"class":71},[57,554,555],{"class":67}," Font: \"Sohne\", system-ui. Weights 400 and 600.\n",[57,557,558,560],{"class":59,"line":309},[57,559,545],{"class":71},[57,561,562],{"class":67}," Type scale: 14, 16, 20, 32, 56 px\n",[57,564,565,567],{"class":59,"line":332},[57,566,545],{"class":71},[57,568,569],{"class":67}," Spacing: 4, 8, 16, 24, 48 px. Radius 8 px.\n",[57,571,572,574],{"class":59,"line":341},[57,573,545],{"class":71},[57,575,576],{"class":67}," Use only these values. Ask before adding a new one.\n",[11,578,579],{},"This is the cheapest fix with the largest effect. The agent stops drifting between tasks because the constraints never leave its context.",[18,581,583],{"id":582},"_3-paste-the-sections-markup","3. Paste the section's markup",[11,585,586],{},"For \"rebuild this pricing table\", values are not enough. The agent also needs the structure. In devtools, right-click the section, choose Copy, then Copy outerHTML, and paste that along with the computed styles.",[11,588,589],{},"It is ugly. The markup carries the source site's class names, which mean nothing without its stylesheet, and a real section can be thousands of lines. It still beats a screenshot, because the copy, the nesting and the image URLs are real.",[18,591,593],{"id":592},"_4-let-the-agent-fetch-it-itself","4. Let the agent fetch it itself",[11,595,596],{},"The first three methods all have you in the middle, copying. An MCP server removes you: the agent calls a tool with a URL and gets the values back while it works.",[11,598,599],{},"With one connected you type this:",[48,601,604],{"className":602,"code":603,"language":503,"meta":53},[501],"Match the hero on linear.app. Pull the real design first.\n",[26,605,603],{"__ignoreMap":53},[11,607,608],{},"The agent calls a design extraction tool, receives the section as a component with the resolved colors, fonts and spacing, and writes against that. Setup is a URL in ChatGPT, Claude and Cursor, and one command in Claude Code.",[18,610,612],{"id":611},"the-four-compared","The four, compared",[614,615,616,638],"table",{},[617,618,619],"thead",{},[620,621,622,626,629,632,635],"tr",{},[623,624,625],"th",{},"Method",[623,627,628],{},"Setup",[623,630,631],{},"You copy each time",[623,633,634],{},"Gets structure",[623,636,637],{},"Gets hover and breakpoints",[639,640,641,659,672,686,699],"tbody",{},[620,642,643,647,650,653,656],{},[644,645,646],"td",{},"Screenshot",[644,648,649],{},"None",[644,651,652],{},"Yes",[644,654,655],{},"Roughly",[644,657,658],{},"No",[620,660,661,664,666,668,670],{},[644,662,663],{},"Devtools snippet",[644,665,649],{},[644,667,652],{},[644,669,658],{},[644,671,658],{},[620,673,674,677,680,682,684],{},[644,675,676],{},"Tokens file in the repo",[644,678,679],{},"10 minutes",[644,681,658],{},[644,683,658],{},[644,685,658],{},[620,687,688,691,693,695,697],{},[644,689,690],{},"Pasted outerHTML + styles",[644,692,649],{},[644,694,652],{},[644,696,652],{},[644,698,658],{},[620,700,701,704,707,709,711],{},[644,702,703],{},"MCP server",[644,705,706],{},"2 minutes",[644,708,658],{},[644,710,652],{},[644,712,652],{},[11,714,715],{},"My recommendation: do the tokens file today whatever else you choose. It costs ten minutes and fixes the most common complaint. Add an MCP server when you rebuild sections often enough that copying becomes the slow part.",[18,717,719],{"id":718},"common-problems","Common problems",[11,721,722,726],{},[723,724,725],"strong",{},"The agent still invents a color."," Your list was missing a role, usually the muted text or the border. Add it, and say \"use only these\".",[11,728,729,732],{},[723,730,731],{},"The font is wrong."," The site uses a licensed typeface your project does not have. The agent cannot fix that. Pick the closest font you are allowed to use and put that in the tokens file.",[11,734,735,738],{},[723,736,737],{},"It looks right at desktop and breaks on a phone."," Computed styles are for one width. Give the agent the mobile values too, or the breakpoints.",[11,740,741,744],{},[723,742,743],{},"The page is a JavaScript app and the HTML is nearly empty."," Tools that read the served HTML find little. Copy from devtools after the page has rendered, or use an extractor that runs the page in a browser first.",[18,746,748],{"id":747},"or-use-one-api-call","Or use one API call",[11,750,751,756],{},[752,753,755],"a",{"href":754},"/api","MiroMiro"," is the MCP server from method 4, and the same thing as a REST API. It resolves which CSS rules win for each element of a live page and returns the result as data:",[48,758,762],{"className":759,"code":760,"language":761,"meta":53,"style":53},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","curl \"https://miromiro.app/api/v1/code?url=linear.app&section=hero&framework=jsx\" \\\n  -H \"Authorization: Bearer $MIROMIRO_API_KEY\"\n","bash",[26,763,764,781],{"__ignoreMap":53},[57,765,766,769,772,775,778],{"class":59,"line":60},[57,767,768],{"class":535},"curl",[57,770,771],{"class":71}," \"",[57,773,774],{"class":91},"https://miromiro.app/api/v1/code?url=linear.app&section=hero&framework=jsx",[57,776,777],{"class":71},"\"",[57,779,780],{"class":67}," \\\n",[57,782,783,786,788,791,794],{"class":59,"line":104},[57,784,785],{"class":91},"  -H",[57,787,771],{"class":71},[57,789,790],{"class":91},"Authorization: Bearer ",[57,792,793],{"class":67},"$MIROMIRO_API_KEY",[57,795,796],{"class":71},"\"\n",[11,798,799],{},"You get the section as a React component, the tokens it uses, and its image and font URLs. Other calls return the brand palette, the full token set, or every image and icon on the page.",[11,801,802,803,807,808,807,812,807,816,820,821,825],{},"To connect it to an agent, follow the page for yours: ",[752,804,806],{"href":805},"/api/agents/chatgpt","ChatGPT",", ",[752,809,811],{"href":810},"/api/agents/claude","Claude",[752,813,815],{"href":814},"/api/agents/claude-code","Claude Code",[752,817,819],{"href":818},"/api/agents/codex","Codex"," or ",[752,822,824],{"href":823},"/api/agents/cursor","Cursor",". There is no key to paste. You can start for free, with 300 credits a month and no card.",[11,827,828],{},"It reads public pages only, and complex sections do not always come back clean. Look at what it returned before you trust it.",[18,830,832],{"id":831},"summary","Summary",[11,834,835],{},"Screenshots are for layout. Values have to come from the page. Start with a tokens file in the repo, use the devtools snippet for one-offs, and connect an MCP server once you are copying more than you are building.",[18,837,839],{"id":838},"frequently-asked-questions","Frequently asked questions",[841,842,844],"h3",{"id":843},"why-does-ai-generated-ui-look-almost-right-but-not-quite","Why does AI-generated UI look almost right but not quite?",[11,846,847],{},"Every value was estimated from pixels. A default blue for the brand color, 48px for a 56px heading, a system font for a custom one. Small errors, and a lot of them.",[841,849,851],{"id":850},"is-a-screenshot-ever-enough","Is a screenshot ever enough?",[11,853,854],{},"For layout, yes. For colors, type, spacing and copy, no. Use both: the screenshot for where things go, the values for what they are.",[841,856,858],{"id":857},"can-claude-or-cursor-read-a-live-websites-css","Can Claude or Cursor read a live website's CSS?",[11,860,861],{},"They can fetch the files, but working out which of several thousand rules applies to which element is the hard part. An extraction tool does that and returns the answer.",[841,863,865],{"id":864},"what-should-i-put-in-the-prompt","What should I put in the prompt?",[11,867,868],{},"The values, and the sentence \"use exactly these, do not invent others\". Explicit numbers beat adjectives.",[870,871,872],"style",{},"html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}",{"title":53,"searchDepth":104,"depth":104,"links":874},[875,876,877,878,879,880,881,882,883,884],{"id":20,"depth":104,"text":21},{"id":42,"depth":104,"text":43},{"id":511,"depth":104,"text":512},{"id":582,"depth":104,"text":583},{"id":592,"depth":104,"text":593},{"id":611,"depth":104,"text":612},{"id":718,"depth":104,"text":719},{"id":747,"depth":104,"text":748},{"id":831,"depth":104,"text":832},{"id":838,"depth":104,"text":839,"children":885},[886,887,888,889],{"id":843,"depth":165,"text":844},{"id":850,"depth":165,"text":851},{"id":857,"depth":165,"text":858},{"id":864,"depth":165,"text":865},"AI Engineering","2026-10-12","Why a screenshot gives your AI agent the wrong colors and spacing, and four ways to hand it the real values: a devtools snippet, a tokens file, pasted markup, or an MCP server.",[894,896,898,900],{"question":844,"answer":895},"Because the model estimated every value from pixels. A screenshot does not contain a hex code, a font name or a spacing scale, so the agent picks plausible ones: a default blue for the brand color, 48px for a 56px heading, a system font for a custom typeface. Each error is small. Together they read as a near miss.",{"question":858,"answer":897},"Not on their own in a useful way. Fetching a page returns its HTML and links to stylesheets with thousands of rules, and the agent would have to work out which rules win for which element. A design extraction tool does that resolution and returns the result: the colors, fonts, spacing and the component code for a section.",{"question":851,"answer":899},"Yes, for layout. A screenshot tells the agent what goes where and roughly how big. It is not enough for exact colors, type, spacing or copy. Pair a screenshot with the real values and you get both.",{"question":865,"answer":901},"The values and one instruction: use exactly these, do not invent others. List the colors with their roles, the font families and weights, the type sizes, the spacing steps and the corner radii. Agents follow explicit values far more reliably than adjectives like modern or clean.",null,{},"/api-blog/make-ai-agent-match-a-real-website-design",[906,907,908,909],"connect-miromiro-mcp-claude-cursor-chatgpt","add-design-extraction-to-claude-code-mcp","figma-mcp-setup-and-alternatives","how-to-extract-design-tokens-from-any-website-in-python",{"title":5,"description":892},"Make Claude, Cursor or ChatGPT Match a Real Website's Design","api-blog/make-ai-agent-match-a-real-website-design",[914,915,916,917,918,919,920],"ai agents","claude","cursor","chatgpt","mcp","design tokens","screenshot to code","ggUXN9VMEBMZ2XOx0pM5WH7Jfilae1Y4-sfCSWCIJ-k",[923,1763,2299],{"id":924,"title":925,"author":6,"body":926,"category":890,"date":1737,"dateModified":1738,"description":1739,"extension":520,"faqs":1740,"image":902,"meta":1752,"navigation":227,"path":1753,"readingTime":309,"relatedSlugs":1754,"seo":1756,"seoTitle":1757,"stem":1758,"tags":1759,"__hash__":1762},"apiBlog/api-blog/connect-miromiro-mcp-claude-cursor-chatgpt.md","How to Connect the MiroMiro MCP to Claude, Cursor, ChatGPT and Codex",{"type":8,"value":927,"toc":1718},[928,935,943,947,950,1006,1013,1019,1029,1031,1043,1150,1156,1158,1161,1234,1240,1243,1246,1252,1256,1262,1279,1294,1304,1307,1310,1337,1343,1395,1403,1407,1410,1468,1482,1486,1489,1558,1561,1565,1568,1582,1584,1623,1627,1634,1638,1641,1671,1678,1680,1684,1687,1691,1694,1698,1701,1705,1715],[11,929,930,931,934],{},"Every client that speaks MCP can connect to MiroMiro with one URL. Paste ",[26,932,933],{},"https://miromiro.app/mcp"," into the client's connector settings and nine design-extraction tools appear in your chats: section-to-code, brand, design tokens, images, SVGs, fonts, videos, audio and Lottie.",[11,936,937,938,942],{},"You do not need to paste a key. The bare URL triggers a one-click sign in with your MiroMiro account - ",[752,939,941],{"href":940},"/api/onboarding","free",", 300 credits a month, no card. Client-by-client steps below.",[18,944,946],{"id":945},"claude-web-and-desktop","Claude - web and desktop",[11,948,949],{},"Claude calls these custom connectors. Two ways in:",[951,952,953,972,993,996],"ol",{},[954,955,956,957,960,961,964,965,964,968,971],"li",{},"In any chat, click the ",[723,958,959],{},"+"," button in the input, then ",[723,962,963],{},"Connectors"," → ",[723,966,967],{},"Add connector",[723,969,970],{},"Add custom connector",". (Settings → Connectors gets you to the same dialog.)",[954,973,974,975],{},"In the dialog, fill in:\n",[976,977,978,986],"ul",{},[954,979,980,983,984],{},[723,981,982],{},"Name:"," ",[26,985,755],{},[954,987,988,983,991],{},[723,989,990],{},"URL:",[26,992,933],{},[954,994,995],{},"Leave the OAuth Client ID and Secret fields under Advanced settings empty - Claude discovers them from the server.",[954,997,998,999,1002,1003,78],{},"Click ",[723,1000,1001],{},"Add",". Claude opens the MiroMiro sign-in page; approve it and the tools are live in every chat - ask \"get the brand colors and fonts of stripe.com\" and watch it call ",[26,1004,1005],{},"extract_brand",[11,1007,1008],{},[1009,1010],"img",{"alt":1011,"src":1012},"Claude's + menu: Connectors, then Add connector, then Add custom connector","/api-blog/connector1.png",[11,1014,1015],{},[1009,1016],{"alt":1017,"src":1018},"Claude's Add custom connector dialog with the MiroMiro name and URL filled in","/api-blog/connector2.png",[11,1020,1021,1022,1028],{},"One click faster: ",[752,1023,1027],{"href":1024,"rel":1025},"https://claude.ai/customize/connectors?modal=add-custom-connector&connectorName=MiroMiro&connectorUrl=https%3A%2F%2Fmiromiro.app%2Fmcp",[1026],"nofollow","Add MiroMiro to Claude"," opens this dialog with the name and URL pre-filled - you just click Add and sign in.",[18,1030,824],{"id":916},[11,1032,1033,1034,1039,1040,347],{},"Cursor supports install deeplinks, so ",[752,1035,1038],{"href":1036,"rel":1037},"https://cursor.com/install-mcp?name=miromiro&config=eyJ1cmwiOiJodHRwczovL21pcm9taXJvLmFwcC9tY3AifQ%3D%3D",[1026],"Add MiroMiro to Cursor"," does the whole thing in one click - it opens Cursor with the server config pre-filled. Manual version, in ",[26,1041,1042],{},"~/.cursor/mcp.json",[48,1044,1048],{"className":1045,"code":1046,"language":1047,"meta":53,"style":53},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"mcpServers\": {\n    \"miromiro\": {\n      \"url\": \"https://miromiro.app/mcp\",\n      \"headers\": { \"Authorization\": \"Bearer mm_live_your_key\" }\n    }\n  }\n}\n","json",[26,1049,1050,1055,1069,1083,1103,1136,1141,1145],{"__ignoreMap":53},[57,1051,1052],{"class":59,"line":60},[57,1053,1054],{"class":71},"{\n",[57,1056,1057,1060,1063,1065,1067],{"class":59,"line":104},[57,1058,1059],{"class":71},"  \"",[57,1061,1062],{"class":63},"mcpServers",[57,1064,777],{"class":71},[57,1066,347],{"class":71},[57,1068,306],{"class":71},[57,1070,1071,1074,1077,1079,1081],{"class":59,"line":165},[57,1072,1073],{"class":71},"    \"",[57,1075,1076],{"class":535},"miromiro",[57,1078,777],{"class":71},[57,1080,347],{"class":71},[57,1082,306],{"class":71},[57,1084,1085,1088,1091,1093,1095,1097,1099,1101],{"class":59,"line":224},[57,1086,1087],{"class":71},"      \"",[57,1089,1090],{"class":276},"url",[57,1092,777],{"class":71},[57,1094,347],{"class":71},[57,1096,771],{"class":71},[57,1098,933],{"class":91},[57,1100,777],{"class":71},[57,1102,162],{"class":71},[57,1104,1105,1107,1110,1112,1114,1117,1119,1122,1124,1126,1128,1131,1133],{"class":59,"line":231},[57,1106,1087],{"class":71},[57,1108,1109],{"class":276},"headers",[57,1111,777],{"class":71},[57,1113,347],{"class":71},[57,1115,1116],{"class":71}," {",[57,1118,771],{"class":71},[57,1120,1121],{"class":324},"Authorization",[57,1123,777],{"class":71},[57,1125,347],{"class":71},[57,1127,771],{"class":71},[57,1129,1130],{"class":91},"Bearer mm_live_your_key",[57,1132,777],{"class":71},[57,1134,1135],{"class":71}," }\n",[57,1137,1138],{"class":59,"line":309},[57,1139,1140],{"class":71},"    }\n",[57,1142,1143],{"class":59,"line":332},[57,1144,455],{"class":71},[57,1146,1147],{"class":59,"line":341},[57,1148,1149],{"class":71},"}\n",[11,1151,1152,1153,1155],{},"Drop the ",[26,1154,1109],{}," line and Cursor prompts you to sign in instead - either works. If you do use a key, the header keeps it out of logs. Restart Cursor and check the MCP panel for the nine tools.",[18,1157,806],{"id":917},[11,1159,1160],{},"ChatGPT only takes remote servers, which is exactly what this is:",[951,1162,1163,1175,1221],{},[954,1164,1165,964,1168,1171,1172],{},[723,1166,1167],{},"Settings",[723,1169,1170],{},"Security and login"," → enable ",[723,1173,1174],{},"Developer mode",[954,1176,1177,964,1179,1182,1183,1188,1189,1192,1193],{},[723,1178,1167],{},[723,1180,1181],{},"Plugins"," (or go straight to ",[752,1184,1187],{"href":1185,"rel":1186},"https://chatgpt.com/plugins",[1026],"chatgpt.com/plugins",") → ",[723,1190,1191],{},"New Plugin",":\n",[976,1194,1195,1201,1209,1215],{},[954,1196,1197,983,1199],{},[723,1198,982],{},[26,1200,755],{},[954,1202,1203,1206,1207],{},[723,1204,1205],{},"Connection:"," Server URL, ",[26,1208,933],{},[954,1210,1211,1214],{},[723,1212,1213],{},"Authentication:"," OAuth - ChatGPT reads the sign-in settings from the server, so there is nothing to configure",[954,1216,1217,1218],{},"Tick the custom-server acknowledgment and click ",[723,1219,1220],{},"Create",[954,1222,1223,1224,1227,1228,1230,1231,78],{},"ChatGPT shows a consent card. Click ",[723,1225,1226],{},"Sign in with MiroMiro",", approve, and the tools appear in any chat via the ",[723,1229,959],{}," menu → ",[723,1232,1233],{},"More",[11,1235,1236],{},[1009,1237],{"alt":1238,"src":1239},"ChatGPT's Add MiroMiro to ChatGPT consent screen with the Sign in with MiroMiro button","/api-blog/chatgpt-consent.png",[11,1241,1242],{},"OpenAI has renamed this area twice recently - if your build still says Apps & Connectors, the Developer mode toggle lives under Advanced there instead.",[11,1244,1245],{},"Prefer to delegate? Paste this prompt into the assistant and let it do the guiding - ChatGPT walks you through its own settings, and Codex installs the server for real:",[48,1247,1250],{"className":1248,"code":1249,"language":503,"meta":53},[501],"Add the MiroMiro MCP server to this client.\n\nServer name: miromiro\nServer URL:  https://miromiro.app/mcp\nTransport:   Streamable HTTP (stateless JSON responses)\nAuth:        OAuth (auto-discovered). On first connect you'll be asked to sign in to MiroMiro - a free account includes 300 credits/month, no card. API keys also work: append ?access_key=mm_live_YOUR_KEY or send \"Authorization: Bearer\".\n\nIf you are ChatGPT: Settings → Security and login → enable Developer mode, then Settings → Plugins (chatgpt.com/plugins) → New Plugin with the URL above (authentication: OAuth).\nIf you are Codex CLI: add to ~/.codex/config.toml:\n[mcp_servers.miromiro]\nurl = \"https://miromiro.app/mcp\"\nThen run: codex mcp login miromiro (signs in through the browser).\n\nThen list the tools - you should see extract_code, extract_brand, extract_design_tokens, extract_assets, extract_svgs, extract_fonts, extract_videos, extract_audio and extract_lottie.\n",[26,1251,1249],{"__ignoreMap":53},[18,1253,1255],{"id":1254},"codex-cli","Codex CLI",[11,1257,1258,1259,347],{},"Add to ",[26,1260,1261],{},"~/.codex/config.toml",[48,1263,1267],{"className":1264,"code":1265,"language":1266,"meta":53,"style":53},"language-toml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","[mcp_servers.miromiro]\nurl = \"https://miromiro.app/mcp\"\n","toml",[26,1268,1269,1274],{"__ignoreMap":53},[57,1270,1271],{"class":59,"line":60},[57,1272,1273],{},"[mcp_servers.miromiro]\n",[57,1275,1276],{"class":59,"line":104},[57,1277,1278],{},"url = \"https://miromiro.app/mcp\"\n",[11,1280,1281,1282,1285,1286,1289,1290,1293],{},"Then sign in once: run ",[26,1283,1284],{},"codex mcp login miromiro"," and approve in the browser. ",[26,1287,1288],{},"codex mcp list",", or ",[26,1291,1292],{},"/mcp"," inside Codex, shows it connected. The command line and the IDE extension share this file.",[11,1295,1296,1297,1300,1301,78],{},"To pin a key instead, add ",[26,1298,1299],{},"bearer_token_env_var = \"MIROMIRO_API_KEY\""," under the URL and set that environment variable, or use ",[26,1302,1303],{},"url = \"https://miromiro.app/mcp?access_key=mm_live_your_key\"",[18,1305,815],{"id":1306},"claude-code",[11,1308,1309],{},"One command in your terminal, not inside a session:",[48,1311,1313],{"className":759,"code":1312,"language":761,"meta":53,"style":53},"claude mcp add --transport http miromiro https://miromiro.app/mcp\n",[26,1314,1315],{"__ignoreMap":53},[57,1316,1317,1319,1322,1325,1328,1331,1334],{"class":59,"line":60},[57,1318,915],{"class":535},[57,1320,1321],{"class":91}," mcp",[57,1323,1324],{"class":91}," add",[57,1326,1327],{"class":91}," --transport",[57,1329,1330],{"class":91}," http",[57,1332,1333],{"class":91}," miromiro",[57,1335,1336],{"class":91}," https://miromiro.app/mcp\n",[11,1338,1339,1340,1342],{},"Then run ",[26,1341,1292],{}," inside a session to sign in - Claude Code opens the browser consent page once and stores the token. If you'd rather skip the browser, pass the key directly:",[48,1344,1346],{"className":759,"code":1345,"language":761,"meta":53,"style":53},"claude mcp add --transport http miromiro https://miromiro.app/mcp \\\n  --header \"Authorization: Bearer mm_live_your_key\"\n\nclaude mcp list   # look for \"✓ Connected\"\n",[26,1347,1348,1367,1379,1383],{"__ignoreMap":53},[57,1349,1350,1352,1354,1356,1358,1360,1362,1365],{"class":59,"line":60},[57,1351,915],{"class":535},[57,1353,1321],{"class":91},[57,1355,1324],{"class":91},[57,1357,1327],{"class":91},[57,1359,1330],{"class":91},[57,1361,1333],{"class":91},[57,1363,1364],{"class":91}," https://miromiro.app/mcp",[57,1366,780],{"class":67},[57,1368,1369,1372,1374,1377],{"class":59,"line":104},[57,1370,1371],{"class":91},"  --header",[57,1373,771],{"class":71},[57,1375,1376],{"class":91},"Authorization: Bearer mm_live_your_key",[57,1378,796],{"class":71},[57,1380,1381],{"class":59,"line":165},[57,1382,228],{"emptyLinePlaceholder":227},[57,1384,1385,1387,1389,1392],{"class":59,"line":224},[57,1386,915],{"class":535},[57,1388,1321],{"class":91},[57,1390,1391],{"class":91}," list",[57,1393,1394],{"class":100},"   # look for \"✓ Connected\"\n",[11,1396,1397,1398,1402],{},"Claude Code also runs the ",[752,1399,1401],{"href":1400},"/api/blog/add-design-extraction-to-claude-code-mcp","local npm package"," if you prefer the key in an env var instead of a header.",[18,1404,1406],{"id":1405},"grok-bot-muse-and-openai-dots","Grok Bot, Muse and OpenAI dots",[11,1408,1409],{},"The newer agents take the same URL, each in its own way:",[976,1411,1412,1438,1458],{},[954,1413,1414,1417,1418,1421,1422,1425,1426,964,1428,964,1430,1433,1434],{},[723,1415,1416],{},"Grok Bot"," has no field for a server URL in its settings. Ask the bot instead: \"Add a custom MCP server called miromiro at ",[752,1419,933],{"href":933,"rel":1420},[1026],"\". Confirm, press ",[723,1423,1424],{},"Authorize"," on the card it posts and sign in. It then shows under ",[723,1427,1167],{},[723,1429,1181],{},[723,1431,1432],{},"Yours",". Grok Bot runs on a cloud computer, so servers from your Cursor settings do not carry over. ",[752,1435,1437],{"href":1436},"/api/agents/grok-bot","Grok Bot steps",[954,1439,1440,1443,1444,1446,1447,964,1449,964,1451,1453,1454],{},[723,1441,1442],{},"Muse",": ask it in a chat to add a custom connector for ",[26,1445,933],{}," (remote streamable HTTP, OAuth), then approve the sign-in it opens. Some accounts also have ",[723,1448,1167],{},[723,1450,963],{},[723,1452,970],{},", which takes the same URL. ",[752,1455,1457],{"href":1456},"/api/agents/muse","Muse steps",[954,1459,1460,1463,1464],{},[723,1461,1462],{},"OpenAI dots"," use the plugins switched on in your ChatGPT account, so the setup is the ChatGPT one above. Start with one small request to see it working. ",[752,1465,1467],{"href":1466},"/api/agents/openai-dots","Dots steps",[11,1469,1470,1471,807,1473,807,1475,807,1477,1479,1480,78],{},"Each agent also has its own page with the steps drawn out: ",[752,1472,806],{"href":805},[752,1474,811],{"href":810},[752,1476,815],{"href":814},[752,1478,819],{"href":818}," and ",[752,1481,824],{"href":823},[18,1483,1485],{"id":1484},"sign-in-vs-pasting-a-key","Sign-in vs pasting a key",[11,1487,1488],{},"Both end up in the same place: signing in links your account and provisions a free API key behind the scenes, so the tiers are identical either way.",[614,1490,1491,1503],{},[617,1492,1493],{},[620,1494,1495,1497,1500],{},[623,1496],{},[623,1498,1499],{},"Free account",[623,1501,1502],{},"Paid plans",[639,1504,1505,1515,1526,1537,1547],{},[620,1506,1507,1510,1513],{},[644,1508,1509],{},"Results",[644,1511,1512],{},"Full",[644,1514,1512],{},[620,1516,1517,1520,1523],{},[644,1518,1519],{},"Rate limit",[644,1521,1522],{},"30/min",[644,1524,1525],{},"60 to 300/min",[620,1527,1528,1531,1534],{},[644,1529,1530],{},"Credits",[644,1532,1533],{},"300/month",[644,1535,1536],{},"5,000 to 200,000/month",[620,1538,1539,1542,1545],{},[644,1540,1541],{},"Usage and logs",[644,1543,1544],{},"Dashboard",[644,1546,1544],{},[620,1548,1549,1552,1555],{},[644,1550,1551],{},"Price",[644,1553,1554],{},"Free, no card",[644,1556,1557],{},"From €19/month",[11,1559,1560],{},"Sign-in is the better default: no key to store, tokens expire and refresh on their own, and revoking the connector kills access without touching your other keys. Paste a key only where a client cannot run the sign-in flow.",[18,1562,1564],{"id":1563},"what-to-ask-once-connected","What to ask once connected",[11,1566,1567],{},"You never name tools in prompts - ask design-shaped questions and the agent picks the right one:",[976,1569,1570,1573,1576,1579],{},[954,1571,1572],{},"\"Rebuild stripe.com's pricing section in React\"",[954,1574,1575],{},"\"Extract linear.app's design tokens and restyle our Button component to match\"",[954,1577,1578],{},"\"What fonts does vercel.com actually load?\"",[954,1580,1581],{},"\"Pull the brand palette from ourcustomer.com and generate a theme file\"",[18,1583,719],{"id":718},[976,1585,1586,1597,1603,1613],{},[954,1587,1588,1591,1592,1596],{},[723,1589,1590],{},"\"Invalid or revoked API key\" in the tool result."," The key in your URL or header is wrong or was rotated. Grab the current one from ",[752,1593,1595],{"href":1594},"/api/dashboard/keys","API Keys"," - keys are shown once at creation, so rotate if you lost it.",[954,1598,1599,1602],{},[723,1600,1601],{},"The client keeps asking you to sign in."," Remove the connector and add it again - a stale token from a revoked link is the usual cause. Tokens normally refresh on their own for 180 days.",[954,1604,1605,1608,1609,1612],{},[723,1606,1607],{},"Thin results on an app-like site."," The engine reads static HTML and CSS by default, so a fully client-rendered app returns little - and the tools say so instead of inventing values. The fix is one argument: ",[26,1610,1611],{},"render: true"," loads the page in a real browser and runs its JavaScript before extracting (+5 credits). The thin response includes a hint telling the agent exactly that.",[954,1614,1615,1618,1619,1622],{},[723,1616,1617],{},"Claude web has no header field."," Correct - claude.ai custom connectors cannot send custom headers. You do not need one: the sign-in flow handles auth, and ",[26,1620,1621],{},"?access_key="," still works if you prefer a pinned key.",[18,1624,1626],{"id":1625},"already-using-the-figma-mcp","Already using the Figma MCP?",[11,1628,1629,1630,78],{},"Keep it. Figma's server reads your own design files; MiroMiro reads live websites. They are both remote URLs and work side by side in the same client - the comparison and the Figma setup steps are in ",[752,1631,1633],{"href":1632},"/api/blog/figma-mcp-setup-and-alternatives","Figma MCP: setup and what to use without a Figma file",[18,1635,1637],{"id":1636},"or-skip-mcp-entirely","Or skip MCP entirely",[11,1639,1640],{},"The same engine is a plain REST API:",[48,1642,1644],{"className":759,"code":1643,"language":761,"meta":53,"style":53},"curl \"https://miromiro.app/api/v1/brand?url=stripe.com\" \\\n  -H \"Authorization: Bearer $MIROMIRO_API_KEY\"\n",[26,1645,1646,1659],{"__ignoreMap":53},[57,1647,1648,1650,1652,1655,1657],{"class":59,"line":60},[57,1649,768],{"class":535},[57,1651,771],{"class":71},[57,1653,1654],{"class":91},"https://miromiro.app/api/v1/brand?url=stripe.com",[57,1656,777],{"class":71},[57,1658,780],{"class":67},[57,1660,1661,1663,1665,1667,1669],{"class":59,"line":104},[57,1662,785],{"class":91},[57,1664,771],{"class":71},[57,1666,790],{"class":91},[57,1668,793],{"class":67},[57,1670,796],{"class":71},[11,1672,1673,1674,1677],{},"Full reference at ",[752,1675,1676],{"href":1676},"/api/docs",". You can start for free.",[18,1679,839],{"id":838},[841,1681,1683],{"id":1682},"how-do-i-add-a-custom-mcp-connector-to-claude-web","How do I add a custom MCP connector to Claude web?",[11,1685,1686],{},"The + button in the chat input → Connectors → Add connector → Add custom connector. Name it, paste the URL, click Add, then approve the MiroMiro sign-in page it opens.",[841,1688,1690],{"id":1689},"do-i-need-a-key-to-try-it","Do I need a key to try it?",[11,1692,1693],{},"No. Paste the bare URL and sign in with a MiroMiro account when prompted - free, 300 credits a month, no card. Keys are the fallback for clients that cannot run the sign-in flow.",[841,1695,1697],{"id":1696},"which-clients-does-the-remote-server-work-with","Which clients does the remote server work with?",[11,1699,1700],{},"Claude web and desktop, Cursor, ChatGPT developer mode, Codex, Claude Code, Grok Bot, Muse, Windsurf, and any MCP SDK. If it takes a server URL, it works.",[841,1702,1704],{"id":1703},"where-does-my-key-go-safest","Where does my key go safest?",[11,1706,1707,1708,1711,1712,1714],{},"Header (",[26,1709,1710],{},"Authorization: Bearer",") where the client supports it - Cursor, Claude Code, SDKs. URL (",[26,1713,1621],{},") only where headers are not an option - claude.ai, ChatGPT. Rotate keys anytime in the dashboard.",[870,1716,1717],{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":53,"searchDepth":104,"depth":104,"links":1719},[1720,1721,1722,1723,1724,1725,1726,1727,1728,1729,1730,1731],{"id":945,"depth":104,"text":946},{"id":916,"depth":104,"text":824},{"id":917,"depth":104,"text":806},{"id":1254,"depth":104,"text":1255},{"id":1306,"depth":104,"text":815},{"id":1405,"depth":104,"text":1406},{"id":1484,"depth":104,"text":1485},{"id":1563,"depth":104,"text":1564},{"id":718,"depth":104,"text":719},{"id":1625,"depth":104,"text":1626},{"id":1636,"depth":104,"text":1637},{"id":838,"depth":104,"text":839,"children":1732},[1733,1734,1735,1736],{"id":1682,"depth":165,"text":1683},{"id":1689,"depth":165,"text":1690},{"id":1696,"depth":165,"text":1697},{"id":1703,"depth":165,"text":1704},"2026-07-20","2026-07-23","Step-by-step connector setup for every client: paste one URL into Claude web, one-click install in Cursor, developer mode in ChatGPT, one command in Claude Code. Sign in with your MiroMiro account, no key pasting.",[1741,1743,1746,1749],{"question":1683,"answer":1742},"Click the + button in the chat input, choose Connectors, then Add connector and Add custom connector. Name it, paste the server URL (for MiroMiro: https://miromiro.app/mcp), and click Add. Claude then opens a MiroMiro sign-in page; approve it and the tools are live. Leave the OAuth Client ID and Secret fields empty - discovery fills them in.",{"question":1744,"answer":1745},"Do I need an API key to use the MiroMiro MCP?","No. Paste the bare URL https://miromiro.app/mcp and the client prompts you to sign in with a MiroMiro account (free, 300 credits a month, no card). Pasting a key still works: send it as an Authorization: Bearer header, or append ?access_key=mm_live_your_key in clients without header support.",{"question":1747,"answer":1748},"How do I connect an MCP server to ChatGPT?","Settings, then Security and login, then enable Developer mode. Open Settings, then Plugins (chatgpt.com/plugins), create a New Plugin with the MCP server URL and Authentication set to OAuth, and sign in when prompted. ChatGPT requires remote (URL-based) servers - it cannot run local stdio packages.",{"question":1750,"answer":1751},"What is the difference between the remote MCP server and the npm package?","Same nine tools. The remote server (https://miromiro.app/mcp) is a hosted URL - nothing to install, works in browser clients like claude.ai and ChatGPT. The npm package (npx miromiro-mcp) runs locally and reads the key from an env var, which keeps it out of any URL.",{},"/api-blog/connect-miromiro-mcp-claude-cursor-chatgpt",[908,907,909,1755],"best-design-to-code-apis-2026",{"title":925,"description":1739},"Connect the MiroMiro MCP to Claude, Cursor, ChatGPT & Codex","api-blog/connect-miromiro-mcp-claude-cursor-chatgpt",[918,915,916,917,1760,1761,914],"codex","connectors","q5YZP-NEp3SpYRPWTI4lt7wrnktpj82H4ERiji1SN0Y",{"id":1764,"title":1765,"author":6,"body":1766,"category":890,"date":2276,"dateModified":902,"description":2277,"extension":520,"faqs":2278,"image":902,"meta":2290,"navigation":227,"path":2291,"readingTime":231,"relatedSlugs":2292,"seo":2294,"seoTitle":902,"stem":2295,"tags":2296,"__hash__":2298},"apiBlog/api-blog/add-design-extraction-to-claude-code-mcp.md","Add Design Extraction to Claude Code with MCP",{"type":8,"value":1767,"toc":2260},[1768,1771,1832,1835,1845,1849,1852,1859,1863,1873,1877,1888,1927,1937,1941,1977,1980,1989,1993,1999,2125,2131,2135,2168,2172,2177,2179,2182,2212,2218,2220,2224,2233,2237,2240,2244,2247,2251,2257],[11,1769,1770],{},"Two commands and Claude Code can read any website's design system instead of guessing it from a screenshot. Here is the whole setup:",[48,1772,1774],{"className":759,"code":1773,"language":761,"meta":53,"style":53},"claude mcp add miromiro -s user \\\n  --env MIROMIRO_API_KEY=mm_live_your_key \\\n  -- npx -y miromiro-mcp\n\nclaude mcp list   # look for \"✓ Connected\"\n",[26,1775,1776,1794,1804,1818,1822],{"__ignoreMap":53},[57,1777,1778,1780,1782,1784,1786,1789,1792],{"class":59,"line":60},[57,1779,915],{"class":535},[57,1781,1321],{"class":91},[57,1783,1324],{"class":91},[57,1785,1333],{"class":91},[57,1787,1788],{"class":91}," -s",[57,1790,1791],{"class":91}," user",[57,1793,780],{"class":67},[57,1795,1796,1799,1802],{"class":59,"line":104},[57,1797,1798],{"class":91},"  --env",[57,1800,1801],{"class":91}," MIROMIRO_API_KEY=mm_live_your_key",[57,1803,780],{"class":67},[57,1805,1806,1809,1812,1815],{"class":59,"line":165},[57,1807,1808],{"class":91},"  --",[57,1810,1811],{"class":91}," npx",[57,1813,1814],{"class":91}," -y",[57,1816,1817],{"class":91}," miromiro-mcp\n",[57,1819,1820],{"class":59,"line":224},[57,1821,228],{"emptyLinePlaceholder":227},[57,1823,1824,1826,1828,1830],{"class":59,"line":231},[57,1825,915],{"class":535},[57,1827,1321],{"class":91},[57,1829,1391],{"class":91},[57,1831,1394],{"class":100},[11,1833,1834],{},"That is genuinely it. The rest of this post is what those commands do, the Cursor/Windsurf versions, and how to actually use it in a session.",[11,1836,1837,1838,1840,1841,78],{},"No terminal, or you use Claude in the browser? There is also a hosted server - paste ",[26,1839,933],{}," into any client that takes a URL. Full walkthrough for Claude web, Cursor, ChatGPT and Codex in ",[752,1842,1844],{"href":1843},"/api/blog/connect-miromiro-mcp-claude-cursor-chatgpt","how to connect the MiroMiro MCP",[18,1846,1848],{"id":1847},"why-bother","Why bother",[11,1850,1851],{},"Ask a coding agent to \"make it look like stripe.com\" and it works from a screenshot at best, memory at worst. Either way it guesses: colors eyeballed from pixels, spacing approximated, fonts invented. The output is a plausible imitation with none of the real values.",[11,1853,1854,1855,78],{},"With the MCP server connected, the agent stops guessing. It calls the extraction tools itself, gets the site's actual ranked palette, type scale, spacing, and shadows as data, and builds with those. Same prompt, real values. We wrote more about this gap in ",[752,1856,1858],{"href":1857},"/api/use-cases/ai-agent-ground-truth","ground truth for AI agents",[18,1860,1862],{"id":1861},"step-1-get-a-key","Step 1: get a key",[11,1864,1865,1866,1869,1870,78],{},"Sign in and mint one at ",[752,1867,1868],{"href":1594},"miromiro.app/api/dashboard/keys",". 300 free credits a month, no card. Keys look like ",[26,1871,1872],{},"mm_live_...",[18,1874,1876],{"id":1875},"step-2-add-the-server","Step 2: add the server",[11,1878,1879,1880,1883,1884,1887],{},"The server is a local stdio process (",[26,1881,1882],{},"npx miromiro-mcp",") that reads your key from ",[26,1885,1886],{},"MIROMIRO_API_KEY",". Run this in your terminal - not inside a Claude session; you are configuring the server before the conversation starts:",[48,1889,1891],{"className":759,"code":1890,"language":761,"meta":53,"style":53},"claude mcp add miromiro -s user \\\n  --env MIROMIRO_API_KEY=mm_live_your_key \\\n  -- npx -y miromiro-mcp\n",[26,1892,1893,1909,1917],{"__ignoreMap":53},[57,1894,1895,1897,1899,1901,1903,1905,1907],{"class":59,"line":60},[57,1896,915],{"class":535},[57,1898,1321],{"class":91},[57,1900,1324],{"class":91},[57,1902,1333],{"class":91},[57,1904,1788],{"class":91},[57,1906,1791],{"class":91},[57,1908,780],{"class":67},[57,1910,1911,1913,1915],{"class":59,"line":104},[57,1912,1798],{"class":91},[57,1914,1801],{"class":91},[57,1916,780],{"class":67},[57,1918,1919,1921,1923,1925],{"class":59,"line":165},[57,1920,1808],{"class":91},[57,1922,1811],{"class":91},[57,1924,1814],{"class":91},[57,1926,1817],{"class":91},[11,1928,1929,1932,1933,1936],{},[26,1930,1931],{},"-s user"," registers it for every project; drop it to scope to the current one. The ",[26,1934,1935],{},"-y"," matters: it lets npx start the package unattended, so the editor can spawn the server without an install prompt.",[18,1938,1940],{"id":1939},"step-3-verify-and-use-it","Step 3: verify and use it",[48,1942,1944],{"className":759,"code":1943,"language":761,"meta":53,"style":53},"claude mcp list\n# miromiro ... ✓ Connected\n\nclaude\n> Use the miromiro server to get the brand colors and fonts of stripe.com\n",[26,1945,1946,1955,1960,1964,1969],{"__ignoreMap":53},[57,1947,1948,1950,1952],{"class":59,"line":60},[57,1949,915],{"class":535},[57,1951,1321],{"class":91},[57,1953,1954],{"class":91}," list\n",[57,1956,1957],{"class":59,"line":104},[57,1958,1959],{"class":100},"# miromiro ... ✓ Connected\n",[57,1961,1962],{"class":59,"line":165},[57,1963,228],{"emptyLinePlaceholder":227},[57,1965,1966],{"class":59,"line":224},[57,1967,1968],{"class":535},"claude\n",[57,1970,1971,1974],{"class":59,"line":231},[57,1972,1973],{"class":71},">",[57,1975,1976],{"class":67}," Use the miromiro server to get the brand colors and fonts of stripe.com\n",[11,1978,1979],{},"All seven extraction tools appear in Claude's toolbox automatically: design tokens, brand, images, SVGs, fonts, Lottie, and section-to-code. You do not name tools in prompts - ask design-shaped questions and the agent picks the right one. Prompts that work well:",[976,1981,1982,1984,1987],{},[954,1983,1575],{},[954,1985,1986],{},"\"Get vercel.com's hero section as Tailwind and adapt it for our landing page\"",[954,1988,1581],{},[18,1990,1992],{"id":1991},"cursor-and-windsurf","Cursor and Windsurf",[11,1994,1995,1996,1998],{},"Both take the standard ",[26,1997,1062],{}," JSON block:",[48,2000,2002],{"className":1045,"code":2001,"language":1047,"meta":53,"style":53},"{\n  \"mcpServers\": {\n    \"miromiro\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"miromiro-mcp\"],\n      \"env\": { \"MIROMIRO_API_KEY\": \"mm_live_your_key\" }\n    }\n  }\n}\n",[26,2003,2004,2008,2020,2032,2052,2083,2113,2117,2121],{"__ignoreMap":53},[57,2005,2006],{"class":59,"line":60},[57,2007,1054],{"class":71},[57,2009,2010,2012,2014,2016,2018],{"class":59,"line":104},[57,2011,1059],{"class":71},[57,2013,1062],{"class":63},[57,2015,777],{"class":71},[57,2017,347],{"class":71},[57,2019,306],{"class":71},[57,2021,2022,2024,2026,2028,2030],{"class":59,"line":165},[57,2023,1073],{"class":71},[57,2025,1076],{"class":535},[57,2027,777],{"class":71},[57,2029,347],{"class":71},[57,2031,306],{"class":71},[57,2033,2034,2036,2039,2041,2043,2045,2048,2050],{"class":59,"line":224},[57,2035,1087],{"class":71},[57,2037,2038],{"class":276},"command",[57,2040,777],{"class":71},[57,2042,347],{"class":71},[57,2044,771],{"class":71},[57,2046,2047],{"class":91},"npx",[57,2049,777],{"class":71},[57,2051,162],{"class":71},[57,2053,2054,2056,2059,2061,2063,2065,2067,2069,2071,2073,2075,2078,2080],{"class":59,"line":231},[57,2055,1087],{"class":71},[57,2057,2058],{"class":276},"args",[57,2060,777],{"class":71},[57,2062,347],{"class":71},[57,2064,114],{"class":71},[57,2066,777],{"class":71},[57,2068,1935],{"class":91},[57,2070,777],{"class":71},[57,2072,124],{"class":71},[57,2074,771],{"class":71},[57,2076,2077],{"class":91},"miromiro-mcp",[57,2079,777],{"class":71},[57,2081,2082],{"class":71},"],\n",[57,2084,2085,2087,2090,2092,2094,2096,2098,2100,2102,2104,2106,2109,2111],{"class":59,"line":309},[57,2086,1087],{"class":71},[57,2088,2089],{"class":276},"env",[57,2091,777],{"class":71},[57,2093,347],{"class":71},[57,2095,1116],{"class":71},[57,2097,771],{"class":71},[57,2099,1886],{"class":324},[57,2101,777],{"class":71},[57,2103,347],{"class":71},[57,2105,771],{"class":71},[57,2107,2108],{"class":91},"mm_live_your_key",[57,2110,777],{"class":71},[57,2112,1135],{"class":71},[57,2114,2115],{"class":59,"line":332},[57,2116,1140],{"class":71},[57,2118,2119],{"class":59,"line":341},[57,2120,455],{"class":71},[57,2122,2123],{"class":59,"line":368},[57,2124,1149],{"class":71},[11,2126,2127,2128,2130],{},"Cursor: ",[26,2129,1042],{},". Windsurf: Settings → MCP. Restart the editor after saving; both show the server's tools in their MCP panel when connected.",[18,2132,2134],{"id":2133},"things-worth-knowing","Things worth knowing",[976,2136,2137,2146,2152],{},[954,2138,2139,2142,2143,2145],{},[723,2140,2141],{},"It reads static HTML + CSS by default."," A fully client-rendered app can return little that way - and the tools say so rather than inventing a result, which is the behavior you want in an agent pipeline. When that happens, pass ",[26,2144,1611],{}," on any tool: the page loads in a real browser and its JavaScript runs before extraction (+5 credits). The response even includes a hint telling the agent to do exactly that.",[954,2147,2148,2151],{},[723,2149,2150],{},"Credits:"," a token extraction or a brand lookup is 10 credits, section-to-code 25. The free 300/month covers real experimentation; the agent sees remaining quota in each response's usage object.",[954,2153,2154,2157,2158,2161,2162,2165,2166,78],{},[723,2155,2156],{},"Server not connecting?"," It is almost always the key: check ",[26,2159,2160],{},"claude mcp list",", and confirm the env var made it in (",[26,2163,2164],{},"claude mcp get miromiro","). Node 18+ is required for ",[26,2167,2047],{},[18,2169,2171],{"id":2170},"using-it-alongside-the-figma-mcp","Using it alongside the Figma MCP",[11,2173,2174,2175,78],{},"If your team also designs in Figma, run both: Figma's server for the screens you designed, this one for the live sites you reference or migrate from. Claude Code picks the right tool from the prompt. Setup for the Figma side is in ",[752,2176,1633],{"href":1632},[18,2178,1637],{"id":1636},[11,2180,2181],{},"The same engine is a plain REST API if your agent framework speaks HTTP instead:",[48,2183,2185],{"className":759,"code":2184,"language":761,"meta":53,"style":53},"curl \"https://miromiro.app/api/v1/extract?url=stripe.com\" \\\n  -H \"Authorization: Bearer $MIROMIRO_API_KEY\"\n",[26,2186,2187,2200],{"__ignoreMap":53},[57,2188,2189,2191,2193,2196,2198],{"class":59,"line":60},[57,2190,768],{"class":535},[57,2192,771],{"class":71},[57,2194,2195],{"class":91},"https://miromiro.app/api/v1/extract?url=stripe.com",[57,2197,777],{"class":71},[57,2199,780],{"class":67},[57,2201,2202,2204,2206,2208,2210],{"class":59,"line":104},[57,2203,785],{"class":91},[57,2205,771],{"class":71},[57,2207,790],{"class":91},[57,2209,793],{"class":67},[57,2211,796],{"class":71},[11,2213,2214,2215,78],{},"Full setup docs, including the agent quickstart, live at ",[752,2216,2217],{"href":2217},"/api/docs/install-mcp",[18,2219,839],{"id":838},[841,2221,2223],{"id":2222},"how-do-i-add-an-mcp-server-to-claude-code","How do I add an MCP server to Claude Code?",[11,2225,2226,2229,2230,2232],{},[26,2227,2228],{},"claude mcp add \u003Cname> ... -- \u003Ccommand>"," in your terminal, then ",[26,2231,2160],{}," to confirm it connected. Exact MiroMiro command at the top of this post.",[841,2234,2236],{"id":2235},"what-tools-does-the-server-expose","What tools does the server expose?",[11,2238,2239],{},"Seven: design tokens, brand, images, SVGs, fonts, Lottie, and section-to-code. They register automatically; the agent picks per task.",[841,2241,2243],{"id":2242},"why-tokens-instead-of-a-screenshot","Why tokens instead of a screenshot?",[11,2245,2246],{},"Screenshots make the model guess every value. Tokens are the site's real CSS - the difference between imitation and ground truth.",[841,2248,2250],{"id":2249},"does-it-work-with-cursor-and-windsurf","Does it work with Cursor and Windsurf?",[11,2252,2253,2254,2256],{},"Yes - standard ",[26,2255,1062],{}," JSON (above), restart, done.",[870,2258,2259],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}",{"title":53,"searchDepth":104,"depth":104,"links":2261},[2262,2263,2264,2265,2266,2267,2268,2269,2270],{"id":1847,"depth":104,"text":1848},{"id":1861,"depth":104,"text":1862},{"id":1875,"depth":104,"text":1876},{"id":1939,"depth":104,"text":1940},{"id":1991,"depth":104,"text":1992},{"id":2133,"depth":104,"text":2134},{"id":2170,"depth":104,"text":2171},{"id":1636,"depth":104,"text":1637},{"id":838,"depth":104,"text":839,"children":2271},[2272,2273,2274,2275],{"id":2222,"depth":165,"text":2223},{"id":2235,"depth":165,"text":2236},{"id":2242,"depth":165,"text":2243},{"id":2249,"depth":165,"text":2250},"2026-07-18","Install the MiroMiro MCP server in two commands and Claude Code can pull any website's tokens, brand, fonts, and section code instead of guessing.",[2279,2281,2284,2287],{"question":2223,"answer":2280},"Run claude mcp add \u003Cname> with the command that starts the server, in your terminal before starting a session. For MiroMiro: claude mcp add miromiro -s user --env MIROMIRO_API_KEY=your_key -- npx -y miromiro-mcp. Verify with claude mcp list - you want to see Connected.",{"question":2282,"answer":2283},"What does the MiroMiro MCP server let Claude do?","Seven extraction tools appear in Claude's toolbox automatically: design tokens, brand data (logo, palette, fonts), images, SVGs, fonts, Lottie animations, and section-to-code. Claude calls them by itself when you ask design questions about a URL - no manual API calls in your prompts.",{"question":2285,"answer":2286},"Why give a coding agent design tokens instead of a screenshot?","Screenshots make the model guess values - it eyeballs colors, approximates spacing, and invents font names. Tokens are the site's real CSS values, so 'build it like stripe.com' produces the actual palette and type scale instead of a plausible imitation.",{"question":2288,"answer":2289},"Does the MiroMiro MCP server work with Cursor and Windsurf?","Yes. Both take the standard mcpServers JSON block: command npx, args ['-y', 'miromiro-mcp'], and your key in the env. In Cursor it goes in ~/.cursor/mcp.json; in Windsurf under Settings, MCP.",{},"/api-blog/add-design-extraction-to-claude-code-mcp",[906,909,2293],"design-token-types-reference",{"title":1765,"description":2277},"api-blog/add-design-extraction-to-claude-code-mcp",[918,2297,914,919,916],"claude code","GCg_wW_oSWoXNv1z9MhkI1ur2Z7s8b3HpO8eJbVP5HU",{"id":2300,"title":2301,"author":6,"body":2302,"category":890,"date":2638,"dateModified":2638,"description":2639,"extension":520,"faqs":2640,"image":902,"meta":2656,"navigation":227,"path":2657,"readingTime":332,"relatedSlugs":2658,"seo":2659,"seoTitle":2660,"stem":2661,"tags":2662,"__hash__":2666},"apiBlog/api-blog/figma-mcp-setup-and-alternatives.md","Figma MCP: How to Set It Up, What It Gives Your AI, and What to Use Without a Figma File",{"type":8,"value":2303,"toc":2629},[2304,2307,2330,2333,2337,2352,2357,2375,2384,2396,2400,2403,2429,2432,2436,2439,2465,2468,2472,2483,2486,2506,2509,2520,2525,2529,2586,2589,2591,2617,2619,2626],[11,2305,2306],{},"The Figma MCP server lets your coding agent read a Figma file directly - the selected frame's structure, variables and components - so it writes code that matches the design instead of guessing from a screenshot. Add it to Claude Code with one command:",[48,2308,2310],{"className":759,"code":2309,"language":761,"meta":53,"style":53},"claude mcp add --transport http figma https://mcp.figma.com/mcp\n",[26,2311,2312],{"__ignoreMap":53},[57,2313,2314,2316,2318,2320,2322,2324,2327],{"class":59,"line":60},[57,2315,915],{"class":535},[57,2317,1321],{"class":91},[57,2319,1324],{"class":91},[57,2321,1327],{"class":91},[57,2323,1330],{"class":91},[57,2325,2326],{"class":91}," figma",[57,2328,2329],{"class":91}," https://mcp.figma.com/mcp\n",[11,2331,2332],{},"Start Claude Code, sign in to Figma when prompted, and it's connected. The rest of this post covers the other clients, what the server actually gives your agent, and the case it doesn't cover: when the design you want to match isn't in Figma at all.",[18,2334,2336],{"id":2335},"set-it-up-in-your-client","Set it up in your client",[11,2338,2339,2340,2343,2344,2347,2348,2351],{},"Figma recommends the ",[723,2341,2342],{},"remote server"," (",[26,2345,2346],{},"https://mcp.figma.com/mcp","). There's also a ",[723,2349,2350],{},"desktop server"," that runs through the Figma desktop app; it needs a Dev or Full seat on a paid plan.",[11,2353,2354,2356],{},[723,2355,815],{}," - the command above, or Figma's plugin, which bundles the server with ready-made skills:",[48,2358,2360],{"className":759,"code":2359,"language":761,"meta":53,"style":53},"claude plugin install figma@claude-plugins-official\n",[26,2361,2362],{"__ignoreMap":53},[57,2363,2364,2366,2369,2372],{"class":59,"line":60},[57,2365,915],{"class":535},[57,2367,2368],{"class":91}," plugin",[57,2370,2371],{"class":91}," install",[57,2373,2374],{"class":91}," figma@claude-plugins-official\n",[11,2376,2377,2380,2381,2383],{},[723,2378,2379],{},"Cursor, VS Code, Windsurf and other clients"," - add a remote MCP server with the URL ",[26,2382,2346],{}," in the client's MCP settings, then complete the Figma sign-in.",[11,2385,2386,2389,2390,2395],{},[723,2387,2388],{},"Seats:"," the remote server is available on all seats and plans, but seats other than Dev or Full may hit usage limits. Check ",[752,2391,2394],{"href":2392,"rel":2393},"https://help.figma.com/hc/en-us/articles/32132100833559-Guide-to-the-Figma-MCP-server",[1026],"Figma's guide"," for the current limits on your plan.",[18,2397,2399],{"id":2398},"what-it-gives-your-agent","What it gives your agent",[11,2401,2402],{},"With a Figma Design, Make or FigJam file you can view, you select a frame (or paste its link) and ask the agent to build it. The server hands over:",[976,2404,2405,2411,2417,2423],{},[954,2406,2407,2410],{},[723,2408,2409],{},"Structure"," - the frame's layers and layout, so the agent knows what's nested in what.",[954,2412,2413,2416],{},[723,2414,2415],{},"Variables and styles"," - your real color, spacing and type tokens instead of eyeballed hex values.",[954,2418,2419,2422],{},[723,2420,2421],{},"Components"," - which design-system pieces are in use, so the agent can reach for the matching code components.",[954,2424,2425,2428],{},[723,2426,2427],{},"A screenshot"," - for visual reference alongside the data.",[11,2430,2431],{},"The result is much closer to the design than \"here's a screenshot, make this\". The quality depends on the file: frames built with auto layout, named layers and real variables translate cleanly; a flat pile of absolutely-positioned rectangles doesn't.",[18,2433,2435],{"id":2434},"the-case-it-doesnt-cover-no-figma-file","The case it doesn't cover: no Figma file",[11,2437,2438],{},"The Figma MCP reads Figma files. A lot of real work starts somewhere else:",[976,2440,2441,2447,2453,2459],{},[954,2442,2443,2446],{},[723,2444,2445],{},"The reference is a live website"," - \"make our pricing page feel like Linear's\".",[954,2448,2449,2452],{},[723,2450,2451],{},"You're migrating an old site"," whose design file was lost years ago, or never existed.",[954,2454,2455,2458],{},[723,2456,2457],{},"The source of truth is production"," - the shipped site has drifted from the Figma file, and you need what users actually see.",[954,2460,2461,2464],{},[723,2462,2463],{},"You're building from a template or theme"," that only exists as HTML.",[11,2466,2467],{},"In all of these, there's nothing for the Figma MCP to read. Teams fall back to screenshots, and the agent goes back to guessing fonts, spacing and colors from pixels.",[18,2469,2471],{"id":2470},"for-live-websites-a-website-extraction-mcp","For live websites: a website-extraction MCP",[11,2473,2474,2475,2478,2479,2482],{},"This is the gap ",[752,2476,755],{"href":2477},"/api/mcp"," fills. It's an MCP server that reads a ",[723,2480,2481],{},"live URL"," instead of a file, and gives your agent nine tools: component code from any section (Tailwind, React, Vue or HTML), design tokens, brand colors and logo, fonts, SVGs, images, videos, audio and Lottie animations.",[11,2484,2485],{},"Add it the same way - it's also a remote server:",[48,2487,2488],{"className":759,"code":1312,"language":761,"meta":53,"style":53},[26,2489,2490],{"__ignoreMap":53},[57,2491,2492,2494,2496,2498,2500,2502,2504],{"class":59,"line":60},[57,2493,915],{"class":535},[57,2495,1321],{"class":91},[57,2497,1324],{"class":91},[57,2499,1327],{"class":91},[57,2501,1330],{"class":91},[57,2503,1333],{"class":91},[57,2505,1336],{"class":91},[11,2507,2508],{},"Then prompt with a URL instead of a frame:",[2510,2511,2512],"blockquote",{},[11,2513,2514,2515,2519],{},"Use miromiro to extract the pricing section from ",[752,2516,2517],{"href":2517,"rel":2518},"https://linear.app/pricing",[1026]," as React + Tailwind, then adapt it to our plans.",[11,2521,2522,2523,78],{},"The agent gets the page's real rendered CSS, not a guess. Setup for Cursor, ChatGPT, Claude web and Codex is in ",[752,2524,1844],{"href":1843},[18,2526,2528],{"id":2527},"which-one-to-use","Which one to use",[614,2530,2531,2544],{},[617,2532,2533],{},[620,2534,2535,2538,2541],{},[623,2536,2537],{},"Your design lives in...",[623,2539,2540],{},"Use",[623,2542,2543],{},"What the agent gets",[639,2545,2546,2559,2573],{},[620,2547,2548,2551,2556],{},[644,2549,2550],{},"A Figma file your team owns",[644,2552,2553],{},[723,2554,2555],{},"Figma MCP",[644,2557,2558],{},"Frames, variables, components from the file",[620,2560,2561,2564,2570],{},[644,2562,2563],{},"A live website (yours or someone else's)",[644,2565,2566,2569],{},[723,2567,2568],{},"Website MCP"," (MiroMiro)",[644,2571,2572],{},"Rendered code, tokens, fonts and assets from the URL",[620,2574,2575,2578,2583],{},[644,2576,2577],{},"Both - designing new screens to match a live site",[644,2579,2580],{},[723,2581,2582],{},"Both",[644,2584,2585],{},"Figma for the new screens, the live site for the reference",[11,2587,2588],{},"My recommendation: if you design in Figma, install the Figma MCP - it's the best way to get your own designs into code. Add a website MCP when your reference is the web rather than a file. They don't overlap, and agents pick the right tool from the prompt.",[18,2590,719],{"id":718},[976,2592,2593,2599,2605,2611],{},[954,2594,2595,2598],{},[723,2596,2597],{},"\"No design context returned\""," - you need at least view access to the file, and a frame selected (desktop server) or a frame link in the prompt (remote server).",[954,2600,2601,2604],{},[723,2602,2603],{},"Output ignores your design tokens"," - the file probably uses raw values instead of variables. Variables come through as tokens; hard-coded hex values come through as hex.",[954,2606,2607,2610],{},[723,2608,2609],{},"Usage limits on the remote server"," - if you're on a View or Collab seat, you may hit limits. A Dev or Full seat lifts them.",[954,2612,2613,2616],{},[723,2614,2615],{},"The live site doesn't match the Figma file"," - production drifted. Extract from the URL to get what's actually shipped, then decide which one is right.",[18,2618,748],{"id":747},[11,2620,2621,2622,2625],{},"If you're not working inside an agent - a script, a CI job, an internal tool - the same extraction is a plain HTTP API: one GET request returns a section as code, plus its tokens. You can start for free: ",[752,2623,2624],{"href":940},"get a free API key",", 300 credits a month, no card.",[870,2627,2628],{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":53,"searchDepth":104,"depth":104,"links":2630},[2631,2632,2633,2634,2635,2636,2637],{"id":2335,"depth":104,"text":2336},{"id":2398,"depth":104,"text":2399},{"id":2434,"depth":104,"text":2435},{"id":2470,"depth":104,"text":2471},{"id":2527,"depth":104,"text":2528},{"id":718,"depth":104,"text":719},{"id":747,"depth":104,"text":748},"2026-10-03","Set up the Figma MCP server in Claude Code, Cursor and VS Code in one command, see what design context it actually gives your agent, and what to use when the design only exists as a live website.",[2641,2644,2647,2650,2653],{"question":2642,"answer":2643},"How do I add the Figma MCP to Claude Code?","Run claude mcp add --transport http figma https://mcp.figma.com/mcp in your terminal, then start Claude Code and sign in to Figma when prompted. Figma also ships a Claude Code plugin (claude plugin install figma@claude-plugins-official) that adds the same server plus ready-made skills.",{"question":2645,"answer":2646},"Is the Figma MCP server free?","Figma's remote MCP server is available on all seats and plans, but seats other than Dev or Full may have usage limits. The desktop MCP server, which runs through the Figma desktop app, needs a Dev or Full seat on a paid plan.",{"question":2648,"answer":2649},"What does the Figma MCP give my AI agent?","Design context from a Figma file you can view: the structure of a selected frame, its variables and styles, component information and a screenshot. The agent uses that to write code that matches the design instead of guessing from an image.",{"question":2651,"answer":2652},"Can I use an MCP to get design context from a website instead of a Figma file?","Yes. A website-extraction MCP such as MiroMiro reads a live URL and returns the rendered page's real code, design tokens, brand colors, fonts and assets. Use it when the reference is a live site, a competitor, or an old site whose Figma file no longer exists.",{"question":2654,"answer":2655},"Can I use the Figma MCP and a website MCP together?","Yes, and it's a common setup: Figma MCP for the screens your team designed, a website MCP for the live sites you're referencing or migrating from. Both are remote URLs, so you add each once and the agent picks the right tool from the prompt.",{},"/api-blog/figma-mcp-setup-and-alternatives",[906,907,1755],{"title":2301,"description":2639},"Figma MCP: Setup + What to Use Without a Figma File","api-blog/figma-mcp-setup-and-alternatives",[2663,918,2664,2297,916,2665,914],"figma mcp","figma","design to code","2qWWWhWRUhTg5T098ol9uRFjOtx5VuBnbFS-UbeX1kM",1792517976133]