OneApp Docs
PackagesUI

@repo/uni-mcp

Model Context Protocol server for AI assistants to discover and use OneApp UI components. Claude, Cursor, and other AI tools can browse your design system, get component source code, and generate code that matches your patterns. shadcn-compatible registry format.

Quick Start

Connect AI assistants to your UI components in 5 minutes:

pnpm add @repo/uni-mcp

AI assistants get instant access to your design system. Skip to Quick Start →

Why @repo/uni-mcp?

AI assistants generate UI code with random component patterns. They don't know your design system's Button has specific variants. Code suggestions don't match your existing components. Developers copy-paste component code manually for AI context. AI generates code using generic examples instead of your actual components.

@repo/uni-mcp solves this by exposing your UI registry to AI assistants via Model Context Protocol (MCP).

Production-ready with shadcn-compatible format, automatic file watching, path security, and timeout protection.

Use cases

  • AI code generation — AI assistants generate code using your actual design system
  • Component discovery — AI tools can list and search all available components
  • Pattern matching — Generated code follows your component patterns and variants
  • Design system adherence — Ensure AI-generated code matches your UI guidelines
  • Developer productivity — AI suggests code with correct imports and props

How it works

@repo/uni-mcp exposes your UI registry via MCP protocol:

// Configure in Claude Desktop settings
{
  "mcpServers": {
    "uni-mcp": {
      "command": "node",
      "args": ["/path/to/uni-mcp/src/cli.mjs"]
    }
  }
}

// AI can now query your components
// "Create a form with primary and outline buttons"
// AI sees your registry and generates:
<Button variant="default">Submit</Button>
<Button variant="outline">Cancel</Button>

Uses Model Context Protocol to expose registry.json with component source code, dependencies, and metadata. AI assistants read this via registry://uni-mcp/ URIs.

Key features

shadcn-compatible — Works with existing shadcn tooling and registry format

Auto-discovery — AI assistants can list, search, and retrieve all components

Full source code — Includes complete component implementations with dependencies

Live updates — File system watching with automatic AI notifications

Path security — Protection against directory traversal attacks

Multiple AI tools — Works with Claude Desktop, Cursor, and any MCP client

Quick Start

1. Install the package

pnpm add @repo/uni-mcp

2. Find the CLI path

# In your monorepo root
pwd
# Copy the output: /path/to/monorepo

# CLI is at: /path/to/monorepo/platform/packages/uni-mcp/src/cli.mjs

3. Configure Claude Desktop

~/Library/Application Support/Claude/claude_desktop_config.json
{
  "mcpServers": {
    "uni-mcp": {
      "command": "node",
      "args": ["/path/to/monorepo/platform/packages/uni-mcp/src/cli.mjs"]
    }
  }
}

4. Restart Claude Desktop and test

Ask Claude: "What UI components are available in the OneApp design system?"

Claude will query the MCP server and list all components from your registry.

That's it! Claude now has access to your design system components and can generate code using your actual patterns.

Test the integration

Try asking Claude to create a form with buttons. It will use your exact Button component with the correct variants and imports.


Technical Details

For Developers: Technical implementation details

Overview

PropertyValue
Locationpackages/uni-mcp
Dependencies@modelcontextprotocol/sdk
PurposeExpose UI registry to AI assistants
CLIuni-mcp

Features

  • shadcn-compatible - Works with existing shadcn tooling
  • Auto-discovery - AI assistants can list and search components
  • Full source code - Includes complete component implementations
  • Live updates - File system watching with automatic notifications
  • Path security - Protection against traversal attacks
  • Timeout protection - Prevents hanging I/O operations

MCP Server Configuration

Claude Desktop

Configure as an MCP server in Claude Desktop settings:

{
  "mcpServers": {
    // highlight-start
    "uni-mcp": {
      "command": "node",
      "args": ["/path/to/monorepo/platform/packages/uni-mcp/src/cli.mjs"]
    }
    // highlight-end
  }
}

Custom UI Root

{
  "mcpServers": {
    "uni-mcp": {
      "command": "node",
      // highlight-start
      "args": ["/path/to/monorepo/platform/packages/uni-mcp/src/cli.mjs", "--ui-root", "/custom/path/to/ui"]
      // highlight-end
    }
  }
}

Cursor

Cursor Integration

Cursor supports MCP servers. Add the same configuration to your Cursor MCP settings.

{
  "mcp": {
    "servers": {
      "uni-mcp": {
        "command": "node",
        "args": ["/path/to/monorepo/platform/packages/uni-mcp/src/cli.mjs"]
      }
    }
  }
}

CLI Usage

Start Server

# Use default UI root (../../ui)
pnpm --filter @repo/uni-mcp start

# Or with npx
npx uni-mcp

# Custom UI root
npx uni-mcp --ui-root /path/to/ui

# Disable file watching
npx uni-mcp --no-watch

# Show help
npx uni-mcp --help

Development Mode

Hot Reload

Development mode automatically reloads when files change, useful for developing new components.

pnpm --filter @repo/uni-mcp dev

Programmatic Usage

Basic Setup

import { createUniMcpServer } from "@repo/uni-mcp";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";

