or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

examples

edge-cases.mdreal-world-scenarios.md
index.md
tile.json

mcp.mddocs/reference/

Model Context Protocol

MCP server integration for AI assistant workflows. The Model Context Protocol (MCP) server enables AI assistants to discover, search, view, and add components through a standardized protocol.

Capabilities

MCP Server

The MCP server instance that AI assistants can connect to for component management operations.

/**
 * MCP Server instance for AI assistant integration
 * Provides tools for component discovery and management
 *
 * Note: Server type is from '@modelcontextprotocol/sdk/server/index.js'
 */
const server: Server

// Server is the MCP server class from the Model Context Protocol SDK
// It provides a standardized interface for AI assistants to interact with tools
interface Server {
  // MCP server properties and methods (from @modelcontextprotocol/sdk)
  // Details: https://github.com/modelcontextprotocol/typescript-sdk
}

Usage Example:

import { server } from 'shadcn/mcp';

// The server is pre-configured and ready to use
// Typically used by running: npx shadcn mcp

Server Lifecycle:

  • Server starts on stdio when npx shadcn mcp is executed
  • Server runs until process termination (Ctrl+C or SIGTERM)
  • Server reads MCP protocol messages from stdin
  • Server writes responses to stdout
  • Server maintains state for caching and configuration

MCP Tools

The MCP server provides 7 specialized tools for AI assistants:

get_project_registries

Gets configured registry names from components.json. Returns an error if no components.json exists.

/**
 * Tool: get_project_registries
 * Description: Get configured registry names from components.json
 * Parameters: none
 * Returns: List of configured registry names with usage instructions
 */
{
  name: "get_project_registries"
  inputSchema: {
    type: "object"
    properties: {}
    required: []
  }
}

Parameters: None

Returns: Text message with:

  • List of configured registry names
  • Usage instructions for viewing items
  • Example commands

Usage Scenario:

AI assistant asks: "What registries are configured in this project?"

MCP response includes:

  • @shadcn registry
  • @acme registry (if configured)
  • Instructions: npx shadcn view @shadcn

Success Response Format:

{
  "content": [{
    "type": "text",
    "text": "Configured registries:\n- @shadcn\n- @acme\n\nUsage: npx shadcn view @shadcn"
  }],
  "isError": false
}

Error Cases:

  • No components.json found → Instructions to run init
  • No registries configured → Instructions to add registries section
  • Invalid components.json → Parse error with suggestion to fix configuration

Error Response Format:

{
  "content": [{
    "type": "text",
    "text": "Error: components.json not found\n\n💡 Run: npx shadcn init"
  }],
  "isError": true
}

Edge Cases:

  • If components.json exists but has no registries section, returns instructions to add registries
  • If components.json is malformed JSON, returns parse error
  • If components.json is in parent directory (workspace setup), still works correctly

list_items_in_registries

Lists items from specified registries. Requires components.json to be configured.

/**
 * Tool: list_items_in_registries
 * Description: List items from registries
 * Parameters:
 *   - registries: Array of registry names (e.g., ['@shadcn', '@acme'])
 *   - limit: Maximum items to return (optional, default: 100)
 *   - offset: Pagination offset (optional, default: 0)
 * Returns: Paginated list of items with names, types, and descriptions
 */
{
  name: "list_items_in_registries"
  inputSchema: {
    type: "object"
    properties: {
      registries: {
        type: "array"
        items: { type: "string" }
        description: "Array of registry names to list (must start with @)"
        minItems: 1
      }
      limit: {
        type: "number"
        description: "Maximum number of items to return"
        minimum: 1
        maximum: 1000
        default: 100
      }
      offset: {
        type: "number"
        description: "Number of items to skip for pagination"
        minimum: 0
        default: 0
      }
    }
    required: ["registries"]
  }
}

Parameters:

  • registries: string[] - Array of registry names to list (e.g., ['@shadcn', '@acme']). Must start with @. Required.
  • limit?: number - Maximum number of items to return (1-1000, default: 100). Optional. Values above 1000 are clamped to 1000.
  • offset?: number - Number of items to skip for pagination (minimum: 0, default: 0). Optional. Negative values result in validation error.

Returns: Formatted list of items with:

  • Item name
  • Item type
  • Description
  • Registry source
  • Pagination info (total, offset, hasMore)

Usage Example:

AI assistant: "List all components from @shadcn"

MCP request:

{
  "registries": ["@shadcn"],
  "limit": 20
}

MCP response includes:

  • button (registry:ui) - A button component
  • card (registry:ui) - A card component
  • dialog (registry:ui) - A dialog component
  • ... (up to 20 items)
  • Pagination: Showing 1-20 of 150 items

