Skip to main content
Glama
freema

MCP Design System Extractor

list_components

Discover available UI components in your design system or Storybook. View component names, categories, and stories to identify elements for building interfaces. Filter by category or use pagination for large libraries.

Instructions

List all UI components available in your design system/Storybook. Returns components like modals, dialogs, buttons, forms, cards, etc. with their names, categories, and stories. Use this to explore what components are available for building UI features. Use category="all" or omit category parameter to list all components. Supports pagination to handle large component libraries.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
categoryNoFilter components by category path (e.g., "Components/Buttons", "Layout"). Use "all" or omit to list all components.
pageNoPage number (1-based). Default is 1.
pageSizeNoNumber of components per page (1-100). Default is 50.

Implementation Reference

  • The main handler function that executes the list_components tool: validates input, fetches Storybook stories index, maps stories to components with optional category filter, applies pagination, and formats the response.
    export async function handleListComponents(input: any) {
      let validatedInput: any;
      try {
        validatedInput = validateListComponentsInput(input);
        const client = new StorybookClient();
    
        const storiesIndex = await client.fetchStoriesIndex();
    
        if (!storiesIndex) {
          throw new Error(
            'Failed to fetch stories index - received null or undefined. Ensure Storybook is running and accessible at: ' +
              client.getStorybookUrl()
          );
        }
    
        // Support both v3 (stories) and v4 (entries) format
        const storiesData = storiesIndex.stories || storiesIndex.entries;
    
        if (!storiesData || typeof storiesData !== 'object') {
          throw new Error(
            `Invalid stories index structure. Expected object with 'stories' or 'entries' property, got: ${JSON.stringify(storiesIndex).substring(0, 200)}... Check if your Storybook instance is properly configured.`
          );
        }
    
        const stories = Object.values(storiesData);
    
        if (stories.length === 0) {
          return formatSuccessResponse(
            [],
            `No components found in Storybook at ${client.getStorybookUrl()}. Ensure your Storybook has stories configured and is accessible. Debug info: storiesData keys: ${Object.keys(storiesData).slice(0, 5).join(', ')}`
          );
        }
    
        const filterFn =
          validatedInput.category && validatedInput.category !== 'all'
            ? (_story: any, _componentName: string, category?: string) =>
                category === validatedInput.category
            : undefined;
    
        const componentMap = mapStoriesToComponents(storiesData, filterFn ? { filterFn } : {});
        const allComponents = getComponentsArray(componentMap);
    
        // Apply pagination
        const paginationResult = applyPagination(allComponents, {
          page: validatedInput.page,
          pageSize: validatedInput.pageSize,
        });
    
        const message = formatPaginationMessage(
          paginationResult,
          'Found',
          `filter: ${validatedInput.category || 'none'}`
        );
    
        return formatSuccessResponse(paginationResult.items, message);
      } catch (error) {
        return handleErrorWithContext(error, 'list components', {
          resource: 'components list',
        });
      }
    }
  • JSON schema for tool inputs: category (optional filter), page, pageSize.
    inputSchema: {
      type: 'object',
      properties: {
        category: {
          type: 'string',
          description:
            'Filter components by category path (e.g., "Components/Buttons", "Layout"). Use "all" or omit to list all components.',
        },
        page: {
          type: 'number',
          description: 'Page number (1-based). Default is 1.',
        },
        pageSize: {
          type: 'number',
          description: 'Number of components per page (1-100). Default is 50.',
        },
      },
      required: [],
    },
  • src/index.ts:15-24 (registration)
    Registers 'list_components' tool name to its handler function in the MCP server's toolHandlers Map.
    const toolHandlers = new Map<string, (input: any) => Promise<any>>([
      ['list_components', tools.handleListComponents],
      ['get_component_html', tools.handleGetComponentHTML],
      ['get_component_variants', tools.handleGetComponentVariants],
      ['search_components', tools.handleSearchComponents],
      ['get_component_dependencies', tools.handleGetComponentDependencies],
      ['get_theme_info', tools.handleGetThemeInfo],
      ['get_component_by_purpose', tools.handleGetComponentByPurpose],
      ['get_external_css', tools.handleGetExternalCSS],
    ]);
  • src/index.ts:26-35 (registration)
    Includes listComponentsTool in the allTools array for ListToolsRequest response.
    const allTools = [
      tools.listComponentsTool,
      tools.getComponentHTMLTool,
      tools.getComponentVariantsTool,
      tools.searchComponentsTool,
      tools.getComponentDependenciesTool,
      tools.getThemeInfoTool,
      tools.getComponentByPurposeTool,
      tools.getExternalCSSTool,
    ];
  • TypeScript type definition for ListComponentsInput, matching the tool's input schema.
    export interface ListComponentsInput {
      category?: string;
      page?: number;
      pageSize?: number;
    }
Behavior4/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure. It effectively describes key behaviors: it's a read operation (implied by 'List'), discloses pagination support ('Supports pagination to handle large component libraries'), and specifies return content ('components like modals, dialogs, buttons, forms, cards, etc. with their names, categories, and stories'). It doesn't mention rate limits or authentication needs, but covers the essential operational context well.

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?

The description is efficiently structured in three sentences: the first states purpose and return values, the second provides usage context, and the third covers parameter defaults and pagination. Every sentence adds value with zero wasted words, and key information is front-loaded appropriately.

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

Completeness4/5

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

Given no annotations and no output schema, the description does a good job covering the tool's purpose, behavior, and parameter guidance. It explains what the tool returns and how to use it effectively. The main gap is the lack of explicit output format details (though it hints at structure), which prevents a perfect score since there's no output schema to compensate.

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

Parameters3/5

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

Schema description coverage is 100%, so the schema already fully documents all three parameters. The description adds minimal value beyond the schema by mentioning the 'all' value for category and the pagination context, but doesn't provide additional semantic meaning or usage examples that aren't already in the schema descriptions. This meets the baseline of 3 for high schema coverage.

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 clearly states the specific action ('List all UI components'), identifies the resource ('available in your design system/Storybook'), and distinguishes it from siblings by focusing on comprehensive listing rather than specific retrieval (e.g., get_component_by_purpose) or searching (search_components). It provides concrete examples of what gets returned ('modals, dialogs, buttons, etc. with their names, categories, and stories').

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 explicitly states when to use this tool ('to explore what components are available for building UI features') and provides guidance on parameter usage ('Use category="all" or omit category parameter to list all components'). However, it doesn't explicitly contrast when to use this tool versus alternatives like search_components or get_component_by_purpose, which would be needed for a score of 5.

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/freema/mcp-design-system-extractor'

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