services: agap-mcp: build: . restart: unless-stopped network_mode: host environment: - PORT=3100 - NODE_TLS_REJECT_UNAUTHORIZED=0 - HTTPS_PROXY= - HTTP_PROXY= - ALL_PROXY= - https_proxy= - http_proxy= - all_proxy= - BITWARDENCLI_APPDATA_DIR=/bw-data - BW_EMAIL=adolf46@proton.me - BW_PASSWORD=${BW_PASSWORD} - VAULTWARDEN_URL=http://localhost:8041 - GITEA_URL=http://localhost:3000 - HA_URL=http://192.168.1.4:8123 - ZABBIX_URL=http://192.168.1.4:81 - RADICALE_URL=http://localhost:5232 - RADICALE_USER=alvis # kb#147 (A2A-15) — vault trust gate, OFF by default (0). Flipping this # to 1 requires a container restart AND real values for # AGENT_REGISTRY_PATH/AGAP_MCP_AGENT_TOKENS below to be populated first # (see src/trust-gate.js) — that restart is the deliberate handover # step this task does NOT perform (never restart the live agap-mcp # service unattended). Until both are set, vw_* tools behave exactly # as before this change. - AGAP_MCP_ENFORCE_VAULT_TRUST=0 - AGENT_REGISTRY_PATH=/agent-registry.yaml # JSON map {"": ""}. Real per-agent tokens must # be generated, stored in Vaultwarden (e.g. AGAP_MCP_TOKEN_ADOLF, # AGAP_MCP_TOKEN_CLAUDE_CODER), and referenced here via .env — never # inlined in this committed file. Empty object = no caller resolves to # any agent, i.e. fail-closed once ENFORCE is turned on. - AGAP_MCP_AGENT_TOKENS=${AGAP_MCP_AGENT_TOKENS:-{}} # kb#180 (DESIGN-a2a-agents.md §4) — authentication of the LISTENER # itself, a strictly larger gate than the vw_*-only one above. With # this on (the default in code), /mcp, /sse, /messages and # /capture-idea all require `Authorization: Bearer ` resolving # to an agent id in AGAP_MCP_AGENT_TOKENS; /health stays open for this # healthcheck. :3100 is bound on every interface (network_mode: host) # and the LAN carries VPN-terminated peers, so an open listener means # any peer can call ha_call_service / gitea_wiki_write / wiki_edit / # todoist writes. # # ACTIVATION IS NOT AUTOMATIC-SAFE: with auth on and # AGAP_MCP_AGENT_TOKENS empty, the process REFUSES TO START (loud # crash instead of denying every caller while /health says ok). So # AGAP_MCP_AGENT_TOKENS must be populated in this directory's .env # BEFORE the next restart of this service, and every caller # (Adolf/shared-mcp.json, Claude Code .claude.json, the # todoist-capture-plugin) must be given its token — see the kb#180 # migration list. Set AGAP_MCP_REQUIRE_AUTH=0 in .env only as a # deliberate emergency rollback to the old open listener. - AGAP_MCP_REQUIRE_AUTH=${AGAP_MCP_REQUIRE_AUTH:-1} volumes: - /home/alvis/.config/Bitwarden CLI:/bw-data # Read-only: agent-registry.yaml is the version-controlled source of # truth for trust classes (kb#134/kb#147) — mounted, never copied, so # a registry edit takes effect on container restart with no rebuild. - /home/alvis/agap_git/openai/agent-registry.yaml:/agent-registry.yaml:ro # kb#190: /health responds 200 with no auth/side effects (confirmed). # This is a SEPARATE compose project from openai/docker-compose.yml # (network_mode: host, reached from adolf-llm etc. via # host.docker.internal), so it cannot be wired into that file's # depends_on/condition chain -- this only gives it its own status. healthcheck: test: ["CMD-SHELL", "node -e \"fetch('http://localhost:3100/health').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))\""] interval: 15s timeout: 10s retries: 5 start_period: 20s