Pagination Example:

{
  "content": [{
    "type": "text",
    "text": "Items from @shadcn:\n\n1. button (registry:ui) - A button component\n2. card (registry:ui) - A card component\n...\n\nPagination: Showing 1-20 of 150 items (hasMore: true)"
  }],
  "isError": false
}

Error Cases:

  • Invalid registry name (doesn't start with @) → Validation error with format requirement
  • Registry not found → RegistryNotFoundError with suggestion to check components.json
  • No components.json → ConfigMissingError with init instructions
  • Network error → RegistryFetchError with retry suggestion
  • Empty registry → Returns empty list (not an error)

Edge Cases:

  • If limit exceeds 1000, it's automatically clamped to 1000
  • If offset exceeds total items, returns empty list
  • If multiple registries specified and one fails, partial results may be returned
  • If registry requires authentication and credentials missing, returns RegistryUnauthorizedError

search_items_in_registries

Searches for components in registries using fuzzy matching. Requires components.json.

/**
 * Tool: search_items_in_registries
 * Description: Search for components using fuzzy matching
 * Parameters:
 *   - registries: Array of registry names to search
 *   - query: Search query string
 *   - limit: Maximum items to return (optional, default: 10)
 *   - offset: Pagination offset (optional, default: 0)
 * Returns: Paginated search results with fuzzy matching
 */
{
  name: "search_items_in_registries"
  inputSchema: {
    type: "object"
    properties: {
      registries: {
        type: "array"
        items: { type: "string" }
        description: "Array of registry names to search (must start with @)"
        minItems: 1
      }
      query: {
        type: "string"
        description: "Search query for fuzzy matching on names and descriptions"
        minLength: 1
      }
      limit: {
        type: "number"
        description: "Maximum number of items to return"
        minimum: 1
        maximum: 100
        default: 10
      }
      offset: {
        type: "number"
        description: "Number of items to skip for pagination"
        minimum: 0
        default: 0
      }
    }
    required: ["registries", "query"]
  }
}

Parameters:

  • registries: string[] - Array of registry names to search. Must start with @. Required.
  • query: string - Search query for fuzzy matching (minimum length: 1). Required. Empty strings result in validation error.
  • limit?: number - Maximum items to return (1-100, default: 10). Optional. Values above 100 are clamped to 100.
  • offset?: number - Pagination offset (minimum: 0, default: 0). Optional.

Returns: Search results with:

  • Matching items sorted by relevance
  • Item details (name, type, description, registry)
  • Pagination metadata
  • Suggestion to use get_item_examples_from_registries for usage examples

Usage Example:

AI assistant: "Search for button components"

MCP request:

{
  "registries": ["@shadcn"],
  "query": "button"
}

MCP response includes:

  • button (registry:ui) - A button component [@shadcn]
  • icon-button (registry:ui) - A button with icon [@shadcn]
  • button-demo (registry:example) - Button examples [@shadcn]

Fuzzy Matching Behavior:

  • Matches component names (partial and full)
  • Matches descriptions (keyword matching)
  • Results sorted by relevance (exact name matches first, then partial matches, then description matches)
  • Case-insensitive matching
  • Handles typos and partial matches (e.g., "btn" matches "button")

Error Cases:

  • Empty query → Validation error (query must be at least 1 character)
  • No matches → Returns empty results array (not an error, isError: false)
  • Registry not found → RegistryNotFoundError
  • Network error → RegistryFetchError

Edge Cases:

  • Very short queries (1-2 characters) may return many results
  • Special characters in query are handled (escaped or treated as literals)
  • If query matches many items, results are limited by limit parameter
  • If multiple registries specified, results are combined and sorted by relevance across all registries

view_items_in_registries

Views detailed information about specific registry items. Shows item metadata, files, and code.

/**
 * Tool: view_items_in_registries
 * Description: View detailed information about registry items
 * Parameters:
 *   - items: Array of item names with registry prefix
 * Returns: Detailed item information including files and content
 * Note: For usage examples, use get_item_examples_from_registries instead
 */
{
  name: "view_items_in_registries"
  inputSchema: {
    type: "object"
    properties: {
      items: {
        type: "array"
        items: { type: "string" }
        description: "Array of item names with registry prefix (e.g., '@shadcn/button')"
        minItems: 1
      }
    }
    required: ["items"]
  }
}

Parameters:

  • items: string[] - Array of item names with registry prefix (e.g., ['@shadcn/button', '@shadcn/card']). Must include registry prefix. Required, minimum 1 item.

Returns: Detailed information including:

  • Item name, type, and description
  • List of files with paths and content
  • Dependencies (npm and registry)
  • Tailwind configuration
  • CSS variables
  • Environment variables
  • Metadata

Usage Example:

AI assistant: "Show me the button component"

MCP request:

{
  "items": ["@shadcn/button"]
}

MCP response includes:

  • Name: button
  • Type: registry:ui
  • Description: A button component
  • Files:
    • components/ui/button.tsx (with full content)
  • Dependencies: class-variance-authority, @radix-ui/react-slot
  • Registry Dependencies: utils

Response Structure:

{
  "content": [{
    "type": "text",
    "text": "Item: @shadcn/button\nType: registry:ui\nDescription: A button component\n\nFiles:\n- components/ui/button.tsx\n\nDependencies:\n- class-variance-authority\n- @radix-ui/react-slot\n\nRegistry Dependencies:\n- utils"
  }],
  "isError": false
}

Error Cases:

  • Item not found → Suggestion to check item name and registry prefix, may suggest similar items
  • Invalid format (missing registry prefix) → Validation error with format example
  • Registry not configured → RegistryNotConfiguredError with configuration instructions
  • Network error → RegistryFetchError with retry suggestion
  • Item exists but fetch fails → RegistryFetchError

Edge Cases:

  • If multiple items specified and some fail, partial results may be returned with errors for failed items
  • If item has large file content, response may be truncated (check response length)
  • If item has circular registry dependencies, dependency resolution may fail
  • If registry requires authentication, missing credentials result in RegistryUnauthorizedError

get_item_examples_from_registries

Finds usage examples and demos with complete code. Searches for demo and example items.

/**
 * Tool: get_item_examples_from_registries
 * Description: Find usage examples and demos with complete implementation code
 * Parameters:
 *   - registries: Array of registry names to search
 *   - query: Search query for examples (e.g., 'accordion-demo', 'button example')
 * Returns: Complete example code with dependencies
 * Common patterns: '{item-name}-demo', '{item-name} example', 'example {item-name}'
 */
{
  name: "get_item_examples_from_registries"
  inputSchema: {
    type: "object"
    properties: {
      registries: {
        type: "array"
        items: { type: "string" }
        description: "Array of registry names to search (must start with @)"
        minItems: 1
      }
      query: {
        type: "string"
        description: "Search query for examples (e.g., 'accordion-demo', 'button example')"
        minLength: 1
      }
    }
    required: ["registries", "query"]
  }
}

Parameters:

  • registries: string[] - Array of registry names to search. Must start with @. Required.
  • query: string - Search query for examples (e.g., 'accordion-demo', 'button example'). Minimum length: 1. Required.

Returns: Example code and metadata:

  • Example name and description
  • Complete implementation code
  • All required dependencies
  • Usage instructions

Common Query Patterns:

  • {component-name}-demo (e.g., accordion-demo)
  • {component-name} demo (e.g., button demo)
  • {component-name} example (e.g., card example)
  • example {component-name} (e.g., example form)

Usage Example:

AI assistant: "Show me button examples"

MCP request:

{
  "registries": ["@shadcn"],
  "query": "button-demo"
}

MCP response includes:

  • button-demo example
  • Complete implementation code showing various button variants
  • Dependencies and imports
  • Usage patterns

Error Cases:

  • No examples found → Suggestions for alternative search patterns, may suggest using search_items_in_registries first
  • Alternative: Use search_items_in_registries and then view_items_in_registries
  • Network error → RegistryFetchError

Fallback Strategy:

  1. Try exact match: {component}-demo
  2. Try with space: {component} demo
  3. Try with "example": {component} example
  4. Try with "examples": {component} examples
  5. If no results, suggest using search_items_in_registries first to find example items

Edge Cases:

  • If multiple example items match, returns the first/most relevant match
  • If example item has dependencies, those are included in the response
  • If example code is very long, response may be truncated

get_add_command_for_items

Gets the shadcn CLI add command for specific items. Returns the exact command to add components.

/**
 * Tool: get_add_command_for_items
 * Description: Get the CLI add command for specific items
 * Parameters:
 *   - items: Array of items to add with registry prefix
 * Returns: The exact npx shadcn add command to run
 */
{
  name: "get_add_command_for_items"
  inputSchema: {
    type: "object"
    properties: {
      items: {
        type: "array"
        items: { type: "string" }
        description: "Array of items to add with registry prefix (e.g., '@shadcn/button')"
        minItems: 1
      }
    }
    required: ["items"]
  }
}

Parameters:

  • items: string[] - Array of items to add with registry prefix (e.g., ['@shadcn/button', '@shadcn/card']). Must include registry prefix. Required, minimum 1 item.

Returns: The exact CLI command to add the items

Usage Example:

AI assistant: "How do I add the button and card components?"

MCP request:

{
  "items": ["@shadcn/button", "@shadcn/card"]
}

MCP response:

{
  "content": [{
    "type": "text",
    "text": "npx shadcn add @shadcn/button @shadcn/card"
  }],
  "isError": false
}

Command Format:

  • Single item: npx shadcn add @shadcn/button
  • Multiple items: npx shadcn add @shadcn/button @shadcn/card
  • Items from same registry can omit prefix: npx shadcn add button card (if @shadcn is default)

Error Cases:

  • Invalid item format → Validation error with format example
  • Item not found → Suggestion to verify item name, may suggest using search_items_in_registries first
  • Registry not configured → RegistryNotConfiguredError

Edge Cases:

  • If item name doesn't include registry prefix, uses default registry from components.json
  • If multiple items from different registries, all registry prefixes are included
  • If item doesn't exist, command is still returned but will fail when executed

get_audit_checklist

Gets a checklist for verifying components after creation. Provides post-addition verification steps.

/**
 * Tool: get_audit_checklist
 * Description: Get checklist for verifying components after creation
 * Parameters: none
 * Returns: Checklist of common issues to verify
 * Note: Use after all required steps have been completed
 */
{
  name: "get_audit_checklist"
  inputSchema: {
    type: "object"
    properties: {}
    required: []
  }
}

Parameters: None

Returns: Checklist including:

  • Ensure imports are correct (named vs default imports)
  • If using next/image, ensure images.remotePatterns in next.config.js is configured
  • Ensure all dependencies are installed
  • Check for linting errors or warnings
  • Check for TypeScript errors
  • Use Playwright MCP if available

Usage Example:

AI assistant: "I've added the button component. What should I check?"

MCP request:

{}

MCP response provides the complete audit checklist.

Checklist Items:

  1. Verify import statements match project structure
  2. Check for missing dependencies in package.json
  3. Verify Tailwind configuration updates
  4. Check CSS variable definitions
  5. Verify environment variables if required
  6. Run linting and type checking
  7. Test component rendering

Response Format:

{
  "content": [{
    "type": "text",
    "text": "Post-Installation Checklist:\n\n[ ] Ensure imports are correct (named vs default imports)\n[ ] If using next/image, ensure images.remotePatterns in next.config.js is configured\n[ ] Ensure all dependencies are installed\n[ ] Check for linting errors or warnings\n[ ] Check for TypeScript errors\n[ ] Use Playwright MCP if available"
  }],
  "isError": false
}

Note: This tool always succeeds and returns the same checklist. It does not validate the actual installation state.

Starting the MCP Server

CLI Command

Start the MCP server from the command line:

npx shadcn mcp

The server runs on stdio and waits for MCP protocol messages from AI assistants.

Server Behavior:

  • Server reads from stdin (MCP protocol messages)
  • Server writes to stdout (MCP protocol responses)
  • Server logs errors to stderr
  • Server runs until process termination (Ctrl+C, SIGTERM, or stdin EOF)
  • Server maintains configuration cache for performance

Programmatic Usage

import { server } from 'shadcn/mcp';

// Server is already configured and ready
// Request handlers are pre-registered
// Connect your MCP client to this server

Note: The server must be connected to stdio streams. For programmatic use, you need to set up stdin/stdout pipes.

MCP Workflow Example

Typical workflow for AI assistant adding a component:

  1. Check Configuration

    • Tool: get_project_registries
    • Verifies components.json exists and is configured
    • If missing, suggests running npx shadcn init
  2. Search for Component

    • Tool: search_items_in_registries
    • Query: "button"
    • Returns matching components
    • If no results, try alternative queries
  3. View Component Details

    • Tool: view_items_in_registries
    • Items: ["@shadcn/button"]
    • Shows component code and dependencies
    • Verify dependencies are acceptable
  4. Find Usage Examples

    • Tool: get_item_examples_from_registries
    • Query: "button-demo"
    • Returns example implementations
    • If no examples found, try alternative query patterns
  5. Get Add Command

    • Tool: get_add_command_for_items
    • Items: ["@shadcn/button"]
    • Returns: npx shadcn add @shadcn/button
  6. Execute Command

    • AI assistant runs the returned command
    • Component is added to project
    • Check exit code for success/failure
  7. Verify Installation

    • Tool: get_audit_checklist
    • Provides checklist for verification
    • Follow checklist items to ensure proper installation

Error Handling in Workflow:

  • At each step, check isError flag in response
  • If error occurs, parse error message for actionable suggestions
  • Retry failed operations with corrected parameters
  • If registry errors occur, verify components.json configuration

Error Handling

MCP tools return structured errors:

// Zod validation error
{
  content: [{
    type: "text",
    text: "Invalid input parameters:\n- registries: Required"
  }],
  isError: true
}

// Registry error
{
  content: [{
    type: "text",
    text: "Error (REGISTRY_NOT_FOUND): Registry @custom not found\n\n💡 Check your components.json configuration"
  }],
  isError: true
}

// General error
{
  content: [{
    type: "text",
    text: "Error: Failed to fetch registry items"
  }],
  isError: true
}

Error Response Structure:

  • isError: true - Indicates error response (always check this first)
  • content - Array with error message (always contains at least one text item)
  • Error messages include suggestions when available
  • Error messages may include error codes for programmatic handling

Common Error Codes:

  • REGISTRY_NOT_FOUND - Registry not configured or invalid
  • CONFIG_MISSING - components.json not found
  • VALIDATION_ERROR - Invalid input parameters
  • NETWORK_ERROR - Failed to fetch from registry
  • NOT_FOUND - Item not found in registry
  • UNAUTHORIZED - Authentication required
  • FORBIDDEN - Access denied
  • PARSE_ERROR - Invalid response format

Error Handling Best Practices:

  1. Always check isError flag before processing response
  2. Parse error messages for actionable suggestions
  3. Handle network errors with retry logic
  4. Validate input parameters before making requests
  5. Provide user-friendly error messages based on error codes

MCP Inspector

Debug and inspect MCP server with the MCP Inspector:

pnpm dlx @modelcontextprotocol/inspector node dist/index.js mcp

This launches an interactive inspector for testing MCP tools and viewing requests/responses.

Inspector Features:

  • Interactive tool testing
  • Request/response viewing
  • Error debugging
  • Protocol message inspection

Configuration Requirements

MCP tools require components.json to be present:

{
  "$schema": "https://ui.shadcn.com/schema.json",
  "style": "new-york",
  "tailwind": {
    "css": "app/globals.css",
    "baseColor": "slate"
  },
  "aliases": {
    "components": "@/components",
    "utils": "@/lib/utils"
  },
  "registries": {
    "@shadcn": "https://ui.shadcn.com/r/{name}.json"
  }
}

If components.json is missing, tools will return appropriate error messages with instructions to run npx shadcn init.

Configuration Discovery:

  • Tools search for components.json in current directory and parent directories
  • Uses same discovery logic as CLI commands
  • Caches configuration for performance

Integration with AI Assistants

AI assistants can integrate with the MCP server to provide intelligent component management:

  1. Component Discovery: Search and browse available components
  2. Code Inspection: View component source code and structure
  3. Example Lookup: Find usage examples and demos
  4. Installation Assistance: Get exact commands to add components
  5. Post-Installation Verification: Provide checklist for verification

The MCP protocol enables seamless interaction between AI assistants and the shadcn CLI ecosystem.

Agent Best Practices

  1. Always Check Configuration First: Use get_project_registries before other operations to verify setup
  2. Handle Errors Gracefully: Check isError flag and parse error messages for actionable suggestions
  3. Use Pagination: For large result sets, use limit and offset parameters to manage response size
  4. Search Before View: Use search_items_in_registries to find components, then view_items_in_registries for details
  5. Get Examples: Always check for examples using get_item_examples_from_registries before implementing
  6. Verify After Addition: Use get_audit_checklist after adding components to ensure proper installation
  7. Validate Input: Ensure registry names start with @ and item names include registry prefix
  8. Handle Network Errors: Implement retry logic for network-related errors
  9. Cache Results: Cache registry lists and item details when appropriate to reduce API calls
  10. Provide Context: When errors occur, provide context about what operation was being performed

Performance Considerations

  • Caching: Registry responses may be cached. Use appropriate cache headers if implementing custom caching
  • Pagination: Always use pagination for large result sets to avoid timeouts
  • Batch Operations: When viewing multiple items, consider batching requests
  • Network Timeouts: Implement timeout handling for registry requests
  • Rate Limiting: Be aware of potential rate limits on registry endpoints

Security Considerations

  • Authentication: Private registries require authentication. Ensure credentials are properly configured
  • Environment Variables: Registry configurations may reference environment variables (e.g., ${TOKEN})
  • Input Validation: Always validate user input before passing to MCP tools
  • Error Messages: Be careful not to expose sensitive information in error messages