Skip to main content
inkbridge
Free

MCP tools & resources

The tools and resources the Inkbridge MCP server exposes to AI agents.

Overview

The server exposes twelve tools and four resources. Tools: `get_capabilities` (what Inkbridge does, a summary of your loaded model, and how to use the server — start here); `list_components` (every component with its kind, variant axes, and stories); `get_component` (the full resolved definition for one component — classes, variants, states; pass `includeJsxTree` for the raw tree); `get_tokens` (your design tokens — `view: "consumer"` for consumer-authored only, or `view: "full"` for the merged map, plus `theme` for a named theme's effective values); `check_conformance` (verify generated code against the model — invented palette colors, hardcoded color values, off-scale radii, token reuse, CVA convention — for Tailwind classes AND MUI sx color refs); `suggest_token` (the nearest existing token for a raw color or dimension — the fix half of check_conformance); `check_story` (verify a story follows the authoring conventions — meta.title, one story per state, fixed-width wrapper); `draft_component` (scaffold a shadcn/CVA component + one-story-per-variant story as text); `write_component` (write a conformant component + story to your working tree — each file gated by check_conformance / check_story, all-or-nothing; you review and commit, which closes the loop); `diagnose_component` (story-readiness of an existing, possibly coupled component — names the form/store/data-fetching/motion couplings, proposes the states worth storying, and verdicts decorator vs presentational extraction — the brownfield onboarding step); `diff_model` (what changed since your last check — components added/changed/removed and whether tokens changed); `scan` (regenerate the model by running the scanner headlessly — refresh after the code changed; the server also auto-scans on first use). Resources: `inkbridge://components`, `inkbridge://tokens`, `inkbridge://guide/readme` (the public README), and `inkbridge://guide/authoring` (the authoring contract — how to write components the scanner can model). Internal plugin docs are never exposed.

The typical loop: list_components get_component + get_tokens → generate (or draft_component to start) → check_conformance → fix with suggest_token write_component → present. The server pushes this workflow to the agent at connect time via its instructions, so plain-language requests follow it without manual tool calls.

Who calls these — and what you do

You never call these tools yourself. Your only setup is having the server registered — the starters ship a committed .mcp.json and inkbridge setup writes one — then you ask your agent for UI in plain language. Three layers make the agent use the model, in increasing order of guidance:

  1. 1

    Server instructions — delivered to every MCP-capable agent at connect time. They say: consult the design system before generating UI, never invent palette colors, verify with check_conformance before presenting. Works with zero further setup, in any agent.

  2. 2

    The authoring contract inkbridge://guide/authoring, an agent-neutral resource the instructions point to: token use, one story per state, the statically-analyzable styling subset, and the self-check step.

  3. 3

    The agent skills (install with inkbridge skill install): inkbridge-component-authoring auto-activates when you bootstrap a component from a Figma frame — Figma MCP supplies the design, this server supplies what your code already has; inkbridge-build-components guides building or porting components in Inkbridge projects. Both make check_conformance the first validation step, before Storybook or typecheck.

Tool reference

get_capabilities

Orientation — what Inkbridge is, a live summary of this project's loaded model (component counts by kind, token presence), every tool and resource, and the typical agent workflow. The server's instructions tell agents to start here.

No inputs.

Returns: A markdown overview. Includes the model's source path, schema version, and generation timestamp, so an agent can tell how fresh the model is.

Example case

You: Open a fresh agent session in the starter and ask “what design system does this project have?”

The agent: Calls get_capabilities and reads the loaded-model summary — 40 components by kind, tokens present, model generated two minutes ago.

You get: An answer grounded in your actual project — component counts, token vocabulary, and how the agent intends to use them — instead of a generic essay about design systems.

list_components

The inventory. Every scanned component, so the agent reuses what exists instead of duplicating it.

InputTypeNotes
kind"atom" | "molecule" | "organism" | "utility" | "other" (optional)Filter to a single atomic kind.

Returns: { count, components[] } — each row: name, kind, type (cva / compound / …), hasStory, stories (names), variantAxes (CVA axes with their values), symbolCandidate, file path.

Example case

You: “Add a newsletter signup section to the marketing page.”

The agent: Lists the components first and finds Button, Input, Label, and Card already exist with stories.

You get: The new section is composed from your primitives — no bare <button>, no re-invented input, and it inherits every variant and state those primitives already render in Figma.

get_component

The full resolved definition for one component — what the Figma plugin renders from: base classes, variant and state classes, atomic kind, usage counts, layout summary, light/dark class split.

InputTypeNotes
namestringCase-insensitive component name (e.g. "Button"). Unknown names return the list of valid ones.
includeJsxTreeboolean (optional, default false)Include the raw JSX tree. It is large — request it only when you need exact structure.

Returns: The component's full analysis object. jsxTree is omitted unless requested.

Example case

You: “Build a Callout component that fits our system.”

The agent: Pulls Button (or another CVA component) as the house template: its variant axes, defaultVariants, and class conventions.

You get: The Callout declares variants the same way your existing components do — same cva() shape, same axis names — so designers get the familiar variant matrix in Figma.

get_tokens

The design-token vocabulary — the values an agent is allowed to use instead of inventing raw hex/px.

InputTypeNotes
view"consumer" | "full" (optional, default "consumer")consumer = only tokens you authored (what a designer edits). full = the merged map including Tailwind defaults (what the runtime resolves against).
themestring (optional)Return a named theme's EFFECTIVE values — its per-theme overrides merged over the base. Unknown theme errors with the available names.

Returns: Without theme: { view, availableThemes, tokens } — token groups colors/radius/fonts/spacing/fontSize/shadows plus a themes sub-object. With theme: { view, theme, tokens } — the merged effective map (themes dropped).

Example case

You: Implement a card for the “secondary” brand.

The agent: Calls get_tokens { theme: 'secondary' } and reads the merged palette — the secondary brand's primary colour, not the default's.

You get: The card uses the right per-theme values without the agent having to hand-merge base + overrides itself.

check_conformance

Objective self-review. Verifies that component source only uses the design system — for Tailwind classes AND MUI sx color refs — and flags every violation before you present the result. The server's connect-time instructions tell agents to do exactly that.

InputTypeNotes
codestringComponent source to check, inline.
pathstringProject-relative file path to check instead of inline code. Guarded — paths outside the project root are rejected.

Returns: A conformance report (see the field reference below). Pass exactly one of code or path.

Example case

You: “Add a success state to the Callout.”

The agent: First draft reaches for bg-green-500 (or, in a MUI project, sx={{ bgcolor: 'brand.neon' }}) — there is no success token. check_conformance flags it as an invented palette color, so the agent swaps in an existing semantic token and re-checks.

You get: You only ever see the conformant version — the same guarantee for MUI sx as for Tailwind classes.

suggest_token

The fix half of check_conformance. Given a raw color or dimension, return the nearest EXISTING design-system tokens so the agent swaps in a real token instead of guessing. Unrecognizable input is rejected — no silent "nearest to white".

InputTypeNotes
valuestringA raw color (#hex, oklch(...), rgb(...)) or dimension (12px, 0.75rem).
kind"color" | "dimension" (optional)Force the kind; auto-detected from the value otherwise.
limitnumber (optional, default 3)Max suggestions to return.

Returns: { kind, query, suggestions } — colors sorted by RGB distance ({ token, value, distance, exact }); dimensions by px delta ({ token, group, px, deltaPx }).

Example case

You: check_conformance flagged bg-[#1e7729] as a hardcoded color.

The agent: Calls suggest_token { value: '#1e7729' }, gets primary as the nearest token, and rewrites the class as bg-primary.

You get: The invented value becomes a real token in one step — the agent never has to eyeball which token is closest.

check_story

Verify a *.stories.tsx follows the authoring contract before you present it — the story counterpart to check_conformance. Text-level: meta.title, a named story export, and a fixed-width wrapper are checked cleanly; "one story per visual state" is approximated (the full check happens when the scanner builds the model).

InputTypeNotes
codestringStory source to check, inline.
pathstringProject-relative path to a .stories.tsx file. Guarded to the project root.

Returns: { conforms, violations[], warnings[], notes[], summary }. Pass exactly one of code or path.

Example case

You: The agent just wrote a story with all states toggled inside one Default export.

The agent: Runs check_story, sees the one-story-per-state warning, and splits each state into its own export.

You get: Every visual state becomes its own Figma frame when the design system regenerates — no missing states.

draft_component

A correct-by-construction starting point: returns a shadcn/CVA component + one-story-per-variant story as TEXT (no files written), modelled on an existing CVA component so the variant axes and story structure already match your system. Shadcn/CVA only — returns guidance for MUI rather than a wrong scaffold.

InputTypeNotes
namestringName of the new component (e.g. "Callout").
basedOnstring (optional)Existing CVA component to model after; defaults to the first one found.

Returns: { drafted, files: [{ path, content }], basedOn, notes }. When no CVA template exists (e.g. a pure-MUI project) or the template is MUI: { drafted: false, files: [], notes }.

Example case

You: “Start a Callout component like our Button.”

The agent: Calls draft_component { name: 'Callout', basedOn: 'Button' }, gets a cva() shell with Button's variant axes + a story per variant, fills the class slots with real tokens, and runs check_conformance.

You get: The new component follows the house CVA shape and one-story-per-state convention from the first line — no boilerplate drift.

write_component

Close the loop: write agent-generated component/story files into your project, but only after they pass the design-system gate. Each .tsx runs through check_conformance and each .stories.tsx through check_story; if any file fails, nothing is written (all-or-nothing). Files land in the working tree for you to review and commit — no PR, no push. Presentational scope only.

InputTypeNotes
files{ path, content }[]Component (.tsx) and/or story (.stories.tsx) files to write, with project-relative paths.
allowOverwriteboolean (optional)Allow replacing existing files. Default false — refuses to clobber.

Returns: { ok: true, written: [...paths] } on success, or { ok: false, blockers: [{ path, kind, issues }] } when a file fails the gate (nothing written).

Example case

You: “Add the Callout you drafted to the codebase.”

The agent: Fills the draft_component scaffold with real tokens, runs check_conformance / check_story, then calls write_component { files } to land the .tsx + .stories.tsx.

You get: The component + story appear in your working tree, already conformant — you review the diff and commit. A non-conformant draft is rejected with the exact violations instead.

diagnose_component

The brownfield onboarding step: point it at an existing, possibly coupled component (react-hook-form, redux/zustand, data fetching, router, framer-motion) and get a story-readiness report — which runtime couplings it has (with evidence), which states deserve their own story, and whether the fix is a story decorator / mocked args or extracting a presentational view. Statically-handled coupling (useState, effects, animation end-states) is noted, never blocking.

InputTypeNotes
codestring (optional)Component source to diagnose, inline.
pathstring (optional)Project-relative path — also checks whether a sibling *.stories.* file exists. Pass exactly one of code or path.

Returns: { verdict: 'story-ready' | 'needs-decorator' | 'needs-extraction', couplings: [{ kind, wrappable, evidence }], proposedStates, recommendations, notes, summary }.

Example case

You: “Get our SearchInput into the design system — it's wired to react-hook-form and redux.”

The agent: Calls diagnose_component { path: 'src/components/search-input.tsx' }, sees needs-extraction (form + store), extracts a presentational SearchInputView, stories each state, and lands it all with write_component.

You get: The messy component becomes model-visible through its view — states storied, behaviour untouched in the container.

diff_model

What changed in the design-system model since your last check — components added / changed / removed, and whether tokens changed. Hashes are code-derived, so a plugin rebuild never reads as "everything changed".

No inputs.

Returns: First call: { baseline: true, message, components } (records a baseline). After that: { added[], changed[], removed[], tokensChanged } comparing against your previous call.

Example case

You: “Summarise what this branch changed in the design system.”

The agent: Records a baseline on main, then after checking out the branch and re-scanning calls diff_model again.

You get: A precise change set — e.g. Badge changed, Callout added, tokens unchanged — without diffing raw scan JSON by hand.

scan

Regenerate the model by running the scanner over the project — headless, no Figma. The server also auto-scans on first use when the model is missing, so no manual bootstrap step exists.

No inputs.

Returns: { scanned, components, tokens, consumerTokens, generatedAt, source } — a summary of the fresh model.

Example case

You: You just merged a PR that adds a size axis to Badge, then ask the agent to use it.

The agent: Calls scan; the model regenerates from the current code in seconds.

You get: The agent builds against today's Badge, not last week's — the same freshness the Figma plugin gets from its scan route.

check_conformance in depth

The checker gathers every class token from the source's string literals and validates each one against the model's vocabulary. Zero violations is the bar — everything else in the report is context.

The rules

Invented palette colors are violations

Any color utility using a raw Tailwind palette name (bg-green-500, text-rose-300, shadow-emerald-400, …) across the full color-utility set: bg, text, border, ring, divide, fill, stroke, from, to, via, outline, caret, accent, decoration, placeholder, shadow.

Hardcoded color values are violations

Arbitrary color values — bg-[#…], text-[oklch(…)], border-[rgb(…)], ring-[var(--…)]. An agent should write bg-primary, not re-derive the token by hand.

Variant prefixes don't hide anything

dark:hover:bg-green-500 is stripped to its final segment before checking — modifiers (dark:, hover:, focus-visible:, [&>svg]:, …) never mask a violation.

Radii must be on the resolved scale

rounded-* values are checked against the FULL resolved radius scale, not just consumer-authored keys — in Tailwind v4 the named scale (sm…4xl) derives from your --radius via @theme calc()s, so rounded-md is in-system. rounded-full and rounded-none are always exempt. Color vocabulary, by contrast, comes strictly from the consumer view (base + every theme) — the full map would legitimize the entire Tailwind palette.

Non-color utilities pass through

text-sm, border-2, ring-2, size arbitraries like text-[11px], and CSS keywords (transparent, current, inherit, white, black, none) are neither violations nor noise.

MUI sx color refs are checked too

For color properties in sx (bgcolor, color, borderColor, fill, stroke, …), an invented palette ref (bgcolor: 'brand.neon') and a hardcoded color (color: '#f00') are violations; a real MUI-named token (primary.main) counts as reuse. The check is anchored on the color property, so ordinary dotted strings never false-positive.

The report

FieldMeaning
conformstrue when no violations were found. The one-boolean verdict.
violations[]Everything that must be fixed: invented palette colors (Tailwind bg-green-500 or MUI sx bgcolor: 'brand.neon'), hardcoded color values, radii outside the token scale — each with the offending token and the reason.
tokensReused[]The design-system color tokens the source actually uses — Tailwind (bg-primary, bg-primary/50 → primary) and MUI sx refs (primary.main → primary/main). Zero reuse on a styled component is suspicious — the notes say so.
radiusUsed[]Every rounded-* value found, whether valid or not.
unrecognized[]Color-looking utilities whose value is neither a known token nor a CSS keyword — not violations, but flagged for manual review.
cva / followsCvaConventionWhether the source uses cva(), declares a variant axis, and sets defaultVariants — the project's variant convention, checked structurally.
notes[]Honesty markers: a source with no strings to read reports "nothing to check" instead of a hollow pass; a styled component that reuses zero tokens is flagged as suspicious.
summaryOne sentence for logs and quick reads.

Example report

{
  "conforms": false,
  "violations": [
    "bg-green-500 (invented Tailwind palette color)",
    "text-[#1a1a2e] (hardcoded color value)"
  ],
  "tokensReused": ["card", "muted-foreground", "primary"],
  "radiusUsed": ["lg"],
  "unrecognized": [],
  "cva": { "present": true, "hasVariantAxis": true, "hasDefaultVariants": true },
  "followsCvaConvention": true,
  "notes": [],
  "summary": "Does not conform: 2 violation(s) — see `violations`."
}

Scope: the checker covers Tailwind class usage and MUI sx color refs (invented palette refs and hardcoded colors in sx). It doesn’t police MUI spacing — that’s legitimately an arbitrary multiplier — and a source with no strings to read says so in notes rather than passing silently.

Resources

inkbridge://components

The full component model as JSON (the scanner's components array).

inkbridge://tokens

Consumer-owned design tokens as JSON.

inkbridge://guide/readme

The public Inkbridge README.

inkbridge://guide/authoring

The authoring contract — token use, one story per state, the statically-analyzable styling subset for Tailwind and MUI. The write-side counterpart to the read-only model; agents consult it before generating or editing a component.

Internal plugin implementation docs are never exposed — the doc surface is consumer-public only.

Trust model

The server is read-only toward your code and runs locally over stdio — nothing is hosted, and no source leaves your machine. The only thing it writes is its own model file (.inkbridge/component-definitions.json, gitignored) when scanning. check_conformance's path input is guarded to the project root, and the doc resources serve public files only. Same trust model as the dev-only scan route the Figma plugin uses.

Troubleshooting

"No token map in the scan output"

The model on disk predates token inclusion. Call scan — the server regenerates .inkbridge/component-definitions.json with tokens included.

Model missing / first call is slow

The server auto-scans on first use by running the scanner headlessly via the project's tsx. It needs the project's dev dependencies installed (pnpm install).

Model is stale after code changes

Call scan. The server mtime-caches the model file, so a fresh scan is picked up without a restart.

Server can't find the project

The project root defaults to the working directory the client spawns the server in. Override with INKBRIDGE_PROJECT_ROOT, or point INKBRIDGE_DEFS at a specific component-definitions.json (read-only — scan is disabled in that mode).

Quick reference

  1. 1

    `get_capabilities` — orient: what Inkbridge does plus your project's loaded model summary.

  2. 2

    `list_components` — list every component with kind, variant axes, and stories.

  3. 3

    `get_component { name }` — full resolved definition; add `includeJsxTree: true` for the raw JSX.

  4. 4

    `get_tokens { view, theme }` — "consumer" (default) or "full" token map; pass a `theme` name for its effective values.

  5. 5

    `check_conformance { code | path }` — verify generated code (Tailwind classes + MUI sx) before presenting it; fix every violation it reports.

  6. 6

    `suggest_token { value }` — when a value is flagged, get the nearest real token to use instead (fix, don't guess).

  7. 7

    `check_story { code | path }` — verify a story follows the authoring conventions before presenting it.

  8. 8

    `draft_component { name, basedOn }` — get a correct-by-construction CVA scaffold to start from, then fill the class slots.

  9. 9

    `write_component { files }` — write the conformant component + story to your working tree (gated by check_conformance / check_story); review the diff and commit.

  10. 10

    `diagnose_component { path }` — for an existing coupled component (forms/store/motion), learn what blocks storying it: the couplings, the states worth storying, and decorator vs extraction.

  11. 11

    `diff_model` — what changed since your last call (baseline on first use); good for summarising a change set.

  12. 12

    `scan` — regenerate the model after code changes (auto-runs on first use if the model is missing).

Related