mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-02-09 02:49:29 +08:00
feat(shadcn): add mcp support for codex (#8348)
This commit is contained in:
5
.changeset/smart-items-open.md
Normal file
5
.changeset/smart-items-open.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"shadcn": minor
|
||||
---
|
||||
|
||||
add mcp support for codex
|
||||
@@ -28,6 +28,7 @@ Select your MCP client and follow the instructions to configure the shadcn MCP s
|
||||
<TabsTrigger value="claude">Claude Code</TabsTrigger>
|
||||
<TabsTrigger value="cursor">Cursor</TabsTrigger>
|
||||
<TabsTrigger value="vscode">VS Code</TabsTrigger>
|
||||
<TabsTrigger value="codex">Codex</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="claude" className="mt-4">
|
||||
**Run the following command** in your project:
|
||||
@@ -69,6 +70,31 @@ Select your MCP client and follow the instructions to configure the shadcn MCP s
|
||||
- Create a contact form using components from the shadcn registry
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="codex" className="mt-4">
|
||||
<Callout className="mt-0">
|
||||
**Note:** The `shadcn` CLI cannot automatically update `~/.codex/config.toml`.
|
||||
You'll need to add the configuration manually for Codex.
|
||||
</Callout>
|
||||
|
||||
**Run the following command** in your project:
|
||||
```bash
|
||||
npx shadcn@latest mcp init --client codex
|
||||
```
|
||||
|
||||
**Then, add the following configuration** to `~/.codex/config.toml`:
|
||||
```toml
|
||||
[mcp_servers.shadcn]
|
||||
command = "npx"
|
||||
args = ["shadcn@latest", "mcp"]
|
||||
```
|
||||
|
||||
**Restart Codex** and try the following prompts:
|
||||
- Show me all available components in the shadcn registry
|
||||
- Add the button, dialog and card components to my project
|
||||
- Create a contact form using components from the shadcn registry
|
||||
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
|
||||
---
|
||||
@@ -169,6 +195,23 @@ After adding the configuration, open `.vscode/mcp.json` and click **Start** next
|
||||
|
||||
See the [VS Code MCP documentation](https://code.visualstudio.com/docs/copilot/chat/mcp-servers) for more details.
|
||||
|
||||
### Codex
|
||||
|
||||
<Callout>
|
||||
**Note:** The `shadcn` CLI cannot automatically update `~/.codex/config.toml`.
|
||||
You'll need to add the configuration manually.
|
||||
</Callout>
|
||||
|
||||
To configure MCP in Codex, add the shadcn server to `~/.codex/config.toml`:
|
||||
|
||||
```toml title="~/.codex/config.toml" showLineNumbers
|
||||
[mcp_servers.shadcn]
|
||||
command = "npx"
|
||||
args = ["shadcn@latest", "mcp"]
|
||||
```
|
||||
|
||||
After adding the configuration, restart Codex to load the MCP server.
|
||||
|
||||
---
|
||||
|
||||
## Configuring Registries
|
||||
|
||||
@@ -26,6 +26,7 @@ Ask your registry consumers to configure your registry in their `components.json
|
||||
<TabsTrigger value="claude">Claude Code</TabsTrigger>
|
||||
<TabsTrigger value="cursor">Cursor</TabsTrigger>
|
||||
<TabsTrigger value="vscode">VS Code</TabsTrigger>
|
||||
<TabsTrigger value="codex">Codex</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="claude" className="mt-4">
|
||||
**Configure your registry** in your `components.json` file:
|
||||
@@ -93,6 +94,30 @@ Ask your registry consumers to configure your registry in their `components.json
|
||||
- Create a landing page using items from the acme registry
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="codex" className="mt-4">
|
||||
**Configure your registry** in your `components.json` file:
|
||||
|
||||
```json title="components.json" showLineNumbers
|
||||
{
|
||||
"registries": {
|
||||
"@acme": "https://acme.com/r/{name}.json"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Add the following configuration** to `~/.codex/config.toml`:
|
||||
```toml
|
||||
[mcp_servers.shadcn]
|
||||
command = "npx"
|
||||
args = ["shadcn@latest", "mcp"]
|
||||
```
|
||||
|
||||
**Restart Codex** and try the following prompts:
|
||||
- Show me the components in the acme registry
|
||||
- Create a landing page using items from the acme registry
|
||||
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
|
||||
You can read more about the MCP server in the [MCP documentation](/docs/mcp).
|
||||
|
||||
@@ -5,6 +5,7 @@ import { loadEnvFiles } from "@/src/utils/env-loader"
|
||||
import { getConfig } from "@/src/utils/get-config"
|
||||
import { getPackageManager } from "@/src/utils/get-package-manager"
|
||||
import { handleError } from "@/src/utils/handle-error"
|
||||
import { highlighter } from "@/src/utils/highlighter"
|
||||
import { logger } from "@/src/utils/logger"
|
||||
import { spinner } from "@/src/utils/spinner"
|
||||
import { updateDependencies } from "@/src/utils/updaters/update-dependencies"
|
||||
@@ -58,6 +59,15 @@ const CLIENTS = [
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "codex",
|
||||
label: "Codex",
|
||||
configPath: ".codex/config.toml",
|
||||
config: `[mcp_servers.shadcn]
|
||||
command = "npx"
|
||||
args = ["shadcn@${SHADCN_MCP_VERSION}", "mcp"]
|
||||
`,
|
||||
},
|
||||
] as const
|
||||
|
||||
const DEPENDENCIES = [`shadcn@${SHADCN_MCP_VERSION}`]
|
||||
@@ -82,7 +92,7 @@ export const mcp = new Command()
|
||||
})
|
||||
|
||||
const mcpInitOptionsSchema = z.object({
|
||||
client: z.enum(["claude", "cursor", "vscode"]),
|
||||
client: z.enum(["claude", "cursor", "vscode", "codex"]),
|
||||
cwd: z.string(),
|
||||
})
|
||||
|
||||
@@ -125,11 +135,52 @@ mcp
|
||||
cwd,
|
||||
})
|
||||
|
||||
const config = await getConfig(options.cwd)
|
||||
|
||||
if (options.client === "codex") {
|
||||
if (config) {
|
||||
await updateDependencies([], DEPENDENCIES, config, {
|
||||
silent: false,
|
||||
})
|
||||
} else {
|
||||
const packageManager = await getPackageManager(options.cwd)
|
||||
const installCommand = packageManager === "npm" ? "install" : "add"
|
||||
const devFlag = packageManager === "npm" ? "--save-dev" : "-D"
|
||||
|
||||
const installSpinner = spinner("Installing dependencies...").start()
|
||||
await execa(
|
||||
packageManager,
|
||||
[installCommand, devFlag, ...DEPENDENCIES],
|
||||
{
|
||||
cwd: options.cwd,
|
||||
}
|
||||
)
|
||||
installSpinner.succeed("Installing dependencies.")
|
||||
}
|
||||
|
||||
logger.break()
|
||||
logger.log("To configure the shadcn MCP server in Codex:")
|
||||
logger.break()
|
||||
logger.log(
|
||||
`1. Open or create the file ${highlighter.info(
|
||||
"~/.codex/config.toml"
|
||||
)}`
|
||||
)
|
||||
logger.log("2. Add the following configuration:")
|
||||
logger.log()
|
||||
logger.info(`[mcp_servers.shadcn]
|
||||
command = "npx"
|
||||
args = ["shadcn@${SHADCN_MCP_VERSION}", "mcp"]`)
|
||||
logger.break()
|
||||
logger.info("3. Restart Codex to load the MCP server")
|
||||
logger.break()
|
||||
process.exit(0)
|
||||
}
|
||||
|
||||
const configSpinner = spinner("Configuring MCP server...").start()
|
||||
const configPath = await runMcpInit(options)
|
||||
configSpinner.succeed("Configuring MCP server.")
|
||||
|
||||
const config = await getConfig(options.cwd)
|
||||
if (config) {
|
||||
await updateDependencies([], DEPENDENCIES, config, {
|
||||
silent: false,
|
||||
@@ -173,7 +224,10 @@ async function runMcpInit(options: z.infer<typeof mcpInitOptionsSchema>) {
|
||||
}
|
||||
|
||||
const configPath = path.join(cwd, clientInfo.configPath)
|
||||
const dir = path.dirname(configPath)
|
||||
await fsExtra.ensureDir(dir)
|
||||
|
||||
// Handle JSON format.
|
||||
let existingConfig = {}
|
||||
try {
|
||||
const content = await fs.readFile(configPath, "utf-8")
|
||||
@@ -186,8 +240,6 @@ async function runMcpInit(options: z.infer<typeof mcpInitOptionsSchema>) {
|
||||
{ arrayMerge: overwriteMerge }
|
||||
)
|
||||
|
||||
const dir = path.dirname(configPath)
|
||||
await fsExtra.ensureDir(dir)
|
||||
await fs.writeFile(
|
||||
configPath,
|
||||
JSON.stringify(mergedConfig, null, 2) + "\n",
|
||||
|
||||
Reference in New Issue
Block a user