Add just goose for one-command agent setup + fix API token auth#20
Add just goose for one-command agent setup + fix API token auth#20
just goose for one-command agent setup + fix API token auth#20Conversation
Adds an idempotent setup script and justfile recipe so that connecting
a Goose agent to a local Sprout relay is a single command:
just goose
What this does:
- scripts/setup-goose-agent.sh: mints a Nostr keypair + API token on
first run, persists to .sprout-agent.env (gitignored, chmod 600).
Subsequent runs are a no-op.
- justfile: 'just goose' sources the agent env and launches goose with
the sprout-mcp-server extension.
- .gitignore: excludes .sprout-agent.env.
Also fixes a bug where API token authentication was not wired up in the
relay's NIP-42 auth handler. The AuthService intentionally has no DB
access, so sprout_ tokens need to be intercepted in handle_auth before
calling verify_auth_event. The handler now:
1. Extracts the auth_token tag from the NIP-42 event
2. If it starts with sprout_, hashes it, looks it up via
Db::get_api_token_by_hash, and delegates to
AuthService::verify_api_token_against_hash
3. Updates last_used_at on success
4. Falls through to the existing JWT/no-token paths otherwise
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e186c6d916
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if [[ -f "${AGENT_ENV}" ]]; then | ||
| success "Agent identity already exists at .sprout-agent.env — skipping." | ||
| exit 0 |
There was a problem hiding this comment.
Keep building binaries when agent env already exists
Exiting immediately when .sprout-agent.env exists means subsequent just goose runs can fail after cargo clean (or any missing target/debug/sprout-mcp-server), because the setup script never reaches the build checks while the goose recipe still execs that binary. In this scenario users have a valid identity file but no executable MCP server, so the one-command flow breaks until they manually rebuild or delete the env file.
Useful? React with 👍 / 👎.
What
One-command setup to connect a Goose agent to a local Sprout relay:
First run mints a Nostr keypair + API token and persists them to
.sprout-agent.env. Subsequent runs reuse the existing identity. Drops you into a Goose session with all 16 Sprout MCP tools available.Changes
just goosesetup (3 files)scripts/setup-goose-agent.sh— Idempotent script that buildssprout-admin+sprout-mcp-serverif needed, mints a token withmessages:read,messages:write,channels:read,channels:writescopes, and writes credentials to.sprout-agent.env(chmod 600).justfile— Newgooserecipe that runs the setup script, sources the env, and launchesgoose session --with-extensionwith the sprout MCP server..gitignore— Added.sprout-agent.envso credentials are never committed.API token auth fix (1 file)
crates/sprout-relay/src/handlers/auth.rs— The NIP-42 auth handler now interceptssprout_API tokens before callingAuthService::verify_auth_event. Previously, API tokens hit a dead-endErr(TokenInvalid)insideAuthServicebecause it has no DB access by design. The fix: verify NIP-42 signature → hash token → DB lookup viaDb::get_api_token_by_hash→ delegate toAuthService::verify_api_token_against_hashfor constant-time comparison, expiry, pubkey, and scope resolution → updatelast_used_at.The auth fix is included because without it the minted token fails at connection time — the two changes are coupled.
Prerequisites
just setup)just relay)Testing