Teaching AI to Speak
Web Components
CEM CLI & the Model Context Protocol
← → or h j k l
The AI Promise
AI assistants that understand your design system

- Compose complex layouts correctly
- Use the right attributes and slots
- Follow accessibility patterns
- Maintain design consistency
"Build me a three-card hero section"
The Reality
AI hallucinates component APIs
- Invents non-existent attributes
- Uses wrong slot names
- Misses required properties
- Creates invalid HTML
Manual corrections for every generation

What If AI Actually Knew?
What if we could give AI the actual component documentation, in an AI-native way?
Quick Context: Web Components
- Custom elements: Define your own HTML tags
- Shadow DOM: Encapsulated styling and markup
- Framework-agnostic: Works everywhere
Used by major design systems:
Browser-native, long-term stable
Custom Elements Manifest
JSON schema describing components in detail
W3C community group recommendation
{
"schemaVersion": "2.1.0",
"modules": [{
"kind": "javascript-module",
"path": "elements/rh-button/rh-button.js",
"declarations": [{
"kind": "class",
"name": "RhButton",
"tagName": "rh-button",
"customElement": true,
"attributes": [{
"name": "variant",
"type": { "text": "primary | secondary | tertiary" },
"description": "Button style variant"
}],
"slots": [{
"name": "icon",
"description": "Optional icon before text"
}]
}],
"exports": [{
"kind": "custom-element-definition",
"name": "rh-button",
"declaration": { "name": "RhButton" }
}]
}]
}
Everything an AI (or IDE) needs to know
CEM CLI: The Toolkit
Open source tool for working with Custom Elements Manifests
Three main capabilities:
- Generate - Create manifests from code
- LSP - IDE integration
- MCP - AI integration
1. Generate
Create manifests automatically from your codebase
$ npm install --save-dev @pwrs/cem
$ npx cem generate elements/**/*.ts
Outputs custom-elements.json with complete metadata
2. LSP: IDE Superpowers
Language Server Protocol brings component knowledge to your editor
- Autocomplete for custom elements and attributes
- Hover documentation inline
- Validation with autofixes
- Go-to-definition for components
- Slot validation for proper composition
LSP Filetypes
- HTML files
- TypeScript template literals
- JSX/TSX (with proper setup)
VS Code extension available
MCP
Model Context Protocol connects structured data to AI systems
Developed by Anthropic for Claude (but open to all)
Two key concepts:
- Resources: Static data AI can read
- Tools: Actions AI can perform
CEM CLI provides both for web components
MCP Resources
cem://packages- Workspace package discoverycem://elements- All available elementscem://element/{tagName}- Component detailscem://element/{tagName}/attributes- Attribute docscem://element/{tagName}/slots- Slot guidelinescem://element/{tagName}/css/*- Styling APIscem://accessibility- A11y patternscem://guidelines- Design system rules
MCP Tools
What the AI can do:
- Validate HTML: Check generated markup against schemas
- Suggest attributes: Recommend correct properties
- Generate HTML: Create valid component markup
- CSS integration: Understand design tokens and styling
All powered by the manifest
How It Works
🏦 Custom Elements Manifest
↓
🖥️ MCP Server
↓
🧠 AI Assistant
↓
⌨️ LSP Editor Support
↓
🧑🍳 Awesome HTML ✓
Standards-based metadata enables AI that works for you
Standards Enable Ecosystems
Structured metadata from Custom Elements Manifest powers:
- ✓ IDE tooling (LSP autocomplete, validation)
- ✓ Documentation generators (Storybook, SSGs)
- ✓ AI assistants (MCP, code generation)
Better standards → Better tooling → Better developer experience
Community-Driven
Custom Elements Manifest:
- W3C Web Components Community Group
- Open specification
- Growing adoption across frameworks and tools
Community-Driven
CEM CLI:
- Free and open source (GPL v3)
- Written in Go
- Community contributions welcome
Let's Try It!
Clone the Scaffolding, Install deps, Start the Server.
$ gh clone bennypowers/cem-mcp-codelab-starter
$ npm ci
$ npm start
In a new shell, add to your Claude Code config, and start Claude
$ claude mcp add --transport stdio cem cem mcp
$ claude
Verify that mcp is loaded with /mcp
Fetches `@rhds/elements`, `@web/dev-server`, and `@pwrs/cem`.
Restart Claude Code to connect
Try It 🎲
What You Learned
- ✓ Custom Elements Manifest provides structured component metadata
- ✓ CEM CLI generates, validates, and serves manifests
- ✓ LSP brings component knowledge to your IDE
- ✓ MCP connects manifests to AI systems
- ✓ Standards enable entire tooling ecosystems
Resources
github.com/bennypowers/cem
github.com/webcomponents/custom-elements-manifest
modelcontextprotocol.io
ux.redhat.com
Thanks
Red Hat