mcpmon provides both command-line interfaces and programmatic APIs for hot-reloading MCP servers during development.
# Simple nodemon-like usage
mcpmon node server.js
mcpmon python server.py
mcpmon deno run --allow-all server.ts
# With arguments
mcpmon node --inspect server.js
mcpmon python server.py --port 3000# Direct command
npx @modelcontextprotocol/inspector mcpmon node server.js
# With environment variables
API_KEY=your-key npx @modelcontextprotocol/inspector mcpmon node server.js# Show help
mcpmon --help
# Also shows help when called without arguments
mcpmon| Variable | Default | Description |
|---|---|---|
MCPMON_WATCH |
Auto-detected | Override files/directories to watch (comma-separated) |
MCPMON_DELAY |
1000 |
Restart delay in milliseconds |
MCPMON_VERBOSE |
false |
Enable verbose logging |
# Override which files to watch
MCPMON_WATCH="server.js,config.json" mcpmon node server.js
# Change restart delay
MCPMON_DELAY=500 mcpmon node server.js
# Enable verbose logging
MCPMON_VERBOSE=1 mcpmon node server.js
# Combine multiple options
MCPMON_VERBOSE=1 MCPMON_DELAY=2000 mcpmon node server.jsimport { createMCPProxy } from "mcpmon";
// Create and start proxy
const proxy = await createMCPProxy({
command: "node",
args: ["server.js"],
watchFile: "server.js", // Optional - auto-detected if not specified
restartDelay: 1000,
env: { API_KEY: "your-key" }
});
// Start the proxy (runs indefinitely)
proxy.start();
// Handle shutdown
process.on("SIGTERM", async () => {
await proxy.shutdown();
process.exit(0);
});interface MCPProxyConfig {
/** Command to execute (e.g., 'node', 'python', 'deno') */
command: string;
/** Arguments passed to the command */
commandArgs: string[];
/** @deprecated Use watchTargets instead. Single file/directory to watch */
entryFile?: string | null;
/** Array of files, directories, packages, or other resources to monitor */
watchTargets?: string[];
/** Restart delay in milliseconds */
restartDelay?: number;
/** Environment variables to pass to server */
env?: Record<string, string>;
/** Maximum time to wait for graceful shutdown */
killDelay?: number;
/** Delay after server starts before considering it ready */
readyDelay?: number;
}class MCPProxy {
/** Start the proxy and initial server */
async start(): Promise<void>;
/** Stop the proxy and server */
async shutdown(): Promise<void>;
/** Restart the server (debounced) */
readonly restart: () => Promise<void>;
}import { createMCPProxy } from 'mcpmon';
const proxy = await createMCPProxy({
command: 'node',
args: ['server.js'],
watchFile: 'server.js', // Single file to watch (auto-detected if not specified)
restartDelay: 1000,
env: { API_KEY: 'your-key' },
killDelay: 1000,
readyDelay: 2000,
});Enable verbose logging with MCPMON_VERBOSE=1:
🔧 mcpmon starting...
📟 Command: node server.js
👀 Watching: /path/to/server.js
📝 File change detected: server.js
🔄 File change detected, restarting server...
🛑 Killing server process...
✅ Server restarted successfully
- 🔧 Startup: mcpmon initialization
- 📟 Command: Server command and arguments
- 👀 Watching: Files being monitored
- 📝 File changes: Change events detected
- 🔄 Restart: Server restart sequence
- 🛑 Shutdown: Graceful shutdown process
- ✅ Success: Operations completed
- ❌ Errors: Detailed error information
- stdout: JSON-RPC messages only (for MCP communication)
- stderr: All logging and status messages (when verbose enabled)
-
Command not found
Error: spawn node ENOENT -
File not found
Error: No file to watch detected -
Server startup failure
Error: Server process exited with code 1 -
Permission denied
Error: EACCES: permission denied
mcpmon automatically handles many error conditions:
- Server crashes: Automatically restarts the server
- File watch errors: Attempts to re-establish file watching
- Process cleanup: Ensures proper cleanup on shutdown
- Signal handling: Graceful shutdown on SIGINT/SIGTERM
| Code | Meaning |
|---|---|
| 0 | Normal shutdown |
| 1 | General error |
| 130 | Interrupted (Ctrl+C) |
mcpmon can be imported and used as a library in your Node.js applications:
import { MCPProxy, NodeProcessManager, NodeFileSystem } from 'mcpmon';
// Create custom proxy with platform implementations
const proxy = new MCPProxy({
procManager: new NodeProcessManager(),
fs: new NodeFileSystem(),
stdin: process.stdin,
stdout: process.stdout,
stderr: process.stderr,
exit: process.exit
}, {
command: 'node',
commandArgs: ['server.js'],
entryFile: 'server.js',
restartDelay: 1000
});
// Or use the helper function for simpler setup
import { createMCPProxy } from 'mcpmon';
const proxy = await createMCPProxy({
command: 'node',
args: ['server.js'],
watchFile: 'server.js',
restartDelay: 1000,
env: { API_KEY: 'your-key' }
});mcpmon automatically detects which files to watch:
- Looks for the first script file in your arguments (
.js,.mjs,.ts,.py,.rb,.php) - Falls back to current directory if no script file found
- Can be overridden with
MCPMON_WATCHenvironment variable
Watch multiple files or directories:
# Multiple files
MCPMON_WATCH="server.js,config.json,package.json" mcpmon node server.js
# Directories and files
MCPMON_WATCH="src/,config/settings.json,package.json" mcpmon node server.jsAdjust timing for different server types:
# Fast restart for simple servers
MCPMON_DELAY=500 mcpmon node server.js
# Slower restart for complex initialization
MCPMON_DELAY=3000 mcpmon python heavy_server.py{
"mcpServers": {
"my-server": {
"command": "mcpmon",
"args": ["node", "/absolute/path/to/server.js"],
"env": {
"API_KEY": "your-key",
"MCPMON_VERBOSE": "1"
}
}
}
}# Direct usage
npx @modelcontextprotocol/inspector mcpmon node server.js
# With custom environment
API_KEY=your-key MCPMON_VERBOSE=1 \
npx @modelcontextprotocol/inspector mcpmon node server.jsFROM node:18-alpine
COPY . /app
WORKDIR /app
RUN npm install -g mcpmon
# Set environment for development
ENV MCPMON_VERBOSE=1
ENV MCPMON_DELAY=1000
CMD ["mcpmon", "node", "server.js"]# Test without hot-reload in CI
node server.js
# Test with mcpmon but no file watching
MCPMON_WATCH="" mcpmon node server.js| Old (mcp-hmr) | New (mcpmon) |
|---|---|
mcp-hmr --server my-server |
mcpmon node server.js |
mcp-hmr --list |
Not needed |
mcp-hmr --setup my-server |
Not needed |
Old config file approach:
{
"mcpServers": {
"my-server": {
"command": "mcp-hmr",
"args": ["--server", "my-server", "--config", "config.json"]
}
}
}New direct command approach:
{
"mcpServers": {
"my-server": {
"command": "mcpmon",
"args": ["node", "server.js"],
"env": { "API_KEY": "your-key" }
}
}
}Old (mcp-hmr):
MCP_SERVER_COMMAND=node
MCP_SERVER_ARGS=server.js
MCP_WATCH_FILE=server.jsNew (mcpmon):
# Most settings auto-detected from command
mcpmon node server.js
# Override if needed
MCPMON_WATCH=server.js mcpmon node server.js