Skip to main content
Glama

carbon-mcp

Local MCP (Model Context Protocol) server for the Carbon Design System β€” Advanced MVP for internal demos and production use.

🚧 Status: Proposal Submitted to Carbon

This project is a proposal submitted to the Carbon Design System repository.

  • Issue: #20855

  • Status: Awaiting maintainer feedback

  • Proposed: Add to Carbon monorepo or create official carbon-design-system/carbon-mcp repository

The Carbon team is reviewing this proposal. Once feedback is received, the code will be adapted accordingly.


πŸš€ Quickstart

  1. Clone repo

    git clone https://github.com/SandeepBaskaran/carbon-mcp.git cd carbon-mcp
  2. Install dependencies

    npm install # or pnpm install
  3. Configure environment (optional)

    cp .env.example .env # Edit .env to add API keys if needed (FIGMA_TOKEN, GITHUB_TOKEN)
  4. Start the server

    npm run dev

    Server will start on http://localhost:4000

  5. Test it out

    # List available tools curl http://localhost:4000/tools # Generate a component (dry-run) curl -X POST http://localhost:4000/tool/generateComponent \ -H "Content-Type: application/json" \ -d '{"component_name": "PrimaryCard", "dry_run": true}'

πŸ› οΈ Tools (MVP)

Developer Tools

  • generateComponent β€” Generate Carbon React component + Storybook story + tests (dry-run default)

  • codemodReplace β€” Apply codemods to convert existing components to Carbon equivalents (dry-run default)

  • validateComponent β€” Validate component against Carbon patterns and accessibility guidelines

  • tokenConverter β€” Convert design tokens (JSON) to CSS variables, SCSS maps, and JS tokens

Documentation Tools

  • searchDocs β€” Search local Carbon docs index with semantic/keyword matching

Designer Tools

  • themePreview β€” Generate static HTML previews for Carbon theme variants (light/dark/custom)

  • figmaSync β€” Scaffold for Figma token sync (requires FIGMA_TOKEN in environment)

πŸ”’ Safety & Destructive Operations

All destructive changes (writing to disk, modifying files) require:

  • confirm_destructive: true

  • dry_run: false

Recommended workflow:

  1. Run with dry_run: true (default) to preview changes

  2. Review the output/patches

  3. Run again with dry_run: false and confirm_destructive: true to apply

Example: Generate Component (Safe Workflow)

# Step 1: Dry-run to preview curl -X POST http://localhost:4000/tool/generateComponent \ -H "Content-Type: application/json" \ -d '{ "component_name": "PrimaryCard", "dry_run": true, "explain": true }' # Step 2: Apply changes curl -X POST http://localhost:4000/tool/generateComponent \ -H "Content-Type: application/json" \ -d '{ "component_name": "PrimaryCard", "dry_run": false, "confirm_destructive": true }'

πŸ“š API Reference

Endpoints

Method

Endpoint

Description

GET

/health

Health check

GET

/tools

List all available tools

GET

/tool/:name/schema

Get schema for specific tool

POST

/tool/:name

Execute a tool

Tool Examples

1. Generate Component

POST /tool/generateComponent { "component_name": "PrimaryCard", "props": { "compact": "boolean", "icon": "string" }, "target_path": "src/components/PrimaryCard", "dry_run": true, "explain": true }

Response:

{ "files": [ { "path": "src/components/PrimaryCard/PrimaryCard.tsx", "content": "import React from 'react'..." } ], "changed_files": [], "dry_run": true, "logs": [...], "trace_id": "genc-1234567890", "explanation": "Generated Carbon React component..." }

2. Codemod Replace

POST /tool/codemodReplace { "codemod_name": "btn-old-to-carbon", "files_glob": "src/**/*.{tsx,jsx}", "dry_run": true }

Response:

{ "dry_run_result": "3 files would be modified", "patches": [ { "file": "src/pages/Home.tsx", "patch": "@@ -1,6 +1,6 @@..." } ], "changed_files": ["src/pages/Home.tsx"], "logs": [...], "trace_id": "codemod-1234567890" }

3. Search Docs

POST /tool/searchDocs { "query": "Carbon Button aria roles", "k": 5 }

Response:

{ "results": [ { "title": "Button β€” Carbon React", "path": "docs/components/button.md", "snippet": "The Button component supports kinds: primary, secondary...", "score": 0.98 } ], "logs": [...], "trace_id": "search-1234567890" }

