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

codemode-x

v0.4.2

Published

Compress any API, database, or docs into 2 MCP tools (cmx_search + cmx_execute)

Readme

codemode-x

MCP plugin for Claude Code. Compresses your APIs, databases, Lambda functions, and docs into 2 MCP tools (~1,000 tokens) instead of N tools (100K+ tokens).

Claude writes TypeScript against a typed SDK. Code runs in a sandbox.

Built by Carbon and Codelitt.

How it works

cmx_search("users orders")                                     →  typed SDK signatures for matching tools
cmx_execute("await sdk.api.getUsers()")                         →  real API call, sandboxed
cmx_execute("await sdk.data.rawQuery({ sql: 'SELECT ...' })")  →  database query, read-only

Two tools:

  1. cmx_search(query) — FTS5 full-text search across all your APIs, database tables, and docs. Returns typed SDK signatures for matches only.
  2. cmx_execute(code) — runs TypeScript in a VM sandbox using sdk.<domain>.<method>(). AST-validated. Credentials injected at runtime, never in context.

This is not RAG. The search index holds function signatures, not data. sdk.api.getUsers() makes a real HTTP request to your running server. sdk.data.rawQuery({ sql: '...' }) hits your actual database. The compression is about discovery — Claude finds the right endpoint in ~500 tokens instead of loading every tool definition into context.

Why not just use a bigger context window?

Every MCP tool you register costs tokens on every request, even if Claude only uses one. 25 endpoints = ~100K tokens of tool schemas before Claude writes a single line of code. codemode-x makes that ~1K tokens.

Same reason databases have indexes even when you have plenty of RAM.

Maturity

Developers at Codelitt dogfood codemode-x at Carbon for real estate operations. Express, OpenAPI, and Database adapters run against production APIs and data daily. Markdown, Lambda (manifest mode), Python, and MCP Bridge have test coverage but less mileage. Lambda AWS discovery is beta.

Quick start

cd your-project
npm install codemode-x

# Interactive setup — detects Express/OpenAPI files, generates config
npx codemode-x init

# Or create a config manually
cat > codemode-x.config.js << 'EOF'
export default {
  sdkName: 'myapp',
  domains: [
    {
      name: 'api',
      adapter: 'express',
      source: './server.js',
      baseUrl: 'http://localhost:3000',
      auth: { scope: 'readwrite' },
      // Or use header-based auth with an env var:
      // auth: { type: 'header', key: 'X-API-Key', envVar: 'MY_API_KEY' },
    },
  ],
};
EOF

# Test your config
npx codemode-x test

# Start as MCP server
npx codemode-x start

Install

Option 1: Claude Code marketplace

/install codemode-x

Installs as a Claude Code plugin with automatic updates. Then run npx codemode-x init in your project to generate a config.

If codemode-x isn't in your marketplace yet:

/plugin marketplace add codelitt/codemode-x
/plugin install codemode-x@codemode-x

Option 2: npm

npm install -g codemode-x
cd your-project
npx codemode-x init    # generates codemode-x.config.js + .mcp.json

Restart Claude Code. cmx_search and cmx_execute appear automatically.

Option 3: Manual .mcp.json

Create .mcp.json in your project root:

{
  "mcpServers": {
    "codemode-x": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "codemode-x", "start"],
      "cwd": "/path/to/your/project"
    }
  }
}

Add .mcp.json to .gitignore if it contains secrets.

Adapters

Each adapter introspects a source (API code, spec file, database, etc.) and generates typed SDK methods.

| Adapter | Source | What it does | Status | |---------|--------|--------------|--------| | express | Express.js app file | Parses route handlers via AST | Production | | openapi | OpenAPI 3.x spec (JSON) | Extracts operations + schemas | Production | | database | SQLite database file | Introspects schema, generates query tools | Production | | markdown | Markdown files/globs | Indexes docs as searchable content | Stable | | lambda | AWS Lambda functions | Manifest file or AWS discovery | Manifest: Stable, AWS discovery: Beta | | python | Python modules | Introspects functions via subprocess | Stable | | mcp-bridge | Existing MCP servers | Bridges MCP tools into codemode-x | Stable |

Production = dogfooded in real workloads. Stable = implemented with test coverage, not yet production. Beta = functional but limited testing.


Express

Parses Express.js source via AST. Extracts app.get(), app.post(), etc. and generates typed SDK methods.

