diff --git a/README.md b/README.md index 6bc5edb..976e28b 100644 --- a/README.md +++ b/README.md @@ -2,143 +2,42 @@ [![standard-readme compliant](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme) -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). Cutover steps: [`docs/cutover.md`](docs/cutover.md). +MCP server for digests-only timestamping (public HTTP and local stdio). ## Table of Contents +- [Background](#background) - [Install](#install) - [Usage](#usage) - [Contributing](#contributing) - [License](#license) +## Background + +Public writes require caller Bearer (DEC-654). Optional VERAE_MCP_EDGE_URL bills via zap.verae.ai. +Grok: bearer_token_file or local stdio. Job-complete is core NATS only. + + +**Co-contributors:** Grok (xAI), George Lambert, Scott "R00tPiG Security" Lindsey — Verae Inc. ([verae.com](https://verae.com)). + ## Install ```sh -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`. The ns1 unit `verae-mcp-timestamping.service` runs this binary from `/opt/verae/verae-mcp-timestamping-server-go/bin`. `.forgejo/workflows/test-and-deploy.yml` tests on the `138` runner and `scripts/deploy-138.sh` swaps that binary, with a probe of `http://127.0.0.1:8000/mcp` and rollback to the previous file. - ## 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 +./bin/verae-mcp-timestamping-server -transport http -addr :8000 +# or -transport stdio for laptop host auth ``` -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. - -### Public HTTP vs local stdio (DEC-654) - -| Transport | Writes | -| --- | --- | -| Public HTTP (`mcp.verae.ai`, default streamable-http) | Caller must send `Authorization: Bearer ` on every tools/call. No host-login fallback. | -| Local stdio (`-transport stdio`) | Host login from `~/.verae/auth.properties` is used when no caller bearer is sent. | - -### Grok Build CLI - -**Option A — local stdio (recommended for laptop agents):** host auth, no public lockdown. - -```toml -# ~/.grok/config.toml -[mcp_servers.verae-timestamping] -command = "/absolute/path/to/bin/verae-mcp-timestamping-server" -args = ["-transport", "stdio"] -enabled = true - -[mcp_servers.verae-timestamping.env] -VERAE_NATS_LISTEN = "" -``` - -**Option B — public URL with caller bearer:** - -```sh -./scripts/sync-mcp-bearer.sh # writes ~/.verae/mcp-bearer from auth.properties -``` - -```toml -[mcp_servers.verae-timestamping] -url = "https://mcp.veraetime.net/mcp" -enabled = true -bearer_token_file = "~/.verae/mcp-bearer" -``` - -Reconnect the MCP server after config changes (new Grok session or `/mcps` toggle). - -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 -Questions: this research workspace / marchon@gmail.com. PRs coordinated in-workspace first. Protocol questions: https://github.com/modelcontextprotocol. +Questions: open an issue on the project Forgejo/GitHub remote, or contact Verae engineering. +PRs are accepted when they include tests and do not leak secrets. ## License -UNLICENSED © George Lambert +UNLICENSED © Verae Inc. (verae.com)