<!-- source: https://deepwiki.com/qhkm/zeptoclaw/8.6-binary-plugin-system -->

# Binary Plugin System

- src/gateway/startup_guard.rs
- src/plugins/loader.rs
- src/plugins/registry.rs
- src/plugins/types.rs
- src/tools/binary_plugin.rs
- src/tools/custom.rs
- src/tools/delegate.rs
- src/tools/mcp/wrapper.rs
- src/tools/plugin.rs
- src/tools/registry.rs
- src/tools/types.rs

The Binary Plugin System enables extending ZeptoClaw's tool capabilities through standalone executable binaries that communicate via JSON-RPC 2.0 over stdin/stdout. This allows tools to be written in any programming language while maintaining a unified interface for the LLM.

**Scope**: This page covers the binary plugin architecture, JSON-RPC protocol, plugin execution lifecycle, and implementation details. For general tool system architecture, see [3.4](https://github.com/qhkm/zeptoclaw/blob/2c743d31/3.4) For the Model Context Protocol (MCP) integration which provides a more sophisticated server-based alternative, see [8.7](https://github.com/qhkm/zeptoclaw/blob/2c743d31/8.7) For provider plugins (LLM backends), see [10.6](https://github.com/qhkm/zeptoclaw/blob/2c743d31/10.6)

## Architecture Overview

The binary plugin system wraps external executables with a standardized JSON-RPC interface. Each tool call spawns the binary, exchanges a single request-response pair, and terminates.

```

```

**Diagram: Binary Plugin Architecture** - Shows data flow from agent through the plugin adapter to external binaries.

**Sources**: [src/tools/binary_plugin.rs1-73](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/tools/binary_plugin.rs#L1-L73) [src/plugins/loader.rs19-43](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/plugins/loader.rs#L19-L43) [src/tools/registry.rs166-181](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/tools/registry.rs#L166-L181)

## Core Components

### BinaryPluginTool

The `BinaryPluginTool` struct implements the `Tool` trait and acts as an adapter between the tool registry and external plugin binaries.

**Implementation**: [src/tools/binary_plugin.rs68-73](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/tools/binary_plugin.rs#L68-L73)

### PluginToolDef

Defines a tool's metadata and execution requirements. This structure is parsed from the `plugin.json` manifest.

```

```

**Sources**: [src/plugins/types.rs111-146](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/plugins/types.rs#L111-L146)

## JSON-RPC 2.0 Protocol

Communication between ZeptoClaw and plugin binaries uses JSON-RPC 2.0 over stdin/stdout. Each invocation consists of a single request-response exchange.

### Request Format

```

```

**Wire Type**: `PluginJsonRpcRequest` containing `PluginExecuteParams` [src/tools/binary_plugin.rs22-34](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/tools/binary_plugin.rs#L22-L34)

### Response Format (Success)

```

```

**Wire Type**: `PluginJsonRpcResponse` with `PluginJsonRpcResult` [src/tools/binary_plugin.rs36-49](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/tools/binary_plugin.rs#L36-L49)

### Response Format (Error)

```

```

**Wire Type**: `PluginJsonRpcError` [src/tools/binary_plugin.rs52-57](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/tools/binary_plugin.rs#L52-L57)

### Protocol Rules

1. Single-line exchange : Request and response are each single JSON lines.
2. Binary exit : Plugin process must exit after producing a single response src/tools/binary_plugin.rs 4-6
3. Execution context : The binary is spawned on-demand for each tool call src/tools/binary_plugin.rs 63-67

**Sources**: [src/tools/binary_plugin.rs1-67](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/tools/binary_plugin.rs#L1-L67)

## Execution Flow

The following diagram shows the complete lifecycle of a binary plugin tool call.

```

```

**Diagram: Binary Plugin Execution Sequence** - Shows message flow and state transitions during tool execution.

### Key Implementation Details

#### Spawn with ETXTBSY Retry

Linux filesystems may transiently return `ETXTBSY` (error 26) immediately after script creation. The implementation retries twice with increasing delays (25ms then 50ms):

[src/tools/binary_plugin.rs149-186](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/tools/binary_plugin.rs#L149-L186)

#### Working Directory and Environment

If `ToolContext` provides a workspace, the plugin binary is spawned with that directory as its working directory. Environment variables from the `PluginToolDef` are also injected:

[src/tools/binary_plugin.rs158-168](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/tools/binary_plugin.rs#L158-L168)

**Sources**: [src/tools/binary_plugin.rs130-196](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/tools/binary_plugin.rs#L130-L196)

## Tool Registration

Binary plugins are registered into the `ToolRegistry` with the `Tool` trait implementation:

```

```

**Diagram: Tool Trait Implementation** - Maps trait methods to their data sources.

### Tool Trait Implementation

[src/tools/binary_plugin.rs108-130](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/tools/binary_plugin.rs#L108-L130)

```

```

**Note**: Binary plugins default to `ToolCategory::Shell` if no category is specified in the manifest [src/plugins/types.rs161-163](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/plugins/types.rs#L161-L163)

**Sources**: [src/tools/binary_plugin.rs108-130](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/tools/binary_plugin.rs#L108-L130) [src/plugins/types.rs155-165](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/plugins/types.rs#L155-L165)

## Plugin Discovery and Loading

Plugins are discovered by scanning directories for `plugin.json` manifest files.

### Manifest Structure

The `PluginManifest` defines the plugin's identity and its tools.

[src/plugins/types.rs55-81](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/plugins/types.rs#L55-L81)

```

```

### Discovery and Validation

The `loader` module handles scanning directories and validating manifests. Validation ensures:

- Plugin name is 1-64 alphanumeric/hyphen characters src/plugins/loader.rs 157-164
- Execution mode "binary" requires a valid BinaryPluginConfig src/plugins/loader.rs 185-192
- Binary path does not use path traversal ( .. ) or absolute paths src/plugins/loader.rs 211-218

**Sources**: [src/plugins/loader.rs19-139](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/plugins/loader.rs#L19-L139) [src/plugins/types.rs55-104](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/plugins/types.rs#L55-L104)

## Plugin Registry

The `PluginRegistry` manages loaded plugins and ensures tool name uniqueness across the system.

[src/plugins/registry.rs60-66](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/plugins/registry.rs#L60-L66)

**Sources**: [src/plugins/registry.rs60-205](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/plugins/registry.rs#L60-L205)

## Summary

The Binary Plugin System provides a language-agnostic extension mechanism for ZeptoClaw tools through:

- JSON-RPC 2.0 protocol over stdin/stdout for standardized communication.
- On-demand execution with automatic process cleanup and timeout protection.
- PluginRegistry for global tool management and conflict detection.
- Manifest-based discovery for easy extension without Rust code changes.
- Security-first design with path validation and category-based enforcement.

**Sources**: [src/tools/binary_plugin.rs1-196](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/tools/binary_plugin.rs#L1-L196) [src/plugins/types.rs55-165](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/plugins/types.rs#L55-L165) [src/plugins/registry.rs60-127](https://github.com/qhkm/zeptoclaw/blob/2c743d31/src/plugins/registry.rs#L60-L127)
