Skip to main content
Glama
freema

MCP Design System Extractor

get_component_by_purpose

Find design system components by their purpose to build specific UI features. Search for components like form inputs, navigation, feedback, data display, layout, buttons, progress indicators, or media elements.

Instructions

Find design system components by their purpose or use case. Available purposes: "form inputs" (input fields, selects, checkboxes), "navigation" (menus, breadcrumbs, tabs), "feedback" (alerts, toasts, modals, dialogs, popups), "data display" (tables, cards, lists), "layout" (grids, containers, dividers), "buttons" (all button types), "progress" (loaders, spinners), "media" (images, videos, carousels). Use this when looking for components to build specific UI features. Supports pagination for large result sets.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
purposeYesThe purpose to search for (e.g., "form inputs", "navigation", "feedback", "data display")
pageNoPage number (1-based). Default is 1.
pageSizeNoNumber of components per page (1-100). Default is 50.

Implementation Reference

  • The main handler function for the 'get_component_by_purpose' tool. Validates input, fetches Storybook stories index, filters components matching the purpose using regex patterns (predefined or ad-hoc), maps stories to components, applies pagination, and returns a formatted success response with component details.
    export async function handleGetComponentByPurpose(input: any) {
      let validatedInput: any;
      try {
        validatedInput = validateGetComponentByPurposeInput(input);
        const purposeLower = validatedInput.purpose.toLowerCase();
        const client = new StorybookClient();
    
        // Fetch all components
        const index = await client.fetchStoriesIndex();
        const stories = index.stories || index.entries;
    
        if (!stories) {
          throw new Error('No stories found in Storybook index');
        }
    
        // Find matching purpose patterns
        let patterns: RegExp[] = [];
        let description = '';
    
        // Check predefined purposes
        if (PURPOSE_PATTERNS[purposeLower]) {
          patterns = PURPOSE_PATTERNS[purposeLower].patterns;
          description = PURPOSE_PATTERNS[purposeLower].description;
        } else {
          // Create patterns from the purpose string
          const words = purposeLower.split(/\s+/);
          patterns = words.map((word: string) => new RegExp(word, 'i'));
          description = `Components related to ${validatedInput.purpose}`;
        }
    
        // Create filter function for purpose matching
        const filterFn = (story: any, componentName: string) => {
          const componentTitle = story.title || '';
          const storyName = story.name || story.story || '';
    
          return patterns.some(
            pattern =>
              pattern.test(componentTitle) || pattern.test(storyName) || pattern.test(componentName)
          );
        };
    
        const componentMap = mapStoriesToComponents(stories, {
          filterFn,
          useComponentKey: 'title',
        });
        const allComponents = getComponentsArray(componentMap);
    
        // Apply pagination
        const paginationResult = applyPagination(allComponents, {
          page: validatedInput.page,
          pageSize: validatedInput.pageSize,
        });
    
        const result: ComponentByPurpose = {
          purpose: validatedInput.purpose,
          components: paginationResult.items,
          description,
        };
    
        const message = formatPaginationMessage(
          paginationResult,
          'Found',
          `for purpose: ${validatedInput.purpose}`
        );
    
        return formatSuccessResponse(result, message);
      } catch (error) {
        return handleErrorWithContext(error, 'get components by purpose', {
          resource: 'components by purpose',
        });
      }
    }
  • Tool registration object defining the name, description, and input schema for 'get_component_by_purpose'.
    export const getComponentByPurposeTool: Tool = {
      name: 'get_component_by_purpose',
      description:
        'Find design system components by their purpose or use case. Available purposes: "form inputs" (input fields, selects, checkboxes), "navigation" (menus, breadcrumbs, tabs), "feedback" (alerts, toasts, modals, dialogs, popups), "data display" (tables, cards, lists), "layout" (grids, containers, dividers), "buttons" (all button types), "progress" (loaders, spinners), "media" (images, videos, carousels). Use this when looking for components to build specific UI features. Supports pagination for large result sets.',
      inputSchema: {
        type: 'object',
        properties: {
          purpose: {
            type: 'string',
            description:
              'The purpose to search for (e.g., "form inputs", "navigation", "feedback", "data display")',
          },
          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: ['purpose'],
      },
    };
  • Zod schema for validating the input of get_component_by_purpose tool.
    const GetComponentByPurposeInputSchema = z.object({
      purpose: z.string(),
      page: z.number().int().positive().optional(),
      pageSize: z.number().int().min(1).max(100).optional(),
    });
  • src/index.ts:33-34 (registration)
    Registration of the tool in the main server index file as part of allTools array.
    tools.getComponentByPurposeTool,
    tools.getExternalCSSTool,
  • src/index.ts:22-22 (registration)
    Maps the tool name to its handler function in the toolHandlers Map.
    ['get_component_by_purpose', tools.handleGetComponentByPurpose],
  • TypeScript interface defining the input shape for the tool.
    export interface GetComponentByPurposeInput {
      purpose: string;
      page?: number;
      pageSize?: number;
    }
  • Predefined regex patterns for common component purposes used in filtering components.
    const PURPOSE_PATTERNS: Record<string, { patterns: RegExp[]; description: string }> = {
      'form inputs': {
        patterns: [
          /input/i,
          /textfield/i,
          /textarea/i,
          /select/i,
          /dropdown/i,
          /checkbox/i,
          /radio/i,
          /switch/i,
          /toggle/i,
          /slider/i,
          /datepicker/i,
          /timepicker/i,
          /form/i,
          /field/i,
        ],
        description: 'Components for collecting user input in forms',
      },
      navigation: {
        patterns: [
          /nav/i,
          /menu/i,
          /breadcrumb/i,
          /tabs?/i,
          /stepper/i,
          /pagination/i,
          /link/i,
          /sidebar/i,
          /drawer/i,
          /appbar/i,
          /toolbar/i,
          /header/i,
        ],
        description: 'Components for navigating through the application',
      },
      feedback: {
        patterns: [
          /alert/i,
          /snackbar/i,
          /toast/i,
          /notification/i,
          /message/i,
          /error/i,
          /warning/i,
          /success/i,
          /info/i,
          /banner/i,
          /dialog/i,
          /modal/i,
          /popup/i,
          /tooltip/i,
          /popover/i,
        ],
        description: 'Components for providing feedback to users',
      },
      'data display': {
        patterns: [
          /table/i,
          /datagrid/i,
          /list/i,
          /card/i,
          /chip/i,
          /badge/i,
          /avatar/i,
          /image/i,
          /icon/i,
          /typography/i,
          /text/i,
          /label/i,
          /tag/i,
        ],
        description: 'Components for displaying data and content',
      },
      layout: {
        patterns: [
          /grid/i,
          /container/i,
          /box/i,
          /stack/i,
          /flex/i,
          /spacer/i,
          /divider/i,
          /layout/i,
          /panel/i,
          /section/i,
          /wrapper/i,
          /column/i,
          /row/i,
        ],
        description: 'Components for structuring and laying out content',
      },
      buttons: {
        patterns: [/button/i, /fab/i, /icon.*button/i, /action/i, /cta/i],
        description: 'Interactive button components',
      },
      progress: {
        patterns: [
          /progress/i,
          /loading/i,
          /spinner/i,
          /skeleton/i,
          /loader/i,
          /circular.*progress/i,
          /linear.*progress/i,
        ],
        description: 'Components for showing loading and progress states',
      },
      media: {
        patterns: [
          /image/i,
          /video/i,
          /audio/i,
          /media/i,
          /gallery/i,
          /carousel/i,
          /slider/i,
          /player/i,
        ],
        description: 'Components for displaying media content',
      },
    };
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 search/find operation (implied read-only), it supports pagination for large result sets, and it operates on design system components. The description doesn't mention authentication requirements, rate limits, or error conditions, but provides sufficient context for basic usage.

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: it starts with the core purpose, provides the complete list of available purposes with helpful examples, gives usage guidance, and ends with technical detail about pagination. Every sentence earns its place, and there's no wasted text or redundancy.

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 the tool's moderate complexity (3 parameters, 100% schema coverage, no output schema), the description provides good contextual completeness. It explains what the tool does, when to use it, valid input values, and pagination behavior. The main gap is the lack of output format information (since there's no output schema), but the description compensates reasonably well for a search tool.

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?

The input schema has 100% description coverage, so the schema already documents all three parameters well. The description adds value by providing the complete list of valid purpose values with examples (e.g., 'form inputs' includes 'input fields, selects, checkboxes'), which goes beyond the schema's generic description. However, it doesn't add significant semantic context beyond what's already in the structured schema.

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 tool's purpose: 'Find design system components by their purpose or use case.' It provides a specific verb ('find') and resource ('design system components'), and distinguishes itself from siblings like 'list_components' or 'search_components' by focusing on purpose-based filtering rather than general listing or keyword searching.

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: 'Use this when looking for components to build specific UI features.' It provides clear context by listing available purposes (e.g., 'form inputs', 'navigation'), which helps the agent understand appropriate use cases. However, it doesn't explicitly mention when NOT to use it or name specific alternatives among the sibling tools.

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