§ Codex — the learning wiki
Architecture — one container, three faces
Codex is a single Node service (Express) backed by Postgres, in two Docker containers. The same process serves three interfaces over one port (3200): the HTML UI, a JSON API, and the MCP server. They all talk to one shared store module (db.js), so there is exactly one source of truth.
Why one process, not three services
The MCP server could be its own container. It isn't, on purpose: the MCP, the API, and the UI all need identical read/write logic over the same tables. Splitting them means duplicating that logic or inventing an internal RPC. Mounting all three on one Express app means they literally call the same JavaScript functions (createPage, tree, search). One bug to fix, one store to reason about.
The request paths
┌─────────────────────────────┐
browser ──HTML──▶ │ Express (server.js) │
agent ──MCP───▶ │ / → EJS views │
scripts ──JSON──▶ │ /api/* → JSON │ ──▶ db.js ──▶ Postgres
│ /mcp → MCP transport │ (store)
└─────────────────────────────┘
Publishing
The app binds only to 127.0.0.1:3200 — never 0.0.0.0 — so the container port can't bypass the firewall. Nginx (via the site helper) is the single public path in, terminating TLS with the wildcard cert and proxying to that local port. One command put it live: site new wiki.oaoisme.top proxy 3200.
See data-model for the tables and markdown-pipeline for how page bodies become HTML.
Subpages