// highlight-start
// Create server (async)
const { server, uiRoot, close } = await createUniMcpServer();
// highlight-end

// Connect to stdio transport
const transport = new StdioServerTransport();
await server.connect(transport);

// Cleanup on exit
process.on("SIGINT", async () => {
  await close(); // Stop file watchers
  process.exit(0);
});

Advanced Configuration

import { createUniMcpServer } from "@repo/uni-mcp";

const { server, uiRoot, close } = await createUniMcpServer({
  // highlight-start
  // Custom UI package path
  uiRoot: "/custom/path/to/ui",

  // Server metadata
  name: "my-custom-registry",
  version: "1.0.0",

  // Disable file watching
  watch: false,

  // Watch options
  watchOptions: {
    debounceMs: 300 // Custom debounce delay
  }
  // highlight-end
});

MCP Resources

Registry Index

URI: registry://uni-mcp/index

Returns the complete registry.json with all available items.

{
  "$schema": "https://ui.shadcn.com/schema/registry.json",
  "name": "uni-mcp",
  "homepage": "https://github.com/onedigital/monorepo",
  // highlight-start
  "items": [
    {
      "name": "button",
      "type": "registry:ui",
      "title": "Button",
      "files": [
        {
          "type": "registry:ui",
          "path": "button.tsx",
          "content": "..."
        }
      ]
    }
  ]
  // highlight-end
}

Component Resource

URI Pattern: registry://uni-mcp/{componentName}

Returns a specific component with full source code.

{
  "name": "button",
  "type": "registry:ui",
  "title": "Button",
  // highlight-start
  "files": [
    {
      "type": "registry:ui",
      "path": "button.tsx",
      "content": "import * as React from 'react'\n..."
    }
  ],
  // highlight-end
  "dependencies": ["@radix-ui/react-button"],
  "devDependencies": [],
  "registryDependencies": ["utils"],
  "meta": {
    "source": "https://github.com/onedigital/monorepo/tree/main/packages/ui/src/button.tsx",
    "category": "components"
  }
}

Component List

URI: registry://uni-mcp/components

Returns a list of all available component names.

{
  "components": [
    "accordion",
    "alert",
    "alert-dialog",
    "button",
    "card",
    "dialog",
    "input"
    // ...more components
  ]
}

File Watching

Live Updates

When file watching is enabled (default), the server automatically notifies AI assistants when components change.

Enable/Disable Watching

// Enable watching (default)
const { server, close } = await createUniMcpServer({
  watch: true
});

// Disable watching
const { server } = await createOneAppUiRegistryServer({
  watch: false
});

Custom Watch Options

const { server, close } = await createUniMcpServer({
  watch: true,
  // highlight-start
  watchOptions: {
    debounceMs: 500 // Wait 500ms after last change before notifying
  }
  // highlight-end
});

Security

Path Traversal Protection

Security Feature

The server validates all file paths to prevent directory traversal attacks. Only files within the UI package are accessible.

// ✅ Valid - within UI package
registry://uni-mcp/button

// ❌ Invalid - outside UI package
registry://uni-mcp/../../secrets/api-key

Timeout Protection

// Default 5-second timeout for file operations
const { server } = await createUniMcpServer({
  timeout: 5000 // milliseconds
});

AI Assistant Usage

Query Component List

// AI assistant queries available components
const response = await mcp.call("resources/list");

// Returns list of registry:// URIs
[
  "registry://uni-mcp/index",
  "registry://uni-mcp/button",
  "registry://uni-mcp/card"
  // ...
];

Get Component Source

// AI assistant requests component details
const component = await mcp.call("resources/read", {
  uri: "registry://uni-mcp/button"
});

// Returns full component source code and metadata
console.log(component.files[0].content);

Generate Code

AI Integration

AI assistants use the registry data to generate code that matches your design system patterns.

Example AI prompt:

Create a form with a primary button and cancel button using the OneApp UI components.

AI generates code using registry data:

import { Button } from "@repo/ui/button";

export function MyForm() {
  return (
    <form>
      {/* AI knows button variants from registry */}
      <Button variant="default">Submit</Button>
      <Button variant="outline">Cancel</Button>
    </form>
  );
}

Testing

Test Utilities

import { createTestServer, cleanupTestServer } from "@repo/uni-mcp/test-utils";

// Create test server with custom UI root
const { server, uiRoot } = await createTestServer("/test/fixtures/ui");

// Use server...

// Cleanup
await cleanupTestServer(server);

Unit Tests

# Run tests
pnpm --filter @repo/uni-mcp test

# With coverage
pnpm --filter @repo/uni-mcp test:coverage

Troubleshooting

Server Not Responding

Check that the UI package exists and contains a registry.json:

ls packages/ui/registry.json

File Watching Not Working

Platform-Specific

File watching uses native OS APIs. Some Docker/VM setups may not support it. Use --no-watch flag if needed.

# Disable watching if it's not working
npx uni-mcp --no-watch

Invalid Component Path

Ensure component names match those in registry.json:

# List available components
cat packages/ui/registry.json | jq '.items[].name'

Permission Errors

# Ensure executable permissions
chmod +x packages/uni-mcp/src/cli.mjs

External Resources

On this page