Skip to main content
Glama

MCP Design System Extractor

get-component-dependencies.ts4.06 kB
import { Tool } from '@modelcontextprotocol/sdk/types.js'; import { StorybookClient } from '../utils/storybook-client.js'; import { handleError, formatSuccessResponse } from '../utils/error-handler.js'; import { validateGetComponentDependenciesInput } from '../utils/validators.js'; import { ComponentDependencies } from '../types/storybook.js'; export const getComponentDependenciesTool: Tool = { name: 'get_component_dependencies', description: 'Analyze rendered HTML to find which other components a given component internally uses by detecting React components, web components, and CSS class patterns', inputSchema: { type: 'object', properties: { componentId: { type: 'string', description: 'The story ID of the component (e.g., "example-button--primary")', }, }, required: ['componentId'], }, }; export async function handleGetComponentDependencies(input: any) { try { const validatedInput = validateGetComponentDependenciesInput(input); const client = new StorybookClient(); // Fetch the component HTML const componentHTML = await client.fetchComponentHTML(validatedInput.componentId); // Analyze the HTML to find other components const dependencies = new Set<string>(); const internalComponents = new Set<string>(); const externalComponents = new Set<string>(); // Common patterns for component detection const componentPatterns = [ // React-style components: <Button>, <MuiButton> /<([A-Z][a-zA-Z0-9]*)\s*[^>]*>/g, // Web components: <my-button>, <app-header> /<([a-z]+-[a-z-]+)\s*[^>]*>/g, // Angular/Vue style: <app-button>, <v-btn> /<(app-[a-z-]+|v-[a-z-]+)\s*[^>]*>/g, ]; // Extract component names from HTML for (const pattern of componentPatterns) { let match; while ((match = pattern.exec(componentHTML.html)) !== null) { const componentName = match[1]; if (componentName && !isHTMLElement(componentName)) { dependencies.add(componentName); } } } // Also check for CSS classes that might indicate component usage const classPatterns = [ /\b([A-Z][a-zA-Z0-9]+)-root\b/g, /\bMui([A-Z][a-zA-Z0-9]+)\b/g, /\bcomponent-([a-z-]+)\b/g, ]; for (const pattern of classPatterns) { let match; while ((match = pattern.exec(componentHTML.html)) !== null) { const componentName = match[1]; if (componentName) { dependencies.add(componentName); } } } // Try to categorize dependencies const allDependencies = Array.from(dependencies); for (const dep of allDependencies) { // Heuristic: if it starts with Mui, Material, Ant, etc., it's external if (/^(Mui|Material|Ant|Bootstrap|Semantic)/i.test(dep)) { externalComponents.add(dep); } else { internalComponents.add(dep); } } const componentDependencies: ComponentDependencies = { storyId: validatedInput.componentId, dependencies: allDependencies.sort(), internalComponents: Array.from(internalComponents).sort(), externalComponents: Array.from(externalComponents).sort(), }; return formatSuccessResponse( componentDependencies, `Retrieved dependencies for component: ${validatedInput.componentId}` ); } catch (error) { return handleError(error); } } function isHTMLElement(tagName: string): boolean { const htmlElements = [ 'div', 'span', 'p', 'a', 'button', 'input', 'form', 'label', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'li', 'table', 'tr', 'td', 'th', 'thead', 'tbody', 'tfoot', 'img', 'video', 'audio', 'canvas', 'svg', 'path', 'g', 'header', 'footer', 'nav', 'main', 'section', 'article', 'aside', 'details', 'summary', 'figure', 'figcaption', ]; return htmlElements.includes(tagName.toLowerCase()); }

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