A Model Context Protocol (MCP) server that provides process management and monitoring capabilities for AI agents, with strict security boundaries enforced by executable allowlists and resource limits.
This package is now maintained in its own repository: https://github.com/Digital-Defiance/mcp-process
This repository is part of the AI Capabilities Suite on GitHub.
- Features
- Security
- Installation
- Quick Start
- Configuration
- MCP Tools
- Usage Examples
- Troubleshooting
- Development
- License
- Process Launching: Spawn processes with specified arguments and environment variables
- Resource Monitoring: Track CPU, memory, thread count, and I/O usage in real-time
- Output Capture: Capture and retrieve stdout and stderr streams separately
- Process Termination: Graceful (SIGTERM) and forced (SIGKILL) termination with timeout escalation
- Service Management: Long-running services with auto-restart and health checks
- Process Groups: Manage related processes and create pipelines
- Timeout Management: Automatic process termination after specified duration
- I/O Management: Send stdin input and retrieve buffered output
- Security: Multi-layer security with executable allowlists, argument validation, and resource limits
- Audit Logging: Complete operation tracking for security and compliance
This server implements defense-in-depth security with 6 layers of validation:
- Executable Allowlist: Only pre-approved executables can be launched
- Argument Validation: Command arguments validated for injection attacks
- Environment Sanitization: Dangerous environment variables removed
- Resource Limits: CPU, memory, and time limits prevent resource exhaustion
- Privilege Prevention: No privilege escalation or setuid executables
- Audit Logging: Complete operation tracking
See SECURITY.md for detailed security implementation.
docker pull digitaldefiance/mcp-process:latestSee DOCKER.md for detailed Docker usage instructions.
npm install @ai-capabilities-suite/mcp-processyarn add @ai-capabilities-suite/mcp-processnpm install -g @ai-capabilities-suite/mcp-process# Pull the image
docker pull digitaldefiance/mcp-process:latest
# Create config directory
mkdir -p config
# Create configuration
cat > config/mcp-process-config.json << EOF
{
"allowedExecutables": ["node", "python3", "npm"],
"maxConcurrentProcesses": 5,
"enableAuditLog": true
}
EOF
# Run with docker-compose
docker-compose up -dSee DOCKER.md for detailed Docker instructions.
mcp-process --create-config ./mcp-process-config.jsonThis creates a sample configuration file with secure defaults.
Edit mcp-process-config.json to add your allowed executables:
{
"allowedExecutables": ["node", "python3", "npm", "git"],
"defaultResourceLimits": {
"maxCpuPercent": 80,
"maxMemoryMB": 1024,
"maxCpuTime": 300
},
"maxConcurrentProcesses": 10,
"maxProcessLifetime": 3600,
"enableAuditLog": true,
"blockShellInterpreters": true,
"blockSetuidExecutables": true,
"allowProcessTermination": true,
"allowGroupTermination": true,
"allowForcedTermination": false,
"allowStdinInput": true,
"allowOutputCapture": true,
"requireConfirmation": false
}mcp-process --config ./mcp-process-config.jsonOr use environment variables:
export MCP_PROCESS_CONFIG_PATH=./mcp-process-config.json
mcp-processConfigure your AI agent (e.g., Kiro, Claude Desktop) to connect to the MCP server via stdio transport.
The server looks for configuration in the following order:
--configcommand line argumentMCP_PROCESS_CONFIG_PATHenvironment variableMCP_PROCESS_CONFIGenvironment variable (JSON string)./mcp-process-config.json./config/mcp-process.json
See SECURITY.md for detailed configuration options and security settings.
{
"allowedExecutables": ["node", "python3"],
"defaultResourceLimits": {
"maxCpuPercent": 80,
"maxMemoryMB": 1024
},
"maxConcurrentProcesses": 10,
"maxProcessLifetime": 3600,
"enableAuditLog": true,
"blockShellInterpreters": true,
"blockSetuidExecutables": true,
"allowProcessTermination": true,
"allowGroupTermination": true,
"allowForcedTermination": false,
"allowStdinInput": true,
"allowOutputCapture": true,
"requireConfirmation": false
}The server exposes 12 MCP tools for process management:
Launch a new process.
Parameters:
executable(string, required): Path to executableargs(string[], optional): Command-line argumentscwd(string, optional): Working directoryenv(object, optional): Environment variablestimeout(number, optional): Timeout in millisecondscaptureOutput(boolean, optional): Whether to capture stdout/stderrresourceLimits(object, optional): Resource limits
Returns:
pid(number): Process IDstartTime(string): ISO timestamp of process start
Terminate a process.
Parameters:
pid(number, required): Process IDforce(boolean, optional): Use SIGKILL instead of SIGTERMtimeout(number, optional): Timeout for graceful termination (ms)
Returns:
exitCode(number): Process exit codeterminationReason(string): "graceful" or "forced"
Get process resource usage statistics.
Parameters:
pid(number, required): Process IDincludeHistory(boolean, optional): Include historical data
Returns:
cpuPercent(number): CPU usage percentagememoryMB(number): Memory usage in MBthreadCount(number): Number of threadsioRead(number): Bytes readioWrite(number): Bytes writtenuptime(number): Process uptime in secondshistory(array, optional): Historical statistics
Send input to process stdin.
Parameters:
pid(number, required): Process IDdata(string, required): Data to sendencoding(string, optional): Text encoding (default: "utf-8")
Returns:
bytesWritten(number): Number of bytes written
Get captured process output.
Parameters:
pid(number, required): Process IDstream(string, optional): "stdout", "stderr", or "both" (default: "both")encoding(string, optional): Text encoding (default: "utf-8")
Returns:
stdout(string): Captured stdoutstderr(string): Captured stderrstdoutBytes(number): Stdout buffer sizestderrBytes(number): Stderr buffer size
List all managed processes.
Returns:
- Array of process information objects with PID, command, state, and uptime
Get detailed process status.
Parameters:
pid(number, required): Process ID
Returns:
state(string): "running", "stopped", or "crashed"uptime(number): Process uptime in secondsstats(object): Current resource usage statistics
Create a process group.
Parameters:
name(string, required): Group namepipeline(boolean, optional): Whether to create a pipeline
Returns:
groupId(string): Group identifier
Add a process to a group.
Parameters:
groupId(string, required): Group identifierpid(number, required): Process ID
Terminate all processes in a group.
Parameters:
groupId(string, required): Group identifier
Start a long-running service with auto-restart.
Parameters:
name(string, required): Service nameexecutable(string, required): Path to executableargs(string[], optional): Command-line argumentscwd(string, optional): Working directoryenv(object, optional): Environment variablesrestartPolicy(object, optional): Restart configurationhealthCheck(object, optional): Health check configuration
Returns:
serviceId(string): Service identifierpid(number): Initial process ID
Stop a service and disable auto-restart.
Parameters:
serviceId(string, required): Service identifier
// Launch a process
const result = await mcpClient.callTool("process_start", {
executable: "node",
args: ["--version"],
captureOutput: true,
});
console.log("Process started:", result.pid);
// Wait a moment for it to complete
await new Promise((resolve) => setTimeout(resolve, 1000));
// Get output
const output = await mcpClient.callTool("process_get_output", {
pid: result.pid,
});
console.log("Output:", output.stdout);// Start a process
const result = await mcpClient.callTool("process_start", {
executable: "python3",
args: ["my_script.py"],
resourceLimits: {
maxCpuPercent: 50,
maxMemoryMB: 512,
},
});
// Monitor resources
const stats = await mcpClient.callTool("process_get_stats", {
pid: result.pid,
includeHistory: true,
});
console.log("CPU:", stats.cpuPercent + "%");
console.log("Memory:", stats.memoryMB + "MB");// Start an interactive process
const result = await mcpClient.callTool("process_start", {
executable: "python3",
args: ["-i"],
captureOutput: true,
});
// Send input
await mcpClient.callTool("process_send_stdin", {
pid: result.pid,
data: 'print("Hello from AI agent")\n',
});
// Wait and get output
await new Promise((resolve) => setTimeout(resolve, 500));
const output = await mcpClient.callTool("process_get_output", {
pid: result.pid,
});
console.log("Output:", output.stdout);// Start a service with auto-restart
const service = await mcpClient.callTool("process_start_service", {
name: "my-api-server",
executable: "node",
args: ["server.js"],
restartPolicy: {
enabled: true,
maxRetries: 3,
backoffMs: 5000,
},
healthCheck: {
command: "curl http://localhost:3000/health",
interval: 30000,
timeout: 5000,
},
});
console.log("Service started:", service.serviceId);// Create a process group
const group = await mcpClient.callTool("process_create_group", {
name: "data-pipeline",
pipeline: true,
});
// Start first process
const proc1 = await mcpClient.callTool("process_start", {
executable: "cat",
args: ["data.txt"],
captureOutput: true,
});
// Add to group
await mcpClient.callTool("process_add_to_group", {
groupId: group.groupId,
pid: proc1.pid,
});
// Start second process (will receive output from first)
const proc2 = await mcpClient.callTool("process_start", {
executable: "grep",
args: ["pattern"],
captureOutput: true,
});
await mcpClient.callTool("process_add_to_group", {
groupId: group.groupId,
pid: proc2.pid,
});Cause: The executable you're trying to launch is not in the allowedExecutables configuration.
Solution: Add the executable to your configuration file:
{
"allowedExecutables": ["node", "python3", "/path/to/your/executable"]
}You can use:
- Absolute paths:
/usr/bin/node - Basenames:
node - Glob patterns:
/usr/bin/*
Cause: You're trying to launch a shell (bash, sh, cmd.exe, etc.) and blockShellInterpreters is enabled.
Solution: Either:
- Set
blockShellInterpreters: falsein your configuration (not recommended) - Launch the actual executable directly instead of through a shell
Cause: The process has already terminated or the PID is invalid.
Solution: Check if the process is still running using process_list or process_get_status.
Cause: The process exceeded configured resource limits.
Solution: Increase resource limits in your configuration or when launching the process:
{
"defaultResourceLimits": {
"maxCpuPercent": 90,
"maxMemoryMB": 2048
}
}Cause: You've reached the maxConcurrentProcesses limit.
Solution:
- Terminate some running processes
- Increase
maxConcurrentProcessesin your configuration - Wait for processes to complete
Cause: The process stdin is closed or the process doesn't support stdin input.
Solution: Ensure the process is still running and was started with stdin enabled.
Cause: The server can't find your configuration file.
Solution:
- Use
--configflag:mcp-process --config /path/to/config.json - Set environment variable:
export MCP_PROCESS_CONFIG_PATH=/path/to/config.json - Place config at
./mcp-process-config.json
Enable debug logging by setting the audit log level:
{
"enableAuditLog": true,
"auditLogLevel": "debug"
}Check the audit log for detailed information about process operations and security violations.
- Node.js >= 18.0.0
- npm >= 8.0.0
# Clone the repository
git clone https://github.com/digital-defiance/ai-capabilities-suite.git
cd ai-capabilities-suite/packages/mcp-process
# Install dependencies
npm install
# Build
npm run build# Run all tests (unit, integration, and e2e)
npm test
# Run tests with coverage
npm run test:coverage
# Run tests in watch mode
npm run test:watch
# Run specific test file
npm test -- SecurityManager.spec.ts
# Run only e2e tests
npm run test:e2e
# Run minimal e2e smoke tests (quick validation)
npm run test:e2e:minimalThe MCP ACS Process Server includes comprehensive e2e tests that validate the complete system behavior by spawning the server as a child process and communicating via stdio using JSON-RPC protocol. These tests ensure the server works correctly in real-world usage scenarios.
E2E Test Structure:
server.e2e.spec.ts- Comprehensive e2e tests covering all MCP tools and protocol featuresserver.minimal.e2e.spec.ts- Quick smoke tests for basic functionality validation (< 30 seconds)
Running E2E Tests:
# Run comprehensive e2e tests
npm run test:e2e
# Run minimal smoke tests for quick feedback
npm run test:e2e:minimal
# Run e2e tests with specific pattern
npm test -- --testPathPattern=e2e.spec.ts
# Run e2e tests with verbose output
npm test -- --testPathPattern=e2e.spec.ts --verboseWhat E2E Tests Validate:
- MCP protocol initialization and handshake
- Tool discovery via tools/list
- Process launch operations with security enforcement
- Process monitoring and resource statistics
- Process termination (graceful and forced)
- Output capture (stdout/stderr)
- Service management with auto-restart
- Error handling and validation
- Security policy enforcement
- Resource limit enforcement
- Timeout handling
- JSON-RPC protocol compliance
E2E Test Requirements:
- The server must be built before running e2e tests:
npm run build - Tests spawn the server from
dist/cli.js - Tests communicate via stdio using JSON-RPC 2.0 protocol
- All spawned processes are cleaned up after tests complete
Debugging E2E Test Failures:
If e2e tests fail, follow these steps:
-
Ensure the server is built:
npm run build
-
Check if the CLI exists:
ls -la dist/cli.js
-
Run tests with verbose output:
npm test -- --testPathPattern=e2e.spec.ts --verbose -
Check for server startup errors:
- E2E tests capture server stderr output
- Look for error messages in test output
- Common issues: missing dependencies, permission errors, port conflicts
-
Verify server can start manually:
node dist/cli.js --help
-
Run minimal tests first:
npm run test:e2e:minimal
If minimal tests pass but comprehensive tests fail, the issue is likely with specific functionality rather than basic server operation.
-
Check process cleanup:
# List any orphaned node processes ps aux | grep node
-
Enable debug logging: Set
DEBUG=*environment variable to see detailed logs:DEBUG=* npm test -- --testPathPattern=e2e.spec.ts
Common E2E Test Issues:
| Issue | Cause | Solution |
|---|---|---|
| "Server executable not found" | Server not built or wrong path | Run npm run build |
| "Server failed to start" | Server crash on startup | Check stderr output in test logs |
| "Request timeout" | Server not responding | Increase timeout or check server logs |
| "Process not cleaned up" | Test cleanup failure | Run npm test -- --forceExit |
| "Port already in use" | Previous test didn't clean up | Kill orphaned processes |
| "Permission denied" | Insufficient permissions | Check file permissions on dist/cli.js |
CI Environment Considerations:
E2E tests are designed to run in CI environments with the following considerations:
- Headless operation: No display server required
- Timeout adjustments: CI environments get 50% longer timeouts
- Process cleanup: All processes cleaned up even on test failure
- No interactive input: Tests run fully automated
- Resource constraints: Tests handle slower CI environments gracefully
CI Configuration Example:
# .github/workflows/test.yml
- name: Build
run: npm run build
- name: Run minimal e2e tests
run: npm run test:e2e:minimal
- name: Run full test suite
run: npm test
env:
CI: trueProperty-Based Testing:
E2E tests include property-based tests using fast-check to validate universal properties:
- JSON-RPC request/response ID matching
- Concurrent request handling
- Process launch with random allowed executables
- Security rejection for blocked executables
These tests run multiple iterations with randomly generated inputs to ensure correctness across a wide range of scenarios.
npm run lint# Clean build directory
npm run clean
# Build TypeScript
npm run build# Publish to npm (requires authentication)
npm run publish:publicThe MCP ACS Process Server consists of several core components:
- MCPServer: Main server implementing MCP protocol
- SecurityManager: Multi-layer security validation
- ProcessLauncher: Process spawning and configuration
- ProcessManager: Process lifecycle management
- ResourceMonitor: CPU, memory, and I/O monitoring
- IOManager: Stdin/stdout/stderr handling
- ProcessTerminator: Graceful and forced termination
- ServiceManager: Long-running service management
- TimeoutManager: Process timeout enforcement
- ProcessGroup: Process group and pipeline management
- ConfigLoader: Configuration file loading and validation
Contributions are welcome! Please see the main repository for contribution guidelines: https://github.com/digital-defiance/ai-capabilities-suite
MIT License - see LICENSE file for details.
- GitHub Issues: https://github.com/digital-defiance/ai-capabilities-suite/issues
- Email: [email protected]
- MCP Filesystem - Filesystem operations for AI agents
- MCP Recording - Session recording and playback
- MCP ACS Debugger - MCP protocol debugging tools
Built with:
- @modelcontextprotocol/sdk - MCP protocol implementation
- pidusage - Process resource monitoring
- which - Executable path resolution
- minimatch - Glob pattern matching