Skip to main content
Glama

UI/UX MCP Server

by willem4130
index.tsโ€ข11.5 kB
import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { CallToolRequestSchema, ListToolsRequestSchema, ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js'; import dotenv from 'dotenv'; // Import tool handlers import { StorybookTools } from './tools/storybook.js'; import { TailwindTools } from './tools/tailwind.js'; import { AnimationTools } from './tools/animation.js'; import { PlaywrightTools } from './tools/playwright.js'; import { ComponentTools } from './tools/components.js'; import { WorkflowTools } from './tools/workflows.js'; // Load environment variables dotenv.config(); // Server metadata const SERVER_NAME = 'ui-ux-mcp-server'; const SERVER_VERSION = '1.0.0'; class UIUXMCPServer { private server: Server; private storybookTools: StorybookTools; private tailwindTools: TailwindTools; private animationTools: AnimationTools; private playwrightTools: PlaywrightTools; private componentTools: ComponentTools; private workflowTools: WorkflowTools; constructor() { this.server = new Server( { name: SERVER_NAME, version: SERVER_VERSION, }, { capabilities: { tools: {}, }, } ); // Initialize tool handlers this.storybookTools = new StorybookTools(); this.tailwindTools = new TailwindTools(); this.animationTools = new AnimationTools(); this.playwrightTools = new PlaywrightTools(); this.componentTools = new ComponentTools(); this.workflowTools = new WorkflowTools(); this.setupHandlers(); } private setupHandlers(): void { // Handle tool listing this.server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [ // Storybook Tools { name: 'storybook_get_stories', description: 'Get list of all Storybook stories', inputSchema: { type: 'object', properties: { url: { type: 'string', description: 'Storybook URL' } } } }, { name: 'storybook_test_component', description: 'Run visual and accessibility tests on a component', inputSchema: { type: 'object', properties: { componentName: { type: 'string' }, storyName: { type: 'string' }, testTypes: { type: 'array', items: { type: 'string', enum: ['visual', 'accessibility', 'interaction'] } } }, required: ['componentName'] } }, // Tailwind Tools { name: 'tailwind_generate_config', description: 'Generate Tailwind configuration from design tokens', inputSchema: { type: 'object', properties: { colors: { type: 'object' }, spacing: { type: 'object' }, typography: { type: 'object' }, breakpoints: { type: 'object' } } } }, { name: 'tailwind_optimize_classes', description: 'Optimize and deduplicate Tailwind classes', inputSchema: { type: 'object', properties: { html: { type: 'string' }, purge: { type: 'boolean', default: false } }, required: ['html'] } }, // Animation Tools { name: 'animation_create_timeline', description: 'Create animation timeline with Framer Motion or GSAP', inputSchema: { type: 'object', properties: { library: { type: 'string', enum: ['framer-motion', 'gsap'], default: 'framer-motion' }, animations: { type: 'array', items: { type: 'object', properties: { target: { type: 'string' }, properties: { type: 'object' }, duration: { type: 'number' }, delay: { type: 'number' }, easing: { type: 'string' } } } } }, required: ['animations'] } }, { name: 'animation_preview', description: 'Generate preview of animation sequence', inputSchema: { type: 'object', properties: { timeline: { type: 'object' }, format: { type: 'string', enum: ['gif', 'mp4', 'webm'], default: 'gif' } }, required: ['timeline'] } }, // Playwright Tools { name: 'playwright_test_ui', description: 'Run UI tests with Playwright', inputSchema: { type: 'object', properties: { url: { type: 'string' }, tests: { type: 'array', items: { type: 'object', properties: { name: { type: 'string' }, actions: { type: 'array' }, assertions: { type: 'array' } } } }, browsers: { type: 'array', items: { type: 'string', enum: ['chromium', 'firefox', 'webkit'] }, default: ['chromium'] } }, required: ['url', 'tests'] } }, { name: 'playwright_capture_screenshots', description: 'Capture screenshots across browsers and viewports', inputSchema: { type: 'object', properties: { url: { type: 'string' }, viewports: { type: 'array', items: { type: 'object', properties: { width: { type: 'number' }, height: { type: 'number' }, deviceScaleFactor: { type: 'number' } } } }, fullPage: { type: 'boolean', default: false } }, required: ['url'] } }, // Component Tools { name: 'component_create', description: 'Create a new UI component with best practices', inputSchema: { type: 'object', properties: { name: { type: 'string' }, type: { type: 'string', enum: ['react', 'vue', 'svelte', 'web-component'] }, props: { type: 'array', items: { type: 'object' } }, styles: { type: 'object' }, accessibility: { type: 'object' } }, required: ['name', 'type'] } }, { name: 'component_analyze', description: 'Analyze component for performance and accessibility', inputSchema: { type: 'object', properties: { code: { type: 'string' }, checks: { type: 'array', items: { type: 'string', enum: ['performance', 'accessibility', 'best-practices', 'seo'] } } }, required: ['code'] } }, // Workflow Tools { name: 'workflow_optimize_ux', description: 'Run comprehensive UX optimization analysis', inputSchema: { type: 'object', properties: { url: { type: 'string' }, analyses: { type: 'array', items: { type: 'string', enum: ['performance', 'accessibility', 'usability', 'mobile', 'seo'] } } }, required: ['url'] } }, { name: 'workflow_build_design_system', description: 'Generate complete design system from components', inputSchema: { type: 'object', properties: { source: { type: 'string', enum: ['storybook', 'code'] }, sourceId: { type: 'string' }, includeTokens: { type: 'boolean', default: true }, includeComponents: { type: 'boolean', default: true }, includeDocumentation: { type: 'boolean', default: true } }, required: ['source', 'sourceId'] } } ] })); // Handle tool execution this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; try { switch (name) { // Storybook tools case 'storybook_get_stories': return await this.storybookTools.getStories(args); case 'storybook_test_component': return await this.storybookTools.testComponent(args); // Tailwind tools case 'tailwind_generate_config': return await this.tailwindTools.generateConfig(args); case 'tailwind_optimize_classes': return await this.tailwindTools.optimizeClasses(args); // Animation tools case 'animation_create_timeline': return await this.animationTools.createTimeline(args); case 'animation_preview': return await this.animationTools.preview(args); // Playwright tools case 'playwright_test_ui': return await this.playwrightTools.testUI(args); case 'playwright_capture_screenshots': return await this.playwrightTools.captureScreenshots(args); // Component tools case 'component_create': return await this.componentTools.create(args); case 'component_analyze': return await this.componentTools.analyze(args); // Workflow tools case 'workflow_optimize_ux': return await this.workflowTools.optimizeUX(args); case 'workflow_build_design_system': return await this.workflowTools.buildDesignSystem(args); default: throw new McpError( ErrorCode.MethodNotFound, `Tool ${name} not found` ); } } catch (error) { if (error instanceof McpError) { throw error; } throw new McpError( ErrorCode.InternalError, `Error executing tool ${name}: ${error}` ); } }); } async start(): Promise<void> { const transport = new StdioServerTransport(); await this.server.connect(transport); console.error(`${SERVER_NAME} v${SERVER_VERSION} started successfully`); } } // Start the server const server = new UIUXMCPServer(); server.start().catch((error) => { console.error('Failed to start server:', error); process.exit(1); });

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