npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

helixir

v0.4.0

Published

MCP server that gives AI agents full situational awareness of any web component library

Readme

HELiXiR

Give AI agents full situational awareness of any web component library.

Stop AI hallucinations. Ground every component suggestion in your actual Custom Elements Manifest.

npm version npm downloads License: MIT Node 20+ Build Tests

Quick Start · Why HELiXiR · Tools Reference · Configuration · AI Tool Configs


Why HELiXiR

  • No more hallucinations — AI reads your real component API from the Custom Elements Manifest, not from training data. Every attribute, event, slot, and CSS part is sourced directly from your library.
  • 30+ MCP tools out of the box — Component discovery, health scoring, design token lookup, TypeScript diagnostics, breaking-change detection, and Storybook story generation — all callable by any MCP-compatible AI agent.
  • Works with any web component framework — Shoelace, Lit, Stencil, FAST, Spectrum, Vaadin, and any library that produces a custom-elements.json CEM file.
  • Any AI editor, zero lock-in — Claude Code, Claude Desktop, Cursor, VS Code (Cline/Continue), Zed — one config, any tool.

Quick Start

Under 60 seconds from zero to a component-aware AI agent.

npm install helixir

Then generate a starter config in your component library:

npx helixir init
# → writes mcpwc.config.json to the current directory

Edit mcpwc.config.json to point at your library:

{
  "cemPath": "custom-elements.json",
  "projectRoot": "/absolute/path/to/your/component-library",
  "componentPrefix": "sl-",
  "tokensPath": "dist/tokens/tokens.json"
}

Add HELiXiR to your Claude Desktop config (see AI Tool Configs for other editors):

{
  "mcpServers": {
    "helixir": {
      "command": "npx",
      "args": ["helixir"],
      "env": {
        "MCP_WC_PROJECT_ROOT": "/absolute/path/to/your/component-library"
      }
    }
  }
}

Restart Claude Desktop. Done — your AI agent now knows every property, event, slot, CSS part, and design token in your library.


What You Get

Without HELiXiR

You: How do I use sl-button?

Claude: You can use <sl-button> like this:

<sl-button type="primary" color="blue" rounded>Click me</sl-button>

It supports type, color, rounded, icon, and label attributes.

All of that is hallucinated. type, color, rounded, icon, and label are not real attributes on sl-button. The correct attribute for the visual style is variant, and rounded doesn't exist at all.


With HELiXiR

You: How do I use sl-button?

Claude: (calls get_componentsl-button) Here's the accurate API for <sl-button>:

Attributes:

  • variant'default' | 'primary' | 'success' | 'neutral' | 'warning' | 'danger' | 'text' (default: 'default')
  • size'small' | 'medium' | 'large' (default: 'medium')
  • disabledboolean (default: false)
  • loadingboolean — Draws the button in a loading state
  • outlineboolean — Draws an outlined button
  • pillboolean — Draws a pill-style button with rounded edges
  • hrefstring | undefined — Renders as <a> when set

Slots: default (button label), prefix (before label), suffix (after label)

Events: sl-blur, sl-focus, sl-invalid

Example:

<sl-button variant="primary" size="medium">Save changes</sl-button>

Every property, event, slot, CSS part, and design token — sourced directly from your Custom Elements Manifest. No hallucinations.


Framework Setup

HELiXiR works with any toolchain that produces a custom-elements.json (CEM). Below are quick-start setups for the most common frameworks.

Shoelace

Shoelace ships custom-elements.json inside its npm package. No build step needed.

npm install @shoelace-style/shoelace
{
  "cemPath": "node_modules/@shoelace-style/shoelace/dist/custom-elements.json",
  "componentPrefix": "sl-"
}

Lit

Use the official CEM analyzer with the Lit plugin:

npm install -D @custom-elements-manifest/analyzer
// package.json scripts
"analyze": "cem analyze --litelement --globs 'src/**/*.ts'"
{
  "cemPath": "custom-elements.json",
  "componentPrefix": "my-"
}

Run npm run analyze after each build to keep the CEM current.

Stencil

Enable CEM output in stencil.config.ts:

// stencil.config.ts
import { Config } from '@stencil/core';

export const config: Config = {
  outputTargets: [{ type: 'docs-custom' }, { type: 'dist-custom-elements' }],
};

Stencil emits custom-elements.json to your dist/ folder:

{
  "cemPath": "dist/custom-elements/custom-elements.json",
  "componentPrefix": "my-"
}

FAST

FAST components ship with CEM support via the @custom-elements-manifest/analyzer:

