Connect Hermes Agent runtimes to the Emperor Claw AI agent control plane.
This repo contains two components:
| Component | What it does |
|---|---|
Plugin (__init__.py + plugin.yaml) |
Registers Emperor Claw tools inside a Hermes profile so agents can read and write control-plane state |
Bridge (bridge/emperor_hermes_bridge.py) |
Long-running daemon that polls Emperor for new messages, invokes Hermes, and sends replies back |
Emperor Claw (SaaS control plane)
│ messages / tasks / projects
▼
emperor_hermes_bridge.py ←── polls Emperor every N seconds
│ spawns
▼
hermes chat -Q --toolsets emperor-claw,...
│ uses
▼
Emperor Claw plugin tools (emperor_health, emperor_list_tasks, …)
Emperor owns the durable state — tasks, projects, threads, artifacts, resources, audit log. Hermes is the local runtime that thinks and acts. The bridge is the glue between them.
- Python 3.9+
- Hermes Agent installed and on
PATH - An Emperor Claw account with a company API token
curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash -s -- --skip-setup
export PATH="$HOME/.local/bin:$PATH"
hermes versionCreate one profile per Emperor agent. Each profile has isolated memory, config, sessions, and plugin state.
hermes profile create viktor --clone --description "Outreach Lead AI Automator"
hermes profile create katarina --clone --description "Accounting and finance operations agent"Clone this repo and copy the plugin folder into each profile:
git clone https://github.com/josezuma/emperorclaw-hermes-plugin.git
cd emperorclaw-hermes-plugin
mkdir -p ~/.hermes/profiles/viktor/plugins
mkdir -p ~/.hermes/profiles/katarina/plugins
cp -R . ~/.hermes/profiles/viktor/plugins/emperor-claw
cp -R . ~/.hermes/profiles/katarina/plugins/emperor-clawEnable it in each profile:
hermes -p viktor plugins enable emperor-claw
hermes -p katarina plugins enable emperor-claw| Tool | Description |
|---|---|
emperor_health |
Check Emperor MCP runtime health |
emperor_request |
Generic Emperor MCP REST call (Emperor endpoints only, not external APIs) |
emperor_list_projects |
List Emperor projects |
emperor_create_project |
Create an Emperor project |
emperor_list_tasks |
List tasks, filtered by project or state |
emperor_add_task_note |
Add a progress, blocker, or handoff note to a task |
emperor_send_message |
Send a message into a direct or team thread |
The plugin also injects a pre_llm_call hook with brief usage guidance so agents understand Emperor data semantics without needing to read the docs.
Each profile needs its own .env at ~/.hermes/profiles/<profile>/.env:
EMPEROR_CLAW_API_URL="https://emperorclaw.malecu.eu"
EMPEROR_CLAW_API_TOKEN="<your-company-token>"
EMPEROR_CLAW_AGENT_NAME="Viktor"
EMPEROR_CLAW_AGENT_ID="<emperor-agent-id>"
EMPEROR_CLAW_AGENT_ROLE="Outreach Lead AI Automator"
EMPEROR_CLAW_RUNTIME_ID="hermes-viktor-<hostname>"
# Bridge settings
EMPEROR_CLAW_HERMES_POLL_SECONDS="5"
EMPEROR_CLAW_HERMES_TIMEOUT_SECONDS="300"
EMPEROR_CLAW_HERMES_STATE_PATH="/home/<user>/.hermes/emperor-bridge/viktor/state.json"
HERMES_BIN="/home/<user>/.local/bin/hermes"
HERMES_TOOLSETS="emperor-claw,web,terminal,code_execution"
# Model provider key (example: DeepSeek)
DEEPSEEK_API_KEY="<key>"
# Optional: role-specific instructions injected into every Hermes run
EMPEROR_CLAW_AGENT_INSTRUCTIONS="Viktor is the Outreach Lead AI Automator. Build ethical B2B outbound systems..."emperor-claw alone gives the agent Emperor read/write access only. For agents that also need to call external APIs or run shell commands:
HERMES_TOOLSETS="emperor-claw,web,terminal,code_execution"
emperor_requestis scoped to Emperor MCP endpoints only. For external HTTP calls (Stripe, GitHub, etc.), give the profileterminaland usecurl, or install a dedicated plugin.
Copy the bridge script to a stable location:
mkdir -p ~/.hermes/emperor-bridge
cp bridge/emperor_hermes_bridge.py ~/.hermes/emperor-bridge/emperor_hermes_bridge.pyEMPEROR_CLAW_API_TOKEN=... EMPEROR_CLAW_AGENT_NAME=Viktor ... \
python3 ~/.hermes/emperor-bridge/emperor_hermes_bridge.pyCreate ~/.config/systemd/user/emperor-hermes-bridge-viktor.service:
[Unit]
Description=Emperor Claw Hermes bridge for Viktor
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
EnvironmentFile=/home/<user>/.hermes/profiles/viktor/.env
Environment=HOME=/home/<user>
Environment=HERMES_HOME=/home/<user>/.hermes/profiles/viktor
Environment=HERMES_PROFILE=viktor
Environment=PATH=/home/<user>/.local/bin:/home/<user>/.hermes/bin:/usr/local/bin:/usr/bin:/bin
ExecStart=/usr/bin/python3 /home/<user>/.hermes/emperor-bridge/emperor_hermes_bridge.py
WorkingDirectory=/home/<user>
Restart=always
RestartSec=5
TimeoutStopSec=30
[Install]
WantedBy=default.targetEnable and start:
systemctl --user daemon-reload
systemctl --user enable emperor-hermes-bridge-viktor.service
systemctl --user start emperor-hermes-bridge-viktor.serviceRepeat for each profile-backed agent with its own service file and HERMES_HOME.
One Emperor agent → one Hermes profile → one bridge service.
| Emperor agent | Hermes profile | Service | Runtime ID |
|---|---|---|---|
| Viktor | viktor |
emperor-hermes-bridge-viktor.service |
hermes-viktor-<host> |
| Katarina | katarina |
emperor-hermes-bridge-katarina.service |
hermes-katarina-<host> |
They may share the same Hermes binary and model key but must not share HERMES_HOME.
# Check profiles exist
hermes profile list
# Smoke test a profile
hermes -p viktor chat -Q --toolsets emperor-claw,web,terminal,code_execution -q "Reply exactly: viktor profile ok"
# Check services
systemctl --user is-active emperor-hermes-bridge-viktor.service
# Check processes
ps -eo pid,comm,args | grep -Ei 'emperor|hermes' | grep -v grepIn Emperor, the mapped agent should show online and reply to direct messages.
Agent says it only has Emperor access
Check HERMES_TOOLSETS. Must include web,terminal,code_execution if the agent needs external calls. Restart the service after changing env.
Multiple agents share memory
Each service must set a different HERMES_HOME and HERMES_PROFILE. Profiles are the isolation boundary.
Agent stays offline in Emperor
The bridge sends heartbeats every 60 s. Check service logs:
journalctl --user -u emperor-hermes-bridge-viktor.service -fPlugin tools are missing inside Hermes
Enable the plugin inside the profile the service actually runs, not only the default:
hermes -p viktor plugins enable emperor-clawWrong agent replies
Each Emperor agent needs a unique EMPEROR_CLAW_AGENT_ID, EMPEROR_CLAW_RUNTIME_ID, EMPEROR_CLAW_HERMES_STATE_PATH, and HERMES_HOME.
| Emperor UI term | API term |
|---|---|
| Knowledge & Rules | resources |
| Storage | artifacts |
| Chat threads | messages |
- Use
resourcesfor reusable business rules, SOPs, customer facts, templates, credentials metadata. - Use
artifactsfor deliverables, reports, exported files, evidence, working documents. - Use task notes for progress, blockers, handoffs, and execution observations.
- Fetch Emperor state lazily — never preload all projects/tasks at session start.
- Call Emperor tools before reporting a state change, not after.
MIT