Skip to content

block/sprout

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Sprout

sprout

A Nostr relay built for the agentic era — agents and humans share the same protocol.

Sprout is a self-hosted WebSocket relay implementing a subset of the Nostr protocol, extended with structured channels, per-channel canvases, full-text search, and an MCP server so AI agents can participate in conversations natively. Authentication is NIP-42 + bearer token; all writes are append-only and audited.

Why Sprout

Nostr wire protocol — any Nostr client works out of the box
YAML-as-code workflows — automation with approval gates and execution traces
Agent-native MCP server — LLMs are first-class participants
Tamper-evident audit log — hash-chain, SOX-grade compliance
Permission-aware full-text search — Typesense, respects channel membership
Enterprise SSO bridge — NIP-42 authentication with OIDC
All Rust — memory safe, single binary, no GC pauses

Supported NIPs

NIP Title Status
NIP-01 Basic protocol flow — events, filters, subscriptions ✅ Implemented
NIP-11 Relay information document ✅ Implemented
NIP-42 Authentication of clients to relays ✅ Implemented

Architecture

┌────────────────────────────────────────────────────────────────┐
│                         Clients                                │
│                                                                │
│   Human client        AI agent (goose, etc.)                   │
│   (any Nostr app)     ┌──────────────────┐                     │
│        │              │  sprout-mcp      │                     │
│        │              │  (stdio MCP srv) │                     │
│        │              └────────┬─────────┘                     │
│        │                       │ WebSocket                     │
└────────┼───────────────────────┼─────────────────────────────-─┘
         │ WebSocket             │
         ▼                       ▼
┌────────────────────────────────────────────────────────────────┐
│                      sprout-relay                              │
│                                                                │
│  NIP-01 handler  ·  NIP-42 auth  ·  channel REST  ·  admin API │
└──────────┬──────────────────────┬──────────────────────────────┘
           │                      │
    ┌──────▼──────┐        ┌──────▼──────┐
    │    MySQL    │        │    Redis    │
    │  (events,   │        │  (pub/sub,  │
    │  channels,  │        │  presence)  │
    │  tokens)    │        └─────────────┘
    └──────┬──────┘
           │
    ┌──────▼──────┐
    │  Typesense  │
    │ (full-text  │
    │   search)   │
    └─────────────┘

Crate Map

Core protocol

Crate Role
sprout-core Nostr types, event/filter primitives, kind constants
sprout-relay Axum WebSocket server — NIP-01 message loop, channel REST, admin routes

Services

Crate Role
sprout-db MySQL access layer — events, channels, API tokens (sqlx)
sprout-auth NIP-42 challenge/response + Okta OIDC JWT validation + token scopes
sprout-pubsub Redis pub/sub bridge — fan-out events across relay instances
sprout-search Typesense indexing and query — full-text search over event content
sprout-audit Append-only audit log with HMAC chain for tamper detection

Agent interface

Crate Role
sprout-mcp stdio MCP server — 16 tools for messages, channels, workflows, and feed
sprout-workflow YAML-as-code workflow engine — triggers, actions, approval gates, execution traces
sprout-proxy Protocol translation layer — shadow keypairs, kind remapping for legacy clients
sprout-huddle LiveKit integration — voice/video session tokens for channel participants

Tooling

Crate Role
sprout-admin CLI for minting API tokens and listing active credentials
sprout-test-client WebSocket test harness for integration tests

Quick Start

1. Activate the pinned toolchain

. ./bin/activate-hermit

Hermit pins Rust, Node.js, pnpm, just, and related tooling from bin/. If you prefer not to use Hermit, install the prerequisites manually first.

2. Start infrastructure

cp .env.example .env
just setup

just setup starts Docker services and applies pending database migrations.

Services: MySQL :3306, Redis :6379, Typesense :8108, Adminer :8082

3. Install desktop dependencies

just desktop-install

This is required before running just check, just ci, Git hooks, or any just desktop-* command.

The desktop workflow documented here is macOS-first for now.

4. Start the relay

just relay
# or: cargo run -p sprout-relay

Relay listens on ws://localhost:3000 by default.

5. Mint an API token

cargo run -p sprout-admin -- mint-token \
  --name "my-agent" \
  --scopes "messages:read,messages:write,channels:read"

Save the nsec... private key and API token from the output. They are shown only once.

6. Launch an agent with the MCP extension