npm install -D @custom-elements-manifest/analyzer
// package.json scripts
"analyze": "cem analyze --globs 'src/**/*.ts'"
{
  "cemPath": "custom-elements.json",
  "componentPrefix": "fluent-"
}

Adobe Spectrum Web Components

Spectrum Web Components use Stencil under the hood and ship their CEM in the package:

npm install @spectrum-web-components/bundle
{
  "cemPath": "node_modules/@spectrum-web-components/bundle/custom-elements.json",
  "componentPrefix": "sp-"
}

Polymer / Generic Web Components

Any project can add CEM generation with the analyzer:

npm install -D @custom-elements-manifest/analyzer
// package.json scripts
"analyze": "cem analyze --globs 'src/**/*.js'"
{
  "cemPath": "custom-elements.json"
}

Tools Reference

All tools are exposed over the Model Context Protocol. Your AI agent can call any of these tools by name.

Discovery

| Tool | Description | Required Args | | ----------------------------- | ------------------------------------------------------------------------------------ | ---------------------- | | list_components | List all custom elements registered in the CEM | — | | find_component | Semantic search for components by name, description, or member names (top 3 matches) | query | | get_library_summary | Overview of the library: component count, average health score, grade distribution | — | | list_events | List all events across the library, optionally filtered by component | tagName (optional) | | list_slots | List all slots across the library, optionally filtered by component | tagName (optional) | | list_css_parts | List all CSS ::part() targets across the library, optionally filtered by component | tagName (optional) | | list_components_by_category | Group components by functional category (form, navigation, feedback, layout, etc.) | — |

Component

| Tool | Description | Required Args | | ----------------------------- | ----------------------------------------------------------------------------------------------------- | -------------------------- | | get_component | Full metadata for a component: members, events, slots, CSS parts, CSS properties | tagName | | validate_cem | Validate CEM documentation completeness; returns score (0–100) and issues list | tagName | | suggest_usage | Generate an HTML snippet showing key attributes with their defaults and variant options | tagName | | generate_import | Generate side-effect and named import statements from CEM exports | tagName | | get_component_narrative | 3–5 paragraph markdown prose description of a component optimized for LLM comprehension | tagName | | get_prop_constraints | Structured constraint table for an attribute: union values with descriptions, or simple type info | tagName, attributeName | | find_components_by_token | Find all components that expose a given CSS custom property token | tokenName | | find_components_using_token | Find all components referencing a token in their cssProperties (works without tokensPath) | tokenName | | get_component_dependencies | Dependency graph for a component: direct and transitive dependencies from CEM reference data | tagName | | validate_usage | Validate a proposed HTML snippet against the CEM spec: unknown attrs, bad slot names, enum mismatches | tagName, html |

Composition

| Tool | Description | Required Args | | ------------------------- | ------------------------------------------------------------------------------------------------ | ------------- | | get_composition_example | Realistic HTML snippet showing how to compose 1–4 components together using their slot structure | tagNames |

Health

| Tool | Description | Required Args | | ----------------------- | ----------------------------------------------------------------------------------- | ---------------------- | | score_component | Latest health score for a component: grade (A–F), dimension scores, and issues | tagName | | score_all_components | Health scores for every component in the library | — | | get_health_trend | Health trend for a component over the last N days with trend direction | tagName | | get_health_diff | Before/after health comparison between current branch and a base branch | tagName | | get_health_summary | Aggregate health stats for all components: average score, grade distribution | — | | analyze_accessibility | Accessibility profile: ARIA roles, keyboard events, focus management, label support | tagName (optional) |

Library

| Tool | Description | Required Args | | ---------------- | ------------------------------------------------------------------------ | ------------- | | load_library | Load an additional web component library by npm package name or CEM path | libraryId | | list_libraries | List all currently loaded web component libraries | — | | unload_library | Remove a loaded library from memory | libraryId |

Safety

| Tool | Description | Required Args | | ------------------------ | ---------------------------------------------------------------------------------- | ----------------------- | | diff_cem | Per-component CEM diff between branches; highlights breaking changes and additions | tagName, baseBranch | | check_breaking_changes | Breaking-change scan across all components vs. a base branch with summary report | baseBranch |

Framework

| Tool | Description | Required Args | | ------------------ | ----------------------------------------------------------------------------------------- | ------------- | | detect_framework | Identifies the web component framework in use from package.json, CEM metadata, and config | — |

TypeScript

| Tool | Description | Required Args | | ------------------------- | --------------------------------------------------------- | ------------- | | get_file_diagnostics | TypeScript diagnostics for a single file | filePath | | get_project_diagnostics | Full TypeScript diagnostic pass across the entire project | — |

