clone

a self-hosted multitenant nostr relay with sites, file storage, git hosting, and inbox and outbox delivery

main
tinyrelay / tinyagent / README.md
README.md 8.9K rendered
1# tinyagent23`tinyagent` is the native Tinyrelay connector helper for Hermes Agent. It is the connector name used by Hermes plugin discovery. The Hermes platform registered by the plugin is named `tiny`.45Build the helper from the repository root:67```sh8mkdir -p bin9go build -o bin/tinyagent ./tinyagent10```1112Install the plugin in a standard Hermes home and put the helper on `PATH`:1314```sh15export HERMES_HOME="${HERMES_HOME:-$HOME/.hermes}"16mkdir -p "$HERMES_HOME/plugins"17cp -R tinyagent/hermes "$HERMES_HOME/plugins/tinyagent"18export PATH="$PWD/bin:$PATH"19```2021Configure the connector with the relay URL, the private key used by this Hermes instance, the room to monitor, and the public keys allowed to control it:2223```sh24export TINY_RELAY_URL=https://relay.example.test25export TINY_PRIVATE_KEY=YOUR_HEX_PRIVATE_KEY26export TINY_CHANNELS=room-id27export TINY_HOME_CHANNEL=room-id28export TINY_ALLOWED_USERS=OPERATOR_PUBLIC_KEY29export TINY_CLI_PATH="$PWD/bin/tinyagent"30hermes plugins enable tinyagent31hermes gateway run32```3334By default, Hermes responds when an allowed user mentions the agent or replies to one of its messages. Set `TINY_REQUIRE_MENTION=false` to respond to all messages from allowed users in the selected rooms. This controls when Hermes responds; notifications still require an explicit mention by the agent.3536`TINY_PRIVATE_KEY` is read from the environment by the helper and is never a command-line argument. The helper receives only `PATH`, `HOME`, `TMPDIR`, the key variable and the proxy variables from the gateway's environment. Give that key membership and an agent grant for the selected rooms on Tiny, including attachment access. Use a relay with the [native interaction extension](../docs/extensions/tinyagent.md) for interactive cards. Hermes loads the adapter through its normal plugin system. Attachments use authenticated Tinyrelay endpoints, with size and hash checks.3738One gateway runs one Tiny identity at a time. On connect, the adapter takes an exclusive lock for the relay and key and releases it on disconnect. The lock lives under `state/tinyagent/locks/` in the Hermes root shared by every profile of an installation (the parent of `profiles/`, or the Hermes home itself), with `tinyagent-locks/` in the system temporary directory as the fallback when that root is not writable, so two profiles cannot run the same key either. A second gateway using the same key fails to connect with `another Hermes gateway already runs this Tiny identity`. Each profile keeps its own delivery cursor under `$HERMES_HOME/state/tinyagent/`, so a restart resumes where the previous run stopped instead of replaying old messages. A message counts as delivered only once Hermes has started or queued a turn for it; a message Hermes refused stays eligible for redelivery for three attempts.3940In a multiplexed gateway, the adapter reads `TINY_PRIVATE_KEY`, `TINY_ALLOWED_USERS` and the other `TINY_*` settings through Hermes's profile secret scope, so each profile hands the helper its own key and operator list; the key still reaches the helper only through its environment variable.4142If the helper process exits, Hermes reports the Tiny platform as disconnected and the adapter restarts the helper on its own, waiting 1 second before the first attempt and doubling the wait up to 30 seconds between failures. Once the helper is back, the adapter resubscribes from the saved cursor and reports the platform as connected again. Pending questions and approvals stay valid across the restart because the adapter itself keeps running.4344The helper exposes a JSON-lines RPC mode for the adapter. Its public commands are:4546```sh47tinyagent keygen48TINY_PRIVATE_KEY=YOUR_HEX_PRIVATE_KEY tinyagent rpc --relay https://relay.example.test49tinyagent call --relay https://relay.example.test identity50tinyagent diagnose --relay https://relay.example.test --rooms room-id --kinds 9,1251```5253`tinyagent diagnose` reports, as JSON, whether the relay answers, whether it accepts the key's signature, the key's membership and grant state, and which of the named rooms and kinds the grant lacks, with a verdict of `ok`, `needs-grant`, `not-a-member`, `unauthorized`, `unreachable` or `error` and one line of advice. A refused signature is never reported as an unreachable relay, a rate limit counts as unreachable for now, and any other protocol failure is `error`. The exit status is 0 for `ok`, 2 when the key or its grant is the problem and 3 when the relay is out of reach or answers wrongly. Hermes gets the same report from the `tiny_diagnose` MCP tool.5455## Long tasks5657A member can hand Hermes a long task with a kind 43001 request that names the agent key in a `p` tag. The adapter treats the request like a mention: the subject and content become one turn, and the conversation runs as a thread anchored at the request (or at the thread the request names). Every request gets its own Hermes session, so several requests in one thread run as separate turns and are never merged into one. Hermes's replies stay in that thread; the task card summarises them. The adapter publishes accepted, progress, result and error events as the turn runs, retries a failed result or error publication twice before giving up, and does not run again a request that already has a result, error or cancel on the relay after a restart. The requester ends a task with a kind 43005 cancel; any allowed user can stop the current turn of a room or thread by sending `!cancel` with the agent mentioned. See [Tiny agent interactions](../docs/extensions/tinyagent.md#long-task-cards) for the events the adapter publishes and when.5859## Relay tools in Hermes6061`tinyagent mcp` gives Hermes the relay's own MCP tools. It is a stdio MCP server that Hermes starts like any other `mcp_servers` entry, and it forwards each call to `<relay>/mcp` with a fresh NIP-98 signature from the agent key. Add it to `config.yaml`:6263```yaml64mcp_servers:65 tiny:66 command: tinyagent67 args: ["mcp", "--relay", "https://relay.example.test", "--allow-writes"]68 env:69 TINY_PRIVATE_KEY: "${TINY_PRIVATE_KEY}"70```7172Hermes resolves `${TINY_PRIVATE_KEY}` from its own environment, including `~/.hermes/.env`, when it loads the server list; an unset variable keeps the literal placeholder. The server process receives only a filtered environment (`PATH`, `HOME`, `USER`, `LANG`, `LC_ALL`, `TERM`, `SHELL`, `TMPDIR`, `XDG_*` and the `env` map above), so the key must be declared in `env`. Hermes resolves `command` against that `PATH`; put the helper on it or give an absolute path. The helper never writes to stdout except protocol messages; diagnostics go to stderr, which Hermes keeps in its MCP log.7374Without `--allow-writes` only read tools are offered: repositories, issues, pull requests, files, attachments, rooms, threads, wiki pages, long tasks and status. With it, Hermes can also open issues and pull requests, comment, post and reply in rooms, react, publish and propose wiki pages, upload attachments, ask for decisions and grants, and request, accept, report and cancel long tasks. `--tools name,name` limits the set to named tools; write tools still need `--allow-writes`, and a name outside the curated set stops the helper at startup. `publish_event` and management tools are never offered. Write tools return an unsigned event, which the helper signs as returned and resubmits, so Hermes sees the relay's publish result. The helper signs only with `--allow-writes`, only for a write tool, and only a kind that tool publishes: 1621 for `create_issue`, 1618 for `create_pull_request`, 1111 for `comment` and `request_grant`, 9 for `post_message`, 11 for `start_thread`, 12 for `reply_in_thread`, 7 for `react`, 30818 for `publish_wiki_page`, 818 for `propose_wiki_merge`, 9 or 1111 for `request_decision`, and 43001 through 43006 for `request_job`, `accept_job`, `job_progress`, `job_result`, `cancel_job` and `job_error`; `upload_attachment` publishes nothing. Any other unsigned event, including one carried by a read tool, is returned to Hermes unsigned as a tool error, so a relay cannot obtain the agent's signature on an event such as a kind 30392 grant. Relay refusals arrive as tool errors starting with `permission:`, which is the cue to call `request_grant`; unreachable relays report `transport:`. When the relay's tool table cannot be loaded, `tools/list` still offers `tiny_diagnose`, which then reports `unreachable`, `unauthorized` or `error` with the reason. See [Tinyagent MCP facade](../docs/extensions/tinyagent-mcp.md).7576The connector currently targets member access to rooms. Direct messages, moderator deletion, and durable interaction callbacks across process restarts are outside this initial integration. Notification recipients are created only from explicit `@` followed by a 64-character public key; assigning an operator to a request does not notify that operator by itself. The implementation provides a native Tinyrelay connection with the Hermes capabilities exercised by the lab and does not promise full parity with every Hermes platform feature.