You have access to the awwwards MCP server: a searchable library of
award-winning websites with inline screenshots and per-site design DNA. Use
it to ground design decisions in real, proven references instead of guessing.
Profile note: this skill's tools are
search_sites,get_site_details,get_site_elements,list_categories,get_annual_categories,get_annual_nominees,get_annual_nominee,get_collections,search_directory,new_winners,watch_site,capture_live_site,analyze_page_structure,record_site_motionand retainedcreate_design_brief. Examples below use 1.x names (defaultfull). OnAWWWARDS_MCP_PROFILE=v2, usesearch_references {request:{kind:"sites", ...}},get_reference {request:{kind:"site_details", slug}}orget_reference {request:{kind:"site_details", slugs}}for a batch of 1-10,get_reference {request:{kind:"site_elements", slug}},browse_awards {request:{kind:"filters"}},browse_awards {request:{kind:"annual_categories"}}(alsokind:"annual_nominees"withcategory, andkind:"annual_nominee"withidorcategory+slug),search_references {request:{kind:"collections"}}(orget_reference {request:{kind:"collection", slug}}for one collection),search_references {request:{kind:"directory", ...}},monitor_awards {request:{action:"poll_winners"}},monitor_awards {request:{action:"add_watch", kind, pattern}},monitor_awards {request:{action:"list_watches"}},monitor_awards {request:{action:"remove_watch", kind, pattern}},capture_page {request:{kind:"screenshot", url}},inspect_page {request:{kind:"structure", url}}andcapture_page {request:{kind:"recording", url}};create_design_briefstays flat. Full mapping: v2-routing.md.
When to use this skill
- First time on this machine? If
~/.awwwards-mcp/preferences.jsondoes not exist yet, run theawwwards-setupskill first — it asks the user's preferences once (result density, viewport, captures, index, watches) and this skill applies them afterward. - During site builds — before writing any UI code, gather references and state a design direction.
- Standalone research — the user wants inspiration, trends, or examples ("show me dark 3D portfolio sites").
- Index & capture ops — building the local search index, or taking fresh screenshots of live URLs.
The inspiration loop
Run this loop before building anything visual:
-
Restate the goal as concrete attributes. Turn the user's request into mood, color, technology, and industry terms. "Make it feel premium" becomes e.g. "dark, elegant, WebGL, agency portfolio".
-
Ground your vocabulary. If unsure which filters exist, call
list_categoriesfirst — it returns every color hex, award filter (sotd,soty,nominees, winner categories, …) and tag/technology slug you can search by. For browsable discovery,get_collectionslists curated/member collections (pass a returnedrefasslugfor one collection's cards), andsearch_directorylists agencies and studios with optional country/category/budget filters. For annual "of the Year" questions, theget_annual_*tools cover the six official annual categories (see Award discovery below). -
Search. Call
search_siteswith 1–3 filters (e.g.{ color: "#404040", tags: ["3d", "portfolio"] }). Judge the results from the inline screenshots, not just titles. Shortlist 2–3 candidates. Free-text queries are porter-stem + prefix-matched and BM25-ranked ("magazines"finds Magazine-tagged sites, best matches first); multi-word queries keep AND semantics — both tokens must hit the same site. 3b. Techniques registry:_memory/techniques.jsoncatalogs researched how-tos per domain (video-understanding, motion-detection, ui-structure, micro-interactions, images). Consult it when a step needs a method — it grows via the flywheel. -
Synthesize the direction. Once you have 2–5 shortlisted slugs, call
create_design_briefwith those slugs and the user's non-blank project goal. Optionally includeaudienceand concreteconstraints. Use the returned shared signals, deliberate outliers, build constraints, evidence, limitations, and Interaction Plan to define an original direction — do not copy any single reference. Apply only its evidence-backed cursor/hover, scroll/pin/scrub, entrance/reveal, easing, and duration cues. Treat empty or null interaction fields as missing evidence: do not invent effects, timings, or scroll behavior. Preserve the plan'sprefers-reduced-motion, content-access, and keyboard-access guardrail. SetincludeStructure: trueonly when optional page-band evidence is needed; it may run browser analysis for sources with usable live URLs. Cached Motion DNA is included when available, but the brief never records motion automatically. -
Live reference URL named? Capture it full-page first. (and later capture your own build the same way — compare both against each other) If the user points at a specific live site (e.g. "recreate cerebrium.ai"), call
capture_live_siteon that URL before anything else and design from the full-page PNG — every section, top to bottom. Ifanalyze_page_structurereportsscrollRoot(an inner scroller), the capture returnsmode:"anchors"instead — six ordered viewport PNGs down that container as JSON paths (no inline image); read the six files. Cached Awwwards screenshots are hero-only crops (~880×660) and hide everything below the fold: the sections that make a site's structure distinctive (pricing, feature layouts, contrast breaks, footer) were never visible in them. For mobile-excellence references passviewport: "mobile"— and capture BOTH viewports when the desktop and mobile designs diverge. -
Get the design DNA as follow-up evidence. Call
get_site_detailson the top pick when the brief reports missing or weak detail evidence, or when a specific source needs deeper inspection. If it reports a layout-drift error, fall back to judging the shortlisted screenshots,get_site_elements(which uses a different parser), or acapture_live_siteof the site's URL for a first-hand capture. For a shortlist,get_site_details { slugs }gives bounded enrichment: up to 10 sites in one call, compact details, no images. -
Study MOTION before building (element videos, not posters). Call
get_site_elementson shortlisted sites — it returns per-element video URLs (preloader, page transition, case study, about…). Download those videos and tile them at 1–2 fps BEFORE writing any animation code:curl -o e.mp4 <video-url> && ffmpeg -i e.mp4 -vf "fps=2,scale=480:-1,tile=6x4" -frames:v 1 tile-e.jpg, then Read the tile. (The full capture→review→build procedure — what to record, what to skip, motion inventories, build verification — is theawwwards-motion-studyskill.) Element posters are single frames — they show layout, not motion; a 3D carousel looks like floating static cards in a poster (this exact mis-build happened). One tile per element shows you the whole animation arc (easing, overlap, entrance order). If a marquee animation needs finer study, re-tile that video at higher fps. The motion IS the design: every reference animation you ship must trace to frames you actually studied, and reference videos pass throughshowcase/ref-motion/as the design's evidence trail. -
State the design direction before writing code. In prose: palette (hexes from the references), type mood, layout patterns, page architecture (one page vs separate horizontal sections — judge this from the reference passages you studied in steps 4–6, not habit), and tech choices, each traceable to a reference. Then build. For a site's own marquee frontend skills, prefer proven patterns (GSAP ScrollTrigger for horizontal scroll chapters, Lenis for smooth scroll) over hand-rolled scroll math.
-
Verify structure, then polish. After building, capture your own build with
capture_live_site(on itsfile://or served URL) and runanalyze_page_structureon BOTH the reference and the build. Compare band maps section by section (count, order, backgrounds, heights). Match the reference's viewport when comparing: for mobile-excellence references passviewport: "mobile", and capture BOTH viewports when the design diverges. Fix distribution mismatches first — a section that is 3× the reference's height is a structural bug no amount of pixel polish fixes. Match the reference's band structure, never just its total height. -
Close the flywheel (repo-checkout only — neither the installed npm package nor this skills package ships this dev script): in a repository checkout, end every loop pass by recording what the verification caught -
node scripts/skill-memory.mjs record --skill awwwards-inspiration --phase <phase> --symptom "..." --rule "..." [--evidence path]. "Nothing new learned" is a recorded negative. Thendistillfolds rules seen ≥2× into your installed copy's managed section;recallprints them at loop start. When promoting a confirmed rule into the shipped copy (human PR),promote --skill awwwards-inspirationprints it with machine-local evidence paths stripped.
Award discovery
Beyond the daily listing sweep, Awwwards exposes an annual-awards layer and finer winner cuts:
- Annual awards (official API) — for "Site of the Year"-style questions,
start with
get_annual_categories, thenget_annual_nominees(per category, hydrated at 1 req/s) andget_annual_nomineefor full structured nominee detail. These cover the six official annual categories. - Daily / monthly / yearly / nominee cuts —
search_siteswithaward: "sotd" | "sotm" | "soty" | "nominees"(plusdeveloper/honorable). - Annual winner categories —
search_siteswithaward: "ecommerce" | "portfolio" | "product" | "typography" | "businessServices" | "noCode". - Unsure of a slug? Call
list_categoriesfirst — it returns every award filter with its label plus the current technology slugs.
Anti-patterns
- Vague single-word searches ("modern", "nice") — use concrete color/tag/ technology/award filters instead.
- Skipping to code without stating a direction — the references are worthless if nothing is derived from them.
- Dumping raw tool output at the user — curate: show the shortlist, the chosen direction, and why.
- Designing from a thumbnail or element poster — thumbnails are hero-only crops, posters are single video frames, and neither shows real structure OR motion. When the reference URL is known, capture it full-page (step 4); when an element has motion, tile its video (step 6) — never animate from posters.
- One filmstrip for everything — a single N×N tiling of the whole recording makes late tiles tiny and animation arcs illegible. Tile per element/per passage at 1–2 fps instead; re-tile finer passages at higher fps when easing or overlap matters.
- Padding empty bands to match total height — if your build's total height matches the reference but a spacer/background band is far taller than the reference's equivalent, the height was stolen from real content sections. Compare band maps, not totals. Spacer and decorative elements are measured against the reference's equivalent band — never invented to absorb height.
Tool reference
| Tool | Key params | Returns | Gotchas |
|---|---|---|---|
search_sites |
query (free text vs titles/tags), color (hex like #404040), tags (array of slugs), technology (slug), award (sotd|sotm|soty|nominees|developer|honorable|ecommerce|portfolio|product|typography|businessServices|noCode), count (1–12, default 6), page (default 1), responseMode ("full" default or "compact") |
Full: text site cards + inline JPEG screenshots for each result. Compact: concise cards + up to two inline previews for the requested page. | Awwwards applies only one URL filter — priority color > award > technology > first tag; the rest are checked client-side (common technology spellings like nextjs/three.js are canonicalized to the live slugs). Winner-category filters verify by URL only and always re-scrape; nominee filters verify via the persisted nominee flag and are served from cache when fresh. Color searches always scrape live (never cached). Deep pagination is unavailable by design (robots.txt). On live-request failure, stale cache is served when present. Compact is opt-in for broad exploration; use default full results to judge screenshots and details/motion tools for shortlisted sites. |
get_site_details |
slug (from search_sites, e.g. l-i-s-a) |
Title, live URL, awards, color palette, technologies, design elements, description, full-size screenshot URL; inline screenshot when available | Cached 7 days; a parse that comes back all-empty is an error, not a quiet empty result. |
get_site_elements |
slug |
Numbered element list (image or video, with video URLs) + up to 8 inline poster JPEGs | Videos are mp4 URLs (posters only are shown inline). Elements feed from the same fetch as get_site_details. |
list_categories |
none | JSON: award filters (with labels), every color hex and filter/tag slug, technology slugs, plus usage guidance | Cached 30 days. Call this whenever filter vocabulary is uncertain — awards and technology slugs included. |
capture_live_site |
url (absolute URL), viewport ("desktop" default or "mobile"), scrollCapture ("auto" default, "anchors" or "viewport") |
Document scroller: full-page PNG saved to disk + inline image. Inner scroller (scrollRoot): six ordered viewport shots as JSON anchors[].scrollTop/file, no inline image; scrollCapture:"viewport" gives one explicit viewport shot |
Requires the optional playwright dependency (npm install -g awwwards-mcp playwright ffmpeg-static && npm exec --global -- playwright install chromium). After installing, switch the MCP registration from npx -y awwwards-mcp to the installed awwwards-mcp command and restart, so captures resolve Playwright from the server's own install. |
analyze_page_structure |
url (absolute URL or file:// path), maxBands (cap on returned bands, default 40) |
JSON: title, totalHeight, and an ordered band map (index, tag, label, background, offsetTop, height, textStart (first ~60 chars of the band's text) per band) |
Requires playwright. Run it on BOTH the reference and your build (step 8) and compare band maps — count, order, backgrounds, heights — never just total height. |
record_site_motion |
url (absolute URL), frames (filmstrip tile count, 4–36, default 16 → a 4x4 grid) |
Inline filmstrip JPEG of a motion-through pass (preloader dwell, slow scroll, hover/cursor interactions) + the saved .webm path as text | Requires playwright + ffmpeg-static. Runs a ~30 s scripted pass — heavier than a capture, use when motion matters (step on from static captures). |
new_winners |
award (sotd default, or developer/honorable) |
Today's freshly-crowned winners since the last poll, as site cards; first-ever call seeds a baseline and dumps the listing instead | UTC-day granular. Each first-seen winner's Elements section is auto-backfilled into the source:"site" element corpus — new winners are searchable by elements immediately without gallery indexing. Longitudinal monitoring: call periodically during a session to catch new SOTDs as they land. |
watch_site |
action (add|list|remove), kind (studio|tag|url), pattern, optional award, note |
list: matching sites per watch + NEW since last check deltas; add/remove confirm |
Never fetches — evaluates against the freshest cached listing, so run new_winners or search_sites first (the first list only seeds its baseline; a second list after rows load reports deltas). url watches take the site slug (e.g. l-i-s-a); studio watches are case-insensitive substrings. |
All image results arrive as MCP image content blocks — look at them, don't just read the text blocks.
On AWWWARDS_MCP_PROFILE=v2 the watch_site row becomes monitor_awards:
add is {request:{action:"add_watch", kind, pattern}}, list is
{request:{action:"list_watches"}}, and remove is
{request:{action:"remove_watch", kind, pattern}} — kind and pattern are
required for both mutations (v2-routing.md).
Staying current
For research that should reflect what's winning now (trend questions,
"latest" anything), open the session with new_winners — it reports today's
freshly-crowned SOTD/Developer/Honorable winners and quietly folds each
winner's elements into the searchable corpus. To track a studio, tag, or
specific site over time, add a watch (watch_site, action: "add",
kind: studio|tag|url) after your first sweep; every later new_winners /
search_sites run refreshes the pool and watch_site list reports what's
new per watch. Watches never fetch on their own — the sweep feeds them.
Index & capture ops
Local index. search_sites works out of the box but unindexed depth is
limited by polite live scraping (~31 sites per filter page). Build the index
once for searches across thousands of sites:
npx -y -p awwwards-mcp awwwards-index # from the published package
npm run index # from a repo checkout
- Crawls all ~200 tag pages at 1 request/second (~4 minutes) into a SQLite
cache at
~/.awwwards-mcp/. - Resumable: interrupt and re-run; completed pages are skipped.
- The MCP server re-indexes automatically in the background whenever the index is stale — you rarely need to run this by hand.
Live captures. capture_live_site needs playwright installed once (see
table above). Two uses: (1) the user wants a screenshot of a URL that is not
an Awwwards site, or a fresher view than the cached thumbnails; and (2) —
the more important one — the user names a live site as the design reference
for a build: capture it full-page first and derive the structure from that
image (see step 4 of the loop).
Motion capture. Static images can't show preloaders, scroll-driven
animation, or transitions — and most award-winning sites are built around
exactly those. When the reference site has motion, record it: launch
Playwright with recordVideo, wait out the preloader (~7 s), scroll slowly
to the bottom in small steps so every scroll-triggered animation fires on
camera, then extract a filmstrip of frames with ffmpeg (npm i -D ffmpeg-static, one frame every ~3 s) and Read the frames — or call
record_site_motion directly: the filmstrip comes back inline and the .webm
path as text.
Filmstrip is the fallback, not the default. First try Reading the
video file directly — if your model supports video input, watching the
scroll-through gives you timing, easing, and transitions the frames can't.
If the Read comes back with media omitted / "model does not support video
input", extract the filmstrip and Read the frames instead. A ready-made
recorder ships only in the awwwards-mcp source checkout at
scripts/record-scrollthrough.mjs (repo-checkout only — not shipped with this
skills package; run it from the repo root; playwright and ffmpeg-static are
devDependencies).