Hermes Agent ↔ OpenCode — Bidirectional MCP Coordination Bridge
One server to rule them all — handoff tasks, request research, and run parallel workflows between your two AI coding agents.
He-OCode is a Model Context Protocol (MCP) server that lets Hermes Agent and OpenCode work together in real time — not as competitors, but as teammates.
The problem: OpenCode can write code, Hermes can research and orchestrate. But they're siloed. You switch between terminals, copy-paste results, and lose context.
The solution: A shared MCP bridge. Both agents connect to He-OCode as an MCP client. They hand off tasks, request research, report results, and work in parallel — all through structured MCP tool calls.
| Feature | Description |
|---|---|
| Agent A hands off a task → Agent B picks it up via MCP | |
| 🔬 Research | OpenCode asks Hermes to research something → Hermes does it |
| ⚡ Parallel | Both agents work on the same task simultaneously |
| 📊 Status | Real-time coordination state (who's doing what) |
| 🔌 No DB | Simple JSON state file (~/.heocode/state.json) |
| 🌐 Dual Transport | stdio (local) + HTTP/SSE (remote) |
| 🔧 10+ MCP Tools | Full coordination toolkit |
# Clone
git clone https://github.com/Nixera-Studio/He-OCode.git
cd He-OCode
# Dependencies (Python 3.10+)
uv pip install mcp# stdio mode (for local MCP clients)
python3 server.py
# HTTP mode (for remote clients)
python3 server.py --http --port 8377Add to your opencode.json:
{
"mcp": {
"heocode": {
"type": "local",
"command": ["python3", "/path/to/He-OCode/server.py"],
"enabled": true
}
}
}Add to ~/.hermes/config.yaml:
mcp_servers:
heocode:
command: python3
args: ["/path/to/He-OCode/server.py"]Now restart both agents. He-OCode tools appear automatically.
| Tool | Purpose | Called By |
|---|---|---|
heocode_handoff |
Hand off a task to another agent | Any agent |
heocode_get_tasks |
Check for pending tasks assigned to you | Any agent |
heocode_submit |
Report result/status of a completed task | Any agent |
heocode_resolve |
Manually resolve a stuck task | Any agent |
| Tool | Purpose | Called By |
|---|---|---|
heocode_research |
Request research from the other agent | Any agent |
heocode_parallel |
Broadcast a task to all agents | Any agent |
| Tool | Purpose | Called By |
|---|---|---|
heocode_status |
Full coordination state + task counts | Any agent |
heocode_ping |
Heartbeat / connectivity check | Any agent |
heocode_export |
Export full state as JSON | Any agent |
heocode_clear |
Clean up completed tasks | Any agent |
sequenceDiagram
participant OC as OpenCode
participant HO as He-OCode
participant HE as Hermes
OC->>HO: heocode_handoff("Refactor auth module")
OC->>OC: Continues other work
HE->>HO: heocode_get_tasks(agent="hermes")
HO-->>HE: [task: refactor auth module]
HE->>HE: Implements refactor
HE->>HO: heocode_submit(task_id, result="Done")
OC->>HO: heocode_get_tasks(status="completed")
HO-->>OC: {task: auth refactor, result: "Done"}
- OpenCode is coding, hits a question about an API
- OpenCode calls
heocode_research(query="How does FastAPI handle background tasks?") - Hermes picks it up, researches via web search
- Hermes calls
heocode_submit(task_id, result="Full answer...") - OpenCode gets the result and continues
- Both agents need to write tests for different modules
- OpenCode calls
heocode_parallel(description="Write unit tests for module X and Y") - Both agents pick up the task simultaneously
- Each submits results independently
All state lives in ~/.heocode/state.json:
{
"tasks": [
{
"id": "task_a1b2c3d4e5f6",
"description": "Refactor auth module",
"from_agent": "opencode",
"to_agent": "hermes",
"status": "completed",
"result": "Done: refactored JWT handling...",
"task_type": "handoff"
}
],
"agents": {
"opencode": {"name": "opencode", "last_seen": "...", "status": "idle"},
"hermes": {"name": "hermes", "last_seen": "...", "status": "busy"}
}
}# Build
docker build -t heocode .
# Run HTTP mode
docker run -p 8377:8377 -v ~/.heocode:/root/.heocode heocode --http --port 8377- State file is local to the machine by default
- HTTP mode binds to
127.0.0.1by default (localhost only) - No authentication built-in (add a reverse proxy for production)
- OpenCode MCP server is
localtype (subprocess), no network exposure
# Quick smoke test with MCP Inspector
npx @modelcontextprotocol/inspector python3 server.py
# Or test manually
python3 -c "
import json, subprocess, sys
proc = subprocess.Popen(
['python3', 'server.py'],
stdin=subprocess.PIPE, stdout=subprocess.PIPE, text=True
)
# Initialize
init = json.dumps({'jsonrpc': '2.0', 'id': 1, 'method': 'initialize', 'params': {}})
proc.stdin.write(init + '\n')
proc.stdin.flush()
# List tools
tools = json.dumps({'jsonrpc': '2.0', 'id': 2, 'method': 'tools/list', 'params': {}})
proc.stdin.write(tools + '\n')
proc.stdin.flush()
import time; time.sleep(0.5)
out = proc.stdout.readline()
print('Tools:', out[:200])
proc.kill()
"Issues, PRs, and ideas welcome! See CONTRIBUTING.md.
MIT — see LICENSE.
Built by Nixera Studio. Proudly open source.