Files
gitops-automation/.env.example
T
william 732246d4fd Add MCP bridge to claude-agent so Hermes can delegate to the real Claude Code CLI
New POST /mcp endpoint (Streamable HTTP transport, stateless — fresh
McpServer+transport per request) exposing one tool, ask_claude_code: runs
the real `claude` binary against a prompt, billed against the Pro/Max
subscription rather than API credits. This works specifically because it's
the actual claude CLI making the request server-side — the same reason
Hermes itself can't authenticate with the subscription directly (proven
earlier: Anthropic rejects the OAuth token from any client that isn't the
real CLI's exact request fingerprint). Read-only: no Edit/Write/git-push/
git-commit tools, since this is a quick-answer bridge, not a repo editor.

Tested end-to-end locally (built + ran the image, curled the full MCP
handshake: initialize -> tools/list -> tools/call) before pushing — got a
real 'pong' back from the actual claude CLI through the MCP protocol.

To register it with Hermes (lives in its own data volume, not git — see
.env.example comment):
  docker exec hermes hermes config set mcp_servers.claude-code.url http://claude-agent:3001/mcp
  docker exec hermes hermes config set 'mcp_servers.claude-code.headers.Authorization' 'Bearer <MCP_BRIDGE_KEY>'
2026-08-23 17:24:46 +00:00

61 lines
2.8 KiB
Bash

# Copy to .env and fill in. Never commit the real .env.
# Note: ACME_EMAIL / Traefik itself are configured separately in ~/traefik/.env —
# Traefik is shared infra, not part of this stack (see docker-compose.yml comment).
# --- domain / TLS ---
MATRIX_SERVER_NAME=matrix.apps.williamturner.eu
AGENT_HOSTNAME=agent.apps.williamturner.eu
HERMES_DASHBOARD_HOSTNAME=hermes.apps.williamturner.eu
# Set to true ONLY for the first-boot window while creating the bot account,
# then back to false (or unset) and redeploy. See README.
MATRIX_ALLOW_REGISTRATION=false
# --- gitea ---
GITEA_URL=https://gitea.apps.williamturner.eu
GITEA_TOKEN=
GITEA_WEBHOOK_SECRET=
# Image the agent runs from — built and pushed by .gitea/workflows/build.yml
GITEA_REGISTRY_IMAGE=gitea.apps.williamturner.eu/<your-gitea-username>/<repo-name>/claude-agent:latest
# --- claude ---
# Run `claude setup-token` interactively (needs a browser + Claude Pro/Max subscription)
# to generate this — it's a long-lived OAuth token, not an API key.
CLAUDE_CODE_OAUTH_TOKEN=
# Any random string — shared secret for claude-agent's /mcp bridge endpoint (see
# agent/src/mcpBridge.js), which lets Hermes delegate a question to the real `claude`
# CLI (billed against the subscription above) via MCP. Register it in Hermes with:
# docker exec hermes hermes config set mcp_servers.claude-code.url http://claude-agent:3001/mcp
# docker exec hermes hermes config set 'mcp_servers.claude-code.headers.Authorization' 'Bearer <this value>'
MCP_BRIDGE_KEY=
# --- litellm (local LLM gateway — used by Hermes, see litellm-config.yaml) ---
OPENROUTER_API_KEY=
# Any random string; also used as litellm's general_settings.master_key.
LITELLM_MASTER_KEY=
# --- hermes (the only agent with a Matrix presence — see README) ---
# Your own Matrix ID — Hermes only responds to this user, and only when @mentioned
# in a room (free-response in DMs).
MATRIX_HUMAN_USER_ID=@william:matrix.apps.williamturner.eu
# Access token for the @hermes bot account — register it on the homeserver, then log
# in as it via /_matrix/client/v3/login to get this token (see README).
HERMES_MATRIX_ACCESS_TOKEN=
# Any random string — bearer key for Hermes's own OpenAI-compatible API server
# (internal network only, not published anywhere).
HERMES_API_SERVER_KEY=
# --- hermes web dashboard (hermes.apps.williamturner.eu) ---
# Hermes's own login gate — mandatory once its dashboard is bound non-loopback (needed
# for Traefik, a separate container, to reach it at all), so this can't be turned off
# while the dashboard is reachable through Traefik.
HERMES_DASHBOARD_USERNAME=william
HERMES_DASHBOARD_PASSWORD=
# 32+ random bytes — `openssl rand -base64 32`
HERMES_DASHBOARD_SECRET=
# --- portainer (GitOps redeploy) ---
PORTAINER_STACK_WEBHOOK_URL=
# --- gitea actions runner ---
ACT_RUNNER_REGISTRATION_TOKEN=