Help us shape the future of Go! Take the 2026 Go Developer Survey

tinyrelay

module
v0.0.0-...-9268282 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 23, 2026 License: MIT

README

tiny

tiny is a self-hosted, multitenant Nostr relay. Each tenant has durable local storage, an owner, relay policy, inbox and outbox delivery, hosted sites, file storage, and optional repository browsing.

flowchart LR
  people((people)) -- "NIP-07 or Nostr Connect" --> ui[web pages]
  agents((agents)) -- "MCP, Buzz, GRASP" --> api[/mcp, /events, git/]
  ui --> tenant
  api --> tenant
  subgraph tenant [one tenant]
    policy[owner and policy] --> store[(durable store)]
    store --> rooms[chat rooms]
    store --> wiki[wiki]
    store --> repos[repositories]
    store --> files[files and sites]
    store --> views[views and records]
  end
  tenant -- "inbox and outbox" --> relays((other relays))

Components

The repository contains five executables in one Go module:

Component Build target Role
tinyrelay make build-tinyrelay Standalone Nostr relay for arbitrary clients.
tiny make build-tiny Combined host with the relay, Git hosting and browser interface.
tinygit make build-tinygit Standalone public Git host using signed repository metadata and refs.
tinyclient make build-tinyclient Standalone frontend connected to the combined tiny backend.
tinyagent make build-tinyagent Native Tiny connection for Hermes, with a signing helper and platform plugin.

make build writes all five binaries to bin/. Go builds embed the checked-in browser assets and do not require Node.js. The integrated tiny command, wire formats and existing tenant data remain compatible. Standalone components have narrower capabilities: tinygit does not start a relay or private-repository service, tinyclient needs a backend and tinyrelay serves the Nostr protocol without the web UI or Git services.

Reusable protocol/nostr and protocol/auth packages supply wire values and proof verification without importing host services. Feature semantics and access policy remain separate. See Architecture, Module boundaries and protocol contracts and the extension catalog for ownership, supported profiles and remaining seams.

Try the disposable Hermes lab to exercise the tiny connection against unchanged mainline Hermes.

Run locally

Build and start the daemon:

go build -o tiny ./cmd/tiny
./tiny serve --data-dir ./data --listen :7447

Run only the standalone relay:

go build -o bin/tinyrelay ./cmd/tinyrelay
./bin/tinyrelay --data-dir ./relay-data --listen :7447 \
  --public-url wss://relay.example

The standalone relay accepts ordinary Nostr clients over WebSocket. tiny relay runs the same standalone server through the combined CLI.

For a public deployment, set the relay URL and provision the owner key:

./tiny serve --data-dir /var/lib/tiny --listen 127.0.0.1:7447 \
  --public-url https://relay.example \
  --provision-owner <64-lowercase-hex-pubkey>

The command is tiny. Useful commands include:

