{"_id":"@anonx3247/process-mcp","_rev":"6-c330c24aaf5e54b3d88da9a2982314cb","name":"@anonx3247/process-mcp","dist-tags":{"latest":"1.0.5"},"versions":{"1.0.0":{"name":"@anonx3247/process-mcp","version":"1.0.0","keywords":["mcp","model-context-protocol","process","process-management","docker","sandbox","executor","claude"],"author":"","license":"ISC","_id":"@anonx3247/process-mcp@1.0.0","maintainers":[{"name":"anonx3247","email":"anas@lecaillon.com"}],"homepage":"https://github.com/anonx3247/process-mcp#readme","bugs":{"url":"https://github.com/anonx3247/process-mcp/issues"},"bin":{"process-mcp":"dist/index.js"},"dist":{"shasum":"6afdc3c8fb5c5245cdbd7ca1c029489757b511dc","tarball":"https://registry.npmjs.org/@anonx3247/process-mcp/-/process-mcp-1.0.0.tgz","fileCount":51,"integrity":"sha512-wjOU+GVI2wyHjw/gQP4UPmBDjWu7zoTfGY8g9M/m+EPJxlKbE8PUcg7fAfX1ugqCFFJBMZtJQKSKzjPFfknu8Q==","signatures":[{"sig":"MEUCIDNE3iZC+vOXvYGFy8wub+YCaoECY80kCrJjjFD3984gAiEAsce6RGNfGdvX2x+c73mFQasD4g22KtbmLc8GrsyZJU8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":120589},"main":"dist/lib.js","type":"module","types":"dist/lib.d.ts","exports":{".":{"types":"./dist/lib.d.ts","import":"./dist/lib.js"},"./config":{"types":"./dist/config.d.ts","import":"./dist/config.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.js"}},"gitHead":"45c873eef93e64e864380261a6072850a9c179b9","scripts":{"dev":"tsx src/index.ts","test":"echo \"Error: no test specified\" && exit 1","build":"tsc","start":"node dist/index.js","typecheck":"tsc --noEmit"},"_npmUser":{"name":"anonx3247","email":"anas@lecaillon.com"},"repository":{"url":"git+https://github.com/anonx3247/process-mcp.git","type":"git"},"_npmVersion":"11.5.1","description":"Multi-process management docker-connected MCP server","directories":{},"_nodeVersion":"24.7.0","dependencies":{"zod":"^4.3.6","dockerode":"^4.0.9","tar-stream":"^3.1.7","@xterm/headless":"^6.0.0","@modelcontextprotocol/sdk":"^1.25.3","@anthropic-ai/sandbox-runtime":"^0.0.32"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","typescript":"^5.9.3","@types/node":"^25.1.0","@types/dockerode":"^4.0.1","@types/tar-stream":"^3.1.4"},"_npmOperationalInternal":{"tmp":"tmp/process-mcp_1.0.0_1769789132623_0.4249765236642493","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@anonx3247/process-mcp","version":"1.0.1","keywords":["mcp","model-context-protocol","process","process-management","docker","sandbox","executor","claude"],"author":"","license":"ISC","_id":"@anonx3247/process-mcp@1.0.1","maintainers":[{"name":"anonx3247","email":"anas@lecaillon.com"}],"homepage":"https://github.com/anonx3247/process-mcp#readme","bugs":{"url":"https://github.com/anonx3247/process-mcp/issues"},"bin":{"process-mcp":"dist/index.js"},"dist":{"shasum":"3fc0058263123319f304c1c06828ece5787ad880","tarball":"https://registry.npmjs.org/@anonx3247/process-mcp/-/process-mcp-1.0.1.tgz","fileCount":51,"integrity":"sha512-zXbieS/R74Dp+GKYZPo6XtibPI5XflVIxU9BMRcygeGC5o3hT3UPNut6+EhzDF5h4ulfstRViyhd5TjcgzM1Kw==","signatures":[{"sig":"MEYCIQChpEgaEylx9FJjyfrETgvRopyHZK8h+LyyMzwUdAw4WAIhAN1tQLnwXundadoXORmKaav8zlge9OoRmpzMQuXgIIkG","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":120589},"main":"dist/lib.js","type":"module","types":"dist/lib.d.ts","exports":{".":{"types":"./dist/lib.d.ts","import":"./dist/lib.js"},"./config":{"types":"./dist/config.d.ts","import":"./dist/config.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.js"}},"gitHead":"45c873eef93e64e864380261a6072850a9c179b9","scripts":{"dev":"tsx src/index.ts","test":"echo \"Error: no test specified\" && exit 1","build":"tsc","start":"node dist/index.js","typecheck":"tsc --noEmit"},"_npmUser":{"name":"anonx3247","email":"anas@lecaillon.com"},"repository":{"url":"git+https://github.com/anonx3247/process-mcp.git","type":"git"},"_npmVersion":"11.6.2","description":"Multi-process management docker-connected MCP server","directories":{},"_nodeVersion":"24.12.0","dependencies":{"zod":"^4.3.6","dockerode":"^4.0.9","tar-stream":"^3.1.7","@xterm/headless":"^6.0.0","@modelcontextprotocol/sdk":"^1.25.3","@anthropic-ai/sandbox-runtime":"^0.0.32"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","typescript":"^5.9.3","@types/node":"^25.1.0","@types/dockerode":"^4.0.1","@types/tar-stream":"^3.1.4"},"_npmOperationalInternal":{"tmp":"tmp/process-mcp_1.0.1_1769889240557_0.1975383854199586","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@anonx3247/process-mcp","version":"1.0.2","keywords":["mcp","model-context-protocol","process","process-management","docker","sandbox","executor","claude"],"author":"","license":"ISC","_id":"@anonx3247/process-mcp@1.0.2","maintainers":[{"name":"anonx3247","email":"anas@lecaillon.com"}],"homepage":"https://github.com/anonx3247/process-mcp#readme","bugs":{"url":"https://github.com/anonx3247/process-mcp/issues"},"bin":{"process-mcp":"dist/index.js"},"dist":{"shasum":"c17443f8f0737be52daea65c0a6ee96e9ede147c","tarball":"https://registry.npmjs.org/@anonx3247/process-mcp/-/process-mcp-1.0.2.tgz","fileCount":51,"integrity":"sha512-3cVSaojfVUnN+WFGsfTRUZ9z33NxCqUH/aP4zezjsF5vIF5fw7DfxTwjRdRPkm5I8vIiNQ/rylVy8zpNlJ2oiQ==","signatures":[{"sig":"MEYCIQDkRyvfBjfyeHFkg336mj/ho9jGbuuIMTui12JQV6Q9oQIhAIPuKBKjNJFUQfS/eCcX51tXrN1DVg6vcj1GY6brprJc","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":112630},"main":"dist/lib.js","type":"module","types":"dist/lib.d.ts","exports":{".":{"types":"./dist/lib.d.ts","import":"./dist/lib.js"},"./config":{"types":"./dist/config.d.ts","import":"./dist/config.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.js"}},"gitHead":"5ff79236e535a37c34f7fd6e2eeee72922d5415c","scripts":{"dev":"tsx src/index.ts","test":"echo \"Error: no test specified\" && exit 1","build":"tsc","start":"node dist/index.js","typecheck":"tsc --noEmit"},"_npmUser":{"name":"anonx3247","email":"anas@lecaillon.com"},"repository":{"url":"git+https://github.com/anonx3247/process-mcp.git","type":"git"},"_npmVersion":"11.6.2","description":"Multi-process management docker-connected MCP server","directories":{},"_nodeVersion":"24.12.0","dependencies":{"zod":"^4.3.6","dockerode":"^4.0.9","tar-stream":"^3.1.7","@xterm/headless":"^6.0.0","@modelcontextprotocol/sdk":"^1.25.3","@anthropic-ai/sandbox-runtime":"^0.0.32"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","typescript":"^5.9.3","@types/node":"^25.1.0","@types/dockerode":"^4.0.1","@types/tar-stream":"^3.1.4"},"_npmOperationalInternal":{"tmp":"tmp/process-mcp_1.0.2_1769897161086_0.031953048604203005","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@anonx3247/process-mcp","version":"1.0.3","keywords":["mcp","model-context-protocol","process","process-management","docker","sandbox","executor","claude"],"author":"","license":"ISC","_id":"@anonx3247/process-mcp@1.0.3","maintainers":[{"name":"anonx3247","email":"anas@lecaillon.com"}],"homepage":"https://github.com/anonx3247/process-mcp#readme","bugs":{"url":"https://github.com/anonx3247/process-mcp/issues"},"bin":{"process-mcp":"dist/index.js"},"dist":{"shasum":"e6f6f52610fadcf64b1481bd194a6da39db1368b","tarball":"https://registry.npmjs.org/@anonx3247/process-mcp/-/process-mcp-1.0.3.tgz","fileCount":51,"integrity":"sha512-zYwII/GeAlZzoEMoKnIQFt4FUwQDpQBU5fU7tPiQlgkoFpf/YYGNgngXBrnM/3YSn84U9rdmTKgYLIbWH8A6xg==","signatures":[{"sig":"MEUCIQC+/n/r9yphhRjrZ1A6yJAwdpWo5uLQ3QgMBQFvpauveAIgPsQmNDuOHgyE75LB7BEa4axWa0JQqdqUi5OVk/YdGs4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":112682},"main":"dist/lib.js","type":"module","types":"dist/lib.d.ts","exports":{".":{"types":"./dist/lib.d.ts","import":"./dist/lib.js"},"./config":{"types":"./dist/config.d.ts","import":"./dist/config.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.js"}},"gitHead":"b0d0d10c0d8b09e5f7179eb140e50905c0f36b03","scripts":{"dev":"tsx src/index.ts","test":"echo \"Error: no test specified\" && exit 1","build":"tsc","start":"node dist/index.js","typecheck":"tsc --noEmit"},"_npmUser":{"name":"anonx3247","email":"anas@lecaillon.com"},"repository":{"url":"git+https://github.com/anonx3247/process-mcp.git","type":"git"},"_npmVersion":"11.6.2","description":"Multi-process management docker-connected MCP server","directories":{},"_nodeVersion":"24.12.0","dependencies":{"zod":"^4.3.6","dockerode":"^4.0.9","tar-stream":"^3.1.7","@xterm/headless":"^6.0.0","@modelcontextprotocol/sdk":"^1.25.3","@anthropic-ai/sandbox-runtime":"^0.0.32"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","typescript":"^5.9.3","@types/node":"^25.1.0","@types/dockerode":"^4.0.1","@types/tar-stream":"^3.1.4"},"_npmOperationalInternal":{"tmp":"tmp/process-mcp_1.0.3_1769904232242_0.4816441442093016","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"@anonx3247/process-mcp","version":"1.0.4","keywords":["mcp","model-context-protocol","process","process-management","docker","sandbox","executor","claude"],"author":"","license":"ISC","_id":"@anonx3247/process-mcp@1.0.4","maintainers":[{"name":"anonx3247","email":"anas@lecaillon.com"}],"homepage":"https://github.com/anonx3247/process-mcp#readme","bugs":{"url":"https://github.com/anonx3247/process-mcp/issues"},"bin":{"process-mcp":"dist/index.js"},"dist":{"shasum":"87be9855fc57110d76f1ff13dbb73dcebb7624f2","tarball":"https://registry.npmjs.org/@anonx3247/process-mcp/-/process-mcp-1.0.4.tgz","fileCount":51,"integrity":"sha512-Vo/UbaatVZQtV2hStHx+mR4UT/ekBbMKqcmIDv1mZ/kfvilLfvC9Qmh/qjFCHRfNU6EsKCnDmMyHktkSIwYshQ==","signatures":[{"sig":"MEUCIQCWdegCCd9P5v/SfrU4RjxhRY6py4HKP3cL3ZsLZKHzOgIgGjXe4at5dgjJ5Vv5ye+WLmEngcFJv/nYSvpl8zw9O4w=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":112724},"main":"dist/lib.js","type":"module","types":"dist/lib.d.ts","exports":{".":{"types":"./dist/lib.d.ts","import":"./dist/lib.js"},"./config":{"types":"./dist/config.d.ts","import":"./dist/config.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.js"}},"gitHead":"1e3666047ed9d925756147085afe34be3ebf9c59","scripts":{"dev":"tsx src/index.ts","test":"echo \"Error: no test specified\" && exit 1","build":"tsc","start":"node dist/index.js","typecheck":"tsc --noEmit"},"_npmUser":{"name":"anonx3247","email":"anas@lecaillon.com"},"repository":{"url":"git+https://github.com/anonx3247/process-mcp.git","type":"git"},"_npmVersion":"11.6.2","description":"Multi-process management docker-connected MCP server","directories":{},"_nodeVersion":"24.12.0","dependencies":{"zod":"^4.3.6","dockerode":"^4.0.9","tar-stream":"^3.1.7","@xterm/headless":"^6.0.0","@modelcontextprotocol/sdk":"^1.25.3","@anthropic-ai/sandbox-runtime":"^0.0.32"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","typescript":"^5.9.3","@types/node":"^25.1.0","@types/dockerode":"^4.0.1","@types/tar-stream":"^3.1.4"},"_npmOperationalInternal":{"tmp":"tmp/process-mcp_1.0.4_1769904433672_0.0017374049784675272","host":"s3://npm-registry-packages-npm-production"}},"1.0.5":{"name":"@anonx3247/process-mcp","version":"1.0.5","description":"Multi-process management docker-connected MCP server","main":"dist/lib.js","types":"dist/lib.d.ts","bin":{"process-mcp":"dist/index.js"},"exports":{".":{"import":"./dist/lib.js","types":"./dist/lib.d.ts"},"./server":{"import":"./dist/server.js","types":"./dist/server.d.ts"},"./config":{"import":"./dist/config.js","types":"./dist/config.d.ts"}},"scripts":{"build":"tsc","dev":"tsx src/index.ts","start":"node dist/index.js","typecheck":"tsc --noEmit","test":"npm run build && node --import tsx --test test/**/*.test.ts"},"repository":{"type":"git","url":"git+https://github.com/anonx3247/process-mcp.git"},"keywords":["mcp","model-context-protocol","process","process-management","docker","sandbox","executor","claude"],"author":"","license":"ISC","type":"module","bugs":{"url":"https://github.com/anonx3247/process-mcp/issues"},"homepage":"https://github.com/anonx3247/process-mcp#readme","dependencies":{"@anthropic-ai/sandbox-runtime":"^0.0.32","@modelcontextprotocol/sdk":"^1.25.3","@xterm/headless":"^6.0.0","dockerode":"^4.0.9","tar-stream":"^3.1.7","zod":"^4.3.6"},"devDependencies":{"@types/dockerode":"^4.0.1","@types/node":"^25.1.0","@types/tar-stream":"^3.1.4","tsx":"^4.21.0","typescript":"^5.9.3"},"gitHead":"3f47fbff18ebe9300f9ed00287f89e29d67e8be2","_id":"@anonx3247/process-mcp@1.0.5","_nodeVersion":"24.12.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-1MRbCPGydvhV1uPSmv0+ETb8EBefpT3cgMx8/XMID2J3KXzp7wRWb/WVgo/NSA2e+BgAHxJxXDiIpQKoR499HQ==","shasum":"555eff4acf3b0542d298105802f0270d026dd17f","tarball":"https://registry.npmjs.org/@anonx3247/process-mcp/-/process-mcp-1.0.5.tgz","fileCount":51,"unpackedSize":112854,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIG7hFEB6WK/XwVbAH4DyWTwGvG1rFyu+ldeoIjNSmz/AAiEA4O9UJDsvwn9Y9jZ3wQjV4HSEc8Wrq8HwN1OuQRj8Bfc="}]},"_npmUser":{"name":"anonx3247","email":"anas@lecaillon.com"},"directories":{},"maintainers":[{"name":"anonx3247","email":"anas@lecaillon.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/process-mcp_1.0.5_1769905661859_0.45988810007185976"},"_hasShrinkwrap":false}},"time":{"created":"2026-01-30T16:05:32.571Z","modified":"2026-02-01T00:27:42.123Z","1.0.0":"2026-01-30T16:05:32.755Z","1.0.1":"2026-01-31T19:54:00.698Z","1.0.2":"2026-01-31T22:06:01.230Z","1.0.3":"2026-02-01T00:03:52.426Z","1.0.4":"2026-02-01T00:07:13.832Z","1.0.5":"2026-02-01T00:27:42.005Z"},"bugs":{"url":"https://github.com/anonx3247/process-mcp/issues"},"license":"ISC","homepage":"https://github.com/anonx3247/process-mcp#readme","keywords":["mcp","model-context-protocol","process","process-management","docker","sandbox","executor","claude"],"repository":{"type":"git","url":"git+https://github.com/anonx3247/process-mcp.git"},"description":"Multi-process management docker-connected MCP server","maintainers":[{"name":"anonx3247","email":"anas@lecaillon.com"}],"readme":"# Process MCP Server\n\nAn MCP (Model Context Protocol) server and library that provides process management capabilities with two execution modes:\n\n1. **Host mode**: Executes processes directly on the host system with sandboxing via `@anthropic-ai/sandbox-runtime`\n2. **Docker mode**: Executes processes in an isolated Docker container\n\n**Use as:**\n- 🔌 **MCP Server** - Standalone server for Claude Desktop and other MCP clients\n- 📦 **Library** - Import into your Node.js applications with `createProcessMCP()`\n\nThe server exposes 5 MCP tools for spawning, monitoring, and controlling long-running processes, with support for interactive TTY sessions, stdin/stdout/stderr handling, and background execution.\n\n## Features\n\n- Dual execution modes (host/docker)\n- TTY support for interactive applications (vim, python REPL, etc.)\n- Background process execution\n- Automatic timeout handling\n- Stdin interaction with escape sequence parsing\n- Output buffering with configurable limits\n- Process registry with cleanup\n- Security sandboxing (host mode) or container isolation (docker mode)\n\n## Installation\n\n### As a Standalone MCP Server\n\n```bash\ngit clone <repository-url>\ncd process-mcp\nnpm install\nnpm run build\n```\n\n### As a Library in Your Project\n\n```bash\nnpm install process-mcp\n```\n\nOr if installing from a local directory:\n```bash\nnpm install /path/to/process-mcp\n```\n\n### Optional Dependencies\n\nFor host mode with sandboxing enabled:\n- **ripgrep**: Required for sandbox-runtime file system monitoring\n  ```bash\n  # macOS\n  brew install ripgrep\n\n  # Ubuntu/Debian\n  apt install ripgrep\n\n  # Other systems\n  # See: https://github.com/BurntSushi/ripgrep#installation\n  ```\n\nIf ripgrep is not installed, the server will run without sandboxing features but processes will still execute normally.\n\n## Usage\n\n### Library Usage\n\nYou can use process-mcp as a library in your own Node.js applications:\n\n```typescript\nimport { createProcessMCP } from 'process-mcp';\n\n// Create server with host mode\nconst { server, executor, cleanup } = await createProcessMCP({\n  mode: 'host',\n  defaults: {\n    workdir: '/tmp',\n    timeoutMs: 10000,\n    maxTimeoutMs: 60000,\n  },\n});\n\n// Option 1: Use with MCP protocol\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nconst transport = new StdioServerTransport();\nawait server.connect(transport);\n\n// Option 2: Use executor directly (without MCP protocol)\nconst result = await executor.spawn({\n  command: 'echo \"Hello World\"',\n  cwd: '/tmp',\n  background: false,\n});\n\nif (result.success) {\n  console.log(result.value.stdout);\n}\n\n// List processes\nconst processes = executor.listProcesses();\n\n// Get output\nconst output = executor.getOutput(pid, 100);\n\n// Kill process\nawait executor.kill(pid, 'SIGTERM');\n\n// Cleanup when done\nawait cleanup();\n```\n\n**Docker Mode Example:**\n\n```typescript\nconst { server, executor, cleanup } = await createProcessMCP({\n  mode: 'docker',\n  docker: {\n    image: 'python:3.11',\n    containerName: 'my-container',\n    volumeName: 'my-volume',\n    useExisting: false,\n  },\n  defaults: {\n    workdir: '/workspace',\n    timeoutMs: 10000,\n    maxTimeoutMs: 60000,\n  },\n});\n```\n\n**See `examples/` directory for more usage examples:**\n- `examples/simple-example.js` - Basic usage\n- `examples/library-usage.ts` - Comprehensive examples including HTTP server integration\n\n### Standalone Server\n\n#### Host Mode (Default)\n\n```bash\nPROCESS_MODE=host npm start\n```\n\nHost mode uses `@anthropic-ai/sandbox-runtime` for OS-level sandboxing. Configure security restrictions via environment variables:\n\n- `SANDBOX_ALLOWED_DOMAINS`: Comma-separated list of allowed network domains (default: `*` for all)\n- `SANDBOX_ALLOW_WRITE`: Additional paths for write access\n- `SANDBOX_DENY_READ`: Paths to block reads\n- `SANDBOX_DENY_WRITE`: Paths to block writes\n\nExample:\n```bash\nPROCESS_MODE=host \\\nSANDBOX_ALLOWED_DOMAINS=\"github.com,api.openai.com\" \\\nSANDBOX_DENY_READ=\"/etc/shadow,/root\" \\\nnpm start\n```\n\n#### Docker Mode\n\n```bash\nPROCESS_MODE=docker npm start\n```\n\nDocker mode creates a single long-running container and executes all processes via `docker exec`.\n\n**Important**: Docker mode uses **existing Docker images** - no Dockerfile is required by default. The server will pull the specified image from Docker Hub if not available locally.\n\n**Configuration via environment variables:**\n- `DOCKER_IMAGE`: Docker image to use (default: `ubuntu:22.04`)\n- `DOCKER_VOLUME`: Volume name for persistence (default: `process-mcp-volume`)\n- `DOCKER_CONTAINER`: Container name (default: `process-mcp-main`)\n- `DOCKER_USE_EXISTING`: Use existing container instead of creating new one (default: `false`)\n\n**Using different images:**\n```bash\n# Python environment\nPROCESS_MODE=docker DOCKER_IMAGE=\"python:3.11\" npm start\n\n# Node.js environment\nPROCESS_MODE=docker DOCKER_IMAGE=\"node:20\" npm start\n\n# Alpine Linux (smaller)\nPROCESS_MODE=docker DOCKER_IMAGE=\"alpine:latest\" npm start\n```\n\n**Custom Image (Optional)**\n\nIf you want a pre-configured environment with additional tools, build the included Dockerfile:\n\n```bash\n# Build custom image\ndocker build -t process-mcp:custom .\n\n# Use custom image\nPROCESS_MODE=docker DOCKER_IMAGE=\"process-mcp:custom\" npm start\n```\n\nThe custom image includes:\n- Ubuntu 22.04 base\n- Python 3, pip, venv\n- Node.js 20.x\n- Git, vim, curl, wget\n- Build tools (gcc, make, etc.)\n- Common utilities (htop, jq, tree)\n\n**Using an Existing Container**\n\nIf you already have a running container with your desired environment and volumes, you can use it directly:\n\n```bash\n# First, ensure your container is running\ndocker run -d \\\n  --name my-dev-container \\\n  -v my-project:/workspace \\\n  -w /workspace \\\n  ubuntu:22.04 \\\n  tail -f /dev/null\n\n# Then point process-mcp to use it\nPROCESS_MODE=docker \\\nDOCKER_USE_EXISTING=true \\\nDOCKER_CONTAINER=my-dev-container \\\nnpm start\n```\n\n**Benefits of using existing containers:**\n- Preserve existing environment setup (installed packages, configurations)\n- Share volumes with other tools/processes\n- Reuse containers from docker-compose or other orchestration\n- Maintain state between server restarts\n\n**Note**: When `DOCKER_USE_EXISTING=true`, the server will:\n- Use the existing container without modification\n- Start it if stopped\n- Fail with an error if the container doesn't exist\n- Never create, remove, or modify the container (you maintain full control)\n\n**Quick Start**: See `example-custom-container.sh` for a complete example of creating and using a custom container.\n\n### MCP Client Configuration\n\nTo use this server with an MCP client (like Claude Desktop), add it to your MCP configuration file:\n\n```json\n{\n  \"mcpServers\": {\n    \"process\": {\n      \"command\": \"node\",\n      \"args\": [\"/absolute/path/to/process-mcp/dist/index.js\"],\n      \"env\": {\n        \"PROCESS_MODE\": \"host\"\n      }\n    }\n  }\n}\n```\n\nSee `mcp-config-example.json` for more configuration examples including Docker mode.\n\n**Common MCP client configuration locations:**\n- Claude Desktop (macOS): `~/Library/Application Support/Claude/claude_desktop_config.json`\n- Claude Desktop (Windows): `%APPDATA%\\Claude\\claude_desktop_config.json`\n\n## Library API\n\n### Main Export\n\n#### `createProcessMCP(config: ProcessMcpConfig): Promise<ProcessMcpServer>`\n\nCreates and initializes a Process MCP server.\n\n**Returns:**\n```typescript\n{\n  server: Server;        // MCP server instance\n  executor: ProcessExecutor; // Process executor\n  cleanup: () => Promise<void>; // Cleanup function\n}\n```\n\n### Configuration Types\n\n```typescript\ninterface ProcessMcpConfig {\n  mode: 'host' | 'docker';\n\n  // Sandbox config (host mode only)\n  sandbox?: {\n    network: {\n      allowedDomains: string[];\n      deniedDomains: string[];\n    };\n    filesystem: {\n      allowWrite: string[];\n      denyRead: string[];\n      denyWrite: string[];\n    };\n  };\n\n  // Docker config (docker mode only)\n  docker?: {\n    image: string;\n    containerName: string;\n    volumeName: string;\n    useExisting: boolean;\n  };\n\n  // Default settings\n  defaults: {\n    workdir: string;\n    timeoutMs: number;\n    maxTimeoutMs: number;\n  };\n}\n```\n\n### Executor Methods\n\n```typescript\ninterface ProcessExecutor {\n  // Spawn a process\n  spawn(options: SpawnOptions): Promise<Result<SpawnResult>>;\n\n  // Send input to TTY process\n  stdin(pid: string, input: string): Promise<Result<void>>;\n\n  // Get process by PID\n  getProcess(pid: string): Result<Process>;\n\n  // List all processes\n  listProcesses(): ProcessInfo[];\n\n  // Get process output\n  getOutput(pid: string, lines?: number): Result<{ stdout: string; stderr: string }>;\n\n  // Kill process\n  kill(pid: string, signal?: string): Promise<Result<void>>;\n\n  // Cleanup\n  cleanup(): Promise<void>;\n}\n```\n\n### Other Exports\n\n```typescript\n// Load config from environment\nimport { loadConfig } from 'process-mcp/config';\n\n// Executor implementations\nimport { HostExecutor, DockerExecutor } from 'process-mcp';\n\n// Types\nimport type {\n  ProcessMcpConfig,\n  ProcessExecutor,\n  Process,\n  SpawnOptions,\n  ProcessInfo,\n  SpawnResult,\n  Result,\n} from 'process-mcp';\n\n// Constants\nimport {\n  DEFAULT_TIMEOUT_MS,  // 10000\n  MAX_TIMEOUT_MS,      // 60000\n  OUTPUT_TRUNCATE,     // 8196\n  TERMINAL_COLS,       // 120\n  TERMINAL_ROWS,       // 30\n} from 'process-mcp';\n```\n\n## MCP Tools\n\n### 1. spawn\n\nExecute a command with optional timeout. Processes exceeding timeout automatically move to background.\n\n**Parameters:**\n- `command` (string, required): The command to execute\n- `cwd` (string, optional): Working directory (default: `/home/agent`)\n- `env` (object, optional): Environment variables\n- `tty` (boolean, optional): Enable TTY mode for interactive applications\n- `background` (boolean, optional): Run in background (bypass timeout)\n- `timeoutMs` (number, optional): Timeout in milliseconds (default: 10000, max: 60000)\n\n**Returns:**\n- `pid`: Process ID\n- `status`: \"running\" or \"terminated\"\n- `exitCode`: Exit code (if terminated)\n- `stdout`: Stdout output (truncated to 8196 chars)\n- `stderr`: Stderr output (truncated to 8196 chars)\n\n**Example:**\n```json\n{\n  \"command\": \"python -c 'print(\\\"hello\\\")'\",\n  \"tty\": false,\n  \"timeoutMs\": 5000\n}\n```\n\n### 2. ps\n\nList all running and recently terminated processes.\n\n**Returns:** Array of process info objects with:\n- `pid`: Process ID\n- `command`: Command that was executed\n- `status`: \"running\" or \"terminated\"\n- `exitCode`: Exit code (if terminated)\n- `cwd`: Working directory\n- `tty`: Whether TTY mode is enabled\n- `createdAt`: Creation timestamp\n\n### 3. stdin\n\nSend input to an interactive process (TTY mode only).\n\n**Parameters:**\n- `id` (string, required): Process ID\n- `input` (string, required): Input to send\n\n**Escape sequences:**\n- `\\n`: Newline\n- `\\r`: Carriage return\n- `\\t`: Tab\n- `\\xHH`: Hex byte (e.g., `\\x03` for Ctrl-C)\n- `\\uHHHH`: Unicode character\n\n**Example:**\n```json\n{\n  \"id\": \"host-1\",\n  \"input\": \"print('test')\\\\n\"\n}\n```\n\n### 4. stdout\n\nView process output. Returns stdout and stderr (or terminal buffer for TTY processes).\n\n**Parameters:**\n- `id` (string, required): Process ID\n- `lines` (number, optional): Number of lines to retrieve (default: 100)\n\n**Returns:**\n- `stdout`: Stdout output (last N lines)\n- `stderr`: Stderr output (last N lines)\n\n### 5. kill\n\nTerminate a process with a signal.\n\n**Parameters:**\n- `id` (string, required): Process ID\n- `signal` (string, optional): Signal to send (default: `SIGTERM`)\n\nCommon signals:\n- `SIGTERM`: Graceful termination\n- `SIGKILL`: Force kill\n- `SIGINT`: Interrupt (Ctrl-C)\n\n## Architecture\n\n```\nMCP Server (5 tools: spawn, ps, stdin, stdout, kill)\n    ↓\nMode Selection (ENV: PROCESS_MODE=host|docker)\n    ↓\nProcessExecutor Interface\n    ↓\nHost Mode              Docker Mode\n(child_process,        (dockerode,\n @anthropic-ai/        single shared\n sandbox-runtime)      container)\n```\n\n## Development\n\n```bash\n# Build\nnpm run build\n\n# Type check\nnpm run typecheck\n\n# Run in development (CLI mode)\nnpm run dev\n\n# Test library functionality\nnode examples/test-library.js\n\n# Run simple example\nnode examples/simple-example.js\n\n# Verify installation\nbash verify.sh\n```\n\n### Publishing as a Package\n\nTo publish this to npm or use it as a local dependency:\n\n```bash\n# Build the package\nnpm run build\n\n# Publish to npm (requires npm account)\nnpm publish\n\n# Or install locally in another project\ncd /path/to/your-project\nnpm install /path/to/process-mcp\n```\n\nThen use in your project:\n\n```typescript\nimport { createProcessMCP } from 'process-mcp';\n```\n\n## Docker Mode Implementation Details\n\n- **No Dockerfile required** - uses existing Docker images (ubuntu:22.04 by default)\n- Single long-running container (`tail -f /dev/null`)\n- Each process spawned via `docker exec`\n- Container configuration:\n  - 512MB RAM limit\n  - 1 vCPU\n  - 4096 PID limit\n  - Unprivileged mode\n  - Tmpfs for `/tmp` and `/var/tmp` (100MB, noexec)\n- Volume persistence for working directory (`process-mcp-volume:/home/agent`)\n- Automatic container reuse (existing containers are restarted)\n- Automatic cleanup on server shutdown\n- PID extraction via command wrapping: `echo \"PID:$$\" >&2 && command`\n\n## Host Mode Implementation Details\n\n- Uses `@anthropic-ai/sandbox-runtime` for security\n- Process spawning via `child_process.spawn()`\n- TTY support via pipes and `@xterm/headless` Terminal\n- Configurable filesystem and network restrictions\n- Automatic sandboxing of all commands\n\n## Security Considerations\n\n### Host Mode\n- Commands wrapped with sandbox restrictions\n- Filesystem access controlled via allowlists/denylists\n- Network access filtered by domain\n- Processes run with minimal permissions\n\n### Docker Mode\n- Containers run unprivileged\n- Resource limits enforced\n- No capability additions\n- Tmpfs with noexec for temporary directories\n\n## Project Status\n\nThe server has been fully implemented according to the plan:\n\n- ✅ Host mode with optional sandboxing\n- ✅ Docker mode with container isolation\n- ✅ 5 MCP tools (spawn, ps, stdin, stdout, kill)\n- ✅ TTY support for interactive applications\n- ✅ Background process execution\n- ✅ Timeout handling\n- ✅ Process registry with cleanup\n- ✅ Comprehensive error handling\n\n### Verification\n\nRun the verification script to ensure everything is working:\n\n```bash\nbash verify.sh\n```\n\n## License\n\nISC\n","readmeFilename":"README.md"}