FastMCP auto-enables DNS rebinding protection when host=127.0.0.1
(the default). Production requests from brain.woltje.com were rejected
with 421 Invalid Host header because the allowed_hosts list was empty.
Added MCP_ALLOWED_HOSTS config field (comma-separated). When set,
DNS rebinding protection is enabled with those hosts; when empty,
protection is disabled. Set MCP_ALLOWED_HOSTS=brain.woltje.com in
Portainer stack env.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
StreamableHTTPSessionManager requires its run() context manager to be
active before handling requests. Without it, every MCP call returned
RuntimeError: Task group is not initialized.
Also changed mount from /mcp to / (at end of route list) so the MCP
endpoint is accessible at /mcp rather than /mcp/mcp, matching the
sub-app's internal route structure.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements v0.0.1 of OpenBrain:
- FastAPI REST API (capture, search, recent, stats) with Bearer auth
- MCP server (streamable HTTP at /mcp) exposing all 4 tools
- pgvector schema (vector(1024) for bge-m3)
- asyncpg connection pool with lazy init + graceful close
- Ollama embedding client with fallback (stores thought without vector if Ollama unreachable)
- Woodpecker CI pipeline (lint + kaniko build + push to Gitea registry)
- Portainer/Swarm deployment compose
- Mosaic framework files: AGENTS.md, PRD.md, TASKS.md, scratchpad
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>