export default {
  sdkName: 'myapp',
  domains: [
    {
      name: 'api',
      adapter: 'express',
      source: './server.js',
      baseUrl: 'http://localhost:3000',
      auth: { scope: 'readwrite' },
    },
  ],
};

Claude sees sdk.api.getProperties(), sdk.api.createUser({ name, email }). Calls go via HTTP to your running server.

OpenAPI

Parses OpenAPI 3.x / Swagger JSON specs. Extracts operations with parameters, request bodies, and response schemas.

export default {
  sdkName: 'myapp',
  domains: [
    {
      name: 'api',
      adapter: 'openapi',
      source: './openapi.json',
      baseUrl: 'https://api.example.com',
    },
  ],
};

Path params, query params, and request body properties become typed method parameters. Response schemas become TypeScript types.

Markdown

Splits markdown files by heading into searchable sections.

export default {
  sdkName: 'myapp',
  domains: [
    {
      name: 'docs',
      adapter: 'markdown',
      source: './docs/**/*.md',
    },
  ],
};

Single files or globs. Claude finds relevant doc sections alongside API methods when searching.

Lambda functions

Two modes:

Manifest mode — you define a JSON file with function names and schemas:

export default {
  sdkName: 'platform',
  domains: [
    { name: 'payments', adapter: 'lambda', source: './manifests/payments.json' },
    { name: 'users', adapter: 'lambda', source: './manifests/users.json' },
  ],
};

AWS discovery mode — scans your account, reads schemas from function tags:

export default {
  sdkName: 'platform',
  domains: [
    {
      name: 'api',
      adapter: 'lambda',
      source: 'us-east-1',
      options: {
        prefix: 'myapp-',              // only functions starting with this
        tags: { team: 'payments' },     // only functions with these tags
      },
    },
  ],
};

Invocation via Lambda.invoke(), not HTTP. Credentials from your environment.

Manifest mode is fully tested. AWS discovery mode is beta — works but hasn't been used in production.

Full guide: docs/lambda-adapter.md

Database

Introspects a SQLite database schema and generates query tools. Read-only by default.

export default {
  sdkName: 'myapp',
  domains: [
    {
      name: 'data',
      adapter: 'database',
      source: './app.db',
      options: {
        tables: ['users', 'orders'],    // optional: only these tables
        // exclude: ['migrations'],      // or: exclude these tables
      },
    },
  ],
};

Per-table query{TableName} tools with columns as optional filters:

await sdk.data.queryUsers()                     // SELECT * FROM users
await sdk.data.queryUsers({ name: 'Alice' })    // WHERE name = 'Alice'
await sdk.data.queryUsers({ age: 30 })          // WHERE age = 30

Plus a rawQuery tool for arbitrary read-only SQL:

await sdk.data.rawQuery({
  sql: 'SELECT u.name, COUNT(o.id) as order_count FROM users u JOIN orders o ON u.id = o.user_id GROUP BY u.name'
})

SQL validation:

  • Allowed: SELECT, PRAGMA, EXPLAIN
  • Blocked: INSERT, UPDATE, DELETE, DROP, ALTER, CREATE
  • Multi-statement queries rejected

Column types map automatically: INTEGERnumber, TEXT/VARCHARstring, REALnumber, BOOLEANboolean.

Full guide: docs/database-adapter.md

Python

Introspects Python modules via subprocess. Extracts function signatures, type hints, and docstrings. Each public function becomes an SDK method.

export default {
  sdkName: 'myapp',
  domains: [
    {
      name: 'analytics',
      adapter: 'python',
      source: './lib/analytics.py',
      options: {
        python: 'python3',              // optional: path to interpreter
        functions: ['run_report'],       // optional: only include these
        // exclude: ['helper_fn'],       // or: exclude these
      },
    },
  ],
};

Given:

def get_user_stats(user_id: str, days: int = 30) -> Dict[str, float]:
    """Get usage statistics for a user over a time period."""
    ...

Claude sees: sdk.analytics.getUserStats({ user_id: string, days?: number }) → Record<string, number>

Type hints map: strstring, int/floatnumber, boolboolean, List[X]X[], Optional[X]X | null.

Functions run via subprocess. Python gets its own process with params as JSON. No shared memory, no import conflicts.

Full guide: docs/python-adapter.md

MCP Bridge

Wraps an existing MCP server's tools as codemode-x SDK methods.

