# Hone UI MCP server

Use to look up Hone UI guides, props and theme variables, and to check a JSX snippet, through MCP tools. It reads the `@hone-ui/react` that the app has installed, so every answer matches the installed version. It makes no network call. The package is not published yet.

## Start

```txt
npx @hone-ui/mcp                       runs over stdio, from the app folder
npx @hone-ui/mcp --project ./apps/web  looks for @hone-ui/react from that folder
HONE_UI_PROJECT=./apps/web             same, as an environment variable
```

The `--project` argument beats `HONE_UI_PROJECT`, and both beat the working folder. A relative path resolves against the working folder. The server walks up from the project folder to the nearest `node_modules/@hone-ui/react`.

An MCP client config names the command and its arguments:

```json
{
  "mcpServers": {
    "hone-ui": { "command": "npx", "args": ["@hone-ui/mcp", "--project", "."] }
  }
}
```

Config file names and locations differ between clients. Read the client's own docs for where this goes.

## Tools

Argument names are exact. `get_props` takes `name`, not `component`. `search_guides` takes `text`, not `query`. A call with a wrong name fails validation.

```txt
list_components()
  Every guide, one line each: "Button: Use for actions." Call it first to find a name.
get_guide({ name })
  name: a guide name such as "Button" or "theming", from list_components.
  The full guide as markdown. Read it before you write code with a component.
  Matching ignores case. "button" finds Button, and "theming" finds the topic guide.
  Also serves DevEditor, eslint-plugin and mcp. An export that is not a component, such as
  ThemeProvider, createTheme or useColorScheme, returns the guide that covers it.
get_props({ name })
  name: a component name such as "Button".
  A component's own props, one per line, with type, allowed values, min, max and default.
  A prop with no literal type prints its source type, such as a callback signature.
  Props inherited from an HTML element are not listed.
search_guides({ text })
  text: the words to look for, case-insensitive.
  Up to 10 guide sections that contain every whole word of text, best first.
  Each is labeled "## Guide > Heading". Long sections are cut; call get_guide for the rest.
get_theme_variables({ look: 'material' | 'minimal', filter? })
  look: which look to read. filter: optional text; keep only names that contain it.
  The --hn-* variables of a look, with light and dark values.
check_usage({ code })
  code: a JSX or TSX snippet, such as one component or a whole file.
  Lints a JSX or TSX snippet with the @hone-ui/eslint-plugin rules, which the server carries
  inside its own bundle. It does not type-check.
```

## Output

```txt
get_props({ name: 'IconButton' })
  color: 'default' | 'inherit' | 'primary' | ... | string (default 'default')
  size: 'small' | 'medium' | 'large' (default 'medium')
  onClick: MouseEventHandler<HTMLButtonElement | HTMLAnchorElement>

get_theme_variables({ look: 'material', filter: 'primary-main' })
  --hn-palette-primary-main: light #1976d2, dark #90caf9

check_usage({ code: '<IconButton size="huge"><DeleteIcon /></IconButton>' })
  1:1 icon-button-label IconButton shows only an icon, so screen readers need a name. ...
    1:18 valid-prop-value "huge" is not a valid size for IconButton. Use one of: small, medium, large.
    suggestion: size="huge" -> size="large"
```

`check_usage` prints one problem per line as `line:column rule message`, with each fix as an indented `suggestion:` line that shows only the changed text, such as `variant="filled" -> variant="outlined"`, or `insert {...params}`. Line numbers count from the first line of your snippet. A clean snippet returns `No problems found.` A snippet with no import from `@hone-ui/react` gets one added for the components it uses, and the output says so. Sibling elements that start with `<` parse because the tool wraps them in a fragment when needed. Any other snippet that does not parse, such as `const = ;`, returns an error with the parser message and its line and column.

## Errors

A name close to a real one returns an error that lists the closest names: `No component named "Buton". Closest names: Button.` Retry with one of them. A name that is close to nothing returns `"DataGrid" is not part of Hone UI, and no component has a similar name.` Do not retry; the library has no such component.

Without an installed `@hone-ui/react`, the server still starts and lists its six tools. Every call returns an error that names the folder it searched and says to pass `--project <your app folder>` or set `HONE_UI_PROJECT`. A missing or unreadable props manifest makes `get_props` fail with a message to reinstall `@hone-ui/react`. `check_usage` still runs, but `valid-prop-value` reports nothing. The server loads `@typescript-eslint/parser` on the first `check_usage` call. If that load fails, only `check_usage` returns an error, and the other tools keep working.

## Do

Call `get_guide` or `get_props` before you write a component, then run `check_usage` on the code you wrote. Pass a whole file or a single element.

## Don't

- Don't guess prop values from memory. `get_props` lists the allowed ones.
- Don't treat `No problems found.` as a type check. `check_usage` reads only literal values it can see, and skips spreads, variables and open unions.
- Don't point `--project` at a folder without an installed `@hone-ui/react`. Every tool then fails.
