Skip to content

RickConsole/hydra

Repository files navigation

demo

β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β‘€β €β €β €β €β’ β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €
β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β’€β €β €β €β €β €β €β €β €β €β €β €β €β ˆβ »β£¦β‘€β €β’Έβ£†β €β €β €β €β €β €β €β €β €β €β €β €β €β €
⠀⠀⠀⠀⣠⣦⣀⣀⣀⣀⣀⣀⑀⠀⣀⣠⑆⠀⠀⠀⠀⠀⠀⠀⠒⠛⣛⣛⣻⣿⣢⣾⣿⣦⣄Ⓙ⣆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠸⠿Ⓙ⣿⣿⣿⣯⣭⣿⣿⣿⣿⣋⣀⠀⠀⠀⠀⠀⠀⣠⣢⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣀⑀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
β €β €β €β €β €β €β €β ™β’Ώβ£Ώβ£Ώβ‘Ώβ’Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£“β ’β „β’ β‘Ύβ’»β£Ώβ£Ώβ£Ώβ£Ώβ‘Ÿβ β €β €β ˆβ ™β’Ώβ£Ώβ£Ώβ£―β‘»β£Ώβ‘„β €β €β €β €β €β €β €β €β €
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠉⠉⠀⠀⠀⠙Ⓙ⣿⣿⣿⣷⣄⠁⠀⣿⣿⣿⣿⣿⑇⠀⠀⠀⠀⠀Ⓒ⣿⣿⣿⣿⣿⣷⣄⑀⠀⠀⠀⠀⠀⠀⠀
β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β ˆβ£Ώβ£Ώβ£Ώβ£·β£Œβ’§β €β£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£„β €β €β €β €β’€β ‰β ™β ›β ›β Ώβ£Ώβ£Ώβ£Ώβ‘†β €β €β €β €β €β €
β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ‘€β  β’»β‘Ÿβ’Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£§β£„β£€β €β ˜β’Άβ£„β£€β €β €β ˆβ’»β Ώβ β €β €β €β €β €β €
β €β €β €β €β €β €β €β €β €β €β €β €β €β €β €β£Έβ£Ώβ£Ώβ£Ώβ£Ώβ£Ύβ €β €β €β »β£ˆβ£™β£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ‘Ώβ£·β£¦β‘€β €β €β €β €β €β €β €
β €β €β €β ˆβ ²β£„β €β €β£€β‘€β €β €β €β €β’ β£Ώβ£Ώβ£Ώβ‘Ώβ£Ώβ ‡β €β €β β Ίβ’‰β£‘β£΄β£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ‘Ώβ’Ώβ£Ώβ£Ώβ£Ώβ£Άβ£Ώβ£Ώβ£Ώβ£Άβ£Άβ‘€β €β €β €
β €β €β €β €β’ β£Ώβ£΄β£Ώβ£·β£Άβ£¦β£€β‘€β €β’Έβ£Ώβ£Ώβ£Ώβ ‡β β €β €β €β’€β£΄β£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ Ÿβ’Ώβ£Ώβ£Ώβ£Ώβ£·β €β Ήβ£Ώβ£Ώβ Ώβ Ώβ ›β »β Ώβ£Ώβ ‡β €β €β €
β €β €β €β£ β£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£·β£―β‘‚β’Έβ£Ώβ£Ώβ£Ώβ €β €β €β €β’€β Ύβ£»β£Ώβ£Ώβ£Ώβ Ÿβ €β €β ˆβ£Ώβ£Ώβ£Ώβ£Ώβ‘‡β €β €β£€β£€β‘€β €β’ β‘žβ ‰β €β €β €β €
β €β €β’Έβ£Ÿβ£½β£Ώβ£―β €β €β’Ήβ£Ώβ£Ώβ£Ώβ‘Ÿβ Όβ£Ώβ£Ώβ£Ώβ£‡β €β €β €β  β’°β£Ώβ£Ώβ£Ώβ£Ώβ‘„β €β €β €β£Έβ£Ώβ£Ώβ£Ώβ‘‡β €β’€β£€β£Όβ£Ώβ£·β£Ύβ£·β‘€β €β €β €β €
β €β’€β£Ύβ£Ώβ‘Ώβ Ÿβ ‹β €β €β’Έβ£Ώβ£Ώβ£Ώβ£Ώβ‘€β’Ώβ£Ώβ£Ώβ£Ώβ£¦β €β €β €β’Ίβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£„β €β €β£Ώβ£Ώβ£Ώβ£Ώβ‘‡β β£Ώβ£Ώβ£Ώβ£Ώβ Ώβ£Ώβ£Ώβ‘Ώβ£¦β €β €β €
β €β’»β£Ώβ β €β €β €β €β’ β£Ώβ£Ώβ£Ώβ‘Ÿβ‘Ώβ €β €β’»β£Ώβ£Ώβ£Ώβ£·β£€β‘€β ˜β£·β »β£Ώβ£Ώβ£Ώβ£Ώβ£·β£Όβ£Ώβ£Ώβ£Ώβ£Ώβ£‡β£Ύβ£Ώβ£Ώβ£Ώβ β €β’Όβ£Ώβ£Ώβ£Ώβ£†β €β €
β €β €β ˆβ €β €β €β €β €β’Έβ£Ώβ£Ώβ£Ώβ‘—β β €β €β €β ™β’Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£·β£Ύβ£†β‘™β£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ Œβ£Ύβ£Ώβ£Ώβ£Ώβ£†β €β €β €β ‰β »β£Ώβ‘·β €
β €β €β €β €β €β €β €β €β’Έβ£Ώβ£Ώβ£Ώβ£·β£„β €β €β €β €β €β ˆβ »β£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ‘β €β ˜β£Ÿβ£Ώβ£Ώβ£Ώβ‘†β €β €β €β €β ™β β €
β €β €β €β €β €β €β €β €β €β »β£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Άβ£€β£€β£€β£€β£ β£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ‘Ώβ €β €β €β’ˆβ£Ώβ£Ώβ£Ώβ‘‡β €β €β €β €β €β €β €
β €β €β €β €β €β €β €β €β €β €β ™β Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ÿβ£ β£€β£€β£Άβ£Ώβ£Ώβ£Ώβ Ÿβ €β €β €β €β €β €β €β €
β €β €β €β €β €β €β’€β£ β£€β£„β €β  β’Άβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ÿβ‘β €β €β €β €β €β €β €β €β €
β’€β£€β €β£ β£€β‘ β žβ£Ώβ£Ώβ£Ώβ£Ώβ£Άβ£Ύβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£Ώβ£΄β£Ώβ£·β£¦β£„β£€β’Ώβ‘½β’»β£¦
β »β Άβ Ύβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ Ώβ ‹

