| 1 | # tiny |
| 2 | |
| 3 | `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. |
| 4 | |
| 5 | `` `mermaid |
| 6 | flowchart LR |
| 7 | people((people)) -- "NIP-07 or Nostr Connect" --> ui[web pages] |
| 8 | agents((agents)) -- "MCP, Buzz, GRASP" --> api[/mcp, /events, git/] |
| 9 | ui --> tenant |
| 10 | api --> tenant |
| 11 | subgraph tenant [one tenant] |
| 12 | policy[owner and policy] --> store[(durable store)] |
| 13 | store --> rooms[chat rooms] |
| 14 | store --> wiki[wiki] |
| 15 | store --> repos[repositories] |
| 16 | store --> files[files and sites] |
| 17 | store --> views[views and records] |
| 18 | end |
| 19 | tenant -- "inbox and outbox" --> relays((other relays)) |
| 20 | `` ` |
| 21 | |
| 22 | ## Components |
| 23 | |
| 24 | The repository contains three executables in one Go module: |
| 25 | |
| 26 | | Component | Build target | Role | |
| 27 | | --- | --- | --- | |
| 28 | | `tinyrelay` , distributed as `tiny` | `make build-tiny` | Integrated relay host with Git hosting and the browser interface. | |
| 29 | | [`tinygit` ](tinygit/README.md) | `make build-tinygit` | Standalone public Git host using signed repository metadata and refs. | |
| 30 | | [`tinyclient` ](tinyclient/README.md) | `make build-tinyclient` | Standalone frontend connected to a compatible tinyrelay backend. | |
| 31 | |
| 32 | `make build` writes all three 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, and tinyclient needs a backend and preserves its public origin and tenant path. |
| 33 | |
| 34 | 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](docs/architecture.md), [Module boundaries and protocol contracts](docs/module-contracts.md) and the [extension catalog](docs/extensions/README.md) for ownership, supported profiles and remaining seams. |
| 35 | |
| 36 | ## Run locally |
| 37 | |
| 38 | Build and start the daemon: |
| 39 | |
| 40 | `` `sh |
| 41 | go build -o tiny ./cmd/tiny |
| 42 | ./tiny serve --data-dir ./data --listen :7447 |
| 43 | `` ` |
| 44 | |
| 45 | For a public deployment, set the relay URL and provision the owner key: |
| 46 | |
| 47 | `` `sh |
| 48 | ./tiny serve --data-dir /var/lib/tiny --listen 127.0.0.1:7447 \ |
| 49 | --public-url https://relay.example \ |
| 50 | --provision-owner <64-lowercase-hex-pubkey> |
| 51 | `` ` |
| 52 | |
| 53 | The command is `tiny` . Useful commands include: |
| 54 | |
| 55 | `` `text |
| 56 | tiny serve [--data-dir PATH] [--listen :7447] |
| 57 | tiny tenant create --name NAME --owner PUBKEY [--template default] [--source wss://...] |
| 58 | tiny tenant list|enable|disable|host [options] |
| 59 | tiny git-token --repo URL [--key-env TINY_AGENT_KEY] [--format header|value|git] |
| 60 | tiny templates |
| 61 | tiny version |
| 62 | `` ` |
| 63 | |
| 64 | Create a permanent tenant with a template: |
| 65 | |
| 66 | `` `sh |
| 67 | tiny tenant create --data-dir /var/lib/tiny \ |
| 68 | --name community --owner <64-lowercase-hex-pubkey> \ |
| 69 | --template chat |
| 70 | `` ` |
| 71 | |
| 72 | Run `tiny templates` to see available templates. Templates that read from an upstream relay accept `--source wss://relay.example` . |
| 73 | |
| 74 | ## Configure and operate |
| 75 | |
| 76 | 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**. |
| 77 | |
| 78 | 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. |
| 79 | |
| 80 | See [Files and private repositories](docs/files-and-private-repositories.md) for encrypted folders, resumable uploads, storage allowances, private Git hosting and Blossom draft support. |
| 81 | |
| 82 | See [Git collaboration](docs/git-collaboration.md) for issues, pull requests, conversation synchronization and participant outboxes. |
| 83 | |
| 84 | See [Membership](docs/membership.md) for invites, joining with NIP-43 and reviewing access requests. |
| 85 | |
| 86 | See [Chat](docs/chat.md) 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. |
| 87 | |
| 88 | See [Social](docs/social.md) for notes, long-form articles, NIP-10 and NIP-22 conversations, reactions, Markdown, media and mixed feeds. |
| 89 | |
| 90 | See [Installed app](docs/app.md) for installing the relay as an app, sharing files to it, opening Nostr links and device notifications. |
| 91 | |
| 92 | See [Agent identities](docs/agents.md) for granting an assistant or bot its own scoped key, what the relay enforces and how to pause or revoke it. |
| 93 | |
| 94 | See [Wiki](docs/wiki.md) for pages, versions and forks, merge requests and redirects. |
| 95 | |
| 96 | See [Custom views](docs/views.md) for rendering fenced code blocks through a transform you run and keeping the result as signed artifacts. |
| 97 | |
| 98 | **Manage > Health** shows the relay and script versions and whether the browser's WebMCP tools are registered. See [WebMCP tools](docs/webmcp.md) for browser-agent integration and authorization behavior. |
| 99 | |
| 100 | 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](docs/mcp.md). An agent acts under a grant the owner signs, and the owner reviews what it proposes: |
| 101 | |
| 102 | `` `mermaid |
| 103 | sequenceDiagram |
| 104 | participant O as owner |
| 105 | participant R as relay |
| 106 | participant A as agent |
| 107 | O->>R: sign a kind 30392 grant (rooms, repos, wiki, sites, kinds) |
| 108 | A->>R: publish under its own key |
| 109 | R-->>A: accepted, or restricted with the reason |
| 110 | R-->>O: wake a device: proposal or request |
| 111 | O->>R: react + or - on the exact event |
| 112 | R-->>A: visible to everyone, or held |
| 113 | `` ` |
| 114 | |
| 115 | ## Deployment |
| 116 | |
| 117 | Build the container image: |
| 118 | |
| 119 | `` `sh |
| 120 | docker build --target runtime -t tiny:local . |
| 121 | docker run --rm -p 7447:7447 -v tiny-data:/data \ |
| 122 | tiny:local serve --listen :7447 --public-url https://relay.example |
| 123 | `` ` |
| 124 | |
| 125 | For systemd, install [`deploy/tiny.service` ](deploy/tiny.service), create `/etc/tiny/tiny.env` , then run: |
| 126 | |
| 127 | `` `sh |
| 128 | sudo systemctl daemon-reload |
| 129 | sudo systemctl enable --now tiny |
| 130 | `` ` |
| 131 | |
| 132 | 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. |
| 133 | |
| 134 | The reference installation keeps the relay off the public interface and lets two sidecars front it: |
| 135 | |
| 136 | `` `mermaid |
| 137 | flowchart LR |
| 138 | internet((internet)) --> https[https sidecar] |
| 139 | tailnet((tailnet)) --> ts[tailscale sidecar] |
| 140 | https --> tiny[tiny] |
| 141 | ts --> tiny |
| 142 | tiny --> data[(data directory)] |
| 143 | `` ` |
| 144 | |
| 145 | See [Personal relay deployment](docs/personal-relay.md) for the reference installation. |
| 146 | |
| 147 | ## Explore the code |
| 148 | |
| 149 | Start with [`cmd/tiny` ](cmd/tiny/doc.go) for commands and process lifetime, or [`daemon` ](internal/daemon/doc.go) 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. |
| 150 | |
| 151 | Use editor symbol help or read the same comments from the command line: |
| 152 | |
| 153 | `` `sh |
| 154 | go doc ./internal/daemon |
| 155 | go doc ./internal/storage SaveOptions |
| 156 | go doc ./internal/work Handler |
| 157 | `` ` |
| 158 | |
| 159 | See [Architecture](docs/architecture.md) for the package map, event acceptance and dependency checks. |
| 160 | |
| 161 | ## Test and diagnose |
| 162 | |
| 163 | `` `sh |
| 164 | make test |
| 165 | make test-race |
| 166 | make docker-test |
| 167 | make benchmark |
| 168 | `` ` |
| 169 | |
| 170 | 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/` . |