Skip to main content
Glama
Jpisnice

@jpisnice/shadcn-ui-mcp-server

by Jpisnice

list_components

Read-only

Retrieve a list of all available shadcn/ui v4 components to understand component structure and installation.

Instructions

Get all available shadcn/ui v4 components

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • The main handler function 'handleListComponents' that executes the tool logic. It fetches available components via axios (which calls GitHub API), sorts them, and returns the list as JSON text.
    import { getAxiosImplementation } from '../../utils/framework.js';
    import { logError } from '../../utils/logger.js';
    
    export async function handleListComponents() {
      try {
        const axios = await getAxiosImplementation();
        const components = await axios.getAvailableComponents();
        return {
          content: [{ 
            type: "text", 
            text: JSON.stringify({ 
              components: components.sort(),
              total: components.length 
            }, null, 2) 
          }]
        };
      } catch (error) {
        logError('Failed to list components', error);
        throw new Error(`Failed to list components: ${error instanceof Error ? error.message : String(error)}`);
      }
    }
    
    export const schema = {}; 
  • The schema for list_components is an empty object (no input parameters required).
    export const schema = {}; 
  • src/tools/index.ts:3-3 (registration)
    Import of the handleListComponents function into the central tools registry.
    import { handleListComponents } from './components/list-components.js';
  • Import of the listComponentsSchema (empty object) into the central tools registry.
    import { schema as listComponentsSchema } from './components/list-components.js';
  • Registration of list_components tool handler in the toolHandlers map.
    list_components: handleListComponents,
  • Registration of listComponentsSchema in the toolSchemas map.
    list_components: listComponentsSchema,
  • Full tool definition for 'list_components' including name, description, and inputSchema (no required params).
    'list_components': {
      name: 'list_components',
      description: 'Get all available shadcn/ui v4 components',
      inputSchema: {
        type: 'object',
        properties: {}
      }
    },
  • The getAxiosImplementation helper that selects the right axios module based on the configured framework (react, svelte, vue, or react-native). Used by the handler to get the correct axios instance.
    export async function getAxiosImplementation() {
      const framework = getFramework();
    
      if (framework === "svelte") {
        // Dynamic import for Svelte implementation
        return import("./axios-svelte.js").then((module) => module.axios);
      } else if (framework === "vue") {
        // Dynamic import for Vue implementation
        return import("./axios-vue.js").then((module) => module.axios);
      } else if (framework === "react-native") {
        // Dynamic import for React Native implementation
        return import("./axios-react-native.js").then((module) => module.axios);
      } else {
        // Dynamic import for React implementation (default)
        return import("./axios.js").then((module) => module.axios);
      }
    }
  • The getAvailableComponents function that actually fetches the component list from the GitHub API (or falls back to a hardcoded list of known shadcn/ui v4 components).
    async function getAvailableComponents(): Promise<string[]> {
        const basePath = getRegistryBasePath();
        try {
            // First try the GitHub API
            const response = await githubApi.get(`/repos/${REPO_OWNER}/${REPO_NAME}/contents/${basePath}/ui`);
            
            if (!response.data || !Array.isArray(response.data)) {
                throw new Error('Invalid response from GitHub API');
            }
            
            const components = response.data
                .filter((item: any) => item.type === 'file' && item.name.endsWith('.tsx'))
                .map((item: any) => item.name.replace('.tsx', ''));
                
            if (components.length === 0) {
                throw new Error('No components found in the registry');
            }
            
            return components;
        } catch (error: any) {
            logError('Error fetching components from GitHub API', error);
            
            // Check for specific error types
            if (error.response) {
                const status = error.response.status;
                const message = error.response.data?.message || 'Unknown error';
                
                if (status === 403 && message.includes('rate limit')) {
                    throw new Error(`GitHub API rate limit exceeded. Please set GITHUB_PERSONAL_ACCESS_TOKEN environment variable for higher limits. Error: ${message}`);
                } else if (status === 404) {
                    throw new Error(`Components directory not found. The path ${basePath}/ui may not exist in the repository.`);
                } else if (status === 401) {
                    throw new Error(`Authentication failed. Please check your GITHUB_PERSONAL_ACCESS_TOKEN if provided.`);
                } else {
                    throw new Error(`GitHub API error (${status}): ${message}`);
                }
            }
            
            // If it's a network error or other issue, provide a fallback
            if (error.code === 'ECONNREFUSED' || error.code === 'ENOTFOUND' || error.code === 'ETIMEDOUT') {
                throw new Error(`Network error: ${error.message}. Please check your internet connection.`);
            }
            
            // If all else fails, provide a fallback list of known components
            logWarning('Using fallback component list due to API issues');
            return getUiLibrary() === 'base' ? getFallbackComponentsBase() : getFallbackComponents();
        }
    }
  • Tool definition in capabilities.ts, declaring list_components with description and inputSchema.
    list_components: {
      description: "Get all available shadcn/ui v4 components",
      inputSchema: {
        type: "object",
        properties: {},
      },
    },
  • Tool definition in the ListToolsRequestSchema handler in server/handler.ts, registering list_components with name, description, inputSchema, and annotations.
      name: 'list_components',
      description: 'Get all available shadcn/ui v4 components',
      inputSchema: {
        type: 'object',
        properties: {},
      },
      annotations: {
        title: "List Components",
        readOnlyHint: true,
      },
    },
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, and the description adds that it gets 'all available' components, confirming no mutation. No further behavioral traits needed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Single sentence with 6 words, perfectly concise and front-loaded with the action and target.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a parameterless listing tool with readOnlyHint annotation, the description fully covers what the tool does, including the version (v4). No output schema exists, but the description doesn't need to explain return format for a simple list.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

No parameters exist, so baseline 4 applies. The description adds no parameter info, which is unnecessary.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb 'Get' and identifies the exact resource 'all available shadcn/ui v4 components'. It clearly distinguishes from siblings like get_component (single component) and list_blocks/list_themes.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context (listing all components for shadcn/ui v4) and implicitly when to use (e.g., before get_component). It lacks explicit exclusions or alternatives, but the tool's simplicity makes this acceptable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Jpisnice/shadcn-ui-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server