shadcn.io is not affiliated with official shadcn/ui
- Group
- Install
- Inputs
base?files?framework?have?name?names?packageManager?- Access
- Read-only
When to use it
- When the agent can't run commands (Claude Desktop, ChatGPT), or to review what an install writes first.
- When a Vue, Svelte or Solid project doesn't use its CLI.
Inputs
base?"base" | "aria" | "ark" | "radix"
React only. Default base (Base UI).
- Type
"base" | "aria" | "ark" | "radix"
files?string[]
Only these files' code: a plan's pending.
framework?"react" | "vue" | "svelte" | "solid"
Default react.
- Type
"react" | "vue" | "svelte" | "solid"
have?string[]
What the ui folder already has: left out.
name?string
Or names for several.
names?string[]
Several at once, in place of name.
packageManager?"npm" | "pnpm" | "yarn" | "bun"
From the lockfile. Default npm.
- Type
"npm" | "pnpm" | "yarn" | "bun"
Example prompts
Name the server, so the agent doesn't answer from memory:
Call and response
Asked “Add the Dialog to my Vue project”, the agent sends this call. The response is real, trimmed: long lists show their first items and long strings are cut.
get_install_plan({ framework: "vue", name: "dialog" }){
"cssVars": {
"dark": {
"destructive-foreground": "var(--color-red-400)",
"info": "var(--color-blue-500)",
"info-foreground": "var(--color-blue-400)",
"success": "var(--color-emerald-500)",
"success-foreground": "var(--color-emerald-400)",
"warning": "var(--color-amber-500)",
"warning-foreground": "var(--color-amber-400)"
},
"light": {
"destructive-foreground": "var(--color-red-700)",
"info": "var(--color-blue-500)",
"info-foreground": "var(--color-blue-700)",
"success": "var(--color-emerald-500)",
"success-foreground": "var(--color-emerald-700)",
"warning": "var(--color-amber-500)",
"warning-foreground": "var(--color-amber-700)"
}
},
"files": [
{
"content": "export { type ClassValue, cn } from \"cn\";\n",
"target": "lib/utils.ts",
"optional": true
},
{
"content": "// Generated from registry/react/components/spinner.tsx by scripts/write-vue-registry.mts.\nimport { defineComponent, h, type IntrinsicElemen…",
"target": "components/ui/spinner.ts"
},
"… 2 more"
],
"install": "npm install @ark-ui/vue @lucide/vue cn tailwind-variants",
"items": [
"utils",
"vue/spinner",
"… 3 more"
],
"next": "1 more file (pending): get_install_plan({ name: \"dialog\", framework: \"vue\", files: <pending> }) returns their code.",
"pending": [
"components/ui/dialog.ts"
],
"steps": [
"Run install (and installDev).",
"Write each file at its target, adjusting @/components/ui and @/lib to the project's aliases; skip an optional one the project has.",
"… 2 more"
],
"cli": "npx shadcn-vue@latest add \"https://kit.dev/r/vue/dialog.json?token=YOUR_TOKEN\" --overwrite",
"name": "dialog",
"target": "Vue · Ark UI"
}
Call it by hand
Your MCP client sends this for you. To try the tool without one, post the call yourself; the server answers in server-sent events, the result on the data: line.
What your agent reads
The server's description of get_install_plan, one of the Install tools. Your agent reads it to decide when to call the tool:
Every file an install writes (path and code), the packages and CSS: an install without a CLI, any framework.namesfor several;haveleaves out what the project has;filesfor thependingones of a long plan.
Next
FAQ
Can I plan several components in one call?
Pass names: one plan with every file once (two components that share a part write it once) and the packages merged.
What if the install plan is too long for one response?
A response holds about 20,000 characters of code, so every client shows it whole. A longer plan sends the files that fit and names the rest in pending; next is the call that returns them: the same one with files: pending. A file is never cut: one longer than that comes alone.