{"_id":"@agent-remote/docker","_rev":"2-3eae1712335d6e831271a26a933f0e84","name":"@agent-remote/docker","dist-tags":{"latest":"0.0.2"},"versions":{"0.0.1":{"name":"@agent-remote/docker","version":"0.0.1","license":"Apache-2.0","_id":"@agent-remote/docker@0.0.1","maintainers":[{"name":"loderunnr","email":"charles.francoise@gmail.com"}],"bin":{"remote-docker-mcp":"dist/server.js"},"dist":{"shasum":"143e217c9e3c75a7fe0beb074a5cc1c08860669b","tarball":"https://registry.npmjs.org/@agent-remote/docker/-/docker-0.0.1.tgz","fileCount":57,"integrity":"sha512-FV2c3gEMnhsZ6PL/YlewETkGRHftOC8HvaXWgeogRlBd8ukbLL6KV6UxDNvhOqJkr9cHcGbkDSMadGIdvsH+ZA==","signatures":[{"sig":"MEUCIBAz/cP6SVMHuyQNveHdHTZo12G6i+AVVT7V6ZV9jH1SAiEAwmABSuVJVQzdhxrnptnTUjWqN9/vj79wDmXrjNmivhw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":310920},"main":"dist/cjs/index.cjs","type":"module","_from":"file:agent-remote-docker-0.0.1.tgz","types":"dist/index.d.ts","module":"dist/esm/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.cjs"}},"scripts":{"test":"vitest run","build":"tsdown","clean":"rimraf dist","server":"tsx src/server/server.ts","test:e2e":"vitest run --project=e2e","test:unit":"vitest run --project=unit","test:watch":"vitest","build:watch":"tsdown --watch","server:watch":"tsx --watch src/server/server.ts","test:watch:e2e":"vitest --project=e2e","test:watch:unit":"vitest --project=unit","test:integration":"vitest run --project=integration","test:watch:integration":"vitest --project=integration"},"_npmUser":{"name":"loderunnr","email":"charles.francoise@gmail.com"},"_resolved":"/tmp/499b12e5ba47e5d9ee80f02b72ec8923/agent-remote-docker-0.0.1.tgz","_integrity":"sha512-FV2c3gEMnhsZ6PL/YlewETkGRHftOC8HvaXWgeogRlBd8ukbLL6KV6UxDNvhOqJkr9cHcGbkDSMadGIdvsH+ZA==","_npmVersion":"11.6.0","description":"Docker remote tools for AI agents","directories":{},"_nodeVersion":"24.9.0","dependencies":{"zod":"^3.25.76","diff":"^8.0.2","pino":"^10.1.0","yargs":"^18.0.0","nanoid":"^5.1.6","minimatch":"^10.0.3","pino-pretty":"^13.1.2","zod-to-json-schema":"^3.24.6","zod-validation-error":"^4.0.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.20.6","tslib":"^2.8.1","rimraf":"^6.0.1","tsdown":"^0.15.9","vitest":"^3.2.4","typescript":"^5.9.3","@types/yargs":"^17.0.33","@agent-remote/core":"0.0.2","@modelcontextprotocol/sdk":"^1.20.0","@anthropic-ai/claude-agent-sdk":"^0.1.21"},"peerDependencies":{"@modelcontextprotocol/sdk":"^1.20.0","@anthropic-ai/claude-agent-sdk":"^0.1.0"},"_npmOperationalInternal":{"tmp":"tmp/docker_0.0.1_1761664055320_0.18126137539576215","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@agent-remote/docker","version":"0.0.2","description":"Docker remote tools for AI agents","license":"Apache-2.0","type":"module","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/esm/index.js","require":"./dist/cjs/index.cjs"}},"publishConfig":{"access":"public"},"dependencies":{"diff":"^8.0.2","minimatch":"^10.0.3","nanoid":"^5.1.6","pino":"^10.1.0","pino-pretty":"^13.1.2","yargs":"^18.0.0","zod":"^3.25.76","zod-to-json-schema":"^3.24.6","zod-validation-error":"^4.0.2"},"peerDependencies":{"@anthropic-ai/claude-agent-sdk":"^0.1.0","@modelcontextprotocol/sdk":"^1.20.0"},"devDependencies":{"@anthropic-ai/claude-agent-sdk":"^0.1.21","@modelcontextprotocol/sdk":"^1.20.0","@types/yargs":"^17.0.33","rimraf":"^6.0.1","tsdown":"^0.15.9","tslib":"^2.8.1","tsx":"^4.20.6","typescript":"^5.9.3","vitest":"^3.2.4","@agent-remote/core":"0.0.2"},"scripts":{"build":"tsdown","build:watch":"tsdown --watch","test":"vitest run","test:watch":"vitest","test:unit":"vitest run --project=unit","test:integration":"vitest run --project=integration","test:e2e":"vitest run --project=e2e","test:watch:unit":"vitest --project=unit","test:watch:integration":"vitest --project=integration","test:watch:e2e":"vitest --project=e2e","server":"tsx src/server/server.ts","server:watch":"tsx --watch src/server/server.ts","clean":"rimraf dist"},"main":"dist/cjs/index.cjs","module":"dist/esm/index.js","types":"dist/index.d.ts","bin":{"remote-docker-mcp":"dist/server.js"},"_id":"@agent-remote/docker@0.0.2","_integrity":"sha512-Yzg4GPVoh32IGM/eEzrMD8LRpPe1R1VCTss1Id/enfGe446llYuhuJhj06bji4El+nQJghrQXn0lTmf6pAt3gQ==","_resolved":"/tmp/85651daa6222cdc0079a4dab7bb9577d/agent-remote-docker-0.0.2.tgz","_from":"file:agent-remote-docker-0.0.2.tgz","_nodeVersion":"24.9.0","_npmVersion":"11.6.0","dist":{"integrity":"sha512-Yzg4GPVoh32IGM/eEzrMD8LRpPe1R1VCTss1Id/enfGe446llYuhuJhj06bji4El+nQJghrQXn0lTmf6pAt3gQ==","shasum":"7f72518c015320889ffb3f457ebeebb81c348a17","tarball":"https://registry.npmjs.org/@agent-remote/docker/-/docker-0.0.2.tgz","fileCount":57,"unpackedSize":310920,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIG1Bhj1My4jErdL0FoHqB+v9ca518CBuGrSNLYjmrXzCAiAXuSqIZyJRn7chcvQe/WIp6XvothdIy9q8mMyy+d26jg=="}]},"_npmUser":{"name":"loderunnr","email":"charles.francoise@gmail.com"},"directories":{},"maintainers":[{"name":"loderunnr","email":"charles.francoise@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/docker_0.0.2_1761667044964_0.011545108825781636"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-28T15:07:35.230Z","modified":"2025-10-28T15:57:25.388Z","0.0.1":"2025-10-28T15:07:35.526Z","0.0.2":"2025-10-28T15:57:25.154Z"},"license":"Apache-2.0","description":"Docker remote tools for AI agents","maintainers":[{"name":"loderunnr","email":"charles.francoise@gmail.com"}],"readme":"# @agent-remote/docker\n\nA TypeScript library for executing commands and managing files on Docker\ncontainers. Designed for integration with the Claude Agent SDK to provide AI\nagents with container access.\n\n## Features\n\n- **Bash execution** - Run commands in persistent shell sessions with background\n  execution support\n- **File operations** - Read, write, and edit files remotely using shell\n  commands\n- **Search tools** - Grep pattern search and glob file matching\n- **Type-safe** - Full TypeScript support with Zod validation\n- **Agent SDK integration** - Easy integration with Claude Agent SDK via MCP\n  server\n- **Standalone MCP server** - Run as a standalone MCP server with stdio\n  transport\n- **Zero setup** - Works with any running Docker container\n\n## Installation\n\n```bash\nnpm install @agent-remote/docker\n```\n\n## Quick Start\n\n### MCP Server (Standalone)\n\nThe package includes a standalone MCP server executable that can be run from the\ncommand line and communicates over stdio transport. The server is self-contained\nwith all dependencies bundled (except Node.js builtins), making it easy to\ndistribute and run without installing node_modules.\n\n**Installation:**\n\n```bash\nnpm install -g @agent-remote/docker\n```\n\n**Usage with command line arguments:**\n\n```bash\n# With container name\nremote-docker-mcp --container my-app\n\n# With custom shell\nremote-docker-mcp --container my-app --shell bash\n```\n\n**Usage with environment variables:**\n\n```bash\nexport DOCKER_CONTAINER=my-app\nexport DOCKER_SHELL=bash\nremote-docker-mcp\n```\n\n**Available options:**\n\n- `--container, -c` - Docker container name (or `DOCKER_CONTAINER` env var)\n- `--shell, -s` - Shell to use for command execution, default 'sh' (or\n  `DOCKER_SHELL` env var)\n- `--debug` - Enable debug output\n\nThe server exposes all remote tools (bash, read, write, edit, grep, glob, etc.)\nthrough the MCP protocol.\n\n**Configuration in Claude Desktop:**\n\nAdd to your Claude Desktop configuration:\n\n```json\n{\n  \"mcpServers\": {\n    \"docker\": {\n      \"command\": \"remote-docker-mcp\",\n      \"args\": [\"--container\", \"my-app\"]\n    }\n  }\n}\n```\n\n### Basic Usage\n\n```typescript\nimport { Remote } from '@agent-remote/docker';\n\n// Create a remote instance\nconst remote = new Remote({\n  container: 'my-app',\n  shell: 'bash', // optional, defaults to 'sh'\n});\n\n// Execute commands\nconst result = await remote.bash.handler({\n  command: 'ls -la',\n});\nconsole.log(result.content[0].text);\n\n// Read files\nconst fileContent = await remote.read.handler({\n  file_path: '/app/config.json',\n});\n\n// Write files\nawait remote.write.handler({\n  file_path: '/tmp/test.txt',\n  content: 'Hello, world!',\n});\n```\n\n### Using with Claude Agent SDK\n\n```typescript\nimport { Remote } from '@agent-remote/docker';\n\nconst remote = new Remote({\n  container: 'my-app',\n  shell: 'bash',\n});\n\n// Create an MCP server with all tools\nconst server = remote.createSdkMcpServer();\n\n// Use with Agent SDK...\n```\n\n### Using Individual Tools\n\n```typescript\nconst remote = new Remote({ container: 'my-app' });\n\n// Each tool is accessible as a property with a handler\nconst tools = [\n  remote.bash,\n  remote.bashOutput,\n  remote.killBash,\n  remote.grep,\n  remote.read,\n  remote.write,\n  remote.edit,\n  remote.glob,\n];\n\n// You can use individual tools in your own MCP server\nimport { createSdkMcpServer, tool } from '@anthropic-ai/claude-agent-sdk';\n\nconst customServer = createSdkMcpServer({\n  name: 'custom-remote-docker',\n  version: '1.0.0',\n  tools: [\n    tool(\n      remote.bash.name,\n      remote.bash.description,\n      remote.bash.inputSchema,\n      remote.bash.handler,\n    ),\n    tool(\n      remote.read.name,\n      remote.read.description,\n      remote.read.inputSchema,\n      remote.read.handler,\n    ),\n    tool(\n      remote.write.name,\n      remote.write.description,\n      remote.write.inputSchema,\n      remote.write.handler,\n    ),\n  ],\n});\n```\n\n## API Reference\n\n### Remote Class\n\nThe main class for managing Docker container access and tools.\n\n#### Constructor\n\n##### `new Remote(config: RemoteConfig)`\n\nCreates a new Remote instance for interacting with a Docker container.\n\n**Parameters:**\n\n- `config` - Docker container configuration (see Configuration below)\n\n**Returns:** A `Remote` instance\n\n**Example:**\n\n```typescript\nconst remote = new Remote({\n  container: 'my-app',\n  shell: 'bash',\n});\n```\n\n#### Instance Methods\n\n##### `createSdkMcpServer(name?: string)`\n\nCreates an MCP server with all remote tools from this Remote instance.\n\n**Parameters:**\n\n- `name` - Optional name for the MCP server (defaults to 'remote-docker')\n\n**Returns:** An MCP server instance from the Claude Agent SDK\n\n**Example:**\n\n```typescript\nconst server = remote.createSdkMcpServer();\n```\n\n#### Tool Properties\n\nEach tool is accessed via a getter property that returns a tool definition with\n`name`, `description`, `inputSchema`, and `handler` properties.\n\n##### `bash: BashToolDefinition`\n\nExecutes commands in a persistent shell session.\n\n**Input:**\n\n```typescript\n{\n  command: string;          // The command to execute\n  timeout?: number;         // Optional timeout in milliseconds (max 600000)\n  description?: string;     // Description of what the command does\n  run_in_background?: boolean; // Run in background\n}\n```\n\n**Output:**\n\n```typescript\n{\n  output: string;    // Combined stdout and stderr\n  exitCode?: number; // Exit code (optional)\n  signal?: string;   // Signal used to terminate the command\n  killed?: boolean;  // Whether the command was killed due to timeout\n  shellId?: string;  // Shell ID if background execution\n}\n```\n\n##### `bashOutput: BashOutputToolDefinition`\n\nRetrieves output from a running or completed background bash shell.\n\n**Input:**\n\n```typescript\n{\n  shell_id: string; // Shell ID to retrieve output from\n}\n```\n\n**Output:**\n\n```typescript\n{\n  output: string;                  // New output since last check\n  status: 'running' | 'completed'; // Shell status\n  exitCode?: number;               // Exit code (when completed)\n  signal?: string;                 // Signal (when completed)\n}\n```\n\n##### `killBash: KillBashToolDefinition`\n\nKills a running background shell by its ID.\n\n**Input:**\n\n```typescript\n{\n  shell_id: string;         // Shell ID to kill\n  signal?: string;          // Signal to send (e.g., 'SIGTERM', 'SIGKILL')\n}\n```\n\n**Output:**\n\n```typescript\n{\n  killed: boolean; // Whether the shell was killed\n}\n```\n\n##### `grep: GrepToolDefinition`\n\nSearches for patterns in files or directories.\n\n**Input:**\n\n```typescript\n{\n  pattern: string;          // Regular expression pattern\n  path: string;             // File or directory to search\n  glob?: string;            // Glob pattern to filter files\n  output_mode?: 'content' | 'files_with_matches' | 'count';\n  '-B'?: number;            // Lines of context before match\n  '-A'?: number;            // Lines of context after match\n  '-C'?: number;            // Lines of context before and after\n  '-n'?: boolean;           // Show line numbers\n  '-i'?: boolean;           // Case insensitive\n  head_limit?: number;      // Limit output lines\n}\n```\n\n**Output:**\n\n```typescript\n{\n  mode: 'content' | 'files_with_matches' | 'count';\n  content?: string;         // Matching lines (if mode is 'content')\n  filenames?: string[];     // Matching files (if mode is 'files_with_matches')\n  numFiles?: number;        // Number of files (if mode is 'files_with_matches')\n  numMatches?: number;      // Number of matches (if mode is 'count')\n}\n```\n\n##### `read: ReadToolDefinition`\n\nReads files from the container filesystem using shell commands.\n\n**Input:**\n\n```typescript\n{\n  file_path: string;        // Absolute path to file\n  offset?: number;          // Line number to start reading from\n  limit?: number;           // Number of lines to read\n}\n```\n\n**Output:**\n\n```typescript\n{\n  content: string; // File content\n  numLines: number; // Number of lines read\n  startLine: number; // Starting line number\n  totalLines: number; // Total lines in file\n}\n```\n\n**Implementation:**\n\nUses `cat` command to read file contents from the container.\n\n##### `write: WriteToolDefinition`\n\nWrites content to files on the container filesystem using shell commands.\n\n**Input:**\n\n```typescript\n{\n  file_path: string; // Absolute path to file\n  content: string; // Content to write\n}\n```\n\n**Output:**\n\n```typescript\n{\n  content: string; // Content that was written\n}\n```\n\n**Implementation:**\n\nUses `printf '%s' '...'` with single-quote escaping to safely handle special\ncharacters, newlines, and unicode.\n\n##### `edit: EditToolDefinition`\n\nEdits files by replacing text on the container filesystem using shell commands.\n\n**Input:**\n\n```typescript\n{\n  file_path: string;        // Absolute path to file\n  old_string: string;       // Text to find\n  new_string: string;       // Text to replace with\n  replace_all?: boolean;    // Replace all occurrences\n}\n```\n\n**Output:**\n\n```typescript\n{\n  replacements: number; // Number of replacements made\n  diff: StructuredPatch; // Unified diff of changes\n}\n```\n\n**Implementation:**\n\nUses `cat` to read, performs replacement locally, then uses `printf` to write\nback.\n\n##### `glob: GlobToolDefinition`\n\nSearches for files matching glob patterns.\n\n**Input:**\n\n```typescript\n{\n  base_path: string;        // Absolute base path to search from\n  pattern: string;          // Glob pattern (e.g., '**/*.ts')\n  include_hidden?: boolean; // Include hidden files\n}\n```\n\n**Output:**\n\n```typescript\n{\n  matches: string[];        // List of matching file paths\n  count: number;            // Number of matches\n}\n```\n\n## Configuration\n\n### RemoteConfig\n\nThe configuration object for creating a Remote instance:\n\n```typescript\n{\n  container: string;  // Name of the Docker container (required)\n  shell?: string;     // Shell to use (default: 'sh')\n}\n```\n\n**Shell options:**\n\n- `'sh'` - Default, uses whatever shell is symlinked as `/bin/sh` in the\n  container\n- `'bash'` - Bash shell (must be available in container)\n- `'zsh'` - Zsh shell (must be available in container)\n- `'dash'` - Dash shell (must be available in container)\n\n**Example:**\n\n```typescript\nconst remote = new Remote({\n  container: 'my-app',\n  shell: 'bash',\n});\n```\n\n## Examples\n\n### Error Handling\n\n```typescript\nconst remote = new Remote({ container: 'my-app' });\n\nconst result = await remote.bash.handler({\n  command: 'some-command',\n});\n\nif (result.isError) {\n  console.error('Command failed:', result.content[0].text);\n} else {\n  console.log('Success:', result.content[0].text);\n}\n```\n\n### Background Command Execution\n\n```typescript\nconst remote = new Remote({ container: 'my-app' });\n\n// Start a long-running command in the background\nconst startResult = await remote.bash.handler({\n  command: 'npm run build',\n  run_in_background: true,\n  description: 'Building project',\n});\n\nconst { shellId } = startResult.structuredContent;\n\n// Check output periodically\nconst checkOutput = async () => {\n  const output = await remote.bashOutput.handler({ shell_id: shellId });\n  console.log(output.content[0].text);\n\n  if (output.structuredContent.status === 'running') {\n    setTimeout(checkOutput, 1000);\n  }\n};\n\ncheckOutput();\n```\n\n### File Search and Edit\n\n```typescript\nconst remote = new Remote({ container: 'my-app' });\n\n// Find all TypeScript files\nconst files = await remote.glob.handler({\n  base_path: '/app',\n  pattern: '**/*.ts',\n});\n\n// Search for a pattern\nconst matches = await remote.grep.handler({\n  pattern: 'TODO',\n  path: '/app/src',\n  glob: '*.ts',\n  output_mode: 'content',\n  '-n': true,\n});\n\n// Edit a file\nawait remote.edit.handler({\n  file_path: '/app/config.ts',\n  old_string: 'localhost',\n  new_string: 'example.com',\n  replace_all: true,\n});\n```\n\n## Requirements\n\n- Docker must be installed and accessible via the `docker` command\n- The target container must be running\n- Basic Unix tools should be available in the container (sh, cat, find, grep)\n\n## License\n\nApache-2.0\n","readmeFilename":"README.md"}