- Go 96.6%
- Shell 3.4%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
Public DEC-654 still requires a caller bearer; anonymous session now returns that guidance as a tool error instead of silent valid:false. Error text names JWT and API key, Grok bearer_token_file, and local stdio. BearerFromRequest also accepts X-Api-Key / X-Verae-Key. Document Grok stdio vs public URL; add scripts/sync-mcp-bearer.sh. |
||
| .forgejo/workflows | ||
| cmd/verae-mcp-timestamping-server | ||
| deploy | ||
| docs | ||
| examples/tsnats-bulk | ||
| internal | ||
| pkg | ||
| scripts | ||
| .gitignore | ||
| go.mod | ||
| go.sum | ||
| README.md | ||
verae-mcp-timestamping-server-go
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.
Table of Contents
Install
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):
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 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 <JWT or API key> 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.
# ~/.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:
./scripts/sync-mcp-bearer.sh # writes ~/.verae/mcp-bearer from auth.properties
[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:
./scripts/parity_smoke.sh
pkg/tsnats
Bulk workers talk to the embedded (or any) NATS URL. Digests only; SubscribeCompleted is core NATS, not JetStream.
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.
License
UNLICENSED © George Lambert