tiny serve [--data-dir PATH] [--listen :7447]
tiny relay [options]
tiny tenant create --name NAME --owner PUBKEY [--template default] [--source wss://...]
tiny tenant list|enable|disable|host [options]
tiny git-token --repo URL [--key-env TINY_AGENT_KEY] [--format header|value|git]
tiny templates
tiny version

Create a permanent tenant with a template:

tiny tenant create --data-dir /var/lib/tiny \
  --name community --owner <64-lowercase-hex-pubkey> \
  --template chat

Run tiny templates to see available templates. Templates that read from an upstream relay accept --source wss://relay.example.

Configure and operate

The web interface uses plain HTML pages and forms. Connect a Nostr signer with NIP-07 or Nostr Connect to sign in and authorize management actions. Chat combines group rooms with one-to-one conversations. Account keeps the current key's profile, relay lists and Chat presence preference together. Use the management pages to configure policy, members, relay connections, delivery jobs, backups, hosted sites, and stored files. Delivery and retry status lives under Manage > Sync.

The browsing pages provide repository lists, source files, branches, history, diffs, file previews, raw downloads, synchronization status, and storage status. Access follows the tenant's current permissions.

See Files and private repositories for encrypted folders, resumable uploads, storage allowances, private Git hosting and Blossom draft support.

See Git collaboration for issues, pull requests, conversation synchronization and participant outboxes.

See Membership for invites, joining with NIP-43 and reviewing access requests.

See Chat for group rooms and one-to-one conversations, open and members-only access, room administration, NIP-17 direct messages, connecting Buzz-compatible clients and agents, and the live room stream.

See Social for notes, long-form articles, NIP-10 and NIP-22 conversations, reactions, Markdown, media and mixed feeds.

See Installed app for installing the relay as an app, sharing files to it, opening Nostr links and device notifications.

See Agent identities for granting an assistant or bot its own scoped key, what the relay enforces and how to pause or revoke it.

See Wiki for pages, versions and forks, merge requests and redirects.

See Custom views for rendering fenced code blocks through a transform you run and keeping the result as signed artifacts.

Manage > Health shows the relay and script versions and whether the browser's WebMCP tools are registered. See WebMCP tools for browser-agent integration and authorization behavior.

Agents outside the browser connect to /mcp, a stateless Model Context Protocol endpoint authenticated with NIP-98, and read /llms.txt for a summary of the relay's machine surface. See MCP. An agent acts under a grant the owner signs, and the owner reviews what it proposes:

sequenceDiagram
  participant O as owner
  participant R as relay
  participant A as agent
  O->>R: sign a kind 30392 grant (rooms, repos, wiki, sites, kinds)
  A->>R: publish under its own key
  R-->>A: accepted, or restricted with the reason
  R-->>O: wake a device: proposal or request
  O->>R: react + or - on the exact event
  R-->>A: visible to everyone, or held

Deployment

Build the container image:

docker build --target runtime -t tiny:local .
docker run --rm -p 7447:7447 -v tiny-data:/data \
  tiny:local serve --listen :7447 --public-url https://relay.example

For systemd, install deploy/tiny.service, create /etc/tiny/tiny.env, then run:

sudo systemctl daemon-reload
sudo systemctl enable --now tiny

Keep the data directory on local durable storage. The process exposes /healthz and /readyz. An optional diagnostics listener provides /metrics and protected pprof endpoints. Set --otlp-endpoint or OTEL_EXPORTER_OTLP_ENDPOINT when exporting traces.

The reference installation keeps the relay off the public interface and lets two sidecars front it:

flowchart LR
  internet((internet)) --> https[https sidecar]
  tailnet((tailnet)) --> ts[tailscale sidecar]
  https --> tiny[tiny]
  ts --> tiny
  tiny --> data[(data directory)]

See Personal relay deployment for the reference installation.

Explore the code

Start with cmd/tiny for commands and process lifetime, or daemon for tenant assembly and event flow. Each internal package has a doc.go overview. Comments on interfaces, constructors and transaction hooks explain ownership, inputs and failure behavior where those contracts are declared. Tests live beside the code they exercise.

Use editor symbol help or read the same comments from the command line:

go doc ./internal/daemon
go doc ./internal/storage SaveOptions
go doc ./internal/work Handler

See Architecture for the package map, event acceptance and dependency checks.

Test and diagnose

make test
make test-race
make docker-test
make benchmark

Run the Linux race suite on a Docker host with LINUX_HOST=<host> ./scripts/test-linux.sh. Run the conformance harness against a started daemon with node scripts/conformance/run.mjs; results are written under artifacts/conformance/.

Directories

Path Synopsis
cmd
tiny command
Command tiny runs and administers a multitenant Nostr relay.
Command tiny runs and administers a multitenant Nostr relay.
tinyclient command
Command tinyclient runs the standalone, server-rendered relay website.
Command tinyclient runs the standalone, server-rendered relay website.
tinygit command
Command tinygit serves signed repository metadata and native Git smart HTTP.
Command tinygit serves signed repository metadata and native Git smart HTTP.
tinyrelay command
Command tinyrelay serves a standalone Nostr relay.
Command tinyrelay serves a standalone Nostr relay.
internal
agentrunner
Package agentrunner runs an optional agent process outside the relay daemon.
Package agentrunner runs an optional agent process outside the relay daemon.
auth
Package auth is a transitional compatibility facade for protocol/auth.
Package auth is a transitional compatibility facade for protocol/auth.
blob
Package blob implements the local relay's Blossom and NIP-96 file endpoints.
Package blob implements the local relay's Blossom and NIP-96 file endpoints.
catalog
Package catalog owns the durable registry and filesystem paths for self-hosted relay tenants.
Package catalog owns the durable registry and filesystem paths for self-hosted relay tenants.
community
Package community owns the tenant's membership, moderation, invitations, rooms, agents and audit records.
Package community owns the tenant's membership, moderation, invitations, rooms, agents and audit records.
communityread
Package communityread defines the read models shared by community and records.
Package communityread defines the read models shared by community and records.
configport
Package configport imports, exports, plans and applies bind.ws relay configuration files.
Package configport imports, exports, plans and applies bind.ws relay configuration files.
daemon
Package daemon assembles the services of a multitenant Nostr relay.
Package daemon assembles the services of a multitenant Nostr relay.
domains
Package domains manages operator-configured host mappings for one tenant.
Package domains manages operator-configured host mappings for one tenant.
event
Package event keeps relay feature kind, job and room-reference semantics separate from the reusable values in protocol/nostr.
Package event keeps relay feature kind, job and room-reference semantics separate from the reusable values in protocol/nostr.
gates
Package gates applies tenant policy and protocol admission rules to relay events.
Package gates applies tenant policy and protocol admission rules to relay events.
mcp
Package mcp serves the Model Context Protocol revision 2026-07-28 through its stateless Streamable HTTP binding.
Package mcp serves the Model Context Protocol revision 2026-07-28 through its stateless Streamable HTTP binding.
peerurl
Package peerurl matches configured private peers across HTTP and WebSocket transports.
Package peerurl matches configured private peers across HTTP and WebSocket transports.
podcasts
Package podcasts reads the native show and episode events defined by NIP-F4.
Package podcasts reads the native show and episode events defined by NIP-F4.
policy
Package policy defines the durable tenant policy and the access decisions derived from it.
Package policy defines the durable tenant policy and the access decisions derived from it.
records
Package records owns durable relay identity, signed protocol records, projections, views, notifications and succession state.
Package records owns durable relay identity, signed protocol records, projections, views, notifications and succession state.
relay
Package relay is the WebSocket transport boundary for the relay.
Package relay is the WebSocket transport boundary for the relay.
relayapp
Package relayapp provides the storage-backed base relay used by the standalone tinyrelay command.
Package relayapp provides the storage-backed base relay used by the standalone tinyrelay command.
relaycmd
Package relaycmd contains the shared standalone relay command runner.
Package relaycmd contains the shared standalone relay command runner.
replication
Package replication plans and executes durable relay synchronization.
Package replication plans and executes durable relay synchronization.
seedmark
Package seedmark renders version 1 of the Seedmark avatar design without JavaScript.
Package seedmark renders version 1 of the Seedmark avatar design without JavaScript.
sites
Package sites implements NIP-5A site manifests and serves their content.
Package sites implements NIP-5A site manifests and serves their content.
storage
Package storage owns a tenant's SQLite database and the transaction boundary for event data, projections and durable work intents.
Package storage owns a tenant's SQLite database and the transaction boundary for event data, projections and durable work intents.
syncprotocol
Package syncprotocol contains the relay's NIP-45 count sketch and NIP-77 negentropy session wrappers.
Package syncprotocol contains the relay's NIP-45 count sketch and NIP-77 negentropy session wrappers.
telemetry
Package telemetry is the relay's process-local observability boundary.
Package telemetry is the relay's process-local observability boundary.
templates
Package templates contains the built-in relay policy and connection catalog.
Package templates contains the built-in relay policy and connection catalog.
views
Package views parses fenced code blocks and connects them to custom view renderers.
Package views parses fenced code blocks and connects them to custom view renderers.
webpush
Package webpush implements browser push delivery for the relay.
Package webpush implements browser push delivery for the relay.
wiki
Package wiki implements storage-independent NIP-54 article behavior.
Package wiki implements storage-independent NIP-54 article behavior.
work
Package work provides durable, fenced work intents backed by a storage.Store.
Package work provides durable, fenced work intents backed by a storage.Store.
protocol
auth
Package auth verifies Nostr request proofs without deciding host access.
Package auth verifies Nostr request proofs without deciding host access.
nostr
Package nostr provides signed Nostr events, JSON filters, canonical wire encoding, signature validation, tag helpers and standard kind ranges.
Package nostr provides signed Nostr events, JSON filters, canonical wire encoding, signature validation, tag helpers and standard kind ranges.
scripts
git-http-baseline command
This benchmark-only server exposes plain native Git Smart HTTP on loopback.
This benchmark-only server exposes plain native Git Smart HTTP on loopback.
client
Package client provides the native Tinyrelay transport used by tinyagent.
Package client provides the native Tinyrelay transport used by tinyagent.
Package tinyclient renders relay HTML pages and browser support modules.
Package tinyclient renders relay HTML pages and browser support modules.
Package tinygit coordinates signed Nostr repository events with native Git object storage and smart HTTP.
Package tinygit coordinates signed Nostr repository events with native Git object storage and smart HTTP.
Package tinyrelay provides an embeddable Nostr relay and a standalone server.
Package tinyrelay provides an embeddable Nostr relay and a standalone server.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL