Midwest MCP Server
Overview
Midwest ships an MCP (Model Context Protocol) server as a bundled executable. It exposes your component library to AI agents — Claude Code, Cursor, Windsurf, or any MCP-compatible client — so they can discover components, look up APIs, search by capability, and pull usage examples without you pasting documentation into a prompt.
The server runs over stdio transport and requires no network configuration. It parses your installed Midwest components at startup and indexes them in memory.
Setup
1. Verify the executable is available
The midwest_mcp executable is included with the gem. After installing or updating Midwest, confirm it's accessible:
bundle exec midwest_mcp --helpIf you installed Midwest globally, the executable is available directly:
midwest_mcp2. Configure your MCP client
Each AI tool has its own configuration format. Below are examples for the most common clients.
Claude Code
Add a .mcp.json file to your project root:
{ "mcpServers": { "midwest": { "command": "bundle", "args": ["exec", "midwest_mcp"] } }}Cursor
Add to your .cursor/mcp.json:
{ "mcpServers": { "midwest": { "command": "bundle", "args": ["exec", "midwest_mcp"] } }}VS Code (Copilot)
Add to your .vscode/mcp.json:
{ "servers": { "midwest": { "command": "bundle", "args": ["exec", "midwest_mcp"] } }}Windsurf
Add to your ~/.codeium/windsurf/mcp_config.json:
{ "mcpServers": { "midwest": { "command": "bundle", "args": ["exec", "midwest_mcp"] } }}3. Restart your AI tool
After adding the configuration, restart the client (or reload MCP servers if the tool supports it). The server starts automatically when the client connects.
How it works
- The client launches
midwest_mcpas a child process - The server locates your Midwest gem installation and scans all component files under
app/components/midwest/ - It parses each component to extract options, slots, constants, public methods, and descriptions
- It parses Lookbook preview files for usage examples and parameter annotations
- It parses Stimulus TypeScript controllers to extract values, targets, and actions
- It parses the view helper module and form builder to index helper methods and form field mappings
- A search index is built over the parsed metadata
- The server listens on stdin/stdout using the MCP stdio transport protocol
- When the AI agent calls a tool, the server queries its in-memory indexes and returns structured JSON
The server is read-only — it never modifies files or makes network requests.
Available tools
The MCP server exposes twenty-five tools to connected AI agents. The first eight — the component-intelligence core — are documented in full below, each with the tool's parameters, an example invocation as the AI agent sends it over the protocol, and the response the agent receives. The remaining seventeen — guidance, preview generation, design-system, migration, chart, Turbo, and email-client tooling — follow under More tools with their parameters and what they return.
list_components
Lists all available Midwest components with basic metadata.
| Parameter | Type | Required | Description |
|---|---|---|---|
category |
string |
no | Filter by "elements" or "form" |
Returns each component's name, class name, category, helper method name, option/slot counts, and description.
Invocation:
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "list_components", "arguments": {} }}Pass "arguments": { "category": "form" } to return only form components.
Response:
{ "components": [ { "name": "button_component", "class_name": "Midwest::ButtonComponent", "category": "elements", "helper": "midwest_button", "options_count": 18, "slots_count": 1, "description": null }, { "name": "dialog_component", "class_name": "Midwest::DialogComponent", "category": "elements", "helper": "midwest_dialog", "options_count": 8, "slots_count": 0, "description": null }, { "name": "form/input_component", "class_name": "Midwest::Form::InputComponent", "category": "form", "helper": "midwest_form_input", "options_count": 25, "slots_count": 0, "description": null } ], "count": 75}The helper field is the view helper method you call in ERB (e.g. <%= midwest_button "Save" %>). Use options_count and slots_count to gauge a component's complexity before diving into its full API.
get_component_api
Returns the full API surface for a specific component — options with defaults, slots with render type, constants with values, and public methods.
| Parameter | Type | Required | Description |
|---|---|---|---|
component |
string |
yes | Component name (e.g. "button_component", "form/input_component", or "button") |
The tool accepts flexible name formats: "button", "button_component", "form/input_component", or "Midwest::ButtonComponent" all resolve correctly.
Invocation:
{ "jsonrpc": "2.0", "id": 2, "method": "tools/call", "params": { "name": "get_component_api", "arguments": { "component": "button" } }}Response:
{ "name": "button_component", "class_name": "Midwest::ButtonComponent", "file_path": "app/components/midwest/button_component.rb", "description": null, "category": "elements", "helper": "midwest_button", "options": [ { "name": "as", "default": "link" }, { "name": "size", "default": "default" }, { "name": "variant", "default": "default" }, { "name": "fill", "default": "false" }, { "name": "pill", "default": "false" }, { "name": "icon", "default": null }, { "name": "icon_position", "default": "start" }, { "name": "disabled", "default": "false" }, { "name": "tooltip", "default": null }, { "name": "loading", "default": "false" } ], "slots": [ { "name": "badge", "renders": "one", "component": null } ], "constants": [ { "name": "AS_OPTIONS", "values": ["link", "button", "submit", "reset", "span"] }, { "name": "VARIANT_OPTIONS", "values": ["default", "outline", "ghost", "tab", "fab"] }, { "name": "SIZE_OPTIONS", "values": ["large", "default", "small", "tiny"] } ], "public_methods": [ { "name": "element_classes" }, { "name": "button_tag" }, { "name": "button_options" } ]}The constants array lists allowed values for enum-like options — an agent can read VARIANT_OPTIONS to know which values are valid for variant:. The options array includes each option's default so the agent only needs to pass values that differ.
For components with Stimulus controllers, the response includes a stimulus key with the controller's values, targets, and actions:
{ "stimulus": { "controller_id": "midwest-dropdown", "values": [ { "name": "computed", "type": "Boolean", "default": "false" }, { "name": "supported", "type": "Boolean", "default": "true" }, { "name": "align", "type": "String", "default": "right" } ], "targets": [], "actions": ["computedCB"] }}This lets agents set data attributes correctly when customizing interactive behavior (e.g. data-midwest-dropdown-align-value="left"). Components without Stimulus controllers omit this key entirely.
If the component is not found, the response contains an error key instead:
{ "error": "Component 'nonexistent' not found" }search_components
Full-text search across component names, descriptions, options, slots, methods, and constants. Results are ranked by relevance.
| Parameter | Type | Required | Description |
|---|---|---|---|
query |
string |
yes | Search term (e.g. "dropdown", "form input", "icon") |
category |
string |
no | Filter by "elements" or "form" |
The search scores matches in: class name (10 pts), description (5 pts), options (3 pts each), slots (3 pts each), methods (2 pts each), and constants (1 pt each). Multi-word queries are split and scored independently.
Invocation:
{ "jsonrpc": "2.0", "id": 3, "method": "tools/call", "params": { "name": "search_components", "arguments": { "query": "dropdown" } }}Pass "category": "form" in arguments to restrict results to form components only.
Response:
{ "query": "dropdown", "results": [ { "component": "dropdown_menu_component", "class_name": "Midwest::DropdownMenuComponent", "category": "elements", "helper": "midwest_dropdown_menu", "relevance": 13.0, "description": null }, { "component": "dropdown_component", "class_name": "Midwest::DropdownComponent", "category": "elements", "helper": "midwest_dropdown", "relevance": 12.0, "description": null }, { "component": "dropdown_item_component", "class_name": "Midwest::DropdownItemComponent", "category": "elements", "helper": "midwest_dropdown_item", "relevance": 12.0, "description": null } ], "count": 7}Results are sorted by relevance descending. The top result is always the closest match. Use this tool when you don't know the exact component name — it will surface related components across the entire library.
get_component_examples
Retrieves usage examples from Lookbook preview files for a given component, including parameter annotations, descriptions, and source file paths.
| Parameter | Type | Required | Description |
|---|---|---|---|
component |
string |
yes | Component name (e.g. "button_component", "form/input_component", or "button") |
Invocation:
{ "jsonrpc": "2.0", "id": 4, "method": "tools/call", "params": { "name": "get_component_examples", "arguments": { "component": "button" } }}Response:
{ "component": "button_component", "class_name": "Midwest::ButtonComponent", "examples": [ { "name": "default", "description": "This is the minimum code needed to make a tag.", "source": "preview", "file": "demo/app/previews/elements/button_component_preview.rb" }, { "name": "playground", "description": "which can be edited live in the Lookbook UI", "source": "preview", "file": "demo/app/previews/elements/button_component_preview.rb", "parameters": [ { "name": "label", "type": "text", "description": "The button label" }, { "name": "variant", "type": "select", "description": "Visual style variant", "choices": ["default", "outline", "ghost"] }, { "name": "size", "type": "select", "description": "Button size", "choices": ["large", "default", "small", "tiny"] }, { "name": "icon", "type": "select" } ] }, { "name": "fab", "description": "Intended to float above content; position it with fixed or absolute in context.", "source": "preview", "file": "demo/app/previews/elements/button_component_preview.rb" } ], "count": 6}Each example maps to a method in the Lookbook preview file. The file path tells you where to read the source code for that example. The parameters array (present on interactive examples like playground) lists the knobs available — the choices array shows allowed values, which correspond to the component's constants.
Use this tool after get_component_api to see how a component is actually used in practice.
get_helper_methods
Lists all view helper methods provided by Midwest, including both standard component helpers and special helpers like midwest_form_with and midwest_table_from.
| Parameter | Type | Required | Description |
|---|---|---|---|
helper |
string |
no | Filter to a single helper by name (e.g. "midwest_button" or "midwest_table_from") |
Without a filter, returns all standard helpers (component → helper mappings) and special helpers (with signatures and descriptions).
Invocation:
{ "jsonrpc": "2.0", "id": 5, "method": "tools/call", "params": { "name": "get_helper_methods", "arguments": {} }}Response:
{ "standard_helpers": [ { "helper": "midwest_button", "component": "Midwest::ButtonComponent" }, { "helper": "midwest_tabs", "component": "Midwest::TabsComponent" }, { "helper": "midwest_form_input", "component": "Midwest::Form::InputComponent" } ], "special_helpers": [ { "method": "midwest_table_from", "signature": "midwest_table_from(presenter, **html_options, &extra_columns)", "description": "Renders a Midwest::TableComponent with columns, sort state, and pagination fully configured from a Midwest::TablePresenter instance." }, { "method": "midwest_form_with", "signature": "midwest_form_with(builder: Midwest::FormBuilder, **args, &)" }, { "method": "midwest_colors", "signature": "midwest_colors" } ], "count": 86}With a helper filter, the response returns just that helper's details:
{ "helper": "midwest_button", "component": "Midwest::ButtonComponent" }Use this tool to discover which helper method to call in ERB for a given component, or to explore the special helpers that don't map 1:1 to a component.
get_form_builder_info
Documents the Midwest form builder — which Rails form methods are available and which Midwest components they render.
| Parameter | Type | Required | Description |
|---|---|---|---|
method |
string |
no | Filter to a single form method (e.g. "email_field", "select") |
Without a filter, returns all form builder methods with their signatures, target components, and any implicit options the builder sets automatically.
Invocation:
{ "jsonrpc": "2.0", "id": 6, "method": "tools/call", "params": { "name": "get_form_builder_info", "arguments": { "method": "email_field" } }}Response (single method):
{ "method": "email_field", "signature": "email_field(method, **options, &)", "component": "Midwest::Form::InputComponent", "implicit_options": { "type": "email" }}The implicit_options hash shows options the form builder sets for you — here, email_field automatically sets type: "email" on the underlying InputComponent, so you don't need to pass it yourself.
Response (all methods):
{ "form_builder_class": "Midwest::FormBuilder", "extends": "ActionView::Helpers::FormBuilder", "usage": "midwest_form_with do |f| ... end", "methods": [ { "method": "text_field", "signature": "text_field(method, **options, &)", "component": "Midwest::Form::InputComponent" }, { "method": "email_field", "signature": "email_field(method, **options, &)", "component": "Midwest::Form::InputComponent", "implicit_options": { "type": "email" } }, { "method": "select", "signature": "select(method, choices = nil, options = {}, **html_options, &)", "component": "Midwest::Form::SelectComponent" } ], "count": 48}Use this tool when building forms with midwest_form_with to know exactly which methods are available and what they render.
get_component_relationships
Shows how a component relates to other components in the library — which components it renders as children via slots, which parent components render it, which view helpers reference it, and which form builder methods create it.
| Parameter | Type | Required | Description |
|---|---|---|---|
component |
string |
yes | Component name (e.g. "carousel", "form/input_component") |
Invocation:
{ "jsonrpc": "2.0", "id": 7, "method": "tools/call", "params": { "name": "get_component_relationships", "arguments": { "component": "carousel" } }}Response:
{ "component": "carousel_component", "class_name": "Midwest::CarouselComponent", "renders_children": [ { "slot": "slides", "kind": "many", "component": "Midwest::SlideComponent" } ], "rendered_by_parents": [], "view_helpers": ["midwest_carousel"], "form_builder_methods": []}The renders_children array shows slot-based composition — here, CarouselComponent accepts many SlideComponent instances via its slides slot. The rendered_by_parents array is the reverse: it shows which parent components render this component in one of their slots.
Use this tool to understand component composition patterns and discover related components.
validate_component_usage
Validates a proposed component usage against the parsed API. Checks that option names are recognized, option values match allowed constants, and slot names exist on the component.
| Parameter | Type | Required | Description |
|---|---|---|---|
component |
string |
yes | Component name |
options |
object |
no | Hash of option names to values to validate |
slots |
array |
no | Array of slot names being used |
Invocation:
{ "jsonrpc": "2.0", "id": 8, "method": "tools/call", "params": { "name": "validate_component_usage", "arguments": { "component": "button", "options": { "colour": "red", "variant": "primary" }, "slots": ["nonexistent_slot"] } }}Response:
{ "component": "button_component", "class_name": "Midwest::ButtonComponent", "valid": false, "errors": [ { "type": "unknown_option", "option": "colour", "message": "Unknown option 'colour'." }, { "type": "invalid_value", "option": "variant", "value": "primary", "message": "Invalid value 'primary' for option 'variant'. Allowed values: default, outline, ghost, tab, tab-vertical, fab, mobile-nav", "allowed_values": ["default", "outline", "ghost", "tab", "tab-vertical", "fab", "mobile-nav"] }, { "type": "unknown_slot", "slot": "nonexistent_slot", "message": "Unknown slot 'nonexistent_slot'." } ], "warnings": [ { "type": "unused_slot", "slot": "badge", "kind": "one", "message": "Component has slot 'badge' (one) that is not being used" } ]}When all inputs are valid, the response returns "valid": true with an empty errors array. The warnings array notes available slots that aren't being used — these are informational, not errors.
This tool is especially useful for agents to self-check generated code before presenting it. An agent can validate its proposed helper call and fix any issues before the user sees the output.
More tools
Beyond the eight component-intelligence tools above, the server exposes seventeen more, grouped by purpose. They follow the same request/response shape (a tools/call with a name and arguments, a JSON payload back); the parameters and return values are summarised here.
Guidance & diagnostics
These tools help an agent choose, debug, and accessibility-check components rather than just describe them.
suggest_components
Suggests components for a piece of context — pass a code/markup snippet or a description of the UI you are building, and it returns ranked suggestions with the reason each was surfaced (matched markup, keyword, or composition with what you already use).
| Parameter | Type | Required | Description |
|---|---|---|---|
context |
string |
yes | A snippet or a description (e.g. "a settings form with a toggle and a save button", or raw ERB/HTML) |
category |
string |
no | Restrict to "elements" or "form" |
limit |
integer |
no | Max suggestions to return (default 8) |
Use this when you don't yet know which components fit — it maps intent to the library.
diagnose_component
Debugs a component that isn't behaving as expected. Given a component and an optional symptom, it returns ranked likely causes with fixes, plus common fixes curated for that component.
| Parameter | Type | Required | Description |
|---|---|---|---|
component |
string |
yes | Component name (e.g. "dropdown_component", "button") |
symptom |
string |
no | The problem (e.g. "clicking does nothing", "double borders", "field is not submitted") |
Returns a ranked list of probable causes and how to fix each.
get_accessibility_info
Returns a component's accessibility contract: ARIA roles and attributes, keyboard interactions, screen-reader behaviour, focus management, and the relevant WCAG success criteria. Inherited shared patterns (e.g. roving focus) are merged in.
| Parameter | Type | Required | Description |
|---|---|---|---|
component |
string |
yes | Component name (e.g. "dropdown_component", "Midwest::TabsComponent") |
get_performance_characteristics
Returns a component's rendering-cost tier (light/moderate/heavy) and, for data-driven components, its dataset limits and scaling strategies (pagination, infinite scroll, lazy loading). Structural signals — whether it renders a collection, ships a Stimulus controller, or has continuous motion — are derived from the code so they never drift; a curated overlay adds recommended dataset sizes and guidance. The cost tier is a structural profile of how the work scales, not a measured benchmark.
| Parameter | Type | Required | Description |
|---|---|---|---|
component |
string |
no | Component name (e.g. "table_component", "Midwest::TreeViewComponent"). Omit for a library-wide overview ranking the dataset-sensitive components by cost tier |
get_bundle_analysis
Analyzes what a component pulls in: the transitive set of components it renders (through slots, template helpers, direct renders, and Ruby constructions — resolved from the syntax tree), the summed asset footprint of that set (co-located CSS + Stimulus controller source, with a per-component breakdown), and any dependency cycles. Useful for gauging how "heavy" using a component is.
| Parameter | Type | Required | Description |
|---|---|---|---|
component |
string |
yes | Component name (e.g. "table_component", "Midwest::TableComponent") |
The footprint is unminified, pre-gzip, and excludes shared base styles/tokens — a relative weight for comparison, not an exact production bundle size.
Preview generation
These tools produce ready-to-use preview artefacts.
generate_preview
Generates a Lookbook preview skeleton for a component from its code — the preview .rb source (a default plus a playground with @param controls inferred from the options) and the sidecar .html.erb templates that render it, ready to drop into demo/app/previews.
| Parameter | Type | Required | Description |
|---|---|---|---|
component |
string |
yes | Component name (e.g. "button", "form/input_component") |
examples |
array |
no | Extra example method names to stub alongside default/playground (e.g. ["with_icon", "disabled"]) |
generate_iframe
Wraps a code block in a sandboxed <iframe srcdoc> that renders it live with Midwest's stylesheet injected — a self-contained preview to embed next to the source. Best for HTML/SVG markup; other languages are injected but only display as text. Scripts never run (the frame is sandboxed for styling only).
| Parameter | Type | Required | Description |
|---|---|---|---|
code |
string |
yes | The markup to inject and render |
language |
string |
no | Language of the block (e.g. "html", "erb", "svg"); only HTML-like markup renders visually |
title |
string |
no | Accessible title for the iframe (default "Midwest preview") |
theme |
string |
no | Colour scheme: "light" or "dark" |
height |
integer |
no | Iframe height in pixels (default 240) |
Design system
These tools document the design system itself — tokens, breakpoints, and motion — parsed from the gem's own source of truth so the values match exactly what components render.
get_design_tokens
Returns the canonical design-token values: spacing, border radius, elevation/shadow, motion (durations and easings), typography, z-index, breakpoints, and colour scales.
| Parameter | Type | Required | Description |
|---|---|---|---|
category |
string |
no | One of font_size, font_weight, font_family, spacing, radius, shadow, duration, easing, line_height, letter_spacing, z_index, breakpoint, colors. Omit for the full token tree |
get_breakpoints
Explains the responsive breakpoint system: the design-token breakpoint scale (xs–2xl), the root-font-size ladder those breakpoints drive, CSS container-query support, and how it all relates to Tailwind's utility-variant breakpoints (which intentionally differ from the token scale).
| Parameter | Type | Required | Description |
|---|---|---|---|
section |
string |
no | One of strategy, breakpoints, container_queries, tailwind. Omit for the full document |
get_animation_info
Returns a single component's motion: durations, easing curves, keyframes, prefers-reduced-motion support, and how to customise it. Parsed durations and easings are matched against the canonical --duration-*/--ease-* tokens, with curated summaries and advisories merged in.
| Parameter | Type | Required | Description |
|---|---|---|---|
component |
string |
yes | Component name (e.g. "accordion_component", "Midwest::ChartComponent") |
get_motion_system
Explains the motion system as a whole: the standardised duration scale (--duration-fast/base/slow/slower) and easing scale (--ease-standard/in/out/emphasized) with what each step is for, the slide-distance scale, the animation/direction/trigger vocabulary, the library-wide prefers-reduced-motion contract, and how app-wide motion defaults are configured and resolved. The per-component counterpart is get_animation_info; raw values are in get_design_tokens.
| Parameter | Type | Required | Description |
|---|---|---|---|
section |
string |
no | One of strategy, durations, easings, distances, vocabulary, reduced_motion, configuration. Omit for the full document |
get_token_usage
Maps which components use which design tokens. Pass component for the tokens it uses (grouped by category), token for the components that use a given token, or neither for an adoption overview (per-category usage, unused tokens, most-used tokens).
| Parameter | Type | Required | Description |
|---|---|---|---|
component |
string |
no | Component name — returns the tokens it uses |
token |
string |
no | A token name (e.g. "theme-6", "space-md", "--duration-fast") — returns the components using it |
Migration
get_migration_guide
Builds a migration guide between Midwest versions from the changelog: removals, changes, additions, and heuristic migration notes.
| Parameter | Type | Required | Description |
|---|---|---|---|
from |
string |
no | Version you are upgrading FROM (e.g. "0.22.0"); its own changes are excluded |
to |
string |
no | Version you are upgrading TO; defaults to the latest release |
topic |
string |
no | Narrow to releases mentioning a term (e.g. "tailwind", "theme", "popover"); scans all history unless from is set |
Charts
These tools document the chart subsystem — how its classes relate and what data each chart type expects.
get_chart_relationships
Explains how the chart subsystem is wired: the ChartComponent facade and the chart-type → chart-class map, the BaseChart → CartesianChart → concrete-type inheritance, the Support value objects (Series, DataPoint, SeriesBuilder, Geometry, config structs), and the data-flow pipeline from a raw series: array to inline SVG.
| Parameter | Type | Required | Description |
|---|---|---|---|
section |
string |
no | One of overview, types, hierarchy, support, data_flow, rendering, related_tools. Omit for the full document |
get_chart_data_requirements
Describes the series: data format each chart type expects — array shape, required keys, a worked example, and the most relevant options — plus the shared series_from: collection builder.
| Parameter | Type | Required | Description |
|---|---|---|---|
type |
string |
no | One of pie, column, bar, line, spline, area, stacked_bar, stacked_area, bubble. Omit for all types |
Turbo
get_turbo_patterns
Documents how Midwest integrates with Hotwire Turbo: the Frame-driven pieces (remote and history-aware dialogs, the TurboTable sort/filter/paginate frame, command-palette and autocomplete frames), the Stream update patterns (the notifications container and single-row table updates via the shared row component), how Turbo Stream broadcasts over a channel plug in, dynamic per-arrival asset loading (midwest_assets), and the table-specific parsing gotchas.
| Parameter | Type | Required | Description |
|---|---|---|---|
section |
string |
no | One of overview, frames, streams, channels, assets, gotchas, related_tools. Omit for the full document |
The email section components (midwest_email_*) are a separate library from the web
components, so they are surfaced through their own tools rather than mixed into the
component-intelligence set above.
get_email_client_support
Explains how the email section components render across mail clients: the library-wide
contract (why tables, inline styles, VML bulletproof buttons, dark-mode class hooks, no
SVG/JS, absolute URLs), the client matrix (what Outlook/Gmail/Apple Mail each support and
break), and per-component caveats. Omit component for the overview; pass one for a single
component's caveats.
| Parameter | Type | Required | Description |
|---|---|---|---|
component |
string |
no | A midwest_email_* component (e.g. button, email/status, or the full class name). Omit for the library-wide overview |
section |
string |
no | Scope the overview to one of summary, clients, contract, testing, components |
list_components also gains a kind parameter — web (default), email, or all — so
the email library is discoverable alongside the web components.
Using the --root flag
By default, the server auto-detects the Midwest gem location — either from a local midwest.gemspec (development) or from the installed gem path. You can override this with --root:
bundle exec midwest_mcp --root /path/to/midwestThis is primarily useful during gem development or when running the server against a checkout that isn't the installed gem.
To pass --root through an MCP client configuration:
{ "mcpServers": { "midwest": { "command": "bundle", "args": ["exec", "midwest_mcp", "--root", "/path/to/midwest"] } }}Tips for effective use
- Ask the agent to search first. A prompt like "which Midwest component handles dropdown menus?" will trigger
search_componentsand return ranked matches — better than guessing the component name. - Request the API before generating code. The agent can call
get_component_apito learn exact option names, defaults, and Stimulus controller data — producing correct helper calls on the first try. - Use examples for context.
get_component_examplesgives the agent real preview code to reference, which improves the quality of generated markup. - Scope with categories. If you're working on a form, tell the agent to filter by the
"form"category to narrow results. - Check helper methods. When unsure which helper to use,
get_helper_methodsmaps every component to its ERB helper name. - Use validation as a safety net. After generating component code, agents can call
validate_component_usageto catch typos and invalid values before presenting the result. - Explore relationships.
get_component_relationshipsreveals composition patterns — which components nest inside others — so agents can generate complete, nested markup. - Describe the UI, not the component. When you don't know what to reach for,
suggest_componentsmaps a plain-language description (or a snippet of markup) to ranked component picks. - Debug with
diagnose_component. Paste the symptom — "clicking does nothing", "double borders" — and get ranked likely causes with fixes instead of guessing. - Check accessibility up front.
get_accessibility_inforeturns a component's ARIA/keyboard/focus contract and the relevant WCAG criteria, so generated markup is accessible by default. - Stay on-system.
get_design_tokens,get_breakpoints, andget_motion_systemexpose the canonical spacing, colour, breakpoint, and motion values — so agents use tokens rather than magic numbers. - Size before you scale. Before rendering a table, chart, or tree with a lot of data,
get_performance_characteristicsgives the component's cost tier, a recommended dataset ceiling, and the built-in strategies (pagination, infinite scroll, lazy loading) to stay fast. - Weigh what you pull in.
get_bundle_analysisshows a component's transitive dependency set and summed asset footprint — handy for comparing two components or understanding everything a single one drags along. - Plan upgrades.
get_migration_guideturns the changelog into a from/to guide (or traces a topic like"tailwind"across all versions) before you bump the gem.