@maltjoy/mcp-server

MCP server for Joy Design System - exposes Vue3 components information
2,788
Install
npm install @maltjoy/mcp-server
Latest Version:0.5.0
License:MIT
Last Updated:Sep 2, 2026
Links: npm
Maintainer: kevin_carnaille

@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.)
  • 🎨 Search design tokens by intent (joy_search_tokens) with usage docs from $extensions.com.maltjoy.docs
  • 🧭 Token groups and usage rules (joy_get_token_group, joy_get_token_usage)
  • 💅 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 files

Note: The build process automatically generates JSON documentation for all components. This is required for the server to work.

Usage

Running the Server

pnpm start

The server runs on stdio and is ready to receive MCP protocol messages.

Development

# Watch mode for development
pnpm dev

Available 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_search_tokens

Find design tokens by intent or name. Prefer this over listing the full catalog.

Parameters:

  • query (string, required): intent (page title), path (color.text.heading), or CSS name
  • layer (string, optional): semantic (default), primitive, or all
  • domain (string, optional): color, spacing, radius, elevation, zIndex, typography, motion, forms, links
  • includeDeprecated (boolean, optional)
  • limit (number, optional): default 8, max 25

Returns: compact hits (name, css, layer, description, useFor, score).

5. joy_get_token

Full record for one token, including com.maltjoy.docs (useFor, doNotUseFor, pairWith, replaces).

Parameters:

  • name (string, required): color.text.heading or --joy-color-text-heading

6. joy_get_token_group

All tokens in a group. Aliases: text, background, border, spacing, color, forms, typography.

Semantic groups are returned first so sibling roles can be compared.

7. joy_get_token_usage

Decision tree plus the relevant semantic tokens.

Parameters:

  • topic (string, required): text | background | border | color | spacing

8. joy_list_design_tokens

Compact list. Defaults to the semantic layer only. Prefer joy_search_tokens when you know the intent.

Parameters:

  • layer (optional): semantic (default), primitive, all
  • domain (optional)
  • includeDeprecated (optional)

9. 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   # Compact token listing (semantic by default)
│       ├── search-tokens.ts        # Token search by intent
│       ├── get-token.ts            # Single token + docs
│       ├── get-token-group.ts      # Token group bundle
│       ├── get-token-usage.ts      # Usage rules / decision tree
│       └── list-css-classes.ts     # CSS classes tool
│   └── tokens/
│       ├── build-catalog.ts        # Flatten DTCG JSON into design-tokens.json
│       └── query.ts                # Search / get / group / usage
├── 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.md

The 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 inspector

Troubleshooting

Common Issues

  • Documentation not generated: Run pnpm run build to 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.json exists
  • 0 components returned: Reload your editor window (Developer: Reload Window in Cursor/VS Code)

License

MIT

Related Packages

vue-harvest-mcp

MCP server for AI-assisted Vue component extraction and design system analysis

1,114 0
@vizejs/musea-mcp-server

MCP server for building Vue.js design systems - component analysis, documentatio...

78,243 908
semi-design-vue3

Semi Design Vue 3 adapter (Foundation 2.103.0) with MCP server for AI tools

166 0
@vue/theme

The VitePress theme for vuejs.org.

78,682 278
vitepress-carbon

Theme for VitePress documentation.

50,939 115

Version History

Version Released License
0.5.0 MIT
0.4.0 MIT
0.3.2 MIT
0.3.1 MIT
0.3.0 MIT
Pre-releases (2)
Version Released License
0.6.0-beta.0 MIT
0.5.0-beta.0 MIT