Story

| Tool | Description | Required Args | | ---------------- | ---------------------------------------------------------------------------------- | ------------- | | generate_story | Generates a Storybook CSF3 story file for a component based on its CEM declaration | tagName |

Bundle

| Tool | Description | Required Args | | ---------------------- | ------------------------------------------------------------------------------------------- | ------------- | | estimate_bundle_size | Estimates minified + gzipped bundle size for a component's npm package via bundlephobia/npm | tagName |

package parameter derivation:

The estimate_bundle_size tool accepts an optional package argument — the npm package name to look up (e.g. "@shoelace-style/shoelace"). When omitted, the tool derives the package name from your componentPrefix config value using a built-in prefix-to-package map:

| Prefix | npm Package | | --------- | -------------------------- | | sl | @shoelace-style/shoelace | | fluent- | @fluentui/web-components | | mwc- | @material/web | | ion- | @ionic/core | | vaadin- | @vaadin/components | | lion- | @lion/ui | | pf- | @patternfly/elements | | carbon- | @carbon/web-components |

If your prefix is not in the list above and you omit package, the tool returns a VALIDATION error. In that case, pass the package argument explicitly.

Benchmark

| Tool | Description | Required Args | | --------------------- | ---------------------------------------------------------------------------------------------------------------------------- | ------------- | | benchmark_libraries | Compare 2–10 web component libraries by health score, documentation quality, and API surface; returns a weighted score table | libraries |

CDN

| Tool | Description | Required Args | | ----------------- | ----------------------------------------------------------------------------------------------------- | ------------- | | resolve_cdn_cem | Fetch and cache a library's CEM from jsDelivr or UNPKG by npm package name (for CDN-loaded libraries) | package |

Tokens

(Requires tokensPath to be configured)

| Tool | Description | Required Args | | ------------------- | ------------------------------------------------------------------------------------- | ------------- | | get_design_tokens | List all design tokens, optionally filtered by category (e.g. "color", "spacing") | — | | find_token | Search for a design token by name or value (case-insensitive substring match) | query |


Configuration

Configuration is resolved in priority order: environment variables > mcpwc.config.json > defaults.

mcpwc.config.json

Place this file at the root of your component library project (or wherever MCP_WC_PROJECT_ROOT points).

| Key | Type | Default | Description | | ------------------ | ---------------- | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | cemPath | string | "custom-elements.json" | Path to the Custom Elements Manifest, relative to projectRoot. Auto-discovered if omitted. | | projectRoot | string | process.cwd() | Absolute path to the component library project root. | | componentPrefix | string | "" | Optional tag-name prefix (e.g. "sl-") to scope component discovery. | | healthHistoryDir | string | ".mcp-wc/health" | Directory where health snapshots are stored, relative to projectRoot. | | tsconfigPath | string | "tsconfig.json" | Path to the project's tsconfig.json, relative to projectRoot. | | tokensPath | string \| null | null | Path to a design tokens JSON file. Set to null to disable token tools. | | cdnBase | string \| null | null | Base URL prepended to component paths when generating CDN <script> and <link> tags in suggest_usage output (e.g. "https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2/cdn"). Does not affect resolve_cdn_cem. Set to null to disable CDN suggestions. | | watch | boolean | false | When true, HELiXiR automatically reloads the CEM on file changes. |

Full example:

{
  "cemPath": "dist/custom-elements.json",
  "projectRoot": "/home/user/my-design-system",
  "componentPrefix": "ds-",
  "healthHistoryDir": ".mcp-wc/health",
  "tsconfigPath": "tsconfig.build.json",
  "tokensPath": "dist/tokens/tokens.json",
  "cdnBase": "https://cdn.jsdelivr.net/npm"
}

Environment Variables

Environment variables override all config file values. Useful for CI or when pointing the same server at different libraries.

| Variable | Overrides | | --------------------------- | ------------------ | | MCP_WC_PROJECT_ROOT | projectRoot | | MCP_WC_CEM_PATH | cemPath | | MCP_WC_COMPONENT_PREFIX | componentPrefix | | MCP_WC_HEALTH_HISTORY_DIR | healthHistoryDir | | MCP_WC_TSCONFIG_PATH | tsconfigPath | | MCP_WC_TOKENS_PATH | tokensPath | | MCP_WC_CDN_BASE | cdnBase |

Set MCP_WC_TOKENS_PATH=null (the string "null") to explicitly disable token tools via env var.

