@maltjoy/mcp-server
v0.4.0
Published
MCP server for Joy Design System - exposes Vue3 components information
Readme
@maltjoy/mcp-server
MCP (Model Context Protocol) server for the Joy Design System. This server exposes information about Vue3 components from the @maltjoy/core-vue library, making it easy to discover and use components through AI assistants.
Features
- 🔍 List all available Joy Vue3 components with descriptions
- 📚 Access component documentation (props, events, slots, exposed members)
- 🏷️ Retrieve TypeScript types definitions for component props (variants, sizes, etc.)
- 🎨 List 132 design tokens (colors, spacing, typography, etc.)
- 💅 List 272 CSS utility classes
- 🤖 AI-friendly interface through MCP protocol
- ✅ Automatic documentation generation on build
Installation
cd packages/joy-mcp-server
pnpm install
pnpm build # This also generates component documentation JSON filesNote: The build process automatically generates JSON documentation for all components. This is required for the server to work.
Usage
Running the Server
pnpm startThe server runs on stdio and is ready to receive MCP protocol messages.
Development
# Watch mode for development
pnpm devAvailable Tools
1. joy_list_components
Lists all available Joy Vue3 components from the @maltjoy/core-vue library, with descriptions extracted from Storybook stories.
Parameters: None
Returns:
{
"components": [
{
"name": "VJoyButton",
"description": "A versatile button component supporting multiple variants, sizes, and states."
},
"..."
],
"count": 74
}2. joy_get_component_info
Retrieves detailed information about a specific Joy Vue3 component including props, events, slots, and exposed members.
Parameters:
componentName(string, required): The exact name of the component (e.g., "VJoyButton", "VJoyAvatar")
Returns:
{
"name": "VJoyButton",
"props": [
{
"name": "size",
"type": "TJoyButtonSizes | undefined",
"required": false,
"default": "\"medium\"",
"description": "Button or Link size",
"possibleValues": "medium, large, small, xsmall, xxsmall"
}
],
"events": [
{
"name": "click",
"description": "Emitted when the button is clicked"
}
],
"slots": [
{
"name": "default",
"description": "Default slot for button text"
}
],
"exposedMembers": [
{
"name": "size",
"type": "TJoyButtonSizes",
"kind": "Property"
}
]
}Error Response:
{
"error": "Component \"VJoyNonExistent\" not found. Use joy_list_components to get a list of available components."
}3. joy_get_component_types
Retrieves the TypeScript types definition files associated with a specific Joy Vue3 component. These types define the allowed values for props (variants, sizes, etc.).
Parameters:
componentName(string, required): The exact name of the component (e.g., "VJoyButton", "VJoyMenu")
Returns:
{
"componentName": "VJoyButton",
"files": [
{
"filename": "JoyButton.types.ts",
"content": "import {TGenericVariants, TPositions, TSizes} from '../../types';\n\nexport type TJoyDefaultButtonVariants = TGenericVariants | 'main' | 'admin' | 'ghost';\nexport type TJoyButtonVariants = TJoyDefaultButtonVariants | ...;\nexport type TJoyButtonSizes = Exclude<TSizes, 'xlarge'>;\nexport type TJoyButtonIconPositions = TPositions;\n"
}
]
}Error Response:
{
"error": "No types file found for component \"VJoyNonExistent\". Use joy_list_components to get a list of available components."
}4. joy_list_design_tokens
Lists all available Joy design tokens (CSS custom properties) organized by domain.
Parameters: None
Returns:
{
"colors": ["--joy-color-primary-100", "..."],
"spacing": ["--joy-core-spacing-1", "..."],
"typography": ["--joy-font-size-primary-1", "..."],
"radius": ["--joy-core-radius-1", "..."],
"elevation": ["--joy-core-elevation-1", "..."],
"zIndex": ["--joy-core-z-index-modal", "..."],
"transitions": ["--joy-transition-fast", "..."],
"forms": ["--joy-form-height-medium", "..."]
}5. joy_list_css_classes
Lists all available Joy CSS utility classes organized by domain.
Parameters: None
Returns:
{
"colors": [".joy-color-primary-100", ".joy-bgcolor-primary-100", "..."],
"spacing": [".joy-m-1", ".joy-p-2", "..."],
"typography": [".joy-font-primary-1", "..."],
"elevation": [".joy-core-elevation-1", "..."],
"radius": [".joy-core-radius-1", "..."],
"misc": [".joy-link", ".joy-link_white"]
}Configuration for Claude Desktop
Add this to your Claude Desktop config (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
{
"mcpServers": {
"joy-design-system": {
"command": "node",
"args": [
"/absolute/path/to/design-system/packages/joy-mcp-server/dist/index.js"
]
}
}
}Configuration for Cursor
Add this to your Cursor MCP settings:
{
"mcpServers": {
"joy-design-system": {
"command": "node",
"args": [
"/absolute/path/to/design-system/packages/joy-mcp-server/dist/index.js"
]
}
}
}Architecture
joy-mcp-server/
├── src/
│ ├── index.ts # Main server entry point
│ ├── parser.ts # JSON documentation parser
│ ├── json-metadata-generator.mjs # Generates MCP metadata from component markdown
│ └── tools/
│ ├── list-components.ts # Component listing tool
│ ├── get-component-info.ts # Component info retrieval tool
│ ├── get-component-types.ts # Component types retrieval tool
│ ├── list-design-tokens.ts # Design tokens tool
│ └── list-css-classes.ts # CSS classes tool
├── dist/
│ └── doc/
│ ├── index.json # Index of all components
│ ├── design-tokens.json # All design tokens
│ ├── css-classes.json # All CSS classes
│ └── VJoy*/ # Component directories
│ ├── metadata.json # Component metadata
│ └── *.types.ts # Component TypeScript types
├── package.json
├── tsconfig.json
└── README.mdThe server reads the generated JSON documentation from dist/doc/ which is automatically created during the build process by extracting metadata from Vue component files in @maltjoy/core-vue.
Component metadata is authored in packages/core-vue/src/components/**/JoyComponentName.metadata.md using Markdown with YAML frontmatter. This keeps a short structured summary in frontmatter while allowing richer Markdown content in the body for multiline descriptions and future code examples. Storybook and the MCP generator both consume the same Markdown source. Storybook JSDoc comments remain a fallback when a component metadata file does not provide a description yet.
Example:
---
category: Buttons
description: >
Short summary used in list views and quick MCP responses.
ignoreMcpDocumentation: false
---
Longer Markdown documentation rendered in Storybook and exposed by the MCP.
```vue
<VJoyButton variant="primary">Save</VJoyButton>
## Development
To add new tools:
1. Create a new file in `src/tools/`
2. Define the tool schema and handler
3. Register the tool in `src/index.ts`
### Available Scripts
```bash
# Build and generate documentation
pnpm run build
# Watch mode for development
pnpm run dev
# Generate only documentation (no compilation)
pnpm run generate:components-docs:json
# Start the server
pnpm start
# Run with MCP inspector for debugging
pnpm run inspectorTroubleshooting
Common Issues
- Documentation not generated: Run
pnpm run buildto compile and generate docs - Changes not taking effect: Reload your editor window to restart the MCP server
- Server fails to start: Check that
dist/doc/index.jsonexists - 0 components returned: Reload your editor window (
Developer: Reload Windowin Cursor/VS Code)
License
MIT
