@runsnative/mcp-server
v0.13.0
Published
RunsNative MCP server — gives any MCP-capable agent access to RunsNative component docs, foundations, design exercises, and theme inference.
Readme
@runsnative/mcp-server
RunsNative MCP server — gives any MCP-capable agent access to RunsNative component docs, foundations, design exercises, and theme inference.
Docs content comes from the RunsNative cloud content API by default — no clone or configuration required, and content updates propagate without reinstalling. Developers working in the runsnative repo can set RUNSNATIVE_CONTENT_ROOT to serve from a local checkout instead.
Quick install
Add one block to your MCP client config. No environment configuration is needed.
Claude Desktop
macOS — ~/Library/Application Support/Claude/claude_desktop_config.json
Windows — %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"runsnative": {
"command": "npx",
"args": ["-y", "@runsnative/mcp-server"]
}
}
}Claude Code / Cursor (project-scoped)
Add .mcp.json to your project root:
{
"mcpServers": {
"runsnative": {
"command": "npx",
"args": ["-y", "@runsnative/mcp-server"]
}
}
}To serve from a local checkout instead of the cloud API, add an env block:
"env": { "RUNSNATIVE_CONTENT_ROOT": "/path/to/runsnative/content" }Authoring skill
Once the MCP server is connected, load the RunsNative authoring skill to give your agent full component-authoring guidance. The skill is served at:
https://runsnative.org/ai/authoring-skillPaste that URL into Claude's "Add custom skill" dialog, or add it to your agent's system prompt as a skill reference. The MCP tools and the authoring skill work together — the skill tells the agent how to author; the tools give it the live content.
Tools provided
| Tool | Description |
|---|---|
| list_components | List all available RunsNative components |
| get_component | Fetch usage, style, code, or accessibility docs for a component |
| list_composition_patterns | List composition patterns (recipes) for complete UI surfaces — sign-in form, dashboard shell, chat room, etc. |
| get_composition_pattern | Fetch the full pattern for a named recipe: preview spec, framework code examples, accessibility notes, customization guidance |
| get_foundation | Fetch a specific foundation doc |
| get_step | Fetch a specific step within an exercise |
| search_docs | Semantic search across all RunsNative docs |
| list_exercises | List available design exercises |
| start_exercise | Start a design exercise |
| infer_theme | Infer a RunsNative theme from a URL or description |
| infer_brand_theme | Infer a theme from brand imagery |
| get_emphasis_scale | The five-treatment emphasis scale with loudness weights |
| get_completeness_map | Component completeness map across docs dimensions |
| link_session | Pair the agent with a logged-in runsnative.org tab (consent-gated) |
| navigate / set_theme | Drive the linked tab: change routes, switch themes |
| set_instance_variant | Change a component instance in the linked tab by marker-capture handle |
| resolve_target | Resolve a natural-language description ("language switcher") to live spotlight targets in the linked tab (JUNE-1257) |
| spotlight | Settle a spotlight ring on a target in the linked tab — a data-tour contract anchor or a resolve_target/marker instance:<handle> (JUNE-621) |
| get_marker_capture | Receive regions circled with the marker overlay — structural head only, pixels not inlined |
| render_marker_capture | Render the most recent marker capture as a live MCP App card with spotlight/change/introspect actions (JUNE-623) |
| fetch_marker_crop | Fetch a marker capture's pixel crop on demand — the lazy-pixel pull |
| render_gathering | Render the user's latest Convene gathering as a live, branded MCP App card in the conversation (JUNE-618) |
Marker capture: push→pull pixel economics (JUNE-623)
get_marker_capture and render_marker_capture deliver a capture's structural head by
default — the resolved component-instance address, render inputs, and note — and never inline
the pixel crop. The agent fetches pixels only when the complaint is visual, via
fetch_marker_crop. The rationale (JUNE-623, founder-normative): the user already sees the real
thing on their screen — the screenshot-paste ritual was always for the agent's benefit, so let
the consumer of the information decide its own input-token budget.
The three-way comparison below is computed, not eyeballed — reproduce it with the formulas below rather than trusting the numbers as given.
| Path | What's sent | Tokens |
|---|---|---|
| (a) Copy-paste screenshot | Full-viewport image, no structural data | ~1,366 |
| (b) Lasso, crop fetched | Structural head (JSON) + the fetched crop image | ~150 |
| (c) Lasso, metadata-only | Structural head (JSON) only — fetch_marker_crop never called | ~98 |
Methodology:
- Image tokens use Claude's documented vision approximation,
tokens ≈ (width_px × height_px) / 750.- (a) assumes a full-viewport screenshot at a common desktop capture size, 1280×800 →
(1280×800)/750 ≈ 1366. - (b) assumes a tight marker-overlay crop around the circled element, 320×120 →
(320×120)/750 ≈ 52.
- (a) assumes a full-viewport screenshot at a common desktop capture size, 1280×800 →
- Text tokens use the standard ~4-characters-per-token approximation, applied to the actual
JSON
get_marker_capture/render_marker_captureemit for a capture head:
391 characters →{ "capture_id": "8f3a2b1c-4d5e-4a6b-9c7d-1e2f3a4b5c6d", "address": { "type": "run-button", "path": "main>section>run-button", "index": 2, "instanceId": "a1b2c3d4-e5f6-4789-abcd-0123456789ab" }, "inputs": { "data-run-skin": "default", "data-run-mode": "light" }, "note": "make this one pop", "created_at": "2026-07-13T14:22:00.000Z", "has_crop": true }391/4 ≈ 98tokens. - (b) = 98 (head) + 52 (crop) ≈ 150. (c) = 98 (head only).
Both lasso paths beat the copy-paste screenshot on tokens; metadata-only is the largest win (~93% fewer tokens than the screenshot) and is exact — the agent already has the machine-readable address, whereas OCR-from-pixels for a structural change ("make this secondary") is a lossy detour on top of the token cost.
Environment variables
| Variable | Default | Description |
|---|---|---|
| RUNSNATIVE_API_URL | https://api.runsnative.org/mcp | Override the content API base URL (e.g. point at wrangler dev locally) |
| RUNSNATIVE_CACHE_DIR | ~/.runsnative/cache | Override the local content cache directory |
| RUNSNATIVE_CONTENT_ROOT | (unset) | Set to use local content instead of the cloud API. For developers working in the RunsNative repo |
| RUNSNATIVE_TENANT_TOKEN | (unset) | Bearer token for tenant-specific content access |
Requirements
- Node.js 18 or later
For RunsNative repo developers
If you're working inside the RunsNative repo, use the .mcp.json at the repo root. It runs the launcher tools/mcp/runsnative-mcp.mjs and sets RUNSNATIVE_CONTENT_ROOT so you get live content from your working tree without hitting the cloud API.
dist/ is gitignored, so git worktrees never have one. The launcher serves this checkout's own dist/index.js when it exists, and otherwise the main checkout's (found via git rev-parse --git-common-dir). It refuses loudly — a failed MCP server at session start, with the reason in the MCP log — when there is no build, or when the build is older than a non-test file in its src/ (a tool merged since would otherwise be silently missing). RUNSNATIVE_MCP_ALLOW_STALE=1 serves a stale build anyway. It never builds for you (RUN-662).
Build once, in the main checkout, and again after any src/ change lands there:
cd packages/mcp-server && npm run build