Agentic Frameworks Done The Right Way
One config file. True isolation. Full control.


Check out the official blog post or on medium

What Makes Hydra Different

Most AI agent frameworks run everything in a single process with application-level permission checks. If the agent can execute code, it can access anything the process can access. Security is an afterthought.

Hydra agents run in containers. Each agent is isolated at the OS level. They can only see what you explicitly mount. Bash commands execute inside the container, not on your host. Agent's cant break things even if they wanted to.

                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚  hydra exec  β”‚  ← You are here (interactive CLI)
                    β””β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚
          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
          β”‚                β”‚                 β”‚
          β–Ό                β–Ό                 β–Ό
   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚  Container  β”‚  β”‚  Container  β”‚  β”‚  Container  β”‚ 
   β”‚             β”‚  β”‚             β”‚  β”‚             β”‚
   β”‚ Claude Code β”‚  β”‚ Claude Code β”‚  β”‚ Claude Code β”‚
   β”‚  (Agent SDK)β”‚  β”‚  (Agent SDK)β”‚  β”‚  (Agent SDK)β”‚
   β”‚             β”‚  β”‚             β”‚  β”‚             β”‚
   β”‚ /workspace/ β”‚  β”‚ /workspace/ β”‚  β”‚ /workspace/ β”‚
   β”‚  β”” agent/   β”‚  β”‚  β”” agent/   β”‚  β”‚  β”” agent/   β”‚
   β”‚  β”” extra/*  β”‚  β”‚  β”” extra/*  β”‚  β”‚  β”” extra/*  β”‚
   β”‚  β”” ipc/     β”‚  β”‚  β”” ipc/     β”‚  β”‚  β”” ipc/     β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
        main             dev              other

   Each container: isolated filesystem, own CLAUDE.md,
   own session state, own mem0 memory, own IPC namespace.

   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
   β”‚  Optional: hydra up (background orchestrator)    β”‚
   β”‚                                                  β”‚
   β”‚  β€’ Telegram bot listener                         β”‚
   β”‚  β€’ Task scheduler (cron, interval, once)         β”‚
   β”‚  β€’ IPC message routing                           β”‚
   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Other key differences:

Typical Agent Framework Hydra
Security model Permission checks in code or prompt OS-level container isolation
Bash commands Runs on host Runs in ephemeral container
File access Full Access?? Only mounted paths exist in the container. Can be read-only
Agent isolation Shared memory, one process Separate containers, resource allocation
Configuration Multiple files, env vars Single hydra.yaml
Runtime Claude API wrapper Claude Agent SDK (Claude Code)

How It Works

  1. Create your agents via the Hydra CLI or hydra.yaml
  2. Assign agent resources such as folder mounts, tools, MCP servers, etc.
  3. Enter interactive sessions inside the containers (running claude code!)
  4. Exit when finished and the container is stopped, memory and progress remains.

Each agent has its own:

  • CLAUDE.md file (persistent memory/instructions)
  • Persistent vector memory via mem0 (self hosted or cloud)
  • Session state (conversation context)
  • Filesystem (isolated from other agents)
  • IPC namespace (can't send messages as other agents)

Quick Start

Guided (recommended)

The /setup skill handles config creation, .env, agent setup, and container build interactively:

git clone https://github.com/RickConsole/hydra.git
cd hydra
npm install && npm run build && npm link
./container/build.sh
claude          # then run /setup inside the session

Manual

git clone https://github.com/RickConsole/hydra.git
cd hydra
npm install && npm run build && npm link
./container/build.sh

# Add your API key to secrets.env (outside project root, never mounted)
mkdir -p ~/.config/hydra
echo "ANTHROPIC_API_KEY=sk-ant-..." > ~/.config/hydra/secrets.env

# Create a minimal hydra.yaml
cat <<'EOF' > hydra.yaml
version: "1"
project: my-project
agents:
  - name: Main
    folder: main
EOF

# Create your first agent and start a session
hydra agent create --name "Main" --folder main
hydra exec main

Configuration

Everything lives in one file: hydra.yaml.

Minimal config

The smallest working config β€” just a version and one agent:

version: "1"
project: my-project
agents:
  - name: Main
    folder: main

Full config

version: "1"
project: hydra

# Agents (each runs in its own container)
agents:
  - name: Main Assistant
    folder: main
    container:
      mounts:
        - host_path: ~/projects
          container_path: projects
          readonly: false

  - name: Dev Helper
    folder: dev
    bot: mydevbot                    # Connect to Telegram
    chat_id: "-1009876540010"        # Telegram chat ID
    container:
      timeout: 600000
      mounts:
        - host_path: ~/src
          container_path: src
          readonly: false
      secrets:                       # Per-agent secrets from secrets.env
        - AWS_ACCESS_KEY_ID
        - AWS_SECRET_ACCESS_KEY

# Telegram bots
bots:
  mydevbot:
    name: MyDevBot
    token: env:TELEGRAM_BOT_TOKEN   # References .env variable
    platform: telegram

# Self-hosted memory (requires `hydra infra up`)
memory:
  provider: qdrant
  qdrant_url: http://localhost:6333
  ollama_url: http://localhost:11434

# Security (mount allowlist lives separately for tamper-proofing)
security:
  mounts:
    non_main_readonly: true
    blocked_patterns:
      - .ssh
      - .gnupg
      - password
      - secret

Environment Variables

Sensitive values in hydra.yaml use env:VAR_NAME syntax to reference the host environment:

token: env:TELEGRAM_BOT_TOKEN

These are resolved at config load time from whatever is in your shell environment or .env file. This is for Hydra's own config (bot tokens, etc.) β€” not for what gets passed into containers.

Secrets (Container Injection)

Agent containers receive secrets from ~/.config/hydra/secrets.env β€” a dedicated file that lives outside the project root and is never mounted into any container. This follows the same tamper-proof principle as the mount allowlist.

# ~/.config/hydra/secrets.env
ANTHROPIC_API_KEY=sk-ant-...
AWS_ACCESS_KEY_ID=AKIA...
AWS_SECRET_ACCESS_KEY=...
CUSTOM_TOKEN=abc123

A set of base variables (ANTHROPIC_API_KEY, CLAUDE_CODE_OAUTH_TOKEN, MEM0_API_KEY, QDRANT_URL, OLLAMA_URL, OPENAI_API_KEY, LITELLM_API_KEY) are injected into every container if present. Additional secrets are opt-in per agent:

agents:
  - name: Deploy Bot
    folder: deploy
    container:
      secrets:
        - AWS_ACCESS_KEY_ID
        - AWS_SECRET_ACCESS_KEY

Only the keys listed in secrets (plus the base vars) are injected. An agent can't access secrets it hasn't been granted β€” even if they exist in secrets.env.

Mount Security (Two-File Model)

Mounts require approval from two independent config files:

  1. hydra.yaml β€” declares what an agent wants mounted (lives in the project)
  2. ~/.config/hydra/mount-allowlist.json β€” declares what's allowed to be mounted (lives outside the project)

Both must agree for a mount to work. Even if an agent modifies hydra.yaml, it can't grant itself access to paths that aren't pre-approved in the external allowlist. The allowlist is never mounted into containers and can't be reached by agents.

// ~/.config/hydra/mount-allowlist.json
{
  "allowedRoots": [
    { "path": "~/src", "allowReadWrite": true, "description": "Source code" }
  ],
  "blockedPatterns": [".ssh", ".gnupg", ".aws", "credentials"],
  "nonMainReadOnly": true
}

If the allowlist file doesn't exist, all additional mounts are blocked by default.

CLI Reference

Command Description
hydra up [-f] Start orchestrator (daemon; -f for foreground)
hydra down Stop orchestrator and infrastructure
hydra status Show orchestrator/agent status
hydra exec <agent> [args] Interactive Claude Code session in agent container
hydra agents List configured agents
hydra agent create --name "X" --folder x Create new agent (or run without flags for interactive)
hydra tasks List scheduled tasks
hydra logs [agent] [-n N] Tail orchestrator or agent logs
hydra config validate [path] Validate hydra.yaml

Claude Code skills: Run claude in the project root, then use /setup for first-time installation or /add-agent to create agents with Telegram, mounts, and secrets.

Supported Channels

  • CLI (hydra exec) β€” Direct interactive sessions with agents
  • Telegram β€” Multimodal support (images, PDFs, etc)

Requirements

  • Node.js 20+
  • Docker + Docker Compose (for self-hosted memory)
  • Anthropic API key or Claude Code OAuth
  • Telegram bot token (optional)

Environment Variables

Container secrets go in ~/.config/hydra/secrets.env. Host-side config (bot tokens, etc.) can use .env in the project root or your shell environment.

Variable Where Description
ANTHROPIC_API_KEY secrets.env API key for Claude (injected into all containers)
CLAUDE_CODE_OAUTH_TOKEN secrets.env OAuth token from Claude Code (auto-managed)
QDRANT_URL secrets.env Qdrant vector DB URL (default: http://localhost:6333)
OLLAMA_URL secrets.env Ollama embedding server URL (default: http://localhost:11434)
LITELLM_API_KEY secrets.env LiteLLM Proxy API key

Security Model

  1. Container isolation β€” Each agent runs in a separate container
  2. Explicit mounts β€” Agents can only see mounted directories
  3. Scoped secrets β€” Agents only receive secrets they're granted in hydra.yaml; source file lives outside project root
  4. IPC namespacing β€” Agents can only send messages to their own chats
  5. External allowlist β€” Mount permissions live outside agent reach
  6. Main privilege β€” Only the main agent can register new agents

See docs/SECURITY.md for the full security model.

Contributing

Hydra is designed to be small enough to understand and modify. PRs welcome for:

  • Security fixes
  • Bug fixes
  • Clear improvements to core functionality

For new features, consider whether they belong in core or as optional extensions.

Credits

Shoutout to Nanoclaw (https://github.com/qwibitai/nanoclaw) which was the inspiration for agentic containerization.

License

AGPL-3.0

About

Multi-agent AI orchestration system

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •