Hermes Council: Multi-Agent Deliberation for Hermes Agent
MCP server for adversarial multi-perspective deliberation with Hermes Agent.
- Author
- Ridwannurudeen
- Stars
- 46
- Language
- Python
- License
- MIT
- Upstream updated
- 2026-05-11

Hermes Council is an MCP server that provides an adversarial judgment layer for Hermes Agent, enabling it to stress-test plans, diffs, claims, decisions, and risky actions before executing them. Once wired up, an agent can call on a council of specialized personas to deliberate on any proposal and receive a structured verdict with explicit fields like allow, deny, top_risks, and required_checks. This integration turns a single-agent system into one that benefits from multiple intellectual traditions arguing and synthesizing a final decision.
What It Does
Hermes Council gives Hermes Agent a dedicated judgment layer. Before the agent ships a plan, changes code, accepts a claim, or takes a risky action, it can call a council that forces multiple intellectual traditions to argue, dissent, and produce a structured final verdict. The result is not another long chain-of-thought prompt. It is an MCP toolset with explicit verdict fields: allow, allow_with_conditions, deny, top_risks, required_checks, missing_evidence, verified_sources, and next_actions.
- Preflight risky actions: Review deploys, migrations, file operations, public messages, and other high-stakes actions before execution. Returns a verdict, blocking risks, required checks, and safer alternatives.
- Review plans and diffs: Stress-test implementation plans and code diffs for bugs, missing tests, integration failures, security regressions, and weak assumptions.
- Fact-check claims with evidence: Fetch supplied URLs, optionally search the web, pass source snippets to the council, and separate
verified_sourcesfrom model-citedsources. - Compare decisions: Evaluate multiple options against explicit criteria and return one recommended path with risks, evidence gaps, and next actions.
- Run adversarial deliberation: Use Advocate, Skeptic, Oracle, Contrarian, and Arbiter personas to expose disagreement and synthesize a calibrated verdict.
- Produce RL signals: Extract DPO preference pairs and normalized rewards from council verdicts for evaluator and training workflows.
Supporting features include custom personas, fast/standard/deep modes, optional audit logs, packaged Hermes skills, OpenAI-compatible provider support, and stdio MCP transport.
Setup
Install
Install the package directly from the GitHub repository:
pip install "hermes-council @ git+https://github.com/Ridwannurudeen/hermes-council.git"
For RL/evaluator usage, install with the rl extra:
pip install "hermes-council[rl] @ git+https://github.com/Ridwannurudeen/hermes-council.git"
Configure Hermes Agent
Add the MCP server to ~/.hermes/config.yaml:
mcp_servers:
council:
command: python
args: ["-m", "hermes_council.server"]
hermes-council-server is also installed as a console script. The python -m form is recommended because it works even when the Python user scripts directory is not on PATH.
You can also wire the server up interactively with Hermes Agent's own CLI:
hermes mcp add
hermes mcp add/list/remove/test writes to the same mcp_servers key in ~/.hermes/config.yaml, so either path produces an equivalent config.
Set one provider key. The API key priority is:
COUNCIL_API_KEY > OPENROUTER_API_KEY > NOUS_API_KEY > OPENAI_API_KEY
For example, to use OpenRouter:
export OPENROUTER_API_KEY=your-key-here
PowerShell:
$env:OPENROUTER_API_KEY = "your-key-here"
Then restart Hermes Agent or run /reload-mcp.
Install Hermes Skills
hermes-council install-skills
This copies skill definitions to ~/.hermes/skills/council/.
Smoke Test Without Hermes Agent
python -m hermes_council.server
The server speaks MCP over stdio, so it waits for JSON-RPC messages. Use this mainly to verify that the module entrypoint imports cleanly.
Use The Evaluator Directly
import asyncio
from hermes_council.rl.evaluator import CouncilEvaluator
async def main():
evaluator = CouncilEvaluator(model="nousresearch/hermes-3-llama-3.1-70b")
verdict = await evaluator.evaluate(
content="Ship the migration after tests pass.",
question="Is this deployment plan safe enough?",
criteria=["safety", "rollback", "evidence"],
)
print(verdict.confidence_score)
print(evaluator.normalized_reward(verdict))
asyncio.run(main())
Configuration Reference
Environment Variables
| Variable | Description | Default |
|---|---|---|
COUNCIL_API_KEY | Council-specific API key | unset |
OPENROUTER_API_KEY | OpenRouter API key | unset |
NOUS_API_KEY | Nous API key | unset |
OPENAI_API_KEY | OpenAI API key | unset |
COUNCIL_BASE_URL | Base URL when COUNCIL_API_KEY is used | https://openrouter.ai/api/v1 |
OPENAI_BASE_URL | Base URL when OPENAI_API_KEY is used | https://api.openai.com/v1 |
COUNCIL_MODEL | Model for persona calls | nousresearch/hermes-3-llama-3.1-70b |
COUNCIL_TIMEOUT | LLM request timeout in seconds | 60 |
COUNCIL_CONFIG | Custom persona config path | ~/.hermes-council/config.yaml |
COUNCIL_EVIDENCE_SEARCH | Enable web search evidence retrieval | 1 |
COUNCIL_EVIDENCE_TIMEOUT | Evidence fetch timeout in seconds | 8 |
COUNCIL_AUDIT_LOG | Write local JSON audit records | 0 |
COUNCIL_AUDIT_DIR | Audit record directory | ~/.hermes-council/audit |
Council Modes
| Mode | Calls | Use Case |
|---|---|---|
fast | Skeptic + Arbiter | Cheap pre-checks |
standard | Advocate + Skeptic + Oracle + Contrarian + Arbiter | Normal review |
deep | Standard + second Arbiter pass | High-stakes or contentious decisions |
Default Personas
| Persona | Tradition | Role |
|---|---|---|
| Advocate | Steel-manning | Builds the strongest case for the proposal |
| Skeptic | Popperian falsificationism | Finds the observation that would kill the claim |
| Oracle | Empirical base-rate reasoning | Grounds the debate in history and data |
| Contrarian | Kuhnian paradigm critique | Rejects the framing and proposes alternatives |
| Arbiter | Bayesian synthesis | Updates on all arguments and emits the final verdict |
Custom Personas
Create ~/.hermes-council/config.yaml:
personas:
security_analyst:
tradition: "Adversarial security thinking"
system_prompt: "You are a security analyst. Evaluate every claim for attack vectors, failure modes, and adversarial scenarios."
scoring_weights:
threat_assessment: 0.4
evidence: 0.3
rigor: 0.3
tags: ["security", "adversarial"]
Custom personas merge with the defaults. Use the same name to override a default.
How It Works

