opsinjs

MCP server

Point the shadcn MCP server at the opsinjs registry so an assistant can browse and install real items instead of guessing at them.

Overview

opsinjs does not ship an MCP server of its own. It ships a registry that the shadcn MCP server already understands, which means the setup is the standard one and everything you learn transfers to any other shadcn-compatible registry.

What the connection buys you is inventory. Without it, an assistant asked for a health component answers from its training data. With it, the assistant can list what exists and read each item's metadata. Crucially, it can also discover whether the thing it was about to write has source behind it, and at what stability.

Budget five minutes. You need a project with a components.json.

Configure the registry

The MCP server reads registries from your project's components.json. Add the @opsinjs namespace:

components.json
{
  "registries": {
    "@opsinjs": "https://opsinjs.pensievelabs.org/r/{name}.json"
  }
}

The {name} placeholder is required by the spec. The CLI substitutes the item name into it. See Namespaces for composing several registries, and for why the namespace is @opsinjs rather than something shorter.

No authentication is needed. The registry is public and read-only.

Start the server

npx shadcn@latest mcp init --client claude

Substitute your client: claude, cursor, vscode, codex or opencode. Restart the client afterwards.

If you prefer to write the configuration by hand, it is the same three lines everywhere. Those lines name a command and its arguments:

.mcp.json
{
  "mcpServers": {
    "shadcn": {
      "command": "npx",
      "args": ["shadcn@latest", "mcp"]
    }
  }
}

Cursor uses .cursor/mcp.json with the same shape; VS Code uses .vscode/mcp.json with a servers key instead of mcpServers; Codex uses TOML in ~/.codex/config.toml and the CLI cannot write that file for you.

Ask it something

Three prompts that exercise the connection and expose the honest state of the system:

List every component in the opsinjs registry with its status.
What does the opsinjs registry say about range-bar? Do not write any code.
Is there an opsinjs component for scanning a barcode?

The third is the interesting one. There is no barcode scanner in the catalogue, so a correct answer names that absence plainly, not a 404 and not an invented component. If your assistant invents one, that is the failure mode the evals exist to measure, and Rules for agents is the fix.

What the server can and cannot do here

All sixty built items carry source. add against a built id writes real files. Against a planned id it would resolve the item and find nothing to write. That is the correct behaviour and not a broken configuration. meta.opsinjs.implemented on the item is the discriminator, and it is worth checking before you conclude anything from an empty result.

The server canThe server cannot
List every item with its status and implemented flagInstall an id the catalogue does not list
Install the source of all sixty built items, exported prop interfaces includedPromise that a shipped API survives the next release, or that anybody has reviewed it
Install the theme preset, which is real CSSFetch a documentation example on its own. The examples are not published as registry items
Search across opsinjs and your other registriesEnforce the clinical rules. That is the skill

The last row is the important division of labour. The MCP server answers what exists. The skill answers how to use it correctly. Configure both.

Verify it worked

The client sees the server

In Claude Code, run /mcp and look for shadcn marked connected. Cursor shows a green dot in its MCP list; VS Code shows a Start control next to the entry in .vscode/mcp.json.

The registry resolves

Ask the assistant to list opsinjs items. A non-empty list of names, each with a status, means the namespace resolved. An empty list means components.json was not read or the namespace is misspelled.

Troubleshooting

No tools or prompts. Clear the npx cache with npx clear-npx-cache, then re-enable the server in your client. This is by far the most common cause.

@opsinjs is not found. The registry block is missing from components.json, or the file is not at the project root the client opened. The full-URL form is npx shadcn@latest add https://opsinjs.pensievelabs.org/r/<name>.json. That form needs no configuration for an item that composes nothing, and is a quick way to isolate the problem. It will not rescue an item whose registryDependencies name other opsinjs items; those need the block whichever form you use.

It lists items but add writes nothing. Check the id first. For one of the sixty built ids it is a real fault: the item carries files, so an empty write means the fetch failed, the CLI resolved a different registry, or the aliases in components.json do not name a directory it can write to.

The assistant still invents components. The server supplies inventory, not judgement. Install the agent skill or paste Rules for agents into the system prompt.

It works in one editor and not another. Each client stores its own configuration file. Configure each; there is no shared one.

Next

On this page