# @corva/ui MCP Server

MCP (Model Context Protocol) server that exposes `@corva/ui` component library documentation to AI coding agents. Setup
supports Claude Code, Cursor, and Codex CLI.

## Table of Contents

- [Overview](#overview)
    - [Available Tools](#available-tools)
    - [Usage](#usage)
    - [Available Prompts](#available-prompts)
- [Setup](#setup)
    - [Quick Setup](#quick-setup)
    - [Local Setup (Recommended)](#local-setup-recommended)
    - [Monorepo Setup](#monorepo-setup)
    - [Global Installation (Rare)](#global-installation-rare)
- [Verifying It Works](#verifying-it-works)
- [Telemetry and Privacy](#telemetry-and-privacy)
- [FAQ](#faq)

## Overview

### Available Tools

- `search_corva_ui` - Search components, hooks, utils by name or description. When a search restricted to one
  `category` (`v2` or `v1`) returns nothing at all and components from the other version do match, the response
  surfaces them in a labeled fallback block so a single search still discovers a candidate. Any hook or util hit
  already counts as a result and suppresses the fallback.
- `get_component_docs` - Get detailed component documentation with props and examples
- `get_hook_docs` - Get hook documentation
- `get_theme_docs` - Get theme/styling documentation
- `list_corva_ui` - List all available items by category
- `get_constants_docs` - Get constants documentation (values, namespaces, usage)
- `get_client_docs` - Get API client documentation (methods, endpoints). A large client answers with its endpoint categories and counts; pass one back as `tag` to get that category complete
- `get_diagnostics` - Get MCP server health metrics (server version, uptime, memory, request stats, telemetry status, project identity, registered prompts)
- `submit_feedback` - Send feedback about `@corva/ui` or this MCP server to the maintainers (docs gaps, wrong/missing
  props, search misses). The assistant can also call this on its own when it hits a gap.
- `get_migration_guide` - Get the component migration manifest (source -> target pairs, tiers, per-prop transforms)
- `get_dataset_types_guide` - Static reference for typing Corva dataset payloads from live field coverage: reading
  `datasets_fields` output, mapping it to TypeScript, and wiring self-contained types into `@corva/ui` data callers.
  Pairs with the `generate_dataset_types` prompt, which runs the full generate-and-stamp workflow.
- `get_corva_mcp_setup_guide` - Static connection reference for the Corva MCP data server: endpoints, per-client
  registration commands, browser OAuth flow, and the verification call. Pairs with the `setup_corva_mcp` prompt, which
  runs the guided end-to-end setup.
- `get_figma_to_code_guide` - Static method reference for implementing Figma designs with `@corva/ui`: source
  precedence, capability-based component search across V2 and V1, token and prop discipline, and gap reporting. Pairs
  with the `figma_to_code` prompt, which runs the strict guided workflow.

### Usage

No special keywords required. The AI automatically uses these tools when you ask about:

- **Components**: "What's the Button component?", "How do I use Tooltip?"
- **Hooks**: "How does useSubscriptions work?"
- **Theme**: "What colors are in the palette?"
- **Browsing**: "List all v2 components"

Mentioning `@corva/ui`, component names, or asking about the design system triggers the MCP automatically.

### Available Prompts

MCP prompts are surfaced as slash commands in clients that support them. In Claude Code they appear under
`/mcp__corva-ui__<name>`.

- `figma_to_code` — Translate a Figma node into React components that follow `@corva/ui` conventions. Orchestrates the
  Figma MCP server (for design context and Code Connect mappings) and the `@corva/ui` MCP tools above (for component,
  icon, theme, and hook lookups).

**Argument** (optional; the assistant asks if missing):

- `input` — Freeform request. Paste the full Figma node URL (e.g.
  `https://www.figma.com/design/<fileKey>/...?node-id=<nodeId>`) together with any extra context: target path or
  directory in the app, an existing file to extend, naming preferences, edge cases. The assistant extracts the URL
  itself.

> A single freeform argument is intentional: Claude Code's MCP-prompt bridge splits positional string arguments on
> whitespace, so a multi-arg schema would only capture the first token of each.

**Example invocation** (Claude Code):

```
/mcp__corva-ui__figma_to_code https://www.figma.com/design/ABC/Sample?node-id=1-2 create under src/apps/drilling/RigStatusCard.tsx
```

**Prerequisite:** a Figma MCP server must be connected in the same client session so the prompt can call its
`get_design_context` tool (the prompt detects the server alias itself). Either connect Figma's remote server
(`https://mcp.figma.com/mcp`, browser OAuth — Figma's recommended option) or enable the desktop one: open the file in
Figma Desktop, switch to Dev Mode (`Shift+D`) and click **Enable desktop MCP server** in the MCP server section of the
inspect panel, then register `http://127.0.0.1:3845/mcp` as an HTTP MCP server in your client — enabling it in Figma
alone does not connect it. Reconnect or restart your client afterwards.

**Scope:** primarily consumer mode — app repos that depend on `@corva/ui` and import from its entry points. Authoring
mode (inside the `@corva/ui` repo itself) is auto-detected from `package.json` and adjusts output conventions.

- `feedback` — Send feedback about `@corva/ui` or this MCP server to the maintainers. The prompt collects your message
  (and an optional sentiment / which component the feedback is about) and submits it via the `submit_feedback` tool.

**Argument** (optional; the assistant asks if missing):

- `input` — Your feedback. Optionally mention a sentiment (positive / negative / neutral) and which component, hook, or
  tool it is about.

**Example invocation** (Claude Code):

```
/mcp__corva-ui__feedback the Button docs are missing the `variant` prop
```

- `healthcheck` — Check the health of this MCP server: server version, uptime, memory usage, request statistics,
  telemetry status, project identity, and registered prompts. Runs the `get_diagnostics` tool and presents the report.
  **Takes no arguments.**

**Example invocation** (Claude Code):

```
/mcp__corva-ui__healthcheck
```

- `migrate_components` — Migrate `@corva/ui` components from an older form to their current recommended replacement
  (e.g. V1 → V2, deprecated V2 → Next, and future generations). Discovers `@corva/ui` imports across the workspace,
  proposes a tiered plan (🟢 automatic / 🟡 supervised / 🔴 assisted), edits on your confirmation, leaves
  `// TODO(migrate)` breadcrumbs for non-mechanical changes, then typechecks/lints. Backed by the
  `get_migration_guide` tool.

**Argument** (optional):

- `input` — Freeform. Empty or `all` = broad scan of the whole workspace. One or more component names (e.g.
  `Button Modal`) = targeted. Natural language ("migrate our buttons and modals") is parsed for intent.

**Example invocations** (Claude Code):

```
/mcp__corva-ui__migrate_components
/mcp__corva-ui__migrate_components Button Modal
/mcp__corva-ui__migrate_components all
```

- `setup_corva_mcp` — Set up the remote **Corva MCP** (`corvian.corva.ai`) — the companion server for live Corva data
  (separate from this docs server). Registers the remote HTTP server for Claude Code / Cursor / Codex CLI (any other
  MCP client works via its own config) — globally for your user (default) or locally for the current project — walks
  you through browser OAuth, and verifies with one read-only data call. Skips straight to verification when already
  connected.

**Argument** (optional):

- `input` — Say `qa` to target the QA endpoint (`https://corvian.qa.corva.ai/mcp`); default is production
  (`https://corvian.corva.ai/mcp`). Say `project` (or `local`) to register for the current project only; default is
  user-global. Extra context (e.g. a preferred dataset for the verification call) is passed through.

**Example invocations** (Claude Code):

```
/mcp__corva-ui__setup_corva_mcp
/mcp__corva-ui__setup_corva_mcp qa
/mcp__corva-ui__setup_corva_mcp project
```

**Notes:** auth is a browser OAuth flow — no API keys are stored or asked for. Newly registered MCP servers become
visible only after a reconnect (`/mcp` in Claude Code) or a client restart; once reconnected the server is ready to
use — re-running the prompt afterwards is an optional just-in-case check that verifies the connection with one data
call. User-global registration makes the data server available in all your projects; project registration defaults
to user-private config files and writes repo-tracked ones (a shared `.mcp.json`, a project `.codex/config.toml`)
only after you explicitly accept that.

- `generate_dataset_types` — Generate a best-effort TypeScript payload type for a Corva dataset collection from its
  **live field coverage**, read through the Corva MCP's dataset tools. Dataset payloads are dynamic, so the result is
  a **hint, not a contract**: partially-present fields become optional, ambiguous ones become `unknown`, and the type
  carries a provenance stamp (collection, environment, sample size, date). The emitted types are self-contained (an
  app-local record wrapper plus the `Payload`) and plug into `@corva/ui` data callers with a cast at the response
  boundary. Re-running it for a collection whose generated type already exists
  reports drift against the stamp instead of silently overwriting.

**Argument** (optional; the assistant asks if missing):

- `input` — The collection to type, as `provider#dataset` (e.g. `corva#wits`) or a searchable name. Extra context is
  passed through: `qa` reads the QA environment, an asset/company narrows sampling scope, and a target file or type
  name directs where the type lands.

**Example invocations** (Claude Code):

```
/mcp__corva-ui__generate_dataset_types corva#wits
/mcp__corva-ui__generate_dataset_types corva#completion.wits into src/apps/frac/types.ts as FracWitsPayload
```

**Prerequisite:** the remote Corva MCP must be connected in the same client session — run
`/mcp__corva-ui__setup_corva_mcp` first if it is not. The prompt reads real data to compute the shape, so sampling
stays scoped and minimal, and raw sample values are never pasted into committed code.

## Setup

> **Just generated a fresh project with the latest `create-corva-app`?** MCP is already configured for Claude Code,
> Cursor, and Codex CLI in the generated project — skip the setup steps below and jump
> to [Verifying It Works](#verifying-it-works). Older projects scaffolded before MCP was added to the template still
> need the setup below.

> **Minimum Version:** the `npx … corva-ui-mcp` configs work from `@corva/ui` **3.44.0**; the Quick Setup command and
> the direct `server.mjs` paths need **3.46.0** or newer. Tool and prompt descriptions in this document match current
> releases.

> **Node:** `@corva/ui` declares `engines.node: ^24`, so use Node 24.x for the setup command and the server. Other
> majors are outside that range: npm prints an unsupported-engine warning when it installs the package, and Yarn
> classic normally rejects the install unless engine checks are disabled. The nvm examples below assume a Node 24
> install.

### Quick Setup

Run from your project root:

```bash
npx -p @corva/ui corva-ui-mcp-setup
```

This creates `.mcp.json` (Claude Code), `.cursor/mcp.json` (Cursor), and `.codex/config.toml` (Codex CLI) automatically.
Restart your IDE or reload MCP servers afterward.

> If any of these files already exist, the setup command **extends** them — your existing MCP server entries are
> preserved, and the `corva-ui` entry (`corva_ui` in the Codex TOML) is added only when it is missing. An entry that
> already exists is kept exactly as it is, so anything you added by hand, such as an `env` block with
> `CORVA_UI_MCP_TELEMETRY_DISABLED`, a `startup_timeout_sec`, or the Windows `cmd /c` form, survives a re-run after an
> upgrade; the command prints `(kept)` for that file. Pass `--force` to replace the entry with the stock one. A write
> re-serializes the whole file, so when the command adds or replaces an entry in the Codex TOML, comments and hand
> formatting are lost (the command says so in its output). A file that fails to parse is never written: the command
> prints the parse error and the path, and exits with a non-zero code. On native Windows the generated entry uses plain
> `npx`; if your client cannot spawn it, apply the `cmd /c` form from the Native Windows note under
> [Local Setup](#local-setup-recommended).

> **Monorepo:** Run the setup command from the monorepo root, not from individual
> `apps/*` directories. See [Monorepo Setup](#monorepo-setup) for details.

### Local Setup (Recommended)

**This is the recommended approach.** Add the MCP config to your project and it just works — no global installs, no PATH
issues, always in sync with your project's `@corva/ui` version.

| IDE         | Config File          |
|-------------|----------------------|
| Claude Code | `.mcp.json`          |
| Cursor      | `.cursor/mcp.json`   |
| Codex CLI   | `.codex/config.toml` |

> These configs reference `npx -p @corva/ui corva-ui-mcp` (no machine-specific paths), so they're safe to commit if your
> team wants project-wide MCP support.

#### Claude Code

1. Create `.mcp.json` in your project root:

```json
{
  "mcpServers": {
    "corva-ui": {
      "command": "npx",
      "args": [
        "-p",
        "@corva/ui",
        "corva-ui-mcp"
      ]
    }
  }
}
```

2. Restart Claude Code or run `/mcp` to reload servers

3. Verify: Ask Claude "search corva-ui for Button" - it should use the MCP tool

> **Native Windows note:** `npx` is a `.cmd` shim, and several MCP clients on native Windows (Claude Code; some Codex
> CLI builds) fail to spawn it directly with `ENOENT` or `spawn npx`. If you hit that, wrap with `cmd /c`:
>
> ```json
> { "command": "cmd", "args": ["/c", "npx", "--yes", "--package", "@corva/ui", "corva-ui-mcp"] }
> ```
>
> `--yes` skips npx's first-run "Need to install …?" prompt, which an MCP server start-up has no way to answer
> interactively. (`--package` is the long form of `-p`; in npm proper `-p` aliases `--parseable`, so the long
> form is clearer.) Cursor on Windows generally accepts plain `"command": "npx"` — try that first, only switch to the
> `cmd /c` form if it fails. WSL users (with the client also running in WSL) don't hit this — plain `npx` works.

#### Cursor

1. Create `.cursor/mcp.json` in your project root:

```json
{
  "mcpServers": {
    "corva-ui": {
      "command": "npx",
      "args": [
        "-p",
        "@corva/ui",
        "corva-ui-mcp"
      ]
    }
  }
}
```

2. Restart Cursor (or toggle the `corva-ui` server off and on under **Customize** in the sidebar)

3. Servers from `.cursor/mcp.json` show up under **Customize** in the sidebar, where they can be enabled or disabled.
   If one fails to start, its output is in the Output panel under "MCP Logs".

4. Verify: In the agent chat, ask about a @corva/ui component

#### OpenAI Codex CLI

1. Create `.codex/config.toml` in your project root:

```toml
[mcp_servers.corva_ui]
command = "npx"
args = ["-p", "@corva/ui", "corva-ui-mcp"]
```

2. Restart Codex CLI or start a new session

3. Verify: Ask about a @corva/ui component

#### Troubleshooting: Direct Path (Last Resort)

If `npx` doesn't work in your environment (e.g., restricted shell, corporate proxy blocking npm registry), you can
reference the module directly:

```json
{
  "mcpServers": {
    "corva-ui": {
      "command": "node",
      "args": [
        "node_modules/@corva/ui/mcp-server/server.mjs"
      ]
    }
  }
}
```

**Trade-offs:**

- Path may break if @corva/ui changes internal structure
- Won't work with monorepo hoisting (yarn/pnpm workspaces)
- Config isn't portable across different project structures

---

### Monorepo Setup

Use the same per-IDE configs from [Local Setup](#local-setup-recommended), but place them in the **monorepo root**.

For monorepos, place MCP config files (`.mcp.json`, `.cursor/mcp.json`, `.codex/config.toml`) in the
**monorepo root** — just like other shared configs (e.g., DC app configs placed at repo root). Do **not** place them
separately in each `apps/*` directory.

> **Cursor-specific note:** If you open each app in a separate Cursor window, the monorepo-root MCP configs won't be
> detected. To fix this, add the parent monorepo folder to the Cursor workspace: **File → Add Folder to Workspace**,
> then select the monorepo root.

---

### Global Installation (Rare)

Use this **only** if you need `@corva/ui` docs in projects that don't have `@corva/ui` as a dependency (e.g., backend
repos, scratch projects). For all other cases, prefer the [local setup](#local-setup-recommended) above.

**Trade-offs vs local setup:**

- You must manually run `npm i -g @corva/ui` to get documentation updates
- nvm users need absolute paths (PATH isn't inherited by MCP clients)
- Documentation version may drift from what your project actually uses

| IDE         | Config File            |
|-------------|------------------------|
| Claude Code | `~/.claude.json`       |
| Cursor      | `~/.cursor/mcp.json`   |
| Codex CLI   | `~/.codex/config.toml` |

> These are user-level configs — they apply to all projects on your machine. Do not commit them.

#### Step 1: Install Globally

```bash
npm i -g @corva/ui
```

> Required for the with-nvm setups below — they reference the binary by an absolute path (macOS / Linux),
> source `nvm.sh` to put it on PATH (Windows + WSL), or point Node at `mcp-server/server.mjs` directly
> (nvm-windows). Optional for the "without nvm" setups: those use `npx --yes --package @corva/ui`, which runs
> a matching local dependency when present or installs into npm's cache otherwise — `npx` does not honour the
> global install. If you need a strictly pinned version regardless of cache state (or are working offline / behind
> a registry-blocking proxy), use the [Troubleshooting: Direct Node Path](#troubleshooting-direct-node-path) form
> below.

#### Claude Code (with nvm)

MCP clients can't find nvm-managed binaries due to PATH
issues ([reference](https://github.com/modelcontextprotocol/servers/issues/64)). Use full paths.

##### macOS / Linux

1. Find your paths:

```bash
nvm which current      # e.g., /Users/you/.nvm/versions/node/v24.15.0/bin/node
which corva-ui-mcp     # e.g., /Users/you/.nvm/versions/node/v24.15.0/bin/corva-ui-mcp
```

2. Add the `mcpServers` entry to your `~/.claude.json` (create the file if it doesn't exist, or merge into existing
   config):

```json
{
  "mcpServers": {
    "corva-ui": {
      "command": "/Users/you/.nvm/versions/node/v24.15.0/bin/node",
      "args": [
        "/Users/you/.nvm/versions/node/v24.15.0/bin/corva-ui-mcp"
      ]
    }
  }
}
```

##### Windows + WSL

Node lives inside WSL, so where you point the MCP config depends on where the *MCP client* runs:

- **Client also runs inside WSL** (e.g. you launch `claude` from a WSL shell): follow the macOS / Linux instructions
  above unchanged. WSL is Linux for this purpose.
- **Client is the native Windows app** (Claude Code installed on Windows, Node only in WSL): wrap with `wsl.exe`. The
  most reliable shape is to source `nvm.sh` explicitly so the spawned shell finds your Node and the global bin,
  regardless of how your `.bashrc` is structured:

```json
{
  "mcpServers": {
    "corva-ui": {
      "command": "wsl.exe",
      "args": [
        "-e",
        "bash",
        "-lc",
        ". \"$HOME/.nvm/nvm.sh\" && exec corva-ui-mcp"
      ]
    }
  }
}
```

Notes for this config:

- `wsl.exe` with no `-d` uses your default distro. If your dev environment lives in a non-default distro, add
  `-d <DistroName>` (run `wsl.exe -l -v` to list them).
- First MCP-server start may be slow if WSL is cold (the VM has to boot). If your client times out, restart the client
  once WSL is warm.
- Simpler shapes like `["--", "corva-ui-mcp"]` or `["--", "bash", "-lc", "corva-ui-mcp"]` *can* work, but they're
  fragile: WSL's non-interactive shell may not source `nvm.sh`, so `corva-ui-mcp` won't be on PATH. Prefer the
  explicit-source form above unless you've verified the simpler one works on your setup.
- If you'd rather avoid `wsl.exe` from the Windows-side client, install Node natively on Windows and follow
  [Native Windows (nvm-windows)](#native-windows-nvm-windows) below — keep WSL for everything else and run the MCP
  server off the native Node.

##### Native Windows (nvm-windows)

`nvm which` doesn't exist on `nvm-windows`. Find the active Node bin path and the global npm prefix:

```cmd
:: cmd
where node
npm prefix -g
```

```powershell
# PowerShell — bare `where` is an alias for Where-Object, so use where.exe (or Get-Command):
where.exe node
npm prefix -g
```

`where node` typically returns the `NVM_SYMLINK` path (default `C:\Program Files\nodejs\node.exe`) rather than the
per-version path. Either path works in the MCP config. `npm prefix -g` returns the directory holding global
executables and `node_modules\` — on a default `nvm-windows` setup that's `%APPDATA%\nvm\v<version>`, but it can
differ if you've customized the npm prefix or installed `nvm-windows` to a non-default root.

Then in `~/.claude.json` (use forward slashes, or escape backslashes — both are valid JSON; substitute the prefix you
got from `npm prefix -g`):

```json
{
  "mcpServers": {
    "corva-ui": {
      "command": "C:/Program Files/nodejs/node.exe",
      "args": [
        "C:/Users/you/AppData/Roaming/nvm/v24.15.0/node_modules/@corva/ui/mcp-server/server.mjs"
      ]
    }
  }
}
```

The script path is `mcp-server/server.mjs` (the `bin` entry from `@corva/ui` `package.json`), **not** the `dist/`
build path. Pointing `command` directly at `corva-ui-mcp.cmd` is technically possible but unreliable as an MCP
`command` value across clients; the explicit `node.exe` + `.mjs` form mirrors the macOS / Linux example and is the
recommended shape.

#### Claude Code (without nvm)

Add the `mcpServers` entry to your `~/.claude.json` (merge into existing config):

```json
{
  "mcpServers": {
    "corva-ui": {
      "command": "npx",
      "args": [
        "--yes",
        "--package",
        "@corva/ui",
        "corva-ui-mcp"
      ]
    }
  }
}
```

> **Windows:** `npx` is a `.cmd` shim — see the [Native Windows note](#claude-code) under Local Setup for the
> `cmd /c` workaround. WSL users running the native-Windows client should follow the `wsl.exe` config from
> [Claude Code Windows + WSL](#windows--wsl) instead.

#### Cursor (with nvm)

Use the same path-discovery and JSON-shape rules as [Claude Code (with nvm)](#claude-code-with-nvm) above, but write
the config to `~/.cursor/mcp.json`.

##### macOS / Linux

1. Find your paths (same as Claude Code above)

2. Add to `~/.cursor/mcp.json` (create the file if it doesn't exist, or merge into existing config):

```json
{
  "mcpServers": {
    "corva-ui": {
      "command": "/Users/you/.nvm/versions/node/v24.15.0/bin/node",
      "args": [
        "/Users/you/.nvm/versions/node/v24.15.0/bin/corva-ui-mcp"
      ]
    }
  }
}
```

##### Windows + WSL

If Cursor runs inside WSL, follow the macOS / Linux instructions above. If Cursor is the native Windows app and Node
lives in WSL, write to `~/.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "corva-ui": {
      "command": "wsl.exe",
      "args": [
        "-e",
        "bash",
        "-lc",
        ". \"$HOME/.nvm/nvm.sh\" && exec corva-ui-mcp"
      ]
    }
  }
}
```

See the [Claude Code Windows + WSL notes](#windows--wsl) above for distro selection (`-d <DistroName>`), cold-start
caveats, and why the explicit `nvm.sh` source is preferred over simpler shapes.

##### Native Windows (nvm-windows)

Find your paths with `where.exe node` and `npm prefix -g` as described in the
[Claude Code native-Windows section](#native-windows-nvm-windows), then write to `~/.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "corva-ui": {
      "command": "C:/Program Files/nodejs/node.exe",
      "args": [
        "C:/Users/you/AppData/Roaming/nvm/v24.15.0/node_modules/@corva/ui/mcp-server/server.mjs"
      ]
    }
  }
}
```

> **Note:** the server shows up under **Customize** in the sidebar, where it can be enabled or disabled; if it fails to
> start, its output is in the Output panel under "MCP Logs".

#### Cursor (without nvm)

Add to `~/.cursor/mcp.json` (merge into existing config):

```json
{
  "mcpServers": {
    "corva-ui": {
      "command": "npx",
      "args": [
        "--yes",
        "--package",
        "@corva/ui",
        "corva-ui-mcp"
      ]
    }
  }
}
```

> **Windows:** `npx` is a `.cmd` shim. Cursor on Windows usually accepts plain `npx` — if it fails, use the
> `cmd /c` workaround from the [Native Windows note](#claude-code) under Local Setup. WSL users running
> native-Windows Cursor should follow the `wsl.exe` config from [Cursor Windows + WSL](#windows--wsl-1) instead.

> **Note:** the server shows up under **Customize** in the sidebar, where it can be enabled or disabled; if it fails to
> start, its output is in the Output panel under "MCP Logs".

#### Troubleshooting: Direct Node Path

If `npx` isn't viable (offline, corporate proxy blocking the registry, or you need a strictly pinned version
regardless of npm cache state), point Node directly at the global install's `server.mjs`. This shape requires
Step 1 above and works for any IDE — drop it into `~/.claude.json` or `~/.cursor/mcp.json`; the Codex CLI equivalent
for `~/.codex/config.toml` follows the JSON.

Find your global install's path with `npm prefix -g`, then substitute it below:

```json
{
  "mcpServers": {
    "corva-ui": {
      "command": "node",
      "args": [
        "<npm-prefix>/lib/node_modules/@corva/ui/mcp-server/server.mjs"
      ]
    }
  }
}
```

```toml
[mcp_servers.corva_ui]
command = "node"
args = ["<npm-prefix>/lib/node_modules/@corva/ui/mcp-server/server.mjs"]
```

Native-Windows substitution (default nodejs.org installer): `command` becomes `"C:/Program Files/nodejs/node.exe"`,
`args` becomes `["C:/Users/you/AppData/Roaming/npm/node_modules/@corva/ui/mcp-server/server.mjs"]`. nvm-windows
users should use the [Native Windows (nvm-windows)](#native-windows-nvm-windows) shape above instead — its
`%APPDATA%\nvm\v<version>\node_modules` path is the same direct-Node form.

## Verifying It Works

Ask your AI agent a question about a `@corva/ui` component (e.g., "How do I use the Button component from @corva/ui?") —
it should call one of the MCP tools and return real documentation.

For server health (uptime, memory, request stats, telemetry status), run the healthcheck slash command in Claude Code:

```
/mcp__corva-ui__healthcheck
```

This runs the `get_diagnostics` tool under the hood. Clients without slash-command support can call the
`get_diagnostics` tool directly instead.

If the AI doesn't pick up the MCP tools, restart your IDE / reload MCP servers, and confirm the config file is at the
location listed in the [Local Setup](#local-setup-recommended) table for your IDE.

If the very first connection times out, the cause is usually the download. `npx -p @corva/ui corva-ui-mcp` reuses the
`@corva/ui` installed under the directory the client starts the server from; when it finds none — a repo that doesn't
depend on it, a workspace root where it isn't hoisted, or a project whose dependencies aren't installed yet — it first
installs `@corva/ui` with its full dependency tree into npx's cache. One cold-cache run measured roughly 40 seconds and
about 1 GB on a fast connection; timings vary, but that is past the default MCP startup timeouts of Claude Code (30 s)
and Codex CLI (10 s). npx then reuses that cache until a newer `@corva/ui` is published. Install `@corva/ui` in the
project, or run the Quick Setup command once from the same user account (it fills the same npx cache), then
reconnect. If neither is an option, raise the client's timeout instead: `MCP_TIMEOUT=90000 claude` in a POSIX shell
for Claude Code, or `startup_timeout_sec = 90` under `[mcp_servers.corva_ui]` in the Codex config.

## Telemetry and Privacy

The MCP server may collect usage telemetry when it is configured to: for every tool call, the tool name, arguments,
result, latency and MCP client name/version; for every prompt invocation (slash command), the prompt name, arguments,
latency and the size of the response. Each run also carries a random instance id, the server and `@corva/ui` versions
and `NODE_ENV`. No hostnames, usernames, IP addresses, or other direct machine/user identifiers are collected — but
arguments and results are not scrubbed, so they can contain identifying information you typed.

When your client reports workspace roots, the session is also tagged with the **project identity**, so the
maintainers can tell which app the queries come from: the `name` from the nearest `package.json` and, in Corva apps,
the `application.key` from the nearest `manifest.json`, each searched upward from the first root. Either may be
absent. `/mcp__corva-ui__healthcheck` shows the resolved values.

**Tool arguments, tool results and prompt arguments are exported in full, without redaction or truncation.** Span
payloads may therefore contain content from your queries (file paths, source snippets, component names, or other text
you sent to the tool) alongside the documentation responses. This includes anything you send via the `feedback` prompt
/ `submit_feedback` tool — the free-text message is recorded verbatim and is intended for the `@corva/ui` maintainers.

Data goes to Corva's Uptrace project over fixed OTLP endpoints (`otlp.uptrace.dev`). The credentials and the sampling
rate are not hard-coded: after checking the opt-out below, the server reads `mcp-server/telemetry-config.local.json`
under its working directory (a development override — a valid file wins, an invalid or disabled one turns telemetry
off) and otherwise fetches the DSN and sampling rate from a Corva-hosted URL baked in at build time, with a 10-second
timeout. If that URL is unset, the fetch fails, or the fetched configuration is disabled, telemetry stays off for the
session.

To check whether telemetry is currently active for your install, run `/mcp__corva-ui__healthcheck` (or call the
`get_diagnostics` tool directly) — it reports the resolved telemetry status and sampling rate.

To opt out entirely, set `CORVA_UI_MCP_TELEMETRY_DISABLED=1` in the server's environment (e.g. in the `env` block of
your MCP config file) — any non-empty value other than `0` or `false` works. The switch is honored at runtime before
any telemetry configuration is read.

Feedback travels over the same channel, so `submit_feedback` reports one of 2 delivery states:

- **queued** — telemetry is enabled and the message was handed to it for export. Delivery is not confirmed. Feedback is
  exempt from the sampling rate, so it is never sampled out.
- **not sent** — nothing reaches the maintainers, and the response names the cause: the opt-out is set
  (`CORVA_UI_MCP_TELEMETRY_DISABLED`, or `"enabled": false` in the local config), or telemetry has no valid
  configuration in this session (or failed to start).

The `feedback` prompt relays that state to you, and `get_diagnostics` shows it as the feedback channel.

## FAQ

### Does this affect my application bundle or runtime?

No. The MCP server adds ~3 MB unpacked to the published `@corva/ui` npm package (bundled server, setup CLI, and pre-generated
documentation data). These files live in `node_modules/@corva/ui/mcp-server/` and are only used when running the CLI binaries (
`corva-ui-mcp`, `corva-ui-mcp-setup`). Consuming app bundlers resolve imports from the library's ESM/CJS entry points,
which don't reference MCP files — so they are never included in application bundles or executed at runtime.