4. Token Converter

POST /tool/tokenConverter { "input_path": "tokens/tokens.json", "outputs": ["css_vars", "scss_map", "js_tokens"], "output_dir": "tokens", "dry_run": true }

5. Validate Component

POST /tool/validateComponent { "file_path": "src/components/MyButton/MyButton.tsx", "rules": ["props", "accessibility", "tokens"] }

Response:

{ "valid": false, "errors": [], "warnings": [ { "type": "warning", "rule": "accessibility", "message": "Icon-only buttons should have aria-label" } ], "logs": [...], "trace_id": "validate-1234567890" }

6. Theme Preview

POST /tool/themePreview { "themes": ["white", "g10", "g90", "g100"], "output_path": "theme-previews", "dry_run": true }

πŸ”§ Development

Project Structure

carbon-mcp/ β”œβ”€β”€ src/ β”‚ β”œβ”€β”€ server/ β”‚ β”‚ β”œβ”€β”€ index.ts # Server bootstrap β”‚ β”‚ β”œβ”€β”€ toolRegistry.ts # Tool registration β”‚ β”‚ └── tools/ # Tool handlers β”‚ β”‚ β”œβ”€β”€ generateComponent.ts β”‚ β”‚ β”œβ”€β”€ codemodReplace.ts β”‚ β”‚ β”œβ”€β”€ searchDocs.ts β”‚ β”‚ β”œβ”€β”€ tokenConverter.ts β”‚ β”‚ β”œβ”€β”€ validateComponent.ts β”‚ β”‚ β”œβ”€β”€ themePreview.ts β”‚ β”‚ └── figmaSync.ts β”‚ β”œβ”€β”€ lib/ # Utilities β”‚ β”‚ β”œβ”€β”€ logger.ts β”‚ β”‚ β”œβ”€β”€ fileUtils.ts β”‚ β”‚ β”œβ”€β”€ templateUtils.ts β”‚ β”‚ β”œβ”€β”€ codemodUtils.ts β”‚ β”‚ β”œβ”€β”€ diffUtils.ts β”‚ β”‚ └── tokenUtils.ts β”‚ β”œβ”€β”€ schemas/ # JSON schemas β”‚ └── templates/ # Component templates β”œβ”€β”€ package.json β”œβ”€β”€ tsconfig.json └── README.md

Available Scripts

npm run dev # Start development server with hot reload npm run build # Build TypeScript to dist/ npm start # Run production server npm test # Run tests npm run lint # Lint code

Adding a New Tool

  1. Create handler in src/server/tools/myTool.ts

  2. Create schema in src/schemas/myTool.json

  3. Register in src/server/toolRegistry.ts

  4. Update this README

πŸ§ͺ Testing

npm test

Tests use Jest + ts-jest. Test files are located next to source files with .test.ts extension.

πŸ” Security & Privacy

  • No secrets in logs: The logger automatically redacts sensitive keys (tokens, passwords, API keys)

  • Telemetry opt-in: Set ANALYTICS_ENABLED=true in .env to enable (disabled by default)

  • File access: Tools only access files within the repo root

  • Audit trails: All operations are logged with trace IDs for auditing

🌐 Environment Variables

Variable

Required

Description

PORT

No

Server port (default: 4000)

FIGMA_TOKEN

No

Figma Personal Access Token for figmaSync

GITHUB_TOKEN

No

GitHub token for PR automation

ANALYTICS_ENABLED

No

Enable telemetry (default: false)

CARBON_VERSION

No

Carbon version to use (default: latest)

πŸ“– Common Codemods

btn-old-to-carbon

Replaces old <button className="btn-old"> with Carbon <Button kind="primary">

class-to-style

Refactors className styles that match Carbon tokens into token usage

replace-grid

Swaps custom grid with Carbon Grid

image-to-asset

Converts inline base64 images to static assets

🀝 Contributing

  1. Follow TypeScript best practices

  2. Add tests for new tools

  3. Update schemas and documentation

  4. Keep tools deterministic and idempotent

  5. Use dry-run by default for destructive operations

πŸ“ License

MIT

πŸ”— Resources


Made with ❀️ for the Carbon Design System community

-
security - not tested
A
license - permissive license
-
quality - not tested

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/SandeepBaskaran/carbon-mcp'

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