Hermes Agent features guide running on Telegram with SSH worker backend.
Architecture — Dual Container
The agentiko setup runs two Docker containers that communicate via SSH:
Telegram ──→ agentiko-hermes (172.20.0.3) ──SSH──→ agentiko-worker (172.20.0.2)
│ │
│ /opt/data/ │ /root/
│ ├── AGENTS.md (read at boot) │ ├── output/recon_us/
│ ├── SOUL.md (reference) │ ├── tools/
│ ├── skills/207 (skill library) │ ├── scripts/
│ └── config.yaml │ └── .ssh/
│ │
│ Runs Hermes Agent core │ Runs recon tools
│ Reads AGENTS.md/SOUL.md at boot │ Executes nmap/curl/python3
│ Loads skills from /opt/data/skills/ │ No /opt/data/ access
│ Handles Telegram chat │ Pure execution node
Important: When you are in the worker terminal (SSH), you will NOT find AGENTS.md, SOUL.md, or /opt/data/. Those live on the Hermes host (.3). This is correct behaviour — the worker is a pure execution environment.
Connection: Telegram → Hermes Gateway → Worker SSH (Alpine container) Toolkit: nmap, masscan, ffuf, nuclei, httpx, subfinder, dnsx, Python 3, gcc, git, and 199+ skills (21 recon, 100+ redteam, 4 meta, 4 apple, 2 chains, plus built-in)
Language policy: ALL output — responses, documentation, reports, findings — in English. Always. No exceptions.
Slash Commands (Telegram)
Commands that work in this chat:
| Command | What it does |
|---|---|
/model <name> |
Switch model (e.g. /model deepseek/deepseek-flash) |
/model |
Show current model |
/config |
Show current config |
/reset |
Fresh session |
/yolo |
Toggle YOLO mode (skip dangerous command approvals) |
/title <name> |
Name the session |
/skills |
Manage skills |
/skill <name> |
Load a skill into session |
/platforms |
Show connected platform status |
/status |
Current session info |
/profile |
Active profile |
/usage |
Token usage |
/help |
List commands |
/cron |
Manage scheduled jobs |
/search <query> |
Search past conversations |
/retry |
Resend last message |
/stop |
Kill background processes |
Important: Do NOT run
hermescommands in the worker terminal — they don't exist there. Use slash commands in chat.
YOLO Mode
Skips dangerous command approval prompts. Useful for active hunting sessions where every command would otherwise block.
Enable via chat
/yolo
Toggles on/off. Immediate effect.
Enable via config (persistent)
hermes config set approvals.mode off
Run this on the Hermes host (not the worker). Takes effect after /reset.
What it does
Normally, commands like rm, masscan with raw sockets, or SQL injection probes prompt for user confirmation. YOLO mode auto-approves them. Cron jobs already run YOLO-equivalent by default.
Cron Jobs (Recurring Automation)
Schedule scans and tasks that run automatically and deliver results to Telegram.
Basic syntax
/cron add "<schedule>" "<prompt>"
Schedule formats
| Format | Example | Every... |
|---|---|---|
| Minutes | 30m |
30 minutes |
| Hours | every 2h |
2 hours |
| Days | every 1d |
1 day |
| Fixed time | every 9am |
Daily at 9am |
| ISO | 2026-07-01T09:00:00 |
One-shot at date |
| Cron | 0 */6 * * * |
Every 6 hours |
Practical examples
# Port scan every 12h
/cron add "every 12h" "scan target.com ports 1-1000 with nmap and save to output"
# Subdomains every morning
/cron add "every 9am" "enumerate subdomains of target.com with subfinder + httpx and report new ones"
# Health check every hour
/cron add "every 1h" "ping target.com and alert if down"
# Daily web fuzzing
/cron add "every 1d" "ffuf target.com/FUZZ with common wordlist and report new directories"
# Full weekly scan (Sunday 8am)
/cron add "0 8 * * 0" "full scan target.com: nmap -sV -sC -p- + nuclei"
Management
| Command | What it does |
|---|---|
/cron list |
List all jobs |
/cron run <id> |
Execute now |
/cron pause <id> |
Pause |
/cron resume <id> |
Resume |
/cron remove <id> |
Delete |
Script-only mode (zero LLM cost)
For jobs that just run a script and deliver stdout verbatim:
/cron add "every 5m" "check if nginx is running" --no-agent --script check-nginx.sh
Skills in cron jobs
Load skills in cron jobs for context:
# With agentiko-worker, agent knows which tools are installed
/cron add "every 6h" "scan target.com" --skills agentiko-worker
# With redteam context
/cron add "every 12h" "full recon target.com" --skills agentiko-worker
# redteam skills available at: redteam/web2-recon, redteam/offensive-osint, etc.
Silent mode
Add [SILENT] to suppress delivery when there's nothing to report:
/cron add "every 1h" "[SILENT] check if port 443 of target.com is open. Only report if closed."
Dual-frequency pattern (recommended for long-term monitoring)
# Lightweight: every 1h — script-only, zero LLM tokens
# Heavy analysis: every 6h — DeepSeek V4 Pro analyzes changes
Light cron (no_agent=True): every 1h — script stdout verbatim
Heavy cron (with LLM): every 6h — compare results, model: deepseek/deepseek-v4-pro
Subagent Delegation (Parallelism)
Hermes dispatches subagents in parallel automatically for complex tasks.
Capacity: Up to 3 concurrent subagents Each has: isolated context + its own terminal session Results: Combined into a single response
When to ask for it
"Full scan on target.com: nmap common ports, subfinder subdomains, httpx on results — all in parallel"
"Research X and Y simultaneously and give me a comparison"
What NOT to delegate
- Tasks needing user interaction (subagents can't ask questions)
- Simple 1-2 command tasks (just say it normally)
Dual-Agent Hunting (Pro + Flash Architecture)
For targets needing active surveillance (not just passive monitoring), dispatch two subagents working together.
Architecture
Agent Flash (DeepSeek Flash) — fast, cheap, wide scanning
├── subfinder + httpx across all targets
├── ffuf on critical endpoints
├── fast nuclei templates
├── outputs: raw findings, "what changed"
└── saves to /root/output/recon_us/new_targets/
Agent Pro (DeepSeek V4 Pro) — heavy, analysis, exploitation
├── receives Flash findings
├── impact analysis (CORS, XMLRPC, WP users)
├── exploitation chain (e.g. CORS → phishing, XMLRPC → brute)
├── documents new techniques
└── saves to /root/output/recon_us/deep/
When to use
| Scenario | Use |
|---|---|
| "Light maintenance scan" | Flash alone |
| "Hunt vulnerabilities on these targets" | Flash + Pro in parallel |
| "Monitor changes and alert me" | Cron with Flash (frequent) + Pro (analysis) |
| "Deep dive a specific target" | Pro + redteam skills |
Dispatch pattern
delegate_task(tasks=[
{
"goal": "Scan target: subfinder, httpx, nuclei critical. Return JSON.",
"toolsets": ["terminal", "file", "web"]
},
{
"goal": "Analyze findings and suggest exploitation next steps.",
"context": "depends on Flash output",
"toolsets": ["terminal", "file", "skills", "web"]
}
])
Data structure (recon_us folder)
For targets with pre-collected data, organize as:
recon_us/
├── US_COMPANIES_VULNS.md — overview, tables, executive summary
├── deep/ — Agent Pro findings (detailed per-target)
├── new_targets/ — Agent Flash discoveries
├── techniques/ — New techniques discovered during hunting
├── skills/ — Generated skill files
└── targets/
├── target1.com.md — individual deep-dive
└── ...
Each individual deep-dive must contain:
- Vulnerabilities found (table)
- Reproducible PoCs (curl commands)
- Attack chain (step by step)
- Security contact
RSC Content Extraction (Vercel/Next.js Bypass)
When a target runs on Vercel with Next.js and the WAF blocks curl/browser, the content may still be in the first RSC (React Server Components) payload. Extraction method:
Step 1 — Fetch the page
# First request often gets through before Vercel rate-blocks
curl -sL "https://target.com" -m 30 > /tmp/page.html
Step 2 — Extract RSC chunks
import re
with open('/tmp/page.html') as f:
html = f.read()
# Find the RSC content
idx = html.find('PLAYBOOK') # or other marker near your content
if idx >= 0:
chunk = html[idx:idx+150000]
# Decode Next.js RSC escaping
cleaned = chunk.replace('\\n', '\n')
cleaned = cleaned.replace('\\u003c', '<').replace('\\u003e', '>')
cleaned = cleaned.replace('\\u0026', '&').replace('\\u0027', "'")
cleaned = cleaned.replace('\\u0022', '"').replace('\\/', '/')
cleaned = cleaned.replace('\\'', "'").replace(''', "'")
cleaned = cleaned.replace('\\"', '"').replace('"', '"')
# Strip HTML tags
cleaned = re.sub(r'<[^>]+>', '', cleaned)
# Clean RSC noise
lines = [l.strip() for l in cleaned.split('\n') if l.strip() and len(l.strip()) > 2]
content = '\n'.join(lines)
Pitfalls
- First request matters — Vercel Security Checkpoint blocks after detecting automation. The FIRST curl to a fresh IP often gets through before the checkpoint triggers.
- RSC format varies by Next.js version and build. The escape patterns above work for App Router (RSC streaming). Pages Router uses different encoding.
- Rate limits reset — waiting 5-10 minutes before retrying may get a fresh pass through the checkpoint.
Persistent Memory
Hermes remembers you between sessions automatically.
What's saved:
- Preferences (language, tone, preferred model)
- Environment details (worker, paths, tools)
- Project conventions
- Lessons learned
How it works:
- Auto-saves after each interaction
- Memory is loaded at the start of every new session
- Auto-compacts when full (~2200 char limit)
No need to ask to save — it's automatic. To see saved data:
hermes memory status(on Hermes host, not the worker).
Session Search
Hermes searches ALL past conversations (not just the current one):
/search "nmap command from last week"
/search "what was that recon skill we used"
/search "scan results from the old target"
Uses FTS5 (SQLite full-text search) — fast, zero LLM token cost.
Web Dashboard
A Hermes web dashboard runs on the host, accessible via SSH tunnel:
URL: http://localhost:9119
Login: admin / agentiko
What you can do there:
- Manage sessions
- View gateway logs
- Configure providers and models
- Manage skills and plugins
⚠️ The dashboard does NOT show live chat. It's a Hermes management interface, not a conversation replay. Conversations are in the local SQLite database.
Model Switching
Switch models mid-conversation without losing context:
/model deepseek/deepseek-flash # DeepSeek Flash
/model openai/gpt-4o # GPT-4o
/model anthropic/claude-sonnet-4 # Claude Sonnet 4
/model # Show current model
Instant switch — no
/resetneeded. Conversation history stays intact.
Practical Workflows
Automated recon (delegated)
full recon on target.com:
- nmap top 1000 ports
- subfinder for subdomains
- httpx on found subdomains
run everything in parallel and give me a summary
Scan with save
nmap -sV -sC target.com, save the result, then show me
Continuous monitoring
create a cron for every morning at 8am to run subfinder + httpx on target.com and show what changed
Vulnerability analysis
nuclei on target.com with medium and high severity templates, then summarize
Rapid-fire recon with script + cron
create a monitor script for these 7 targets:
ecommerce-wine.com, mattress-retailer.com, realestate-platform.com, tools-retailer.com, target-health-saas.com, retail-chain.com, entertainment-franchise.com
Check: HTTP status, WP users, XMLRPC, CORS every run
Cron: every 1h, script-only
Deep analysis: every 6h with V4 Pro, compare changes
Dual-agent overnight operation
Spawn 2 agents:
1. DeepSeek V4 Pro — deep exploit existing critical targets
2. DeepSeek Flash — discover NEW vulnerable targets
Both document everything. Cron runs hourly to continue.
Quick Tips
- Long scans: use tmux on worker:
tmux new -s scan && nmap ...(Ctrl+B D to detach,tmux attach -t scanto return) - Save results: always to
/root/output/— persists across container restarts - Worker vs Telegram: shell commands go to worker SSH. Slash commands (
/model,/reset) go to Hermes - Redteam skills: available as
redteam/<skill-name>(e.g.redteam/web2-recon,redteam/hunt-xss). Also:recon/<skill>,chains/<skill>,meta/<skill>,apple/<skill>. Full library: 199+ skills. - [SILENT] in cron: suppress delivery when nothing new to report
- Write_file blocks scripts: use
execute_codewith Pythonopen() + os.chmod()to write.shfiles - Images from Telegram: cached on host at
/root/.hermes/cache/images/— if I can't find it, resend so I can try again - YOLO mode for hunting:
/yolotoggles approval prompts off - Always English — all responses, docs, reports, and findings in English