Skip to main content
Glama
pikujs
by pikujs

Herdr Agent Gateway

Secure, authenticated remote dispatch plugin, skill, and MCP server for the Herdr terminal multiplexer.

License: MIT Herdr Nix Flake Bun TypeScript


🌟 Overview & Why It Exists

When AI coding agents (Claude Code, OpenCode, Codex, Pi, DSH, Antigravity) run on remote servers, in sandboxes, or across background automation loops, they frequently need to dispatch tasks to a developer's local workstation (e.g. running builds, inspecting hardware, running GUI tests, or spawning subagents).

However, granting remote agents raw SSH access or unconstrained root shells creates massive security risks and clobbers the developer's interactive workspace.

Herdr Agent Gateway solves this by exposing a scoped, authenticated control layer for Herdr:

  1. Zero Focus Theft: Spawns tasks inside dedicated terminal tabs in the background without stealing your active typing focus.

  2. Hardened Dual Auth: Rejects unauthorized access using constant-time Bearer tokens and cryptographic SSH Ed25519 request signatures.

  3. PTY Memory Injection: Prompts are passed verbatim into the terminal PTY layer without shell expansion or interpolation vulnerabilities.

  4. Autonomous YOLO Mode: Configures non-interactive flags per agent kind declaratively in herdr_nodes.json.


Related MCP server: pty-mcp

✨ Features

  • šŸ›”ļø Zero Focus Theft: Agents launch in background tabs (focus: false) inside a dedicated workspace (spawned-agents), leaving your active editor session undisturbed.

  • ⚔ Dual Client Interfaces:

    • POSIX CLI & Agent Skill: skills/spawn_herdr_agent/ contains agent-spawn-remote, a zero-dependency script for any agent harness.

    • Model Context Protocol (MCP): Native packages/mcp-server/ exposes gateway tools directly to tool-calling agents.

  • šŸ” Hardened Dual Authentication:

    • Constant-time string comparison (crypto.timingSafeEqual) eliminates timing attacks.

    • SSH Request Signatures verify client identity against ~/.ssh/authorized_keys with SHA-256 body hashing and a 60-second replay window.

  • šŸš€ Declarative YOLO Mode: Run agents autonomously without confirmation prompts using --yolo or --approval-mode yolo. Arguments like --dangerously-skip-permissions are mapped per agent in herdr_nodes.json.

  • ā„ļø First-Class Nix & Home Manager Integration: Full flake support packaging all binaries, runnable apps, devShell, and a declarative Home Manager module with systemd service supervision.

  • 🧭 Multi-Machine Profile Registry: Automatic machine discovery with fallback order across local workstation, LAN desktops, or remote devboxes.


šŸ—ļø Architecture & Data Flow

flowchart LR
    subgraph Remote["Remote / External Agent"]
        CLI["POSIX Skill Client<br/>(agent-spawn-remote)"]
        MCP["MCP Client Agent<br/>(Claude / OpenCode / Codex)"]
    end

    subgraph GatewayDaemon["Developer Workstation (Port :9480)"]
        HTTP["HTTP Listener<br/>(127.0.0.1 / LAN / VPN)"]
        Auth{"Dual Auth Engine<br/>• Timing-Safe Bearer<br/>• SSH Ed25519 Signatures"}
        Router["Request Router & Queue"]
    end

    subgraph Multiplexer["Herdr Multiplexer Core"]
        Socket["Unix Domain Socket<br/>(~/.config/herdr/herdr.sock)"]
        Workspace["Workspace: 'spawned-agents'"]
        Tab1["Tab: worker-01<br/>(Agent: Pi / Claude)"]
        Tab2["Tab: test-runner<br/>(Agent: OpenCode)"]
    end

    CLI -->|"HTTP + Auth Header"| HTTP
    MCP -->|"MCP stdio / JSON-RPC"| HTTP
    HTTP --> Auth
    Auth -->|"Validated"| Router
    Router -->|"JSON-RPC IPC"| Socket
    Socket --> Workspace
    Workspace --> Tab1
    Workspace --> Tab2

šŸ“¦ Quickstart & Installation

Add herdr-agent-gateway to your flake inputs:

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    herdr-agent-gateway.url = "git+https://gitlab.pikujs.com/pikujs/herdr-agent-gateway.git";
  };
}

Enable the service and tools in your Home Manager configuration:

{ inputs, pkgs, ... }:

{
  imports = [
    inputs.herdr-agent-gateway.homeManagerModules.default
  ];

  services.herdr-agent-gateway = {
    enable = true;           # Enables background systemd user service
    client.enable = true;    # Installs agent-spawn-remote in PATH
    mcpServer.enable = true; # Installs herdr-mcp-server in PATH
    host = "127.0.0.1";
    port = 9480;
    defaultWorkspace = "spawned-agents";

    # Declarative YOLO args per agent
    yoloArgs = {
      pi = [ "--yolo" ];
      claude = [ "--dangerously-skip-permissions" ];
      opencode = [ "--yolo" ];
    };
  };
}