See mcpwc.config.json.example for a ready-to-copy template.


AI Tool Configs

Claude Code (CLI)

Add to .mcp.json in your project root (project-scoped) or ~/.claude.json (global):

Option 1 — Install from npm (recommended)

npx helixir init  # generates mcpwc.config.json in your project root

Then add to .mcp.json:

{
  "mcpServers": {
    "helixir": {
      "command": "npx",
      "args": ["helixir"],
      "env": {
        "MCP_WC_PROJECT_ROOT": "/absolute/path/to/your/component-library"
      }
    }
  }
}

Option 2 — Install from local clone (development)

git clone https://github.com/bookedsolidtech/helixir.git
cd helixir
pnpm install
pnpm build

Then add to .mcp.json:

{
  "mcpServers": {
    "helixir": {
      "command": "node",
      "args": ["/absolute/path/to/helixir/build/index.js"],
      "env": {
        "MCP_WC_PROJECT_ROOT": "/absolute/path/to/your/component-library"
      }
    }
  }
}

Reload Claude Code after saving (:mcp to verify the server appears).

Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "helixir": {
      "command": "npx",
      "args": ["helixir"],
      "env": {
        "MCP_WC_PROJECT_ROOT": "/absolute/path/to/your/component-library"
      }
    }
  }
}

Restart Claude Desktop after saving.

Cursor

Add to .cursor/mcp.json in your project root (or ~/.cursor/mcp.json for global):

{
  "mcpServers": {
    "helixir": {
      "command": "npx",
      "args": ["helixir"],
      "env": {
        "MCP_WC_PROJECT_ROOT": "${workspaceFolder}"
      }
    }
  }
}

VS Code (Cline / Continue)

Cline — add to .vscode/cline_mcp_settings.json:

{
  "mcpServers": {
    "helixir": {
      "command": "npx",
      "args": ["helixir"],
      "env": {
        "MCP_WC_PROJECT_ROOT": "${workspaceFolder}"
      }
    }
  }
}

Continue — add to ~/.continue/config.json under mcpServers:

{
  "mcpServers": [
    {
      "name": "helixir",
      "command": "npx helixir",
      "env": {
        "MCP_WC_PROJECT_ROOT": "/absolute/path/to/your/component-library"
      }
    }
  ]
}

Zed

Add to your Zed settings (~/.config/zed/settings.json):

{
  "context_servers": {
    "helixir": {
      "command": {
        "path": "npx",
        "args": ["helixir"],
        "env": {
          "MCP_WC_PROJECT_ROOT": "/absolute/path/to/your/component-library"
        }
      }
    }
  }
}

Security

HELiXiR applies defense-in-depth on all inputs that touch the file system or network:

  • Path containment — all file paths are resolved and verified to stay within projectRoot; .. traversals and absolute paths outside the root are rejected.
  • Input validation — every tool argument is validated with Zod schemas before reaching handler code; unknown properties are rejected via additionalProperties: false.
  • CDN safetyresolve_cdn_cem only fetches from allowlisted CDN origins (jsDelivr, UNPKG); arbitrary URLs are not accepted.
  • No shell execution — the server never spawns subprocesses based on user input; TypeScript diagnostics use the TS compiler API in-process.

See SECURITY.md for the vulnerability disclosure policy.


Quality Gates

Every pull request must pass all five CI checks before merge:

| Workflow | What it checks | | ------------ | --------------------------------------------------- | | build | TypeScript type-check + tsc compile on Node 20/22 | | test | Full vitest suite with coverage on Node 20/22 | | lint | ESLint (TypeScript + Prettier compatibility rules) | | format | Prettier formatting check | | security | pnpm audit --audit-level=high |

Pre-commit hooks (via husky + lint-staged):

  • TypeScript/JavaScript files: ESLint auto-fix → Prettier format
  • JSON/CSS/Markdown/YAML files: Prettier format
  • Commit messages: validated by commitlint against conventional-commits format

Allowed commit types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert, audit

See CONTRIBUTING.md and LOCAL.md for full setup details.


Contributing

See CONTRIBUTING.md for guidelines.

Quick steps:

  1. Fork the repo and create a feature branch.
  2. Run pnpm install to install dependencies.
  3. Make your changes in src/.
  4. Run pnpm test to ensure all tests pass.
  5. Run pnpm run lint && pnpm run format:check before submitting.
  6. Open a pull request with a clear description of the change.

Issues and feature requests are welcome on GitHub.


License

MIT © 2025-2026 Clarity House LLC d/b/a Booked Solid Technology