export default {
  sdkName: 'myapp',
  domains: [
    {
      name: 'github',
      adapter: 'mcp-bridge',
      source: 'node /path/to/github-mcp-server.js',
      options: {
        tools: ['search_repos', 'get_file'],  // optional: only include these
        // exclude: ['delete_repo'],            // or: exclude these
      },
    },
  ],
};

Source can be a command string or config object:

// Command string
source: 'python -m my_mcp_server'

// Config object (for env vars, custom args)
source: {
  command: 'node',
  args: ['./mcp-server/index.js', '--port', '3000'],
  env: { API_KEY: 'xxx' },
}

Connects via stdio, discovers tools via listTools(), maps JSON Schema parameters to typed SDK methods. At runtime, cmx_execute proxies calls through the MCP client.

Any MCP server — GitHub, Slack, Postgres, whatever — gets collapsed into the 2-tool interface with search across all of them.

Full guide: docs/mcp-bridge-adapter.md

Memory database

Pair with memory-x for queryable, persistent memory backed by SQLite. memory-x turns markdown files into structured tables — dynamically infers schema from your content.

Setup

npm install -g memory-x

memoryx init
memoryx import ./CLAUDE.md
memoryx import ./docs/
memoryx status

Using with codemode-x

Add the memory database as a domain:

export default {
  sdkName: 'myapp',
  domains: [
    {
      name: 'memory',
      adapter: 'database',
      source: './memory.db',
      options: { writable: true },  // Claude can write live context
    },
    {
      name: 'api',
      adapter: 'express',
      source: './server.js',
      baseUrl: 'http://localhost:3000',
    },
  ],
};

Claude can query context alongside APIs:

await sdk.memory.queryPeople({ who: 'Alice' })
await sdk.memory.queryTerms({ term: 'SLA' })
await sdk.memory.rawQuery({ sql: "SELECT * FROM people WHERE role LIKE '%Lead%'" })
await sdk.api.getUsers()

Full guide: docs/memory-database.md

Multi-domain configs

Combine adapters in one config. cmx_search searches across all of them:

export default {
  sdkName: 'myapp',
  domains: [
    { name: 'api',      adapter: 'express',  source: './server.js', baseUrl: 'http://localhost:3000', auth: { scope: 'readwrite' } },
    { name: 'payments', adapter: 'lambda',   source: './manifests/payments.json' },
    { name: 'data',     adapter: 'database', source: './app.db' },
    { name: 'memory',   adapter: 'database', source: './memory.db' },
    { name: 'docs',     adapter: 'markdown', source: './docs/**/*.md' },
  ],
};

Search for "users" returns API endpoints, database tables, and doc sections — all typed, all callable through sdk.*.

How we use it at Carbon

We run this at Carbon for real estate operations. Express and OpenAPI adapters hit our rent comps API and property management system in production. Database and markdown adapters handle portfolio context and ops docs.

export default {
  sdkName: 'carbon',
  domains: [
    { name: 'rentComps', adapter: 'express', source: './server.js', baseUrl: 'http://localhost:3001' },
    { name: 'portfolio', adapter: 'database', source: './properties.db' },
    { name: 'memory', adapter: 'database', source: './memory.db' },
    { name: 'docs', adapter: 'markdown', source: './docs/**/*.md' },
  ],
};

"rent comps for Maple Ridge" returns the API endpoint, the property record, and the relevant docs. Still 2 MCP tools.

Architecture

User query → cmx_search → FTS5/BM25 index → typed SDK signatures (~500 tokens)
                                ↓
User code  → cmx_execute → AST validation → VM sandbox → sdk.domain.method()
                                                              ↓
                                              HTTP / Lambda.invoke() / SQLite / Python subprocess / MCP proxy

Security

  • AST validation blocks require, import, fetch, process, eval, Function
  • VM sandbox via vm.createContext — no Node globals exposed
  • Credentials injected at execution time only, never in LLM context
  • Header auth: auth: { type: 'header', key: 'X-API-Key', envVar: 'MY_API_KEY' } injects from env vars at request time
  • Read-only by default — writes require explicit auth: { scope: 'readwrite' }
  • Database read-only by default — writable opt-in via options: { writable: true }
  • SQL validation rejects write statements and multi-statement queries in read-only mode

CLI

npx codemode-x init     # interactive setup
npx codemode-x test     # discover tools, show what Claude sees
npx codemode-x start    # start MCP server (stdio)

Development

npm install
npm run build
npm test

npm run test:watch       # watch mode
npm run test:live        # e2e against running server

Docs

License

MIT