Install directly from the Herdr Marketplace:

# Install from the Herdr plugin index
herdr plugin install pikujs/herdr-agent-gateway

Or link a local checkout into your multiplexer:

# Link local checkout as a Herdr plugin
herdr plugin link plugins/herdr-remote-gateway

# Invoke initial setup action (generates tokens and installs systemd user service)
herdr plugin action invoke setup --plugin herdr-remote-gateway

Option 3: Hermes Plugin System

Install directly from GitHub into Hermes Agent:

# Install from GitHub
hermes plugins install pikujs/herdr-agent-gateway --enable

# Or install in Hermes Desktop via one-click link:
# hermes://plugin/install?repo=pikujs/herdr-agent-gateway&enable=1

Or configure declaratively in NixOS on your Hermes server:

services.hermes-agent = {
  extraPlugins = [
    inputs.herdr-agent-gateway
  ];
  settings.plugins.enabled = [ "herdr" ];
};

Option 4: Standalone Run via Bun

# Run server directly with Bun
cd plugins/herdr-remote-gateway
bun install
bun run src/server.ts

# Or run setup helper to install systemd user service
bun run src/cli.ts setup

šŸ› ļø Usage Reference

1. POSIX CLI Client (agent-spawn-remote)

The client wrapper is located at skills/spawn_herdr_agent/scripts/agent-spawn-remote (with a convenient symlink at scripts/agent-spawn-remote).

# Check connectivity & socket status
agent-spawn-remote health

# List active workspaces, panes, or agents
agent-spawn-remote list workspaces
agent-spawn-remote list agents

# Spawn an agent tab in Herdr with an initial prompt
agent-spawn-remote spawn \
  --kind pi \
  --name worker_refactor \
  --workspace spawned-agents \
  --prompt "Analyze project structure and run unit tests"

# Spawn in autonomous YOLO mode (auto-approves tool execution)
agent-spawn-remote spawn \
  --kind claude \
  --name autotask \
  --workspace spawned-agents \
  --yolo \
  --prompt "Fix failing linter errors"

# Read terminal output from a pane
agent-spawn-remote read w15:p1 --lines 50

# Submit follow-up prompt to an active agent
agent-spawn-remote prompt --agent worker_refactor "Run pytest tests/test_api.py" --wait

# Close a finished pane
agent-spawn-remote close w15:p1

2. Model Context Protocol (MCP Server)

Configure the MCP server in your agent harness (claude_desktop_config.json, OpenCode opencode.json, or Codex):

{
  "mcpServers": {
    "herdr-gateway": {
      "command": "herdr-mcp-server",
      "env": {
        "HERDR_GATEWAY_TOKEN": "your_bearer_token"
      }
    }
  }
}

Exposed MCP Tools:

  • herdr_health: Verify gateway connectivity and Herdr multiplexer status.

  • herdr_list_panes: List all workspaces, tabs, panes, and running agent sessions.

  • herdr_spawn_agent: Create a tab, start an agent runtime, and inject initial prompt.

  • herdr_prompt_agent: Send follow-up instructions to an active named agent.

  • herdr_read_pane: Read terminal scrollback history from a specific pane.

  • herdr_send_keys: Send control sequences (ctrl+c, enter, escape) to an agent.

  • herdr_close_pane: Terminate and close a terminal pane.

3. Hermes Plugin (Tools & Slash Commands)

When installed in Hermes Agent, the plugin registers native tools, a bundled skill, and slash commands:

Registered Tools:

  • herdr_spawn_agent: Spawns an agent in a background Herdr pane locally or on any configured remote machine (node, prompt, workspace, kind, pane_direction, focus).

  • herdr_list_nodes: Reads configured nodes from ~/.config/herdr_nodes.json and reports connectivity with "check_health": true.

  • herdr_node_status: Queries version, uptime, and active pane count for a target node.

Bundled Skill:

  • Resolvable as herdr:spawn_herdr_agent via skill_view().

Slash Commands:

/herdr list              # List configured Herdr nodes and online state
/herdr status [node]     # Show gateway version and active pane capacity
/herdr spawn <prompt>    # Quick agent spawn on default node

4. REST API (curl)

# Health check (unauthenticated)
curl -s http://127.0.0.1:9480/api/v1/health

# Spawn agent tab (Bearer token)
curl -s -X POST http://127.0.0.1:9480/api/v1/agents/spawn \
  -H "Authorization: Bearer $(cat ~/.config/herdr/plugins/config/herdr-remote-gateway/gateway.token)" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_kind": "pi",
    "agent_name": "worker_api",
    "workspace": "spawned-agents",
    "yolo": true,
    "prompt": "echo Hello from Remote Agent"
  }'

āš™ļø Declarative Configuration

Node Registry (herdr_nodes.json)

The client script and MCP server automatically discover machine profiles in ~/.config/herdr/plugins/config/herdr-remote-gateway/herdr_nodes.json:

{
  "$schema": "https://raw.githubusercontent.com/pikujs/herdr-agent-gateway/main/schemas/herdr_nodes.schema.json",
  "default_node": "local-workstation",
  "fallback_order": [
    "local-workstation",
    "lan-desktop"
  ],
  "yolo_args": {
    "pi": ["--yolo"],
    "claude": ["--dangerously-skip-permissions"],
    "opencode": ["--yolo"],
    "codex": ["--yolo"],
    "dsh": ["--yolo"],
    "antigravity": ["--yolo"]
  },
  "nodes": {
    "local-workstation": {
      "endpoint": "http://127.0.0.1:9480",
      "auth_token": "env:HERDR_GATEWAY_TOKEN",
      "default_workspace": "spawned-agents",
      "default_agent": "pi",
      "priority": 10
    },
    "lan-desktop": {
      "endpoint": "http://192.168.1.150:9480",
      "auth_token": "env:HERDR_REMOTE_TOKEN",
      "default_workspace": "spawned-agents",
      "default_agent": "claude",
      "priority": 20
    }
  }
}

Environment Variables

Variable

Type

Default

Description

HERDR_GATEWAY_HOST

String

127.0.0.1

Bind address. Default localhost; can bind to LAN/VPN IP or 0.0.0.0 when set.

HERDR_GATEWAY_PORT

Integer

9480

Port for the HTTP daemon.

HERDR_GATEWAY_TOKEN

String

(None)

Shared Bearer authentication secret.

HERDR_GATEWAY_TOKEN_FILE

String

.../gateway.token

Path to Bearer token file if not set via environment.

HERDR_GATEWAY_DEFAULT_WORKSPACE

String

spawned-agents

Workspace targeted when caller omits workspace.

HERDR_GATEWAY_MAX_PANES

Integer

16

Maximum concurrent active panes (returns 429 if exceeded).

HERDR_SOCKET_PATH

String

~/.config/herdr/herdr.sock

Path to Herdr Unix domain socket.

HERDR_BIN_PATH

String

herdr

Executable path for CLI fallback.


šŸ”’ Security Model

  1. Restricted Interface Binding: Defaults strictly to 127.0.0.1. Never exposes public interfaces unless explicitly requested via HERDR_GATEWAY_HOST.

  2. Constant-Time Authentication: Token validation uses crypto.timingSafeEqual() to protect against timing attacks.

  3. Cryptographic Request Signatures: SSH signatures require SHA-256 payload digest verification with timestamp freshness validation (max 60 seconds clock drift) against ~/.ssh/authorized_keys.

  4. PTY Memory Isolation: Prompts bypass shell expansion and pass directly into Herdr PTY layers as memory strings, preventing shell-injection vulnerabilities.

  5. Input Sanitization: Enforces strict agent kind whitelisting (pi, claude, opencode, codex, dsh, antigravity), alphanumeric session naming (^[a-zA-Z0-9_-]{1,64}$), and a 64KB maximum payload ceiling.


šŸ“ Repository Structure

herdr-agent-gateway/
ā”œā”€ā”€ flake.nix                       # Flake packaging (packages, apps, devShells, HM module)
ā”œā”€ā”€ flake.lock                      # Pinned Nix lockfile
ā”œā”€ā”€ nix/                            # Nix expressions
│   ā”œā”€ā”€ packages.nix                # Derivations for daemon, client, and MCP server
│   └── home-manager-module.nix     # Home Manager service & configuration module
ā”œā”€ā”€ templates/                      # Dedicated external templates for service & configs
ā”œā”€ā”€ plugins/
│   └── herdr-remote-gateway/       # In-daemon Herdr plugin & HTTP server (Bun / TypeScript)
ā”œā”€ā”€ packages/
│   └── mcp-server/                 # Model Context Protocol (MCP) server
ā”œā”€ā”€ skills/
│   └── spawn_herdr_agent/          # Agent Skill specification (SKILL.md)
│       └── scripts/                # Canonical client scripts (agent-spawn-remote)
ā”œā”€ā”€ scripts/                        # Root convenience symlinks
ā”œā”€ā”€ schemas/
│   └── herdr_nodes.schema.json     # Machine profile registry JSON Schema
ā”œā”€ā”€ docs/                           # Detailed architecture and API specifications
└── AGENTS.md                       # Machine rules & development instructions

šŸ“„ License

This project is licensed under the MIT License Ā© 2026 pikujs (Nirmaan J Sarkar).

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables AI agents to interact with terminal environments through multiple concurrent PTY sessions. Supports cross-platform terminal operations including command execution, session management, and real-time communication.
    5 npm
    3
    MIT
  • F
    license
    A
    quality
    D
    maintenance
    Enables AI agents to start and manage pseudo-terminal sessions, run shell commands and interact with REPLs programmatically.
    7
    -
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to create and interact with isolated tmux terminal sessions in real time, supporting command execution, output capture, and session management.
    -
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI agents to securely execute terminal commands with persistent sessions, async jobs, and mission control, while providing a live dashboard for human oversight.
    4
    Apache 2.0