Skills
Give a coding agent working knowledge of PanelUI — the components, the tokens, the CLI — plus an MCP server that lets it read the registry directly.
An agent writing React Native in your project has no idea PanelUI is there. It writes a styled
View where there is a Card, invents a prop Button does not have, and hardcodes #171717
into a screen that has six themes. Not because it is careless — because nothing told it.
The skill tells it. It is a folder of markdown the agent loads when it recognises a PanelUI project: what exists, how the parts compose, which rules are not negotiable, and where to look up the real API rather than guess it.
Install
npx skills add panel-ui/PanelUIThat writes the skill into your project for whichever agent you use — Claude Code, Cursor, Copilot, Windsurf and the rest all read the same format. Run it again to update.
Nothing else is needed: the skill activates on its own when the project has panelui-native in
its dependencies or a panelui.json beside it.
What is in it
Project context
Which of the two ways in this project uses — the package, copied source, or both — because
that decides whether the agent should import from panelui-native or from
@/components/ui/…. It checks rather than assumes.
Every component
All 98, by what they are for, with the URL of each one's documentation as markdown. Generated from the same file the docs are, so it cannot name a component that does not exist.
The rules that are not negotiable
Semantic tokens and never a literal colour. gap-*, because React Native has no space-*.
One provider at the root, or overlays mount and never appear. Reanimated, never core
Animated. Each with a wrong/right pair.
Theming
The six themes, the radius scale a family brings with it, extraThemes and the restart it
needs, and how to read a token in JavaScript instead of restating it.
The CLI
init, add, list, panelui.json, the registry format — and why --overwrite is not
something to pass without asking.
Native controls
That native alone is not Liquid Glass, that a native control ignores every token, and that
hosting elements inside a labelled native button crashes in native code.
MCP server
The skill is what the agent knows. The MCP server is how it looks things up — it reads the same registry the CLI installs from, so the source it quotes is the source you would get.
npx panelui-cli@latest mcp initThat writes the server into .mcp.json. Pass cursor or vscode for those instead; it merges
into whatever is already in the file rather than replacing it.
By hand, it is:
{
"mcpServers": {
"panelui": {
"command": "npx",
"args": ["-y", "panelui-cli@latest", "mcp"]
}
}
}| Editor | Config file |
|---|---|
| Claude Code | .mcp.json |
| Cursor | .cursor/mcp.json |
| VS Code | .vscode/mcp.json |
Tools
| Tool | What it answers |
|---|---|
panelui_get_project_info | How this project is set up, and which components are already in it |
panelui_search_components | "Is there already something for this?" |
panelui_list_components | Everything in the registry |
panelui_view_component | One item in full, including every file's source |
panelui_get_component_docs | A component's page as markdown — anatomy, props, variants, examples |
panelui_get_add_command | The command that copies components in |
The server has no dependencies of its own — it is part of panelui-cli, which is a few
kilobytes. npx fetches it on demand, so there is nothing to install.
Without either of them
Everything both of them read is a public URL, so an agent that can fetch can use the same sources:
| URL | What it returns |
|---|---|
panelui.dev/llms.txt | Every page on this site, as a list |
panelui.dev/llms.mdx/components/button | That page as markdown |
panelui.dev/r/index.json | The registry index |
panelui.dev/r/button.json | One item, with its full source |
Asking for things
With the skill loaded, these do what you would hope:
- "Add a settings screen with sections for profile, notifications and appearance."
- "Put the filters in a bottom sheet."
- "Make this chart use the brand green."
- "Why is nothing styled?"
The last one is the reason half of this exists. The answer is almost always the CSS entry path in
metro.config.js, and it is written down where the agent can find it.