Architecture
The architecture follows a clear pipeline from Hermes Agent to a structured verdict:
Hermes Agent
|
| MCP stdio tool call
v
hermes-council server
|
+--> optional evidence retrieval
| - fetch supplied URLs
| - optional DuckDuckGo HTML search
| - block localhost/private IP targets
|
+--> parallel deliberators
| - Advocate: steel-man the proposal
| - Skeptic: find falsifiers and failure modes
| - Oracle: base rates and empirical grounding
| - Contrarian: challenge the framing
|
+--> Arbiter
- synthesize disagreement
- emit structured JSON verdict
- produce risks, checks, actions, DPO pairs
The server uses an OpenAI-compatible async client. It tries JSON mode first and falls back to text parsing when a provider rejects response_format.
Evidence Model
When evidence_search=true, retrieval runs before persona calls. The evidence layer produces three fields:
| Field | Meaning |
|---|---|
verified_sources | URLs actually fetched and summarized by Hermes Council |
sources | URLs cited by model outputs |
evidence_errors | Non-fatal retrieval errors from the evidence layer |
Security boundaries:
- Only
httpandhttpsURLs are fetched. - Localhost, private IPs, link-local IPs, multicast, reserved, and unspecified IPs are blocked before fetch.
- Set
COUNCIL_EVIDENCE_SEARCH=0to disable DuckDuckGo search while still allowing supplied public URLs to be fetched.
Tools
Hermes Agent exposes MCP tools with a server prefix. With the config above, the runtime names are mcp_council_council_query, mcp_council_council_gate, and so on.
| Tool | Purpose | Best Use |
|---|---|---|
council_query | General adversarial deliberation | Complex questions with no obvious answer |
council_evaluate | Content quality critique | Research, summaries, specs, and generated answers |
council_gate | Safety decision | allow, allow_with_conditions, or deny before action |
council_preflight | Gate with explicit checks | Deployment, migration, irreversible command, public send |
council_review_plan | Plan review | Implementation plan before coding |
council_review_diff | Diff review | Code changes before commit or PR |
council_review_claim | Claim review | Fact-checking with optional evidence retrieval |
council_decision | Option comparison | Pick one path from two or more options |
Gate Output Example
{
"success": true,
"verdict": "allow_with_conditions",
"allowed": true,
"can_proceed_now": false,
"required_checks": ["verify rollback", "run dry-run"],
"blocking_risks": ["rollback untested"],
"safe_alternative": "stage the action first",
"action_summary": {
"recommendation": "Proceed after verifying rollback and dry-run output.",
"top_risks": ["rollback untested"],
"missing_evidence": ["dry-run output"],
"next_actions": ["run dry-run", "verify rollback"]
}
}
Project Layout
hermes-council/
src/hermes_council/
server.py # FastMCP stdio server and public tool handlers
deliberation.py # persona orchestration, modes, JSON negotiation, DPO pairs
evidence.py # URL/search evidence retrieval and SSRF guards
audit.py # optional local JSON verdict logs
client.py # provider config and AsyncOpenAI singleton
personas.py # default and custom persona definitions
schemas.py # Pydantic models for structured model output
parsing.py # fallback text parsers for non-JSON providers
cli.py # skill installer
rl/evaluator.py # direct evaluator API for reward and DPO workflows
skills/council/ # packaged Hermes skill definitions
examples/ # Atropos/Ouroboros evaluator example
tests/ # unit, integration, packaging, and MCP runtime tests
docs/plans/ # original design and implementation notes
Requirements and Limitations
- Python version: 3.11 or higher, as indicated by the badge in the repository.
- Provider key required: A real provider key is required for actual model-backed verdicts. The server will not produce meaningful output without one.
- DuckDuckGo search reliability: DuckDuckGo HTML search can change; supplied URLs are more reliable than search results.
- Evidence truth:
verified_sourcesproves retrieval, not truth. The Arbiter still weighs the evidence. - Transport: The server is stdio MCP only. There is no hosted HTTP service in this repo.
- Latency and cost: The council adds latency and token cost. Use
fastmode for routine preflight. - Model compliance: Model compliance with JSON fields depends on provider/model behavior, though fallback parsing is implemented.
- No bundled config in Hermes Agent: The maintainers of Hermes Agent do not bundle third-party MCP server references in
cli-config.yaml.exampleoroptional-skills/to avoid endorsing one community server over others. Install standalone via the Quickstart above; the server is designed to run that way.
Troubleshooting
Server fails to start
If python -m hermes_council.server fails, check that the package installed cleanly. The smoke test is designed to verify that the module entrypoint imports cleanly. If it does not, reinstall with pip install --force-reinstall "hermes-council @ git+https://github.com/Ridwannurudeen/hermes-council.git".
No key configured
The test suite covers Hermes-compatible no-key failure behavior. If you see errors about missing API keys, set one of the supported environment variables according to the priority order: COUNCIL_API_KEY, OPENROUTER_API_KEY, NOUS_API_KEY, or OPENAI_API_KEY.
Evidence retrieval fails for certain URLs
If evidence retrieval fails for a URL, check that it uses http or https. Localhost, private IPs, link-local IPs, multicast, reserved, and unspecified IPs are blocked before fetch. Non-fatal retrieval errors are reported in the evidence_errors field of the verdict.
DuckDuckGo search stops working
DuckDuckGo HTML search can change without notice. If search results stop appearing, set COUNCIL_EVIDENCE_SEARCH=0 to disable DuckDuckGo search while still allowing supplied public URLs to be fetched. Supplied URLs are more reliable than search results.
Model refuses JSON mode
The server uses an OpenAI-compatible async client. It tries JSON mode first and falls back to text parsing when a provider rejects response_format. If you see malformed output, it may be a provider compatibility issue. The fallback parser handles this, but model compliance with JSON fields depends on provider/model behavior.
Tools not appearing in Hermes Agent
If the MCP tools do not appear after configuration, restart Hermes Agent or run /reload-mcp. Verify the config in ~/.hermes/config.yaml matches the example exactly. The runtime names will have a server prefix, e.g., mcp_council_council_query.
Sources & References
This page was researched from 2 independent sources, combined and verified for completeness.
- 1.Ridwannurudeen/hermes-councilBlog · primary source
- 2.Ridwannurudeen/hermes-council READMEOfficial documentation
The #1 AI Newsletter
The most important ai updates, guides, and fixes — one weekly email.
No spam, unsubscribe anytime. Privacy policy