# Local multi-container stack. HF Spaces uses server/Dockerfile + server/start.sh instead. # This service overrides the Dockerfile CMD so Compose uses the sidecar MCP services below. # In-stack MCP URLs use service DNS on port 8000; host maps are 8001/8002. x-ollama-env: &ollama_env OLLAMA_HOST: ${OLLAMA_HOST:-http://host.docker.internal:11434} OLLAMA_MODEL: ${OLLAMA_MODEL:-} OLLAMA_EMBEDDING_MODEL: ${OLLAMA_EMBEDDING_MODEL:-qwen3-embedding:4b} x-openai-env: &openai_env OPENAI_API_KEY: ${OPENAI_API_KEY:-} OPENAI_BASE_URL: ${OPENAI_BASE_URL:-} x-mcp-healthcheck: &mcp_healthcheck test: - CMD-SHELL - > node -e "fetch('http://localhost:8000/').then(r=>process.exit([200,301,302,307,308,400,404,405].includes(r.status)?0:1)).catch(()=>process.exit(1))" interval: 10s timeout: 5s retries: 20 start_period: 30s services: neo4j: image: neo4j restart: unless-stopped environment: NEO4J_AUTH: neo4j/${NEO4J_PASSWORD:-ilovecoding} ports: - "7474:7474" - "7687:7687" healthcheck: # Substs from project .env; keep NEO4J_AUTH in sync (user/ for neo4j image) test: ["CMD-SHELL", "cypher-shell -a bolt://localhost:7687 -u ${NEO4J_USER:-neo4j} -p ${NEO4J_PASSWORD:-ilovecoding} 'RETURN 1' >/dev/null 2>&1 || exit 1"] interval: 10s timeout: 5s retries: 20 start_period: 30s neurocaster_env: build: context: . dockerfile: server/Dockerfile env_file: - .env command: ["uvicorn", "server.app:app", "--host", "0.0.0.0", "--port", "8000"] environment: SHARED_DATA_ROOT: ${SHARED_DATA_ROOT:-/app/shared_data} NEO4J_URI: ${NEO4J_URI:-bolt://neo4j:7687} NEO4J_USER: ${NEO4J_USER:-neo4j} NEO4J_PASSWORD: ${NEO4J_PASSWORD:-ilovecoding} NEO4J_DATABASE: ${NEO4J_DATABASE:-neo4j} CODE_INDEXING_MCP_URL: ${CODE_INDEXING_MCP_URL:-http://code_indexing_mcp:8000/api/mcp} CODE_INDEXING_MCP_INGEST_TOOL: ${CODE_INDEXING_MCP_INGEST_TOOL:-ingest_repo} CODE_INDEXING_MCP_SEARCH_TOOL: ${CODE_INDEXING_MCP_SEARCH_TOOL:-search_code_graph} NEO4J_CYPHER_MCP_URL: ${NEO4J_CYPHER_MCP_URL:-} NEO4J_CYPHER_MCP_TOOL: ${NEO4J_CYPHER_MCP_TOOL:-read_neo4j_cypher} DECK2VIDEO_MCP_URL: ${DECK2VIDEO_MCP_URL:-http://deck2video_mcp:8000/api/mcp} MERMAID_MCP_URL: ${MERMAID_MCP_URL:-https://mcp.mermaid.ai/mcp} MERMAID_MCP_AUTH_TOKEN: ${MERMAID_MCP_AUTH_TOKEN:-} NEUROCASTER_REPO_POOL: ${NEUROCASTER_REPO_POOL:-/app/shared_data/curriculum/repo_pool.json} NEUROCASTER_CURRICULUM_STATE: ${NEUROCASTER_CURRICULUM_STATE:-/app/shared_data/curriculum/state.json} NEUROCASTER_DEFAULT_GITHUB_REPO: ${NEUROCASTER_DEFAULT_GITHUB_REPO:-psf/requests} NEUROCASTER_DEFAULT_GITHUB_REF: ${NEUROCASTER_DEFAULT_GITHUB_REF:-main} NEUROCASTER_OFFLINE_MCP: ${NEUROCASTER_OFFLINE_MCP:-0} NEUROCASTER_CURRICULUM_LEVEL: ${NEUROCASTER_CURRICULUM_LEVEL:-easy} NEUROCASTER_ENABLE_CRITIC: ${NEUROCASTER_ENABLE_CRITIC:-1} NEUROCASTER_ENABLE_TRIBE: ${NEUROCASTER_ENABLE_TRIBE:-0} GITHUB_TOKEN: ${GITHUB_TOKEN:-} HF_TOKEN: ${HF_TOKEN:-} ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY:-} <<: [*ollama_env, *openai_env] extra_hosts: - "host.docker.internal:host-gateway" ports: - "8000:8000" volumes: - ./shared_data:/app/shared_data depends_on: code_indexing_mcp: condition: service_healthy deck2video_mcp: condition: service_healthy code_indexing_mcp: image: nishithp/code_indexing_mcp restart: unless-stopped ports: - "8001:8000" environment: HOST: "0.0.0.0" PORT: "8000" MCP_PATH: /api/mcp/ SHARED_DATA_ROOT: ${SHARED_DATA_ROOT:-/app/shared_data} NEO4J_URI: ${NEO4J_URI:-bolt://neo4j:7687} NEO4J_USER: ${NEO4J_USER:-neo4j} NEO4J_PASSWORD: ${NEO4J_PASSWORD:-ilovecoding} NEO4J_DATABASE: ${NEO4J_DATABASE:-neo4j} <<: [*ollama_env, *openai_env] extra_hosts: - "host.docker.internal:host-gateway" volumes: - ./shared_data:/app/shared_data depends_on: neo4j: condition: service_healthy healthcheck: *mcp_healthcheck deck2video_mcp: image: nishithp/deck2video_mcp restart: unless-stopped ports: - "8002:8000" environment: HOST: "0.0.0.0" PORT: "8000" MCP_PATH: /api/mcp/ SHARED_DATA_ROOT: ${SHARED_DATA_ROOT:-/app/shared_data} volumes: - ./shared_data:/app/shared_data healthcheck: *mcp_healthcheck