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

@stdiobus/mcpx

v1.0.0

Published

Universal modular launcher for MCP servers — TypeScript CLI

Downloads

93

Readme

Why mcpx?

MCP client configurations (mcp.json) are full of hardcoded bash commands, fragile paths, and duplicated environment setup. When a module moves, changes runtime, or needs new env vars, every client config breaks.

mcpx replaces all of that with a single portable command. Define your module once in module.json, and any MCP client can launch it with mcpx run <module-id>.

How It Works

%%{init: {'theme':'dark', 'themeVariables':{'edgeLabelBackground':'#1a1a2e','lineColor':'#4a90e2','textColor':'#ddd'}}}%%
flowchart TD
    classDef client fill:#1a1a2e,stroke:#f39c12,stroke-width:2px,color:#fff
    classDef launcher fill:#1a1a2e,stroke:#4a90e2,stroke-width:3px,color:#fff,font-weight:bold
    classDef module fill:#16213e,stroke:#50c878,stroke-width:2px,color:#fff
    classDef step fill:#0f3460,stroke:#9b59b6,stroke-width:1px,color:#ddd

    CLIENT["MCP Client<br/><i>Kiro · Claude Desktop · Cursor</i><br/><code>mcp.json: command: mcpx, args: [my-module]</code>"]:::client
    CLIENT -->|"spawn (stdio: pipe)"| MCPX

    MCPX["mcpx launcher"]:::launcher

    subgraph PIPELINE ["Launch Pipeline"]
        direction LR
        style PIPELINE fill:#0d1117,stroke:#4a90e2,stroke-width:2px,color:#8bb9e0
        R["Resolve<br/>Module Root"]:::step
        E["Load Env<br/>.env layers"]:::step
        RT["Select<br/>Runtime"]:::step
        EX["exec()"]:::step
        R --> E --> RT --> EX
    end

    MCPX --> PIPELINE

    MCPX -->|"exec (replaces process)<br/><b>stdout: NEVER TOUCHED</b>"| SERVER

    SERVER["MCP Server — your module<br/><i>stdin/stdout = JSON-RPC (MCP protocol)</i>"]:::module

Quick Start

mcpx discovers modules inside a Module Root (~/.ai/ by default, override with MCPX_ROOT).
Each module is a folder under modules/ with a module.json manifest and an entry file.

~/.ai/                        ← Module Root
└── modules/
    └── my-module/            ← one module = one directory
        ├── module.json       ← manifest: id, runtime, entry
        └── server.ts         ← your MCP server code

Minimal working example

# 1. Install mcpx
npm install -g @stdiobus/mcpx

# 2. Create module directory
mkdir -p ~/.ai/modules/my-module

# 3. Create manifest
cat > ~/.ai/modules/my-module/module.json << 'EOF'
{
  "id": "my-module",
  "name": "My MCP Server",
  "runtime": "nodejs",
  "entry": "server.ts"
}
EOF

# 4. Create entry file
cat > ~/.ai/modules/my-module/server.ts << 'EOF'
// your MCP server code here
EOF

# 5. Run
mcpx run my-module

Use MCPX_ROOT=/your/path mcpx run my-module to point at a different root.

Features

  • Language-agnostic — supports Node.js, Python, Go, Rust, Shell, and Docker
  • Stdio-transparent — uses exec to replace the process; zero buffering, zero corruption
  • Manifest-driven — one module.json describes everything: runtime, entry, env, args
  • Env management — layered .env loading with precedence rules, secret masking, template expressions
  • Cross-platform — macOS, Linux, and Windows (Node.js 18+)
  • MCP-native — drop-in replacement for hardcoded commands in any mcp.json

Usage

mcpx run <module>

Launch a module by ID. This is the default command — mcpx my-module is equivalent to mcpx run my-module.

mcpx run my-module
mcpx run my-module -- --port 3000    # pass extra args
MCPX_ROOT=/path/to/modules mcpx run my-module

mcpx list

Show all discovered modules with their status.

mcpx list
mcpx list --json

Output:

  my-module         My MCP Server        nodejs   ready
  python-tools      Python Tools         python   ready
  broken-mod        Broken Module        go       unavailable

mcpx doctor

Validate manifests, check runtime availability, verify env resolution.

mcpx doctor
mcpx doctor --json

mcpx env <module>

Display resolved environment variables for a module (values masked).

