Run the Server

Implemented ยท basicDraft 0.1

Basic, local, and unauthenticated. One Go binary serves a web UI, an HTTP API, and an MCP server on one port. It has no authentication, no signatures, and no authorization. It listens on localhost unless you pass another address, so keep it on your machine or a trusted network.

Run it

make seed    # load the Spring Spin example story into share/techlog.db
make run     # serve the UI, the API and MCP at http://localhost:8080
make skill   # optional: install the Claude skill into ~/.claude/skills

Data lives in share/techlog.db, a SQLite file the server creates on first start. The share/ directory is git-ignored.

Make targets

TargetWhat it does
make runBuild and serve. Pass flags with ARGS="--addr :9090".
make seedLoad the Spring Spin example story. Safe to run more than once.
make flushDelete the database and every event in it. It asks first; FORCE=1 skips the prompt. It refuses to run while a server answers on the port.
make resetFlush, then seed.
make skillInstall the Claude skill into ~/.claude/skills as a symlink. make skill-remove undoes it.
make checkLint with golangci-lint and run the tests.

The binary takes --addr (default localhost:8080), --db (default share/techlog.db), and --store (only sqlite exists today). A bare :8080 would listen on every interface.

The web UI

The UI is read-only: it never writes an event.

The HTTP API

RoutePurpose
POST /api/v1/eventsRecord an event. The server assigns the id.
GET /api/v1/events/{id}One event with its outgoing and incoming links.
GET /api/v1/events?q&system&type&since&until&limitSearch, newest first. Default 20, at most 100.
GET /api/v1/systemsThe known systems.
GET /api/v1/systems/{system}/historyThe latest events of one system, oldest first. Default 50, at most 200.
POST /api/v1/linksLink two existing events.

Errors share one shape: {"error": {"code", "message", "details"}}. The codes are invalid_event (422), not_found (404), bad_request (400), and internal (500). There is no update and no delete: events are immutable.

MCP and the Claude skill

The same port serves MCP at /mcp. MCP integration lists the five tools and shows how to connect Claude.

Storage

The server talks to storage through a small interface: insert an event, add a link, get an event, search, list links, list systems. The SQLite backend is pure Go, needs no C toolchain, and keeps the full event JSON next to indexed columns and a full-text index. It uses one connection, and write transactions take the lock up front, so a second process on the same file waits instead of failing.

A new backend is a package under internal/store that passes the shared contract test suite, plus one line that selects it with --store. Nothing else in the server changes.