- adolf-llm/server.js now loads SHARED_MCP_SERVERS from the mounted
/shared-mcp.json instead of a hardcoded stub, so adding a shared MCP
server is a one-file change. Verified end-to-end: a real chat-completions
turn writes a session .mcp.json containing both cognee and openclaw-tools
entries (kimi itself still needs `kimi login` in adolf-llm-home, unrelated
to this change).
- Documented the Gate-1 transport reconciliation: decompiled the installed
@moonshot-ai/kimi-code package to confirm its .mcp.json schema keys remote
servers on `transport` ("stdio"/"http"/"sse", inferred as "http" from a
bare `url`, never "sse"), while OpenClaw's own canonical mcp.servers schema
uses different literals ("streamable-http"/"sse") for the same field name
and treats `type` as a CLI-native alias it normalizes itself. `type: "http"`
is the one shape both consumers tolerate, so shared-mcp.json keeps it.
- New openai/openclaw-tools/ service: a stateless MCP-over-Streamable-HTTP
bridge (Node, @modelcontextprotocol/sdk) exposing message_send, cron_create,
cron_list, nodes_invoke, and browser_invoke, each proxying to the OpenClaw
gateway's POST /tools/invoke. Verified initialize + tools/list handshake and
a tools/call against the not-yet-running `adolf` gateway returns a clean
isError content instead of breaking the MCP connection. Documented that
cron/nodes are hard-denied on that HTTP surface by default until P6 adds
them to gateway.tools.allow; message/browser are not similarly restricted.
- Wired openclaw-tools into docker-compose.yml (openai network, :8020) and
added its shared-mcp.json entry alongside cognee.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LeqyaxJF2nbRXJtae2kNB2
268 lines
9.0 KiB
YAML
268 lines
9.0 KiB
YAML
services:
|
|
litellm-db:
|
|
image: postgres:16-alpine
|
|
container_name: litellm-db
|
|
environment:
|
|
- POSTGRES_DB=litellm
|
|
- POSTGRES_USER=litellm
|
|
- POSTGRES_PASSWORD=litellm
|
|
volumes:
|
|
- /mnt/ssd/dbs/litellm/postgres:/var/lib/postgresql/data
|
|
restart: always
|
|
|
|
litellm:
|
|
image: ghcr.io/berriai/litellm:main-latest
|
|
container_name: litellm
|
|
ports:
|
|
- "4000:4000"
|
|
volumes:
|
|
- ./litellm-config.yaml:/app/config.yaml
|
|
environment:
|
|
- DATABASE_URL=postgresql://litellm:litellm@litellm-db:5432/litellm
|
|
- LITELLM_MASTER_KEY=sk-fjQC1BxAiGFSMs
|
|
- LANGFUSE_PUBLIC_KEY=${LANGFUSE_PUBLIC_KEY:-changeme}
|
|
- LANGFUSE_SECRET_KEY=${LANGFUSE_SECRET_KEY:-changeme}
|
|
- LANGFUSE_HOST=http://langfuse:3000
|
|
- OPENROUTER_API_KEY=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
|
|
command: ["--config", "/app/config.yaml", "--port", "4000"]
|
|
extra_hosts:
|
|
- "host.docker.internal:host-gateway"
|
|
depends_on:
|
|
- litellm-db
|
|
- langfuse
|
|
restart: always
|
|
|
|
kimi-agent:
|
|
build: ./kimi-agent
|
|
container_name: kimi-agent
|
|
volumes:
|
|
- /home/alvis/kimi-workspace:/workspace
|
|
- kimi-agent-home:/root/.kimi-code
|
|
restart: unless-stopped
|
|
|
|
langfuse-db:
|
|
image: postgres:16-alpine
|
|
container_name: langfuse-db
|
|
environment:
|
|
- POSTGRES_DB=langfuse
|
|
- POSTGRES_USER=langfuse
|
|
- POSTGRES_PASSWORD=langfuse
|
|
volumes:
|
|
- /mnt/ssd/dbs/langfuse/postgres:/var/lib/postgresql/data
|
|
restart: always
|
|
|
|
langfuse:
|
|
image: ghcr.io/langfuse/langfuse:2
|
|
container_name: langfuse
|
|
ports:
|
|
- "3200:3000"
|
|
environment:
|
|
- DATABASE_URL=postgresql://langfuse:langfuse@langfuse-db:5432/langfuse
|
|
- NEXTAUTH_URL=https://lf.alogins.net
|
|
- NEXTAUTH_SECRET=532a746b24ac40afa39f9d317031cab94d4d6881107ea3b1209b28020f1a9761
|
|
- SALT=7927b3b0092afe4542274940b557becea6418a5fed79f7acd25c3a789349fdc9
|
|
- AUTH_DISABLE_SIGNUP=true
|
|
depends_on:
|
|
- langfuse-db
|
|
restart: always
|
|
|
|
qdrant:
|
|
image: qdrant/qdrant
|
|
container_name: qdrant
|
|
ports:
|
|
- "6333:6333"
|
|
- "6334:6334"
|
|
restart: always
|
|
volumes:
|
|
- /mnt/ssd/dbs/qdrant:/qdrant/storage:z
|
|
|
|
faster-whisper:
|
|
image: fedirz/faster-whisper-server:latest-cuda
|
|
container_name: faster-whisper
|
|
runtime: nvidia
|
|
ports:
|
|
- "8880:8000"
|
|
environment:
|
|
- WHISPER__MODEL=deepdml/faster-whisper-large-v3-turbo-ct2
|
|
- WHISPER__INFERENCE_DEVICE=cuda
|
|
- WHISPER__COMPUTE_TYPE=int8
|
|
- WHISPER__LANGUAGE=ru
|
|
- NVIDIA_VISIBLE_DEVICES=all
|
|
- NVIDIA_DRIVER_CAPABILITIES=compute,utility
|
|
volumes:
|
|
- /mnt/ssd/ai/faster-whisper:/root/.cache/huggingface
|
|
restart: always
|
|
|
|
silero-tts:
|
|
build: ./silero-tts
|
|
container_name: silero-tts
|
|
ports:
|
|
- "8881:8881"
|
|
volumes:
|
|
- /mnt/ssd/ai/silero-tts:/cache/torch
|
|
restart: always
|
|
|
|
pipecat:
|
|
build: ./pipecat
|
|
container_name: pipecat
|
|
ports:
|
|
- "8882:8882"
|
|
environment:
|
|
- LIVEKIT_URL=ws://host.docker.internal:7880
|
|
- LIVEKIT_PUBLIC_URL=wss://lk.alogins.net
|
|
- LIVEKIT_API_KEY=devkey
|
|
- LIVEKIT_SECRET=ef3ef4b903ca8469b09b2dd7ab6af529c4d2f3c95668f53832fc351cf67777a9
|
|
- ADOLF_URL=http://host.docker.internal:8000/v1
|
|
- STT_URL=http://host.docker.internal:8880/v1
|
|
- TTS_URL=http://host.docker.internal:8881/v1
|
|
- STT_MODEL=deepdml/faster-whisper-large-v3-turbo-ct2
|
|
- TTS_VOICE=onyx
|
|
extra_hosts:
|
|
- "host.docker.internal:host-gateway"
|
|
restart: unless-stopped
|
|
|
|
# Adolf — OpenClaw fork (Matrix-first personal assistant). Skeleton only:
|
|
# real config (Matrix channel, SOUL.md, model provider -> adolf-llm:8010) is
|
|
# wired in P6. Not started until its config/keys exist. Source: /home/alvis/adolf.
|
|
adolf:
|
|
build: ../../adolf
|
|
image: adolf:local
|
|
container_name: adolf
|
|
environment:
|
|
- HOME=/home/node
|
|
- OPENCLAW_HOME=/home/node
|
|
- OPENCLAW_STATE_DIR=/home/node/.openclaw
|
|
- OPENCLAW_CONFIG_PATH=/home/node/.openclaw/openclaw.json
|
|
- OPENCLAW_CONFIG_DIR=/home/node/.openclaw
|
|
- OPENCLAW_WORKSPACE_DIR=/home/node/.openclaw/workspace
|
|
- OPENCLAW_GATEWAY_TOKEN=${ADOLF_GATEWAY_TOKEN:-}
|
|
- TZ=Europe/Riga
|
|
volumes:
|
|
- adolf-state:/home/node/.openclaw
|
|
extra_hosts:
|
|
- "host.docker.internal:host-gateway"
|
|
cap_drop:
|
|
- NET_RAW
|
|
- NET_ADMIN
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
init: true
|
|
ports:
|
|
- "18789:18789"
|
|
- "18790:18790"
|
|
command:
|
|
["node", "dist/index.js", "gateway", "--bind", "lan", "--port", "18789"]
|
|
restart: unless-stopped
|
|
|
|
# cognee-llm — stateless one-shot Kimi-CLI wrapper for Cognee's batch cognify
|
|
# (P3). Opposite policy to kimi-agent: no resume, non-streaming, text-only.
|
|
# Note (SPIKE-FINDINGS gate 5): Cognee should DEFAULT its LLM to LiteLLM; this
|
|
# is the optional low-volume path. Needs `kimi login` in its own volume.
|
|
cognee-llm:
|
|
build: ./cognee-llm
|
|
container_name: cognee-llm
|
|
ports:
|
|
- "8011:8011"
|
|
volumes:
|
|
- cognee-llm-home:/root/.kimi-code
|
|
restart: unless-stopped
|
|
|
|
# adolf-llm — conversational Kimi-CLI wrapper (:8010), the model backend for
|
|
# the Adolf OpenClaw gateway (P2). Real streaming (SSE), chat_id session-keying
|
|
# + 1:1 kimi resume, media, per-session .mcp.json sourced from the shared
|
|
# shared-mcp.json contract (cognee-mcp P4, openclaw-tools P5). Needs
|
|
# `kimi login` in adolf-llm-home.
|
|
adolf-llm:
|
|
build: ./adolf-llm
|
|
container_name: adolf-llm
|
|
ports:
|
|
- "8010:8010"
|
|
volumes:
|
|
- adolf-llm-workspace:/workspace
|
|
- adolf-llm-home:/root/.kimi-code
|
|
- ./shared-mcp.json:/shared-mcp.json:ro
|
|
restart: unless-stopped
|
|
|
|
# cognee — Adolf's memory backend (P4). FastAPI + embedded Kuzu graph +
|
|
# Qdrant vectors. LLM via cognee-llm:8011 (Kimi CLI wrapper), embeddings via
|
|
# ollama directly (host.docker.internal:11436, separate compose project —
|
|
# hence extra_hosts below). Sole owner of the on-disk Kuzu/SQLite files
|
|
# under /mnt/ssd/dbs/cognee/ (Kuzu is not safe for concurrent multi-process
|
|
# access) — never run a second process against those files.
|
|
cognee:
|
|
build: ./cognee
|
|
container_name: cognee
|
|
restart: unless-stopped
|
|
environment:
|
|
# Real OS env var, not just the mounted .env file: the qdrant vector
|
|
# adapter's registration hook (cognee/Dockerfile's sitecustomize.py)
|
|
# gates on os.environ.get("VECTOR_DB_PROVIDER") at Python interpreter
|
|
# start, which only sees actual container env vars — pydantic-settings'
|
|
# env_file=".env" parsing (used for the rest of cognee.env) never
|
|
# populates os.environ itself. Without this, cognee raises
|
|
# "Unsupported vector database provider: qdrant" at startup even though
|
|
# cognee.env sets VECTOR_DB_PROVIDER=qdrant. Verified 2026-07-05.
|
|
- VECTOR_DB_PROVIDER=qdrant
|
|
volumes:
|
|
- ./cognee/cognee.env:/app/.env
|
|
- /mnt/ssd/dbs/cognee/data:/data
|
|
- /mnt/ssd/dbs/cognee/system:/system
|
|
extra_hosts:
|
|
- "host.docker.internal:host-gateway"
|
|
# Not published to the host — only cognee-mcp (same compose network)
|
|
# needs to reach it. Uncomment for local debugging:
|
|
# ports:
|
|
# - "8000:8000"
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 40s
|
|
|
|
# cognee-mcp — thin MCP-to-HTTP proxy in API mode (API_URL=cognee:8000).
|
|
# Never opens the graph/vector files itself, so it's safe to run alongside
|
|
# `cognee` without a second writer on the same Kuzu database. Exposes 3
|
|
# tools: remember / recall / forget.
|
|
cognee-mcp:
|
|
image: cognee/cognee-mcp:1.2.2
|
|
container_name: cognee-mcp
|
|
restart: unless-stopped
|
|
environment:
|
|
- ENV=local
|
|
- LOG_LEVEL=INFO
|
|
- PYTHONUNBUFFERED=1
|
|
- TRANSPORT_MODE=http
|
|
- API_URL=http://cognee:8000
|
|
- MCP_ALLOWED_HOSTS=cognee-mcp:*
|
|
ports:
|
|
- "8001:8000"
|
|
depends_on:
|
|
- cognee
|
|
|
|
# openclaw-tools — MCP bridge (P5) exposing a minimal slice of the Adolf
|
|
# OpenClaw gateway's agent tools (message/cron/nodes/browser) over MCP
|
|
# Streamable HTTP, so Kimi CLI sessions (adolf-llm) can call them instead of
|
|
# bypassing OpenClaw entirely. Proxies each MCP tool call to the gateway's
|
|
# `POST /tools/invoke` HTTP surface (http://adolf:18789). NOTE: `cron` and
|
|
# `nodes` are hard-denied on that surface by default until P6 adds them to
|
|
# `gateway.tools.allow` in the adolf openclaw.json — see openclaw-tools/
|
|
# server.js for the full gate writeup. Not useful until `adolf` (P6) is
|
|
# configured and running; safe to build/run standalone before that.
|
|
openclaw-tools:
|
|
build: ./openclaw-tools
|
|
container_name: openclaw-tools
|
|
environment:
|
|
- OPENCLAW_GATEWAY_URL=http://adolf:18789
|
|
- OPENCLAW_GATEWAY_TOKEN=${ADOLF_GATEWAY_TOKEN:-}
|
|
ports:
|
|
- "8020:8020"
|
|
restart: unless-stopped
|
|
|
|
volumes:
|
|
kimi-agent-home:
|
|
adolf-state:
|
|
cognee-llm-home:
|
|
adolf-llm-workspace:
|
|
adolf-llm-home:
|