mcpx env my-module

Output:

  OPENAI_API_KEY    sk-p****
  DATABASE_URL      post****

module.json Reference

{
  // Required
  "id": "my-module",           // 1–128 chars, lowercase alphanumeric + hyphens
  "name": "My MCP Server",    // 1–256 chars, human-readable
  "runtime": "nodejs",         // nodejs | python | go | rust | shell | docker
  "entry": "src/server.ts",   // relative path from module directory

  // Optional
  "version": "1.0.0",         // semver (MAJOR.MINOR.PATCH)
  "description": "A helpful MCP server",  // max 1024 chars
  "env": {                     // max 64 entries
    "API_KEY": "",             // empty = required, no default
    "PORT": "3000"             // non-empty = default value
  },
  "args": ["--verbose"]        // max 64 elements, passed to process
}

Complete Example

{
  "id": "code-assistant",
  "name": "Code Assistant MCP Server",
  "runtime": "nodejs",
  "entry": "dist/index.js",
  "version": "2.1.0",
  "description": "AI-powered code analysis and generation",
  "env": {
    "OPENAI_API_KEY": "",
    "MODEL": "gpt-4o",
    "MAX_TOKENS": "4096"
  },
  "args": ["--stdio"]
}

Supported Runtimes

| Runtime | Entry Extensions | Tool Required | Exec Command | |----------|--------------------|---------------------|---------------------------------------| | nodejs | .ts | npx, node | npx tsx <entry> | | nodejs | .js, .mjs | node | node <entry> | | python | .py | uv or python3 | uv run <entry> or python3 <entry> | | go | .go or binary | go | go run <entry> or ./<binary> | | rust | (cargo project) | cargo | cargo run or ./target/release/<id>| | shell | .sh | /bin/sh | /bin/sh <entry> | | docker | (image name) | docker | docker run --rm -i <entry> |

Environment Variables

Precedence (highest wins)

  1. System environment — variables already set in the process (from MCP client env field)
  2. Module .env{module_dir}/.env
  3. Root .env{MCPX_ROOT}/.env
  4. Manifest defaultsmodule.json env field values

.env Format

# Comments start with #
API_KEY=sk-your-key-here
DATABASE_URL="postgres://localhost/mydb"
EMPTY_VAR=

mcpx Environment Variables

| Variable | Description | |---------------|--------------------------------------------------| | MCPX_ROOT | Override module root directory | | MCPX_DEBUG | Set to 1 to enable verbose diagnostic output | | MCPX_ARGS | Additional arguments (POSIX shell quoting rules) |

Env Template Expressions

{
  "env": {
    "API_KEY": "$env:OPENAI_API_KEY",
    "CERT": "$file:/etc/ssl/cert.pem",
    "TOKEN": "$cmd:aws secretsmanager get-secret-value --secret-id my-token"
  }
}
  • $env:VAR — read from environment variable
  • $file:path — read file contents
  • $cmd:command — execute command (10s timeout)

MCP Client Integration

Kiro

{
  "mcpServers": {
    "my-module": {
      "command": "mcpx",
      "args": ["my-module"],
      "env": {
        "MCPX_ROOT": "/path/to/modules"
      }
    }
  }
}

Claude Desktop

{
  "mcpServers": {
    "my-module": {
      "command": "mcpx",
      "args": ["run", "my-module"],
      "env": {
        "API_KEY": "sk-your-key"
      }
    }
  }
}

Cursor

{
  "mcpServers": {
    "my-module": {
      "command": "mcpx",
      "args": ["my-module", "--", "--port", "3000"]
    }
  }
}

Exit Codes

| Code | Meaning | |------|------------------------------------------------------| | 0 | Success (module exited normally) | | 1 | General error (module not found, unknown error) | | 2 | Manifest error (invalid JSON, missing required field)| | 3 | Runtime error (tool not installed, exec failed) | | 4 | Environment error (required variable missing) |

Registry Commands

mcpx install <module-name>    # Install from registry
mcpx publish                  # Publish current module
mcpx upgrade [module-id]      # Upgrade installed modules
mcpx search <query>           # Search the registry

Contributing

Contributions are welcome. Please open an issue first to discuss what you'd like to change.

git clone https://github.com/stdiobus/mcpx.git
cd mcpx
yarn install
yarn run build
yarn test

License

Apache-2.0