@hex-core/mcp
Stdio MCP server: emit_app_context, emit_figma_tokens, resolve_spec, and more.
Install
0.4.2Tool / dlx invocationpnpm dlx @hex-core/mcpWhat it does
`@hex-core/mcp` is the stdio MCP (Model Context Protocol) server. It exposes the registry, themes, recipes, and the canonical LLM payload as structured tool calls for AI agents.
Wire it into Claude Code, Cursor, Continue, Zed, ChatGPT Desktop, or any MCP-aware client and your agent gains tools like `search_components`, `get_component`, `list_recipes`, `emit_app_context`, and `emit_figma_tokens`. Every tool's I/O is schema-validated; agents can't pass unknown fields.
As of `@hex-core/mcp@0.4.0`, the server is a thin transport shell over `@hex-core/payload`. The pure-function builders live in `payload`; this package wraps them in `@modelcontextprotocol/sdk`'s server primitives. If you want the same outputs without the stdio handshake, depend on `@hex-core/payload` directly.
Public API
search_components
{
name: "search_components",
input: { query: string; limit?: number },
output: { results: { slug: string; score: number; matchedOn: string[] }[] }
}Fuzzy search across component names, descriptions, tags, and AI hints. Higher score = better match. Agents call this first when picking a primitive.
// agent prompt: "find me a confirmation dialog"
// → search_components({ query: "confirmation dialog" })
// → { results: [{ slug: "dialog", score: 0.94, ... }, { slug: "alert-dialog", score: 0.91, ... }] }get_component / get_component_schema
{
name: "get_component",
input: { slug: string },
output: RegistryItem
}
{
name: "get_component_schema",
input: { slug: string },
output: { props: PropDef[]; variants: VariantDef[]; ai: AIHints }
}`get_component` returns the full registry item — props, variants, examples, AI hints, source. `get_component_schema` returns the schema slice only, for agents reasoning about a component they've already installed.
// agent has already added the button — only needs the schema
// → get_component_schema({ slug: "button" })emit_app_context
{
name: "emit_app_context",
input: {
theme: string; // theme name
components: string[]; // slugs
recipes?: string[];
overrides?: Record<string, string>;
density?: "compact" | "comfortable" | "spacious";
},
output: { content: [{ type: "text", text: /* markdown */ }] }
}Returns the full canonical context markdown — install commands, `globals.css`, `tailwind.config.ts`, components, recipes, and the LLM context prompt. Same artifact `@hex-core/payload`'s `buildAppContext` produces.
// One call powers the studio's /copy page workflow:
// → emit_app_context({
// theme: "default",
// components: ["button", "card", "input"],
// density: "comfortable",
// })emit_figma_tokens
{
name: "emit_figma_tokens",
input: { theme: string },
output: { content: [{ type: "text", text: /* JSON */ }] }
}Emit a Figma Variables JSON document for the named theme. Same shape `@hex-core/payload`'s `buildFigmaTokens` returns — paste into the Figma plugin's import slot.
// → emit_figma_tokens({ theme: "midnight" })
// → { content: [{ type: "text", text: '{"$schema":...}' }] }list_recipes / get_recipe
{ name: "list_recipes", input: {}, output: { recipes: { slug: string; description: string }[] } }
{ name: "get_recipe", input: { slug: string }, output: Recipe }Enumerate the recipe catalog (auth-form, settings-page, command-palette, …) or fetch one in full with its ordered install steps and post-install checklist.
// → list_recipes()
// → { recipes: [{ slug: "auth-form", ... }, { slug: "settings-page", ... }, ...] }resolve_spec / verify_checklist
{ name: "resolve_spec", input: { brief: string }, output: { components: string[]; recipes: string[]; rationale: string } }
{ name: "verify_checklist", input: { installed: string[] }, output: { missingPeers: string[]; ok: boolean } }`resolve_spec` turns a natural-language brief into a ranked component shortlist. `verify_checklist` cross-checks the agent's installed list against the registry's internal-dependency graph.
// → resolve_spec({ brief: "settings page with profile, billing, notifications" })
// → { components: ["tabs", "card", "input", ...], recipes: ["settings-page"], rationale: "..." }Workflows
Wire the server into Claude Code
Drop the snippet into `.claude/settings.json` (project) or `~/.claude/settings.json` (global). The next Claude session picks up the tools.
{
"mcpServers": {
"hex-ui": {
"command": "npx",
"args": ["@hex-core/mcp"]
}
}
}Wire the server into Cursor
Cursor reads `.cursor/mcp.json` at the project root.
{
"mcpServers": {
"hex-ui": {
"command": "npx",
"args": ["@hex-core/mcp"]
}
}
}Skip the transport — call buildAppContext directly
If you're inside a Server Component or a generator script and don't need the tool-call overhead, depend on `@hex-core/payload` instead. Same output, no stdio handshake.
import { buildAppContext, loadRegistryItem } from "@hex-core/payload";
import { defaultTheme } from "@hex-core/tokens";
const components = ["button", "card"].map((slug) => ({
slug,
item: loadRegistryItem(slug),
}));
const markdown = buildAppContext({
theme: { requested: "default", resolved: defaultTheme },
components,
});Compatibility
- Requires Node.js 20.9+ on the client side (whatever spawns the server). The bundled registry travels with the tarball, so the server boots without network access.
- Bin name: `hex-ui-mcp`. Most MCP clients invoke via `npx @hex-core/mcp` rather than the bin directly.
- All tool I/O is Zod-validated with `additionalProperties: false`. Invalid input throws structured errors back to the client.
- Depends on `@modelcontextprotocol/sdk@^1.12.0`, `@hex-core/payload@^0.2.0`, `@hex-core/registry@^0.2.1`.