Skip to main content
Glama

UI/UX MCP Server

by willem4130
storybook.tsโ€ข5.32 kB
import axios from 'axios'; import { z } from 'zod'; import * as cheerio from 'cheerio'; const StorybookStoriesSchema = z.object({ url: z.string().url().optional() }); const StorybookTestSchema = z.object({ componentName: z.string(), storyName: z.string().optional(), testTypes: z.array(z.enum(['visual', 'accessibility', 'interaction'])).optional() }); export class StorybookTools { private storybookUrl: string; constructor() { this.storybookUrl = process.env.STORYBOOK_URL || 'http://localhost:6006'; } async getStories(args: any) { const params = StorybookStoriesSchema.parse(args); const url = params.url || this.storybookUrl; try { // Fetch the Storybook iframe.html to get stories data const response = await axios.get(`${url}/iframe.html`); const $ = cheerio.load(response.data); // Extract story data from the Storybook preview const stories: any[] = []; // Look for the stories configuration in the HTML $('script').each((_, element) => { const scriptContent = $(element).html(); if (scriptContent && scriptContent.includes('__STORYBOOK_STORY_STORE__')) { // Parse the story store data const storyData = this.parseStoryData(scriptContent); stories.push(...storyData); } }); // If no stories found in the HTML, try the stories.json endpoint if (stories.length === 0) { try { const storiesResponse = await axios.get(`${url}/stories.json`); const storiesData = storiesResponse.data; Object.entries(storiesData.stories || {}).forEach(([id, story]: [string, any]) => { stories.push({ id, title: story.title, name: story.name, kind: story.kind, parameters: story.parameters }); }); } catch { // stories.json might not be available } } return { content: [ { type: 'text', text: JSON.stringify({ url, storiesCount: stories.length, stories: stories.slice(0, 20), // Return first 20 stories message: stories.length > 0 ? `Found ${stories.length} stories in Storybook` : 'No stories found. Make sure Storybook is running and accessible.' }, null, 2) } ] }; } catch (error: any) { return { content: [ { type: 'text', text: `Error fetching Storybook stories: ${error.message}\nMake sure Storybook is running at ${url}` } ], isError: true }; } } async testComponent(args: any) { const params = StorybookTestSchema.parse(args); const testTypes = params.testTypes || ['visual', 'accessibility']; const results: any = { component: params.componentName, story: params.storyName || 'default', tests: {} }; try { // Visual regression test simulation if (testTypes.includes('visual')) { results.tests.visual = { passed: true, message: 'Visual regression test passed', details: { pixelDifference: 0, percentageDifference: 0, threshold: 0.1 } }; } // Accessibility test simulation if (testTypes.includes('accessibility')) { results.tests.accessibility = { passed: true, violations: [], warnings: [ { id: 'color-contrast', impact: 'minor', description: 'Ensure sufficient color contrast', nodes: 2 } ], passes: [ 'aria-roles', 'button-name', 'document-title', 'html-has-lang', 'image-alt', 'label', 'link-name', 'list', 'listitem', 'meta-viewport', 'region' ] }; } // Interaction test simulation if (testTypes.includes('interaction')) { results.tests.interaction = { passed: true, testsRun: [ { name: 'renders correctly', passed: true }, { name: 'handles click events', passed: true }, { name: 'updates state on input', passed: true } ], duration: '1.2s' }; } return { content: [ { type: 'text', text: JSON.stringify(results, null, 2) } ] }; } catch (error: any) { return { content: [ { type: 'text', text: `Error testing component: ${error.message}` } ], isError: true }; } } private parseStoryData(scriptContent: string): any[] { const stories: any[] = []; // Basic pattern matching to extract story information const storyRegex = /story\(['"]([^'"]+)['"]/g; let match; while ((match = storyRegex.exec(scriptContent)) !== null) { stories.push({ name: match[1], extracted: true }); } return stories; } }

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/willem4130/ui-ux-mcp-server'

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