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

@directive-run/mcp

v0.6.2

Published

Model Context Protocol server that exposes Directive to AI clients — knowledge files, code examples, and Claude Code skill bundles today, with room to grow into runtime introspection and tooling. stdio for local clients (Claude Desktop, Cursor, MCP Inspec

Downloads

3,930

Readme

@directive-run/mcp

Run a Model Context Protocol (MCP) server that lets AI assistants – Claude Desktop, Cursor, Windsurf, or any MCP client – query Directive's knowledge base, code examples, lint rules, and scaffolding tools live. No pre-bundling, no stale snapshots: the assistant asks, the server answers from the current package contents.

Most readers want this package. Install it if you use Claude Desktop, Cursor, or another MCP-speaking client – or if you're hosting Directive's knowledge as a service for your team's agents.

Which side are you on? This package is the server: it exposes Directive's knowledge so AI clients can read it. If instead you're building a Directive AI agent that needs to call external MCP servers (filesystem, GitHub, Slack), use @directive-run/ai/mcp and its createMCPAdapter.

Install

The fastest path is zero-install via npx. Claude Desktop, Cursor, and other MCP clients will spawn it for you when their config block points here:

npx -y @directive-run/mcp --help

For environments that pin binaries, install globally instead:

npm install -g @directive-run/mcp
directive-mcp --help

Try it (3 steps)

// 1. Paste into your AI client's MCP config and restart it.
//    Claude Desktop:  ~/Library/Application Support/Claude/claude_desktop_config.json
//    Cursor:          .cursor/mcp.json
{
  "mcpServers": {
    "directive": {
      "command": "npx",
      "args": ["-y", "@directive-run/mcp"]
    }
  }
}
2. Verify the server is loaded.
   Claude Desktop:  click the tools/hammer icon – you should see `directive`
                    with 22 tools. Or ask Claude:
                    "Use the directive MCP server's get_server_info tool."
   Cursor:          open Settings → MCP → look for `directive` (status: connected).
   MCP Inspector:   npx @modelcontextprotocol/inspector npx -y @directive-run/mcp
                    → connect → /tools should list 20 entries.
3. Send your first prompt. Any of these will fire a tool round-trip:

   • "Using the directive MCP server, list the knowledge files,
      then read the one about constraints."
   • "Generate a Directive module named 'cart' with constraints + resolvers
      using the directive MCP server."
   • "Review this code with directive's review_source tool, then call
      fix_code on any fixable findings:
      createModule('Cart', { schema: {} });"

How it works

Every Directive MCP request follows the same shape: an AI client (Claude Desktop, Cursor, your own agent) speaks JSON-RPC to one of two transports – stdio for local subprocess clients, SSE for the hosted gateway. The server dispatches to a tool handler, which reads from one of three in-process data sources: the bundled @directive-run/knowledge package (markdown + extracted examples), the lazy-loaded @directive-run/lint registry (ts-morph rules, loaded on first call so the ~25 MB ts-morph cost only hits when review_source or fix_code actually runs), or the pure-string @directive-run/scaffold generators. Nothing touches disk; nothing calls out over the network – except get_package_info, which fetches latest from npm with a 1-hour cache.

┌────────────────────────────────────────────────────────────────────────────────┐
│  Claude Desktop / Cursor / Windsurf / MCP Inspector                            │
│                                                                                │
│  Reads ~/Library/Application Support/Claude/claude_desktop_config.json on      │
│  launch. For each mcpServers entry, spawns the subprocess and pipes JSON-RPC   │
│  over its stdin/stdout.                                                        │
└────────────────────────────┬───────────────────────────────────────────────────┘
                             │ stdio (or SSE for hosted)
                             ▼
┌────────────────────────────────────────────────────────────────────────────────┐
│  @directive-run/[email protected]  (`npx -y @directive-run/mcp` subprocess)            │
│                                                                                │
│  src/cli.ts:                                                                   │
│    parseArgs() → { sse: false (default) }                                      │
│    setServerInfo({ transport: "stdio", authEnabled: false })                   │
│    createDirectiveServer() → McpServer with 22 tools registered                │
│                                                                                │
│  Tool surface (22):                                                            │
│    Knowledge:   list_knowledge, get_knowledge, search_knowledge,               │
│                 list_examples, get_example, search_examples                    │
│    Packages:    list_packages, get_package_info, get_composable_packages       │
│    Generate:    generate_module, list_module_sections                          │
│    Review:      list_review_rules, get_review_rule, review_source, fix_code    │
│    Migration:   list_migration_sources, get_migration_pattern                  │
│    Skills:      list_skills, get_skill                                         │
│    Server:      get_server_info                                                │
└──────┬─────────────────┬──────────────────┬──────────────────┬─────────────────┘
       │                 │                  │                  │
       ▼                 ▼                  ▼                  ▼
  ┌──────────┐    ┌────────────┐    ┌──────────┐       ┌───────────────────┐
  │knowledge │    │claude-plug-│    │ scaffold │       │      lint         │
  │          │    │   in       │    │          │       │  (lazy-loaded     │
  │ • core/* │    │ • skills/* │    │ pure     │       │   via separate    │
  │ • ai/*   │    │  bundled   │    │ functions│       │   tsup entry)     │
  │ • compo- │    │  from      │    │ in /     │       │                   │
  │   sitions│    │  knowledge │    │ strings  │       │ • 10 ts-morph     │
  │   .json  │    │  at build  │    │ out      │       │   rules           │
  │ • migra- │    │            │    │          │       │ • 6 fixable       │
  │   tion.  │    │            │    │ Zero     │       │ • Worker_threads  │
  │   json   │    │            │    │ runtime  │       │   ON by default   │
  │ • Lazy + │    │            │    │ deps     │       │ • 5-second        │
  │   cached │    │            │    │          │       │   parse budget    │
  │   parsers│    │            │    │          │       └──────┬────────────┘
  └──────────┘    └────────────┘    └──────────┘              │
                                                              ▼
                                                  ┌────────────────────────┐
                                                  │  ts-morph (lazy)       │
                                                  │  TypeScript compiler   │
                                                  │  API wrapper. Spins up │
                                                  │  in-memory Project,    │
                                                  │  parses src → AST.     │
                                                  │  Each rule walks the   │
                                                  │  AST via               │
                                                  │  getDescendantsOfKind  │
                                                  └────────────────────────┘

Caching & limits. First call to list_knowledge warms the knowledge cache (~700 KB markdown). First call to review_source spins up a worker thread + the ts-morph project, then keeps both for the process lifetime. Built-in caps: 200 KB max source for review_source/fix_code, 5-second parse budget, 1 MB body cap on SSE, 64 concurrent SSE sessions, 5-minute idle pruning. See get_server_info for the live counts.

For the request-flow trace in code, see src/server.ts (tool registration) and src/lint-runner.ts (worker dispatch).

stdio transport (local clients)

Add to your AI client's MCP config (Claude Desktop's claude_desktop_config.json, Cursor's .cursor/mcp.json, etc.) and restart it:

{
  "mcpServers": {
    "directive": {
      "command": "npx",
      "args": ["-y", "@directive-run/mcp"]
    }
  }
}

Or run the MCP Inspector for a browser-based UI:

npx @modelcontextprotocol/inspector npx -y @directive-run/mcp

SSE transport (hosted)

# Loopback (local dev) – no token required
directive-mcp --sse --port 3000

# Public host – token is mandatory
directive-mcp --sse --port 3000 --host 0.0.0.0 \
  --token "$DIRECTIVE_MCP_TOKEN" \
  --allow-origin https://app.example.com

Security defaults. A public bind (--host 0.0.0.0) without --token exits with error: --token is required when binding to a non-loopback host. With a token set, every /sse and /messages request must send Authorization: Bearer <token>. Defaults: 1 MB body cap, 64 concurrent sessions, 5-minute idle timeout. Token can also come from the DIRECTIVE_MCP_TOKEN environment variable.

Endpoints:

  • GET /sse – establish the SSE stream.
  • POST /messages?sessionId=… – client→server JSON-RPC messages.
  • GET /healthz – liveness probe.

Tools (22)

Knowledge

| Tool | Purpose | |---|---| | list_knowledge | Every knowledge file name (core + AI + skeleton). | | get_knowledge | Read one knowledge file by name. | | search_knowledge | Case-insensitive substring search across every knowledge file. | | list_examples | Every code example name. | | get_example | Read one example by name (returned as a TypeScript code block). | | search_examples | Case-insensitive substring search across the 37 bundled example .ts files. |

Packages

| Tool | Purpose | |---|---| | list_packages | Every @directive-run/* package with one-line description. | | get_package_info | Single-package detail (baked metadata + live npm version, 1 h cache, 3 s timeout, falls back to baked on failure). | | get_composable_packages | Outgoing and incoming composition edges for one package. Returns isError: true with NOT_FOUND prefix when the package isn't known. |

Generate

| Tool | Purpose | |---|---| | generate_module | Generate NEW Directive module or AI orchestrator source. Returns the source string + suggested filenames + required-packages list; the caller writes to disk via its own file tool. | | list_module_sections | Enumerate the valid sections values for generate_module (autodiscovery – no hallucinated enum values). |

Review

| Tool | Purpose | |---|---| | list_review_rules | All 10 ts-morph rules as structured data (id, severity, category, title). | | get_review_rule | One rule's full detail: WRONG/CORRECT example pair + explanation. | | review_source | Run the rule registry against a TypeScript source string. Pre-parse 200 KB cap, 5-second budget enforced via worker.terminate(). Returns structured findings. | | fix_code | Apply a rule's mechanical fix; returns diff + fixed source. 6 of 10 rules ship a fix; the rest return { ok: false, reason }. |

Migration

| Tool | Purpose | |---|---| | list_migration_sources | Source libraries get_migration_pattern accepts. | | get_migration_pattern | Concept map + steps + before/after for migrating from Redux / Zustand / XState / MobX / Jotai / Recoil. |

Skills

| Tool | Purpose | |---|---| | list_skills | Every Claude Code skill bundled in @directive-run/claude-plugin. | | get_skill | One skill's SKILL.md + supporting knowledge files as a single document. |

Server

| Tool | Purpose | |---|---| | get_server_info | Version + transport + auth state + bundled-knowledge hash + session count + package-registry timestamp. |

Playground

| Tool | Purpose | |---|---| | playground_link | Turn TypeScript source into a clickable URL that boots a real Directive project in StackBlitz. Two shapes: pass source (single string) for already-runnable snippets from get_example / fix_code, OR pass files: [{path, source}, …] for the paired library + runner output from generate_module. Optional mode: "preview" \| "instant""preview" (default) lands on directive.run/playground with code + Open-in-StackBlitz button; "instant" lands on directive.run/run which auto-submits the StackBlitz form (no preview UI). 8 KB cap on raw input. Payload travels in the URL hash so it never reaches server logs. | | run_in_sandbox | Execute a Directive snippet inside a bounded worker_threads sandbox and return its observed behavior – captured console.log/warn/error lines, the post-settle() facts snapshot, structured errors, plus a playgroundUrl for click-through editing in StackBlitz. Pair with generate_module to show the user what the generated module ACTUALLY DID when it ran. v0.3.0 boundary: AST allowlist permits @directive-run/{core, ai, query, react, vue, svelte, solid, lit, el, optimistic, timeline, mutator, knowledge, scaffold, claude-plugin, lint} + relative ./*.js; rejects FS/network/eval identifier references AND their property-access bypass chains (globalThis.process, Reflect.get(globalThis, …), .constructor, Function(...)). 5-second wall-clock budget (clamped to [100ms, 10s]), 32 MB heap. Note: react/vue/svelte/solid/lit import OK but their runtime hooks throw in Node – use playground_link for UI demos. |

Composition for a "try it now" link: generate_module returns paired {moduleSource, runnerSource, suggestedFilenames} – pass both to playground_link as a files array (the runner is the entry point at src/main.ts) and the user clicks ONE URL that boots a project where tsx src/main.ts actually logs Directive facts to the StackBlitz terminal. For get_example / fix_code output (already runnable), pass the single source string instead.

Troubleshooting

The four most common first-time failures:

| Symptom | What's happening | Fix | |---|---|---| | Claude Desktop shows no directive server in the hammer/tools menu. | Config file wasn't read, or npx failed to install. | Fully quit Claude Desktop (Cmd-Q, not just close the window) and relaunch. Then check the log: ~/Library/Logs/Claude/mcp-server-directive.log (macOS), %APPDATA%\Claude\logs\mcp-server-directive.log (Windows). | | review_source returns review_source failed – worker-error: ts-morph is not installed. | npm install ran with --no-optional, or your package manager skipped optionalDependencies. | npm install -g ts-morph once. ts-morph (~25 MB) is loaded only when review_source / fix_code fires. | | --sse --host 0.0.0.0 exits with --token is required. | Public bind needs auth. | Pass --token <secret> or set DIRECTIVE_MCP_TOKEN in the environment. Loopback binds (the default 127.0.0.1) don't need a token. | | npx -y @directive-run/mcp is slow on first launch. | npx is downloading + installing the package + ts-morph (~25 MB). | First launch is ~10-20 s on a cold npm cache. Subsequent launches use the cached tarball. To pre-warm: npm install -g @directive-run/mcp and use "command": "directive-mcp" in the config. |

If a tool errors mid-conversation, the fastest recovery is: "Ask the directive MCP server's get_server_info tool to verify connectivity."

Programmatic embedding

For tool authors who want to mount the server inside their own host process:

import {
  createDirectiveServer,
  startSseServer,
  setMaxConcurrentLintWorkers,
} from "@directive-run/mcp";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";

// stdio
const server = createDirectiveServer();
await server.connect(new StdioServerTransport());

// SSE – returns the underlying http.Server
const httpServer = await startSseServer({ port: 3000, host: "0.0.0.0" });

Tuning the lint worker pool

review_source and fix_code each spawn a ts-morph worker thread to parse the input. A multi-client burst – Cursor + Claude + IDE all calling these tools in parallel – could amplify into a thread-spawn storm. setMaxConcurrentLintWorkers(n) caps the simultaneously-running lint workers. Calls beyond the cap queue FIFO; abandoned callers (signal-aborted or dropped promises) deregister cleanly. Defaults to navigator.hardwareConcurrency (falls back to 4); pass Infinity to disable.

import { setMaxConcurrentLintWorkers } from "@directive-run/mcp";
// At server boot – runs once per process.
setMaxConcurrentLintWorkers(4);

See also