type
Service
title
nx-master
description
Agent-first CRM — a Go BFF that owns sessions, conversations and CRM data, with Hermes as the agent and an MCP surface for agent access.
tags
crm, agent, mcp, go, sqlite
status
stable
stale_after
Fri Apr 30 2027 02:00:00 GMT+0200 (Central European Summer Time)
generated
crm-bot/deepseek-v4.1-flash · Fri Oct 30 2026 10:53:57 GMT+0100 (Central European Standard Time)
verified
process:live-probe · Fri Oct 30 2026 10:53:57 GMT+0100 (Central European Standard Time)
sources
repo → https://github.com/nextrum-sy/nx-master; live → https://master.nextrum-sy.de/healthz

What it is

One Go service behind nginx on a single Hetzner box. It is deployed as two containers (app, nginx) with the database and telemetry in a named volume, and it is the only component that holds an agent API key — the browser never talks to Hermes.

The service exists to answer one question with an agent instead of a dashboard: "list the customers", "chart the log severities", "who signed in today" — asked in chat, answered from SQLite and the telemetry files, rendered by the model rather than by hand-written Go.

Shape

Layer Thing Notes
Edge nginx :443 master.nextrum-sy.de only · unknown Host → 444 · HSTS without includeSubDomains
App Go, internal/web OAuth session → user; every route resolves a thread through GetChatSession(id, userID)
Run RunRegistry in memory a turn is a detached goroutine, polled by the browser once a second
Store SQLite, WAL single writer; see the data model
Telemetry OTLP JSONL ×3 logs, traces, metrics — readable with jq, no collector
Interface MCP POST /mcp thirteen tools; see MCP tools
Agent Hermes on the host :8642 OpenAI-compatible, streaming; the app is a BFF in front of it

Contract

Routes, as registered in internal/web:

GET  /{$} · /chat · /chat/new · /chat/{id}      chat surface (the only UI)
POST /ui/chat · /ui/sessions                    send a turn · new thread
POST /ui/sessions/{id}/archive · /unarchive     lifecycle
GET  /ui/runs/{id}                              live run state (polled)
GET  /login · /auth/github · /auth/github/callback · /logout
GET  /users                                     allowlist administration
GET  /healthz                                   liveness
POST /mcp                                       MCP over JSON-RPC 2.0

Environment that changes behaviour:

Key Default Meaning
NX_DATA_DIR ./data SQLite + the three OTLP files
NX_PORT 8080 listen port inside the container
MCP_TOKEN — bearer for /mcp; the app refuses to start without it
HERMES_API_URL http://host.docker.internal:8642 the agent
HERMES_API_KEY — required; the BFF's credential, never exposed to the browser
HERMES_MODEL hermes-agent model name sent to the API
NX_HISTORY_TURNS · _TOKENS · _MSG_CHARS 24 · 6000 · 1200 context packing budget
NX_DEV_AUTH_USER — loopback/private bypass, for testing the UI without OAuth
NX_AUTH_DISABLED — break-glass: unauthenticated UI. Never a steady state

Non-goals

See also

Rendered from nx-master/service.md · OKF bundle · regenerate with npm run render