@variel/mcp-server
v0.2.3
Published
Generate a brand from inside your coding agent, then keep every design token, component, and copy decision on-brand — deterministic on-brand validation served live over MCP.
Maintainers
Readme
@variel/mcp-server
The Variel MCP server — gives your coding agent live access to your brand: tokens, components, voice, and on-brand validation. It runs over stdio and resolves your brand from the Variel API using your project's API key, so there's nothing to clone and no database to point at.
Get started at variel.ai/connect.
Connect
Get your BRAND_API_KEY (vrl_…) from your project's Activation page in
the Variel dashboard, then:
# Claude Code
claude mcp add variel -e BRAND_API_KEY=vrl_… -- npx @variel/mcp-serverFor Cursor / other agents, add an mcpServers entry:
{
"mcpServers": {
"variel": {
"command": "npx",
"args": ["@variel/mcp-server"],
"env": { "BRAND_API_KEY": "vrl_…" }
}
}
}Tools
16 tools are exposed over the ListTools protocol surface:
generate_brand_kickoff— pre-brand onboarding: submit a brief (five fields: whatItIs, audience, oneBelief, antiPosition, categoryNorm) and get N hosted brand direction links to review in your browser. Non-blocking — returns immediately with a kickoff token and N reveal links at/k/<token>/<index>. Available on a keyless/bootstrap connection (noBRAND_API_KEYneeded). Returns{ kickoffToken, status:'pending', routes:[{index,revealUrl}×N], nextStep }— no label/descriptor at kickoff-time (routes are still generating), no api_key, no images.generate_brand_resolve— pre-brand onboarding: poll for the human's brand direction pick after callinggenerate_brand_kickoff. Returns{ status:'generating', picked:false }(still generating — poll again), then{ status:'waiting', picked:false, routes:[{index,revealUrl,label,descriptor}×N] }once routes are ready (labels/descriptors computed from the same source as the reveal page — zero drift), then{ status:'ready', picked:true, brandApiKey, brandHandle, nextStep }after the human picks. All pre-pick states haveisErrorabsent (non-error polling). Available on a keyless/bootstrap connection.get_brand_tokens— the live token set (colors, typography, spacing, radius, shadow, motion, border) plus generated CSS custom properties.list_components— all brand component definitions with their variant names.get_component— full definition and code snippet for a named component in the requested framework (react-tailwind,html-css,vue).validate_design— deterministic, multi-dimensional brand conformance check (token violations, WCAG contrast, voice rules). Pure function: same input always produces identical output. Score 0–100 with actionablestructuredFixpatches per violation.validate_copy— two-tier brand-voice check for bare prose. Tier 1 is deterministic (banned words, hedges, exclamation marks). Tier 2 is model-judged (requiresANTHROPIC_API_KEY).grade_visual_quality— model-judged visual brand grading across 5 dimensions (coherence, hierarchy, spacing, typeCraft, colorHandling). Renders HTML server-side and calls a vision model. RequiresANTHROPIC_API_KEY.generate_component— model-tier generation: produces a bespoke, token-bound React/Tailwind component grounded in your brand's divergent concept. Self-validates and retries once on failure. RequiresANTHROPIC_API_KEY.generate_asset— model-tier asset generation: produces an on-brand PNG image anchored to the brand's moodboard world (narrative, descriptors, anti-references). Self-checks with theslopGatevision model and attaches the verdict. Retries once on failure. Returns ephemeral base64 only (no persistence). RequiresANTHROPIC_API_KEYand a configured moodboard; returns a structured skip when either is absent. Moodboard-gated: only listed when the brand has a moodboard.propose_token— deterministic escape hatch: propose a new design token when nothing in the existing brand set covers your need. Deflects automatically if a covered token exists. Does NOT mutate the live brand.get_logo— deterministic serve of the brand's signature logo: its structured spec plus a token-bound SVG. No model call, no RNG, no clock. Same brand produces byte-identical output. The logo derives from always-present brand coordinates + tokens and degrades gracefully to an abstract glyph when no brand name is available — it is therefore listed unconditionally for every connected brand (unlikeget_signature_motifwhich requires an optional motif). Colors are token-bound viavar(--color-*)orcurrentColor— zero raw hex. Returns a JSON object with the logo spec, the SVG string, and the render mode ("wordmark" or "glyph").get_signature_motif— deterministic serve of the brand's signature motif: its structured spec plus a token-bound SVG static figure. No model call, no RNG, no clock. Same brand + samereducedMotionflag produces byte-identical output. Colors are token-bound viavar(--color-*); animated elements carrylp-motif-anim-*class hooks whose keyframes andvar(--motif-*)tokens must come from the brand's CSS for motion — the SVG alone is static. The spec is also returned so the consumer can wire animation. Motif-gated: only listed when the brand has a signature motif.tune_motif— candidate-only, gate-defended motif tuner. Proposes a modified version of the brand's signature motif by overlaying only the fields you supply (omitted fields keep the current value). The candidate is scored through the same distinctiveness gate that guarded the original: off-mean score must remain above 50 and no gradient-slop may be introduced. A failing candidate is returned as an honest rejection naming the failing axis ("gradient-slop" or "off-mean"). Fully stateless: never mutates the live brand —get_signature_motifandget_brand_tokensare byte-identical before and after. No model call, no RNG, no clock. Palette values must be token-ref keys (e.g. "accent", "ink", "bg") — raw hex is rejected. Motif-gated: only listed when the brand has a signature motif.scan_genericness— deterministic genericness scanner for any URL. Captures the live page locally (requires Chrome — see below), extracts six brand-signal axes (color variety, whitespace density, font variety, cliche imagery, CTA density, content depth), scores against the Variel Category Norm Anchor v1.2, and returns a verdict. Score direction: 0 = Distinctive, 100 = Very Generic (opposite ofvalidate_design). Available on a keyless/bootstrap connection — noBRAND_API_KEYand noANTHROPIC_API_KEYneeded (fully deterministic, zero model calls). Returns{ score, band, signals:[{id,label,weight,fired,observedFact,divergenceNote}], axisDistance, anchorVersion, scannedUrl, assessment }plus an advisory handoff suggestion to seedgenerate_brand_kickofffrom what was found. Fetch posture:"local"— loopback and private-network URLs are allowed (useful for localhost dev), cloud-metadata endpoints (169.254.x.x, link-local) and credentials in URLs are refused. No page data leaves your machine. Requires Chrome to be installed; if Chrome is not found, returnsisError:truewith a step-by-step actionable message (install Chrome, setCHROME_EXECUTABLE_PATH, or use the web scan at variel.ai/scan). Never returns a degraded static score on Chrome failure.share_scan_result— opt-in agent-side mint: re-captures the page locally (same local Chrome pipeline asscan_genericness), then POSTs the raw{html, elements}to the Variel mint endpoint, which re-derives the genericness verdict server-side and returns a permanent card URL. Use this to share a scan result as a shareable report card. Opt-in is structural —scan_genericnessstays zero-egress; egress exists only in this verb. Available on a keyless/bootstrap connection — noBRAND_API_KEYand noANTHROPIC_API_KEYneeded. Requires Chrome (same asscan_genericness). Returns{ cardUrl, capturedAt }— the permanent card URL (valid 90 days) and the ISO timestamp of the capture. Advisory only: no auto-posting.
Resources
6 static resources are exposed over the ListResources protocol surface:
brand://tokens— design tokens (colors, typography, spacing, etc.) plus generated CSS variables.brand://voice— voice and tone guidelines, personality, do/don't lists.brand://components— all brand component definitions.brand://brief— compact, concept-forward brand brief: positioning, anti-position, voice rules. Pull this into context before generating any UI or copy.brand://guidelines— formatted do/don't rules and rationale.brand://moodboard— the brand's visual world: descriptors, narrative, anti-references, image URLs + rationales. Present when the project has a moodboard configured.
Dynamic per-component resources: brand://components/{name}.
Configuration
| Env | Default | Purpose |
|-----|---------|---------|
| BRAND_API_KEY | — | Your project key (vrl_…). Required. |
| VARIEL_API_URL | https://variel.ai | Override for self-host / staging. |
| ANTHROPIC_API_KEY | — | Required only for grade_visual_quality, generate_component, generate_asset, and Tier-2 validate_copy. |
| BRAND_SOURCE | (unset) | Set to db to read Postgres directly (DATABASE_URL) instead of the HTTP API — for local dev / self-host. |
| CHROME_EXECUTABLE_PATH | (auto-detect) | Override the Chrome binary path used by scan_genericness and share_scan_result. If unset, playwright-core auto-detects a system Chrome install. Example: /Applications/Google Chrome.app/Contents/MacOS/Google Chrome. |
| VARIEL_VIA | (unset) | Source attribution tag. Set to "plugin" by the Variel Claude Code plugin config (ticket 476) — forwards as via:"plugin" on the kickoff POST body so the web side can record the install channel. A constant string, never a user or project identifier. You should not need to set this manually; the plugin config sets it automatically. |
Without a valid key the server falls back to a neutral bootstrap brand so your agent still starts.
