MCP Troubleshooting
Purpose and Scope
This page helps diagnose the most common failure modes when using the shadcn MCP Server with an AI assistant. The MCP Server is the bridge between a client such as Claude Code, Cursor, VS Code, Codex, or OpenCode and shadcn-compatible registries. It lets the assistant browse registry contents, search for items, and install components into the current project through natural-language prompts. When a prompt fails, the problem is usually in one of four places: the client was not started with the server enabled, the project registry configuration is wrong, a namespaced item cannot be resolved, or a private registry requires authentication that the server cannot read.
Sources: apps/v4/content/docs/(root)/mcp.mdx, apps/v4/content/docs/changelog/2025-08-cli-3-mcp.mdx, packages/shadcn/src/mcp/utils.ts
The official MCP flow starts from the project directory because registries are read from the project’s components.json. That is important for troubleshooting: an assistant session launched from the wrong working directory may not see the same registry configuration as the terminal where npx shadcn@latest mcp init was run. The implementation reinforces this by loading registry configuration from the current working directory and disabling cache for MCP configuration reads, so fixes to components.json should be visible to a newly started MCP process rather than requiring a stale cache to expire.
Relevant Source Files
apps/v4/content/docs/(root)/mcp.mdx- Defines the reader-facing MCP Server workflow, supported clients, setup commands, restart steps, sample prompts, and the relationship between MCP andcomponents.jsonregistries.apps/v4/content/docs/changelog/2025-08-cli-3-mcp.mdx- Introduces CLI 3.0 MCP-related capabilities, including namespaced registries, private registry authentication, search and discovery commands, improved error handling, and registry resolution behavior.packages/shadcn/src/mcp/utils.ts- Implements MCP utility behavior for loading registry config, formatting search results, reporting unknown search types, listing skipped registries, formatting registry items, and generating shadcn CLI add commands.
First Checks: Client Startup and Project Context
Start troubleshooting by confirming that the MCP client is configured for shadcn and has been restarted or explicitly started. The setup instructions differ by client. Claude Code is initialized with npx shadcn@latest mcp init --client claude, then the user restarts Claude Code and can use the /mcp command to debug the server. Cursor also uses the init command, but the server must be enabled in Cursor Settings. VS Code writes .vscode/mcp.json; the user opens that file and clicks Start next to the shadcn server before trying prompts through GitHub Copilot.
Codex has one extra manual step that is easy to miss. The docs state that the CLI cannot automatically update ~/.codex/config.toml, so the user must add a mcp_servers.shadcn entry with command = "npx" and args = ["shadcn@latest", "mcp"]. OpenCode follows the same overall pattern as other clients: initialize from the project and restart the client. If the assistant cannot see any tools or cannot answer a basic registry listing prompt, treat client activation as the first suspect before investigating registry content.
npx shadcn@latest mcp init --client claude
npx shadcn@latest mcp init --client cursor
npx shadcn@latest mcp init --client vscode
npx shadcn@latest mcp init --client codex
npx shadcn@latest mcp init --client opencodeRegistry Configuration and Namespaces
The MCP Server uses registries configured in components.json. A basic registry map binds a namespace such as @acme to a URL pattern such as https://acme.com/r/{name}.json. If a prompt like “Show me the components in the acme registry” fails, verify that the namespace exists, includes the leading @, and uses a URL template that can resolve both item names and the registry index. Registry developer guidance says MCP works by requesting the registry index, so a registry served at https://acme.com/r/[name].json should also expose https://acme.com/r/registry.json or an equivalent extensionless registry endpoint.
Namespaced registries were introduced as a central CLI 3.0 feature. Users install and reference items with the @registry/name format, for example npx shadcn add @acme/button @internal/auth-system. There is no central registrar, so any team can choose namespaces, but that flexibility also means typos are not corrected globally. If an assistant tries to install @design/button while components.json defines only @acme, the resolution failure is expected. Ask the assistant to list configured registries first, then retry with an exact namespace and item name.
{
"registries": {
"@acme": "https://acme.com/r/{name}.json",
"@internal": {
"url": "https://registry.company.com/{name}",
"headers": {
"Authorization": "Bearer ${REGISTRY_TOKEN}"
}
}
}
}Search, Browse, and Install Prompts
Use small prompts to isolate the failing phase. Browsing asks the server to enumerate registry items. Searching filters registry data. Installing turns a registry item reference into a shadcn add operation. The user-facing docs suggest prompts such as “Show me all available components in the shadcn registry,” “Add the button, dialog and card components to my project,” and “Create a contact form using components from the shadcn registry.” For custom registries, use similarly precise prompts: “Show me the components in the acme registry” or “Create a landing page using items from the acme registry.”
The MCP utility layer formats search responses with pagination, registry labels, descriptions, item types, and an add command for each result. That means a search response that shows only the first page is not necessarily incomplete; it may include a “More items available” note with the next offset. The same utility code validates type filters against CLI-supported searchable types and returns a clear “Unknown type” message listing valid types when a filter is invalid. When troubleshooting search, remove type filters first, confirm that unfiltered listing works, and then add filters back one at a time.
Authentication and Private Registry Failures
Private registries are configured in components.json with headers, bearer tokens, API keys, basic auth, or query parameters. The changelog highlights advanced authentication as part of CLI 3.0 and shows Authorization: Bearer ${REGISTRY_TOKEN} as a common pattern. If a private registry works in a local shell but fails in an MCP client, compare environments. GUI clients and editor-launched servers may not inherit the same environment variables as the terminal. Restarting the client after exporting credentials is not optional; the MCP server process must start with access to the token value.
Skipped registries are another important signal. The utility function formatSkippedRegistries adds a note when some configured registries fail to load while a broader search continues. This matters because a search across all registries can look partially successful even while a private or unavailable registry was ignored. If the assistant says it found only public items, ask it whether any registries were skipped and inspect the registry-specific error message. Then verify the private URL, headers, token variable, and whether the registry index endpoint is reachable with the same credentials.
Implementation Details and Reference
The MCP utility contract is small but useful for debugging. getMcpConfig(cwd = process.cwd()) calls getRegistriesConfig with useCache: false and returns the active registries object. npxShadcn(command: string) builds an add or other CLI command using the package runner detected for the current project, while the constant command target is shadcn@latest. Formatting helpers turn registry search and item data into assistant-readable markdown: formatSearchResultsWithPagination, formatRegistryItems, and formatItemExamples are intended to show names, descriptions, types, dependencies, dev dependencies, file counts, registry source labels, and suggested add commands.
The most actionable implementation-level errors are produced before installation. findUnknownTypesMessage(types?: string[]) reports invalid search filters and includes the valid searchable types. formatSkippedRegistries(results) reports registry load failures without discarding successful results from other registries. Together, these helpers explain why an MCP answer may include a clear validation message, a partial-result warning, or an add command rather than raw JSON. When building troubleshooting prompts, ask for these details explicitly: “Search @acme for login forms and tell me if any registries were skipped” is more diagnosable than “Find a login form.”
Practical Troubleshooting Flow
A reliable flow is to move from environment to registry to item. First, initialize the correct client from the project root, start or restart the client, and run a basic prompt against the default shadcn registry. Second, ask the assistant to list configured registries and confirm that custom namespaces match components.json. Third, test a single namespaced item or a single registry search before asking for a generated page or multi-component install. Fourth, if the registry is private, confirm credentials are available to the MCP server process, not only to an interactive terminal.
When the issue is fixed, keep the prompt concrete. Good examples include “Show me all available components in the shadcn registry,” “Add the button, dialog and card components to my project,” “Search @acme for authentication components,” and “Create a landing page using items from the acme registry.” If those work, move on to broader registry authoring and client setup topics: the MCP overview explains the server model, the client integrations page covers per-client configuration, and the registry authentication and namespaces pages go deeper into protected and decentralized registry setups.