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.
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:
cmx_search(query)— FTS5 full-text search across all your APIs, database tables, and docs. Returns typed SDK signatures for matches only.cmx_execute(code)— runs TypeScript in a VM sandbox usingsdk.<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.
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.
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.
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 startOption 1: Claude Code marketplace
/install codemode-xInstalls 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-xOption 2: npm
npm install -g codemode-x
cd your-project
npx codemode-x init # generates codemode-x.config.js + .mcp.jsonRestart 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.
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.
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.
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.
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.
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
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 = 30Plus 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: INTEGER → number, TEXT/VARCHAR → string, REAL → number, BOOLEAN → boolean.
Full guide: docs/database-adapter.md
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: str → string, int/float → number, bool → boolean, 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
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
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.
npm install -g memory-x
memoryx init
memoryx import ./CLAUDE.md
memoryx import ./docs/
memoryx statusAdd 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
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.*.
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.
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
- 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
npx codemode-x init # interactive setup
npx codemode-x test # discover tools, show what Claude sees
npx codemode-x start # start MCP server (stdio)npm install
npm run build
npm test
npm run test:watch # watch mode
npm run test:live # e2e against running server- Lambda adapter — manifest format, AWS discovery, tagging, filtering
- Database adapter — SQL validation, type mapping, table filtering
- Python adapter — type mapping, subprocess execution, docstring parsing
- MCP Bridge adapter — connecting MCP servers, JSON Schema mapping
- Memory database — using memory-x with codemode-x
MIT