@freshworks/dew-mcp-server
v1.0.0
Published
Generic MCP server for component libraries - works with Dew, Custom UI library, or any component library
Readme
Dew MCP – Dew Design System Model-Context Server
A lightweight Model Context Protocol (MCP) server that exposes the Dew Design System documentation to AI agents (e.g. Cursor) over stdio. It provides a flexible framework that can be configured for different component libraries.
Documentation Site: https://dulcet-seahorse-c3901f.netlify.app/
🚀 Integrated MCP (Components + Figma + Playwright)
Enhanced MCP server that combines component library tools with Figma design integration and Playwright browser automation for comprehensive design-to-code workflows.
Why does this exist?
Instead of hard-coding design-system knowledge in every agent, we expose it via an MCP server. Any MCP-compatible client can connect to dew-mcp-server, ask for component information and (re-)use it while generating code, explaining APIs, etc.
Features
- 📚 Component Docs Tool – fetch Markdown documentation (props, examples, dos & don'ts) for components
- 📋 Component List Tool – discover available component doc stems for effective reuse decisions
- 📘 General Docs + List – installation, CSS/theming, MCP usage, and synonym → documentation topic tables in
knowledgebase/general/general.md - ⚙️ Cursor Rules Generation – automatically configure cursor rules for enhanced AI assistance
- 🔌 Stdio Transport – communicates via stdin/stdout; no HTTP server to maintain
- 🏷 Type-safe Schemas – arguments are validated with zod before tool execution
- 🚀 Smart Defaults – creates intelligent tool configurations based on package name
- 🔄 Smart Merge – user overrides merge with defaults, never replace them entirely
- 🦾 Ready for Cursor / MCP Inspector – works seamlessly with popular MCP clients
- 🎨 Figma Integration – connect design files to component implementation (optional)
- 🌐 Playwright Support – browser automation for testing and validation (optional)
- 📊 Analytics Tracking – optional Haystack usage analytics (
/freshreports/analytics)
🎯 Primary Use Cases
1. DEW Components Users (Zero Setup Required) ✨
If you're using @freshworks/dew-components, you're ready to go! The package includes a pre-configured MCP server.
2. Other Component Libraries (Generic Setup) 🔧
Configure the MCP server for any component library with smart defaults and flexible configuration.
📦 Installation
pnpm add @freshworks/dew-mcp-server🚀 Quick Start
Minimal Configuration (Smart Defaults)
#!/usr/bin/env node
import { createMCPServer } from '@freshworks/dew-mcp-server';
const config = {
name: 'My Component Library MCP',
version: '1.0.0',
packageName: '@myorg/ui-components', // Required for default tools
analytics: {
enabled: false, // Optional: enable usage analytics
},
};
await createMCPServer(config); // by default tool get_component_docs points to DEW's knowledge base, you can override knowledge base using below configOverriding default tools and Custom Tools Configuration
import { createMCPServer } from '@freshworks/dew-mcp-server';
import { z } from 'zod';
const config = {
name: 'Advanced UI Library MCP',
version: '1.0.0',
projectRoot: process.cwd(),
packageName: '@myorg/custom-ui',
figmaApiKey: 'your-figma-api-key', // Optional: for External Figma integration
enableFigma: true, // Optional: enable Figma integration (default: true)
enablePlaywright: true, // Optional: enable Playwright integration (default: true)
analytics: {
enabled: true,
authToken: 'your-haystack-x-auth-token',
baseUrl: 'https://rum.haystack.es/freshreports/analytics',
},
tools: [
{
id: 'get_component_docs',
name: 'get_custom_ui_docs',
description: 'Get Custom UI component documentation',
options: {
knowledgebasePath: '/path/to/custom-docs',
},
},
{
id: 'create_cursor_rule_doc_gen',
name: 'setup_custom_cursor_rules',
options: {
cssPath: '@myorg/styles/main.css',
},
},
{
id: 'search_components',
name: 'search_components',
description: 'Search component library with advanced options',
schema: {
query: z.string().describe('Search query'),
category: z.enum(['basic', 'advanced']).optional().describe('Component category'),
},
callback: async ({ query, category }) => {
const options = arguments[1];
const maxResults = options.maxResults || 5;
const searchIndex = options.searchIndex;
return {
content: [
{
type: 'text',
text: `Found ${maxResults} results for "${query}" in ${
category || 'all'
} categories using index: ${searchIndex}`,
},
],
};
},
options: {
searchIndex: '/path/to/search/index',
maxResults: 20,
enableCache: true,
},
},
],
};
await createMCPServer(config);What you get automatically:
- ✅ Component list tool
- ✅ Component documentation tool (inferred from package name)
- ✅ Cursor rules setup tool
- ✅ Smart library name inference (e.g., "@myorg/ui-components" → "UI")
- ✅ Default knowledgebase path (uses DEW's built-in knowledgebase)
- ✅ Figma integration (optional)
- ✅ Playwright browser automation (optional)
📋 API Reference
createMCPServer (config: IMcpServerConfig)
| Parameter | Type | Required | Description |
| -------------------- | -------------------------- | -------- | ---------------------------------------------------------------------- |
| name | string | ✅ | Server name displayed in MCP client |
| version | string | ✅ | Server version |
| packageName | string | ✅ | NPM package name (required for smart defaults) |
| libraryDisplayName | string | ❌ | Display name for library (inferred from packageName if not provided) |
| tools | IToolConfig[] | ❌ | Array of tools (creates defaults based on packageName if not provided) |
| figmaApiKey | string | ❌ | Figma API key for accessing Figma files (required for external server) |
| enableFigma | boolean | ❌ | Whether to enable Figma integration (default: true) |
| enablePlaywright | boolean | ❌ | Whether to enable Playwright integration (default: true) |
| figmaServerType | 'external' \| 'in-house' | ❌ | Type of Figma MCP server to use (default: 'external') |
| figmaCommand | string | ❌ | Custom Figma MCP server command (optional, only for external server) |
| playwrightCommand | string | ❌ | Custom Playwright MCP server command (optional) |
| figmaPort | number | ❌ | Figma server port (default: 3334, only for external server) |
| playwrightPort | number | ❌ | Playwright server port (default: 3335) |
| maxWaitTime | number | ❌ | Maximum time to wait for external servers (default: 30000ms) |
| pollInterval | number | ❌ | Polling interval for health checks (default: 1000ms) |
| analytics | IAnalyticsConfig | ❌ | Analytics configuration for usage tracking (optional) |
Tool Configuration
{
id: string, // Tool identifier
name?: string, // Tool name (defaults to id)
description?: string, // Tool description (auto-generated for built-ins)
schema?: z.ZodRawShape, // Tool schema (auto-generated for built-ins)
callback?: ToolCallback, // Tool callback (auto-generated for built-ins)
options?: Record<string, unknown>, // Tool-specific options
disabled?: boolean // Whether to disable this tool
}Built-in Tool IDs:
get_component_docs- Component documentation tool (knowledgebase/components/)get_component_list- Lists markdown stems inknowledgebase/components/get_general_docs- General documentation tool (knowledgebase/general/)get_general_list- Lists markdown stems inknowledgebase/general/create_cursor_rule_doc_gen- Cursor rules setup tool
The published Dew CLI (packages/dew-mcp/index.ts) registers friendly MCP names: get_dew_component_docs, get_dew_component_list, get_dew_general_docs, get_dew_general_list, plus the cursor-rules tool.
🛠️ Available Tools
Component Documentation Tool
ID: get_component_docs
Fetches component documentation from your knowledgebase (If knowledgebasePath is not provided, defaults to DEW's knowledgebase).
| Argument | Type | Required | Description |
| ---------------- | -------- | -------- | --------------------------------------- |
| componentsList | string | ✅ | Comma-separated list of component names |
Options:
knowledgebasePath(string, required): Path to the knowledgebase root (parent ofcomponents/,general/, etc.)documentationType(string, optional): Subfolder underknowledgebasePath(default:components). Usegeneralfor the general docs tool.
Component List Tool
ID: get_component_list
Discovers available components in the library to help LLMs make informed decisions about component reuse.
Returns: List of all available markdown stems in the configured documentationType folder.
General Documentation Tool
ID: get_general_docs
Same argument shape as component docs (componentsList: comma-separated topic stems), but reads from knowledgebase/general/. Use for install/CSS/theming and MCP usage overview.
General List Tool
ID: get_general_list
Lists available .md stems under knowledgebase/general/ (excluding index.md and README.md).
Cursor Rules Setup Tool
ID: create_cursor_rule_doc_gen
Creates .cursor/rules/component-documentation.mdc in your project for enhanced AI assistance.
| Argument | Type | Required | Description |
| ------------- | -------- | -------- | ------------------------------------------- |
| projectRoot | string | ✅ | Absolute path to the project root directory |
Options:
cssPath(string, optional): Full CSS import pathdocsOutputPath(string, optional): Documentation output path (defaults to "knowledgebase/components")
📊 Analytics Configuration
The MCP server supports optional Haystack telemetry. Paths are shared across stdio and streamable HTTP (wrapCallbackWithAnalytics, createMCPServer); attachment differs stdio vs HTTP only.
The dew-mcp binary resolves config with resolveAnalyticsConfigFromEnv: deployment process.env overrides a CI-generated builtin ingest token (DEW_MCP_ANALYTICS_AUTH_TOKEN, inject before tsc). Programmatic createMCPServer callers pass analytics on IMcpServerConfig.
Haystack ingest
Send events to /freshreports/analytics. e_rn is always dew_mcp; internal events use prefix dew_mcp (Haystack e_an is uppercase: DEW_MCP_TOOL_CALLED, …).
IAnalyticsConfig (TypeScript)
interface IAnalyticsConfig {
enabled: boolean;
/** Full POST URL …/freshreports/analytics */
baseUrl?: string;
/** x-auth-token header */
authToken?: string;
/** Sent as Haystack field mcp_version (CLI defaults to npm package version) */
mcpVersion?: string;
}Tracked events (existing behavior)
| Internal event | Haystack e_an (prefix dew_mcp) | Properties (all coerced to strings for Haystack except d, t) |
| ------------------------------ | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| tool_called | DEW_MCP_TOOL_CALLED | tool_name, success, optional components (doc tools), error_message |
| server_startup | DEW_MCP_SERVER_STARTUP | total_duration_ms, phase timings, figma_enabled, playwright_enabled, tools_count, inbound_transport (stdio | streamable-http) |
| external_server_connection | DEW_MCP_EXTERNAL_SERVER_CONNECTION | server_name, success, duration_ms |
| component_docs_not_available | DEW_MCP_COMPONENT_DOCS_NOT_AVAILABLE | invalid_components, requested_components |
Every hit also includes:
requested_by— from OS username (deriveUserId()), viarequestedBy→ Haystackrequested_bytimestamp— ISO stringmcp_version— when set in config (CLI sets package version automatically)
Haystack payloads use t (ms) and d (duration_ms when present on the payload, otherwise 0) to mirror browser RUM.
CLI / binary environment variables (DEW_MCP_ANALYTICS_*)
DEW_MCP_ANALYTICS_AUTH_TOKEN is used in two ways:
Release / GitHub Package (stdio) — Set in CI as a secret-backed environment variable before
pnpm run build. Thebuildscript runsscripts/inject-built-analytics.mjs, which writessrc/utils/analytics/builtAnalyticsSecrets.generated.tswith a string literal;tscthen compiles it intodist/. Published packages can ship telemetry without MCP client configuration beyondcommandandargs(the token is not set in MCP client JSON).Hosted MCP server — Set on the deployment host at process start; this value overrides any token baked into the artifact.
src/utils/analytics/builtAnalyticsSecrets.generated.ts is gitignored under packages/dew-mcp. pnpm run build invokes inject-built-analytics.mjs, then tsc. Run pnpm run build before ESLint, tsc -w, or test when this file is absent. Published installs carry literals only inside dist/.
A baked ingest token is included in every packaged install. Restrict distribution (e.g. private registry), treat it as an organization-scoped credential, and rotate after exposure.
Telemetry is disabled when DEW_MCP_ANALYTICS_DISABLED=true, or when no token comes from the builtin literal or host process.env.
# Optional: disable telemetry
# DEW_MCP_ANALYTICS_DISABLED=true
# Hosted deployment: overrides baked token (Beanstalk, container, process manager)
DEW_MCP_ANALYTICS_AUTH_TOKEN=your-token
# CI publish: same variable; inject runs before tsc
#
# Ingest URL (default: staging rum.stage.haystack.es)
DEW_MCP_ANALYTICS_URL=https://rum.haystack.es/freshreports/analytics📁 Knowledgebase Structure
knowledgebase/
├── general/
│ └── general.md # MCP topic **general**: setup, CSS, theming, synonyms → doc name (consumer / LLM)
├── components/
│ ├── Button.md
│ ├── Modal.md
│ └── ...
├── patterns/ # Optional — wire tools with documentationType: 'patterns'
│ └── ...
└── tokens/ # Optional
└── ...Files named index.md or README.md in these folders are ignored by the list/docs tools.
🔧 MCP Client Configuration
Cursor IDE Setup
Go to Cursor Settings → Features → Model Context Protocol:
MCP Configuration (External Figma Server)
{
"mcpServers": {
"dew-mcp-server": {
"command": "npx",
"args": ["-y", "@freshworks/dew-mcp-server", "--figma-api-key=<figma-api-key>"]
}
}
}MCP Configuration (In-House Figma Server)
{
"mcpServers": {
"dew-mcp-server": {
"command": "npx",
"args": ["-y", "@freshworks/dew-mcp-server", "--figma-server-type=in-house"]
}
}
}MCP Configuration (Figma and playwright Disabled)
{
"mcpServers": {
"dew-mcp-server": {
"command": "npx",
"args": ["-y", "@freshworks/dew-mcp-server", "--disable-figma", "--disable-playwright"]
}
}
}Claude Desktop Setup
Add to your claude_desktop_config.json:
MCP Configuration (External Figma Server)
{
"mcpServers": {
"dew-mcp-server": {
"command": "npx",
"args": ["-y", "@freshworks/dew-mcp-server", "--figma-api-key=<figma-api-key>"]
}
}
}MCP Configuration (In-House Figma Server)
{
"mcpServers": {
"dew-mcp-server": {
"command": "npx",
"args": ["-y", "@freshworks/dew-mcp-server", "--figma-server-type=in-house"]
}
}
}Configuration file locations:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
🧪 Development
Getting Started
Install dependencies
pnpm installDevelopment run
pnpm dev # MCP developmentBuild & run
pnpm build # transpiles to ./dist pnpm start # executes node dist/index.jsInspect traffic
pnpm inspect # MCP inspector
Scripts
dev–tsx index.ts(MCP development)build– TypeScript compile todist/start–node dist/index.js(MCP)inspect– Launches MCP Inspector
Repository Layout
packages/dew-mcp-server/
├─ index.ts # MCP entry-point
├─ src/
│ ├─ createMCPServer.ts # Integrated MCP server factory
│ ├─ tools/ # Tool implementations
│ ├─ types/ # TypeScript definitions
│ └─ utils/ # Utility functions
├─ knowledgebase/ # Component documentation
└─ cursorrules/ # Cursor rules templatesKey Benefits
- 🎯 Required Config: Explicit configuration for consistency
- 🚀 Smart Defaults: Intelligent tool creation based on package name
- 🔄 Smart Merge: Overrides merge with defaults, never replace
- 🔧 Selective Override: Change only what you need
- 📈 Type Safe: Full TypeScript support
- 🔗 Clear Feedback: Logs tool creation and warns about configuration issues
- 🎨 Design Integration: Seamless Figma and Playwright integration for comprehensive workflows
- ⚙️ Flexible Configuration: Command-line arguments for easy customization
🤝 Contributing
- Add new tool IDs in built-in tool detection logic
- Implement tool handlers in the
registerToolfunction - Add new option interfaces for type safety
- Test with different component libraries
- Submit a pull request
License
ISC
