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

@agent-remote/docker

v0.0.2

Published

Docker remote tools for AI agents

Readme

@agent-remote/docker

A TypeScript library for executing commands and managing files on Docker containers. Designed for integration with the Claude Agent SDK to provide AI agents with container access.

Features

  • Bash execution - Run commands in persistent shell sessions with background execution support
  • File operations - Read, write, and edit files remotely using shell commands
  • Search tools - Grep pattern search and glob file matching
  • Type-safe - Full TypeScript support with Zod validation
  • Agent SDK integration - Easy integration with Claude Agent SDK via MCP server
  • Standalone MCP server - Run as a standalone MCP server with stdio transport
  • Zero setup - Works with any running Docker container

Installation

npm install @agent-remote/docker

Quick Start

MCP Server (Standalone)

The package includes a standalone MCP server executable that can be run from the command line and communicates over stdio transport. The server is self-contained with all dependencies bundled (except Node.js builtins), making it easy to distribute and run without installing node_modules.

Installation:

npm install -g @agent-remote/docker

Usage with command line arguments:

# With container name
remote-docker-mcp --container my-app

# With custom shell
remote-docker-mcp --container my-app --shell bash

Usage with environment variables:

export DOCKER_CONTAINER=my-app
export DOCKER_SHELL=bash
remote-docker-mcp

Available options:

  • --container, -c - Docker container name (or DOCKER_CONTAINER env var)
  • --shell, -s - Shell to use for command execution, default 'sh' (or DOCKER_SHELL env var)
  • --debug - Enable debug output

The server exposes all remote tools (bash, read, write, edit, grep, glob, etc.) through the MCP protocol.

Configuration in Claude Desktop:

Add to your Claude Desktop configuration:

{
  "mcpServers": {
    "docker": {
      "command": "remote-docker-mcp",
      "args": ["--container", "my-app"]
    }
  }
}

Basic Usage

import { Remote } from '@agent-remote/docker';

// Create a remote instance
const remote = new Remote({
  container: 'my-app',
  shell: 'bash', // optional, defaults to 'sh'
});

// Execute commands
const result = await remote.bash.handler({
  command: 'ls -la',
});
console.log(result.content[0].text);

// Read files
const fileContent = await remote.read.handler({
  file_path: '/app/config.json',
});

// Write files
await remote.write.handler({
  file_path: '/tmp/test.txt',
  content: 'Hello, world!',
});

Using with Claude Agent SDK

import { Remote } from '@agent-remote/docker';

const remote = new Remote({
  container: 'my-app',
  shell: 'bash',
});

// Create an MCP server with all tools
const server = remote.createSdkMcpServer();

// Use with Agent SDK...

Using Individual Tools

const remote = new Remote({ container: 'my-app' });

// Each tool is accessible as a property with a handler
const tools = [
  remote.bash,
  remote.bashOutput,
  remote.killBash,
  remote.grep,
  remote.read,
  remote.write,
  remote.edit,
  remote.glob,
];

// You can use individual tools in your own MCP server
import { createSdkMcpServer, tool } from '@anthropic-ai/claude-agent-sdk';

const customServer = createSdkMcpServer({
  name: 'custom-remote-docker',
  version: '1.0.0',
  tools: [
    tool(
      remote.bash.name,
      remote.bash.description,
      remote.bash.inputSchema,
      remote.bash.handler,
    ),
    tool(
      remote.read.name,
      remote.read.description,
      remote.read.inputSchema,
      remote.read.handler,
    ),
    tool(
      remote.write.name,
      remote.write.description,
      remote.write.inputSchema,
      remote.write.handler,
    ),
  ],
});

API Reference

Remote Class

The main class for managing Docker container access and tools.

Constructor

new Remote(config: RemoteConfig)

Creates a new Remote instance for interacting with a Docker container.

Parameters:

  • config - Docker container configuration (see Configuration below)

Returns: A Remote instance

Example:

const remote = new Remote({
  container: 'my-app',
  shell: 'bash',
});

Instance Methods

createSdkMcpServer(name?: string)

Creates an MCP server with all remote tools from this Remote instance.

Parameters:

  • name - Optional name for the MCP server (defaults to 'remote-docker')

Returns: An MCP server instance from the Claude Agent SDK

Example:

const server = remote.createSdkMcpServer();

Tool Properties

Each tool is accessed via a getter property that returns a tool definition with name, description, inputSchema, and handler properties.

bash: BashToolDefinition

Executes commands in a persistent shell session.

Input:

{
  command: string;          // The command to execute
  timeout?: number;         // Optional timeout in milliseconds (max 600000)
  description?: string;     // Description of what the command does
  run_in_background?: boolean; // Run in background
}

Output:

{
  output: string;    // Combined stdout and stderr
  exitCode?: number; // Exit code (optional)
  signal?: string;   // Signal used to terminate the command
  killed?: boolean;  // Whether the command was killed due to timeout
  shellId?: string;  // Shell ID if background execution
}
bashOutput: BashOutputToolDefinition

Retrieves output from a running or completed background bash shell.

Input:

{
  shell_id: string; // Shell ID to retrieve output from
}

Output:

