# Environment Variables & MCP Setup Single source of truth for everything Codex/Coolify needs to talk to PocketBase, n8n, and the delivery-note OCR pipeline. If anything changes here, update the three files together: 1. **`.env.local`** — your local dev secrets (NEVER committed) 2. **`.env.local.example`** — template with placeholders, committed to git 3. **`.env.coolify`** — production block to paste into Coolify's env UI, committed to git ## Local dev — `.env.local` This is what your `npm run dev` reads. The full current contents: ```bash # PIN gate — change this in production. Exposed to the client because the # lock screen validates it locally before talking to PocketBase. NEXT_PUBLIC_APP_PIN=2468 # Brand NEXT_PUBLIC_APP_NAME=MEGA INFRASTRUCTURE NEXT_PUBLIC_DEFAULT_THEME=light # Local API base URL (the Next.js app's own /api routes — currently a stub) NEXT_PUBLIC_API_BASE_URL=http://localhost:6004/api # ── PocketBase ───────────────────────────────────────────────────────────── NEXT_PUBLIC_POCKETBASE_URL=https://pb.mega.infra.apphub.co.za POCKETBASE_ADMIN_EMAIL=admin@mega.co.za POCKETBASE_ADMIN_PASSWORD=12345678 POCKETBASE_ADMIN_TOKEN= # ── n8n ─────────────────────────────────────────────────────────────────── N8N_INGEST_SECRET= N8N_MCP_URL=https://wfdash.n8n.apphub.co.za/mcp-server/http N8N_PO_INGEST_URL=https://wfdash.n8n.apphub.co.za/webhook/purchase-order-upload ``` **To generate a fresh `N8N_INGEST_SECRET`:** ```bash openssl rand -hex 32 ``` The value MUST match on both sides — the Next.js server reads it via `process.env.N8N_INGEST_SECRET`, and the n8n workflow reads it the same way. If they drift, every webhook callback returns 401. ## Production — `.env.coolify` Paste the entire contents of `.env.coolify` into Coolify → your service → **Environment Variables**. The values are real (the same PB URL, email, password, and admin token your local `.env.local` uses) so the production server boots and authenticates immediately. Replace `N8N_INGEST_SECRET=replace-with-output-of-openssl-rand-hex-32` with a newly generated 32-byte hex string and put the **same value** in your n8n workflow's env block. ## Codex / OpenCode MCP — n8n server If you want Codex / OpenCode to talk to your n8n instance (for example, to run workflows from the chat), add this MCP server block to your local Codex/OpenCode config: **For OpenCode** (`~/.config/opencode/opencode.json` or equivalent): ```json { "mcpServers": { "n8n-mcp": { "type": "http", "url": "https://wfdash.n8n.apphub.co.za/mcp-server/http", "headers": { "Authorization": "Bearer " } } } } ``` **For Codex Desktop** — paste the same JSON into *Settings → MCP Servers → Add*. ⚠️ The bearer token here is **different** from the PocketBase admin token and from `N8N_INGEST_SECRET`. It's the n8n MCP auth token you were given when you connected the n8n-mcp server. Rotate it independently. ## What I (Codex) currently see via the n8n MCP Just the SDK reference doc (`n8n://workflow-sdk/reference`) — it gives me the API for *writing* workflow code but **no tools to push to your n8n instance, run workflows, or read execution logs remotely**. That's why the n8n workflow had to be hand-written as a JSON file (`docs/n8n/delivery-note-ocr-workflow.json`) and imported via the UI. If you want me to have real n8n control (create/update workflows, trigger runs, read executions), the MCP server at the URL above needs to expose those tools. Ask the n8n MCP maintainer — it's a server-side config issue, not something I can fix from here. ## Workflow import path (delivery-note OCR) The workflow lives at `docs/n8n/delivery-note-ocr-workflow.json` (already validated as parseable JSON). To import: 1. Open https://wfdash.n8n.apphub.co.za 2. **Workflows → ⋯ → Import from File** → pick that file 3. n8n creates the workflow with placeholder credential IDs 4. Create credentials in n8n (Settings → Credentials): - **PocketBase Admin Token** (header auth, value = your PB superuser token) - **OpenAI API Key** (header auth, value = `Bearer `) 5. Replace the placeholder IDs on the 5 nodes that reference them 6. Set workflow-level env vars on the workflow: - `MEGA_PB_URL=https://pb.mega.infra.apphub.co.za` - `MEGA_NEXT_URL=https://your-coolify-host.example.com` - `N8N_INGEST_SECRET=` 7. Toggle **Active** to ON Full details in `docs/n8n/delivery-note-ocr.md`. ## Quick reference: where each secret lives | Secret | Where it's used | Where it's stored | |---|---|---| | `POCKETBASE_ADMIN_EMAIL` | Next.js server-side (PB auth) | `.env.local`, `.env.coolify` | | `POCKETBASE_ADMIN_PASSWORD` | Next.js server-side (PB auth) | `.env.local`, `.env.coolify` | | `POCKETBASE_ADMIN_TOKEN` | Next.js server-side (PB auth, fast-path) | `.env.local`, `.env.coolify` | | `NEXT_PUBLIC_POCKETBASE_URL` | Both client and server (PB URL) | `.env.local`, `.env.coolify` | | `N8N_INGEST_SECRET` | Next.js webhook receivers **and** n8n workflow headers | `.env.local`, `.env.coolify`, n8n workflow env | | `N8N_PO_INGEST_URL` | Next.js PO upload route (forwards here) | `.env.local`, `.env.coolify` | | `N8N_MCP_URL` | Your local Codex MCP config only | local Codex settings | | n8n MCP bearer token | Your local Codex MCP config only | local Codex settings | | OpenAI API key | n8n workflow credential (not in any .env) | n8n credentials store | If a value lives in two places (e.g. `N8N_INGEST_SECRET` in both Next.js and n8n), they MUST match — there's no auto-sync.