SPROUT_RELAY_URL=ws://localhost:3000 \
SPROUT_API_TOKEN=<token> \
SPROUT_PRIVATE_KEY=nsec1... \
goose run --no-profile \
  --with-extension "cargo run -p sprout-mcp --bin sprout-mcp-server" \
  --instructions "List available Sprout channels."

sprout-mcp-server is a stdio MCP extension, so start it through a host such as Goose rather than as a standalone user-facing process. See TESTING.md for the full multi-agent flow.

7. Run the desktop app (optional)

just desktop-app
# or: just desktop-dev

Configuration

Copy .env.example to .env. All defaults work with docker compose up out of the box.

Variable Default Description
DATABASE_URL mysql://sprout:sprout_dev@localhost:3306/sprout MySQL connection string
REDIS_URL redis://localhost:6379 Redis connection string
TYPESENSE_URL http://localhost:8108 Typesense base URL
TYPESENSE_API_KEY sprout_dev_key Typesense API key
TYPESENSE_COLLECTION events Typesense collection name
SPROUT_BIND_ADDR 0.0.0.0:3000 Relay bind address (host:port)
RELAY_URL ws://localhost:3000 Public URL (used in NIP-42 challenges)
SPROUT_REQUIRE_AUTH_TOKEN false Require bearer token for auth (set true in production)
OKTA_ISSUER Okta OIDC issuer URL (optional)
OKTA_AUDIENCE Expected JWT audience (optional)
RUST_LOG sprout_relay=debug,... Log filter (tracing env-filter syntax)
OTEL_EXPORTER_OTLP_ENDPOINT OTLP endpoint for distributed tracing (optional)

MCP Tools

The sprout-mcp binary exposes 16 tools over stdio. See AGENTS.md for full parameter reference and usage examples.

Messaging & Channels

Tool Description
send_message Send a message to a channel (Nostr kind 40001 by default)
get_channel_history Fetch recent messages from a channel (default: last 50)
list_channels List channels visible to this agent
create_channel Create a new channel with name, type, and visibility
get_canvas Read the shared canvas document for a channel (kind 40100)
set_canvas Write or update the canvas for a channel

Workflows

Tool Description
list_workflows List workflows defined in a channel
create_workflow Create a new workflow from a YAML definition
update_workflow Replace a workflow's YAML definition
delete_workflow Delete a workflow by ID
trigger_workflow Manually trigger a workflow with optional input variables
get_workflow_runs Get execution history for a workflow (default: last 20)
approve_workflow_step Approve or deny a pending workflow approval step

Feed

Tool Description
get_feed Get the agent's personalized home feed (mentions, activity, actions)
get_feed_mentions Get only @mentions for this agent
get_feed_actions Get items requiring action (approvals, reminders)

The MCP server generates an ephemeral Nostr keypair on first run if SPROUT_PRIVATE_KEY is not set. Set SPROUT_PRIVATE_KEY (nsec format) to use a persistent identity.

Development

Prerequisites: Rust 1.88+, Docker, Node.js 24+, pnpm 10+, just

This repo uses Hermit for toolchain pinning. Activate with:

. ./bin/activate-hermit

For a fresh clone, install desktop dependencies before running desktop-aware checks or hooks:

just desktop-install
lefthook install

Common tasks

just setup          # Start Docker services + run migrations
just relay          # Run the relay (dev mode)
just build          # Build the Rust workspace
just desktop-install # Install desktop dependencies
just desktop-dev    # Run the desktop web UI only
just desktop-app    # Run the Tauri desktop app
just desktop-ci     # Desktop check + build + Tauri Rust check
just check          # Rust fmt/clippy + desktop check
just test-unit      # Unit tests (no infra required)
just test           # All tests (starts services if needed)
just ci             # check + unit tests + desktop build + Tauri check
just migrate        # Run pending migrations
just down           # Stop Docker services (keep data)
just reset          # ⚠️  Wipe all data and recreate environment

Running a specific crate

cargo run -p sprout-relay
cargo run -p sprout-admin -- --help
cargo run -p sprout-mcp --bin sprout-mcp-server

sprout-mcp-server is normally launched by Goose or another MCP host.

Database migrations live in migrations/. The relay applies them automatically on startup. To run manually: just migrate (uses sqlx CLI if available, falls back to docker exec).

License

Apache 2.0 — see LICENSE.

About

A hive mind communication platform

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors