docs: cutover checklist and tsnats usage

Add docs/cutover.md (shadow :8001, embedded NATS :4223, REQUIRE_BEARER
host-token default, cutover/rollback; no JetStream for job-complete).
Expand README Usage with env table and pkg/tsnats snippet; add
examples/tsnats-bulk.
This commit is contained in:
George Lambert 2026-09-29 12:14:46 -04:00
commit 30b5df6757

View file

@ -6,7 +6,7 @@ Go MCP timestamping server for Verae. Digests only; sibling to the Python server
Implements the same tools as https://mcp.verae.ai/mcp (`stamp`, `verify`, `hash_report`, auth tools) using the official MCP Go SDK. Designed for shadow deploy beside Python, then cutover.
AI assistants use MCP. Bulk app workers can import `pkg/tsnats` for core NATS request/reply on `verae.ts.*` (job-complete stays ephemeral; no JetStream for those events).
AI assistants use MCP. Bulk app workers can import `pkg/tsnats` for core NATS request/reply on `verae.ts.*` (job-complete stays ephemeral; no JetStream for those events). Cutover steps: [`docs/cutover.md`](docs/cutover.md).
## Table of Contents
@ -22,19 +22,81 @@ cd verae-mcp-timestamping-server-go
go build -o bin/verae-mcp-timestamping-server ./cmd/verae-mcp-timestamping-server
```
Requires Go 1.26+. Design: `docs/superpowers/specs/2026-09-29-go-mcp-timestamping-server-design.md`.
Requires Go 1.26+. Design: `docs/superpowers/specs/2026-09-29-go-mcp-timestamping-server-design.md`. Shadow systemd unit (not installed by this build): `deploy/verae-mcp-timestamping-go.service`.
## Usage
Shadow beside Python (`:8000` stays live):
```sh
VERAE_MCP_TRANSPORT=streamable-http \
VERAE_MCP_HOST=127.0.0.1 \
VERAE_MCP_PORT=8001 \
VERAE_NATS_LISTEN=127.0.0.1:4223 \
VERAE_MCP_REQUIRE_BEARER=0 \
./bin/verae-mcp-timestamping-server
```
Point clients at `http://127.0.0.1:8001/mcp`. Global stamps use `https://api.veraetime.net` with auth from `~/.verae/auth.properties` (or `VERAE_AUTH_PROPERTIES`). Embedded NATS (default `127.0.0.1:4223`; set `VERAE_NATS_LISTEN=` empty to disable) serves `verae.ts.*` with the same ledger/VeraeTime routing; job-complete is core `verae.ts.completed` only. For stdio MCP: `-transport stdio` or `VERAE_MCP_TRANSPORT=stdio`.
Point MCP clients at `http://127.0.0.1:8001/mcp`. For stdio: `-transport stdio` or `VERAE_MCP_TRANSPORT=stdio`.
| Variable | Default | Notes |
| --- | --- | --- |
| `VERAE_MCP_TRANSPORT` | `streamable-http` | or `stdio` |
| `VERAE_MCP_HOST` | `127.0.0.1` | HTTP bind |
| `VERAE_MCP_PORT` | `8000` | shadow examples use `8001` |
| `VERAE_NATS_LISTEN` | `127.0.0.1:4223` | embedded NATS; set empty to disable |
| `VERAE_MCP_REQUIRE_BEARER` | `0` | `0` = host-token keeper when no caller bearer; `1` = require caller bearer |
| `VERAE_GLOBAL_URL` | `https://api.veraetime.net` | |
| `VERAE_AUTH_PROPERTIES` | `$HOME/.verae/auth.properties` | |
| `VERAE_GLOBAL_TOKEN` | empty | optional static host bearer |
| `VERAE_LEDGER_PATH` | `$HOME/.verae/mcp-timestamp-local.json` | |
| `VERAE_MCP_CORS` | off | set `1` for browser CORS |
Global stamps use VeraeTime with auth from `auth.properties` (or caller Bearer). Embedded NATS serves `verae.ts.*`; job-complete is core `verae.ts.completed` only.
Parity smoke when Python `:8000` and Go `:8001` are both up:
```sh
./scripts/parity_smoke.sh
```
### pkg/tsnats
Bulk workers talk to the embedded (or any) NATS URL. Digests only; `SubscribeCompleted` is core NATS, not JetStream.
```go
package main
import (
"context"
"log"
"os"
"git.georgelambert.org/marchon/verae-mcp-timestamping-server-go/pkg/tsnats"
)
func main() {
url := os.Getenv("NATS_URL")
if url == "" {
url = "nats://127.0.0.1:4223"
}
client, err := tsnats.Connect(url)
if err != nil {
log.Fatal(err)
}
defer client.Close()
ctx := context.Background()
digest := "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
receipts, err := client.Stamp(ctx, digest, tsnats.StampOptions{Scope: "global"})
if err != nil {
log.Fatal(err)
}
log.Printf("receipts: %+v", receipts)
}
```
Runnable sketch: `examples/tsnats-bulk/main.go`.
## Contributing