{
  output: string;                  // New output since last check
  status: 'running' | 'completed'; // Shell status
  exitCode?: number;               // Exit code (when completed)
  signal?: string;                 // Signal (when completed)
}
killBash: KillBashToolDefinition

Kills a running background shell by its ID.

Input:

{
  shell_id: string;         // Shell ID to kill
  signal?: string;          // Signal to send (e.g., 'SIGTERM', 'SIGKILL')
}

Output:

{
  killed: boolean; // Whether the shell was killed
}
grep: GrepToolDefinition

Searches for patterns in files or directories.

Input:

{
  pattern: string;          // Regular expression pattern
  path: string;             // File or directory to search
  glob?: string;            // Glob pattern to filter files
  output_mode?: 'content' | 'files_with_matches' | 'count';
  '-B'?: number;            // Lines of context before match
  '-A'?: number;            // Lines of context after match
  '-C'?: number;            // Lines of context before and after
  '-n'?: boolean;           // Show line numbers
  '-i'?: boolean;           // Case insensitive
  head_limit?: number;      // Limit output lines
}

Output:

{
  mode: 'content' | 'files_with_matches' | 'count';
  content?: string;         // Matching lines (if mode is 'content')
  filenames?: string[];     // Matching files (if mode is 'files_with_matches')
  numFiles?: number;        // Number of files (if mode is 'files_with_matches')
  numMatches?: number;      // Number of matches (if mode is 'count')
}
read: ReadToolDefinition

Reads files from the container filesystem using shell commands.

Input:

{
  file_path: string;        // Absolute path to file
  offset?: number;          // Line number to start reading from
  limit?: number;           // Number of lines to read
}

Output:

{
  content: string; // File content
  numLines: number; // Number of lines read
  startLine: number; // Starting line number
  totalLines: number; // Total lines in file
}

Implementation:

Uses cat command to read file contents from the container.

write: WriteToolDefinition

Writes content to files on the container filesystem using shell commands.

Input:

{
  file_path: string; // Absolute path to file
  content: string; // Content to write
}

Output:

{
  content: string; // Content that was written
}

Implementation:

Uses printf '%s' '...' with single-quote escaping to safely handle special characters, newlines, and unicode.

edit: EditToolDefinition

Edits files by replacing text on the container filesystem using shell commands.

Input:

{
  file_path: string;        // Absolute path to file
  old_string: string;       // Text to find
  new_string: string;       // Text to replace with
  replace_all?: boolean;    // Replace all occurrences
}

Output:

{
  replacements: number; // Number of replacements made
  diff: StructuredPatch; // Unified diff of changes
}

Implementation:

Uses cat to read, performs replacement locally, then uses printf to write back.

glob: GlobToolDefinition

Searches for files matching glob patterns.

Input:

{
  base_path: string;        // Absolute base path to search from
  pattern: string;          // Glob pattern (e.g., '**/*.ts')
  include_hidden?: boolean; // Include hidden files
}

Output:

{
  matches: string[];        // List of matching file paths
  count: number;            // Number of matches
}

Configuration

RemoteConfig

The configuration object for creating a Remote instance:

{
  container: string;  // Name of the Docker container (required)
  shell?: string;     // Shell to use (default: 'sh')
}

Shell options:

  • 'sh' - Default, uses whatever shell is symlinked as /bin/sh in the container
  • 'bash' - Bash shell (must be available in container)
  • 'zsh' - Zsh shell (must be available in container)
  • 'dash' - Dash shell (must be available in container)

Example:

const remote = new Remote({
  container: 'my-app',
  shell: 'bash',
});

Examples

Error Handling

const remote = new Remote({ container: 'my-app' });

const result = await remote.bash.handler({
  command: 'some-command',
});

if (result.isError) {
  console.error('Command failed:', result.content[0].text);
} else {
  console.log('Success:', result.content[0].text);
}

Background Command Execution

const remote = new Remote({ container: 'my-app' });

// Start a long-running command in the background
const startResult = await remote.bash.handler({
  command: 'npm run build',
  run_in_background: true,
  description: 'Building project',
});

const { shellId } = startResult.structuredContent;

// Check output periodically
const checkOutput = async () => {
  const output = await remote.bashOutput.handler({ shell_id: shellId });
  console.log(output.content[0].text);

  if (output.structuredContent.status === 'running') {
    setTimeout(checkOutput, 1000);
  }
};

checkOutput();

File Search and Edit

const remote = new Remote({ container: 'my-app' });

// Find all TypeScript files
const files = await remote.glob.handler({
  base_path: '/app',
  pattern: '**/*.ts',
});

// Search for a pattern
const matches = await remote.grep.handler({
  pattern: 'TODO',
  path: '/app/src',
  glob: '*.ts',
  output_mode: 'content',
  '-n': true,
});

// Edit a file
await remote.edit.handler({
  file_path: '/app/config.ts',
  old_string: 'localhost',
  new_string: 'example.com',
  replace_all: true,
});

Requirements

  • Docker must be installed and accessible via the docker command
  • The target container must be running
  • Basic Unix tools should be available in the container (sh, cat, find, grep)

License

Apache-2.0