?

rousseau in 5 minutes

Rousseau is a single static Go binary that ships with a Bubble Tea TUI, a SQLite session store at ~/.local/share/rousseau/sessions.db, and nine chat transports (WhatsApp, Signal, Telegram, Slack, Discord, Matrix, iMessage, SMS, email). No SaaS control plane, no telemetry, no license server. You bring the LLM.

This page takes you end-to-end:

  • 1. Install rousseau — from source, go install, or a cosign-verified release.
  • 2. Configure your LLM — pick a provider (claudecli by default; Anthropic, Bedrock, Vertex, or any OpenAI-compatible endpoint).
  • 3. Have your first conversationrousseau chat in your terminal.
  • 4. Add a transport — pair WhatsApp with an allowlisted JID.
  • 5. Verify supply chain — cosign-verify the checksums file, then read the CycloneDX SBOM and SLSA-3 provenance.

Most operators finish in under ten minutes.

1. Install rousseau

go install github.com/sebastienrousseau/rousseau-agent/cmd/rousseau@latest
rousseau version

The binary embeds modernc.org/sqlite (see internal/state/sqlite/store.go), so there is no libc or CGo dependency at runtime. Works identically on macOS, Linux, and Windows.

OS-specific prerequisites

brew install go@1.26
# For the container path:
brew install podman
podman machine init && podman machine start

For the default claudecli provider, install Claude Code from https://claude.ai/download and run claude login once.

2. Configure your LLM

Config lives at ~/.config/rousseau/config.yaml (override with --config) and every field is defined in internal/config/config.go. The default provider is claudecli, which shells out to your local claude CLI so no API keys leave your laptop.

claudecli (default, zero keys)

If you already have Claude Code (claude) installed and authenticated, you're done. Rousseau inherits its OAuth session:

provider: claudecli

claudecli:
  binary: claude              # optional; PATH lookup by default
  permission_mode: default    # or bypassPermissions for unattended daemons

See Providers: claudecli.

Anthropic API

Direct Anthropic. Uses the official anthropic-sdk-go in internal/llm/anthropic/client.go:

export ANTHROPIC_API_KEY=sk-ant-…
provider: anthropic
anthropic:
  model: claude-sonnet-4-6
  max_tokens: 4096

ANTHROPIC_API_KEY is read directly from the environment (see config.Load in internal/config/config.go); the key never has to live on disk. See Providers: Anthropic.

AWS Bedrock

Uses the standard AWS credential chain (profile, IMDS, IRSA). Region and model come from internal/config/config.go BedrockConfig:

provider: bedrock
bedrock:
  region: eu-west-2
  model: anthropic.claude-sonnet-4-6-20250101-v1:0
  profile: default            # optional named profile
  max_tokens: 4096

No API key sits in config.yaml. See Providers: Bedrock.

Google Vertex AI

Anthropic-on-Vertex; reads a service-account JSON file. Config fields defined in VertexConfig:

provider: vertex
vertex:
  project: my-gcp-project
  region: europe-west4
  model: claude-sonnet-4-6@20250101
  credentials_file: /etc/rousseau/vertex.json
  max_tokens: 4096

See Providers: Vertex.

OpenAI-compatible (OpenRouter, Ollama, vLLM, LM Studio)

The openai, openrouter, and ollama provider names share OpenAIConfig. Base URLs for OpenRouter and Ollama have defaults in setDefaults (https://openrouter.ai/api/v1 and http://localhost:11434/v1); anything else lands in the openai block with an explicit base_url:

provider: ollama              # or: openai, openrouter
ollama:
  model: llama3.1:70b-instruct
  base_url: http://localhost:11434/v1

See Providers: OpenAI-compatible and Guides: Self-hosted vLLM.

3. Have your first conversation

rousseau chat

You'll see a Bubble Tea TUI (internal/tui/model.go):

  • A viewport at the top scrolls the transcript. Assistant text streams in as it arrives.
  • A textarea at the bottom takes your input. Press Enter to send, Ctrl+C to quit.
  • A spinner shows during LLM turns; a small streaming indicator appears while tokens arrive.
  • Every turn is persisted to SQLite at ~/.local/share/rousseau/sessions.db. WAL journaling is enabled by Open() in internal/state/sqlite/store.go, so you can safely run other rousseau commands (rousseau session list, rousseau mcp) against the same database while the TUI is open.

Ask something small first — e.g. "list the files under internal/tools/builtin" — and rousseau will call the read, grep, edit, write, or bash built-in tools (internal/tools/builtin/*.go) as needed. See User Guide: TUI for keybindings and User Guide: Tools for the schemas.

Screenshot placeholder: the TUI shows a two-line status bar (session id and provider), the viewport with assistant + user messages colour-tinted, and the textarea in focus at the bottom.

4. Add a transport (WhatsApp)

WhatsApp is the reference transport because pairing is the most stringent. Every other transport (slack, discord, telegram, matrix, signal, sms, imessage, email) follows the same shape.

rousseau whatsapp --allow 447900123456@s.whatsapp.net

On first launch, rousseau prints a QR code to stdout. Scan it in WhatsApp > Settings > Linked devices on your phone. The whatsmeow client (internal/transport/whatsapp/client.go) emits three structured log events:

  • whatsapp.qr_ready — QR was rendered.
  • whatsapp.paired — phone accepted the QR.
  • whatsapp.connected — websocket to Meta is up.

Device credentials are cached to ~/.local/share/rousseau/whatsapp.db (a separate SQLite database, so relinking a device does not touch conversation history). The --allow flag pins an allowlist of E.164 JIDs; every other sender is silently dropped by router.transport.rejected.

Rousseau uses the unofficial WhatsApp Web protocol. Meta occasionally bans numbers running unofficial clients — do not run this on a number you rely on. See Transports: WhatsApp for the risk analysis.

5. Verify supply chain

Every tagged release ships:

Artefact Purpose
rousseau_<v>_checksums.txt SHA-256 of every archive in the release.
rousseau_<v>_checksums.txt.sig cosign signature (keyless, OIDC-issued from GitHub Actions).
rousseau_<v>_sbom.cdx.json CycloneDX 1.5 SBOM of the Go module graph.
rousseau_<v>_provenance.intoto.jsonl SLSA-3 provenance attestation.

Verify the signature identity before trusting the checksums:

cosign verify-blob \
  --certificate-identity-regexp 'sebastienrousseau/rousseau-agent' \
  --certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
  --signature rousseau_0.6.0_checksums.txt.sig \
  rousseau_0.6.0_checksums.txt

The --certificate-identity-regexp pins the signer identity to the rousseau-agent repository under Sebastien's namespace. Do not weaken it. A wildcard identity defeats the point of keyless signing.

Once the signature is verified, sha256sum -c proves the tarball you downloaded is the one CI built. Read the SBOM with cyclonedx-cli tree, verify the SLSA-3 provenance with slsa-verifier verify-artifact, and only then extract the archive.

See Security for the full trust boundaries and Guides: Enterprise Onboarding for the platform-team checklist.

Troubleshooting

rousseau version prints "dev" after go install

The version, commit, and buildDate values are stamped by the release toolchain via -ldflags in internal/cli/root.go. go install skips those flags, so the binary reports dev / none / unknown. Use the signed-release path if you need a stable version string; the dev string is harmless at runtime.

claudecli: exec: "claude": executable file not found

provider: claudecli shells out to the claude binary. Either put Claude Code on your $PATH (see Providers: claudecli) or switch provider — the fastest alternative is provider: anthropic with ANTHROPIC_API_KEY exported.

WhatsApp QR is displayed but never accepted

Three common causes: (1) the container clock is skewed by more than 30 seconds — WhatsApp's handshake is time-sensitive; (2) a partially-completed pairing left whatsapp.db in an unreusable state — delete ~/.local/share/rousseau/whatsapp.db and re-scan; (3) Meta invalidated the number — try a fresh phone number. See Transports: WhatsApp.

cosign verify-blob errors with "no matching signatures"

The --certificate-identity-regexp must match the signer's GitHub repository. For rousseau-agent, the correct value is sebastienrousseau/rousseau-agent. A wildcard defeats the point of keyless signing — do not weaken it. If the regex is correct, refresh Sigstore's trust root with cosign initialize.

Every tool call is denied with "denied by pattern policy"

You are running in pattern mode with default: deny and no matching allow rule. Add an allow entry for the tool, or flip default: allow and add narrow deny rules instead. See User Guide: Approval Policies for worked examples.

Related pages

Further reading

  • README.md — repository-level positioning and capability matrix.
  • SECURITY.md — trust boundaries and supply-chain hardening.
  • internal/config/config.go — the authoritative config struct.
  • internal/cli/root.go — Cobra command tree wiring.

Next steps

Where to go Why
Configuration Every knob in ~/.config/rousseau/config.yaml with defaults.
Concepts The agent loop, session store, MCP, cron, skills.
Deployment Rootless Podman + systemd Quadlet unit.
Security Trust boundaries, SLSA-3 provenance, seccomp posture.
Tutorials Full end-to-end walkthroughs.
Reference Every CLI flag, exit code, and config field.

Type to search 150+ pages. Ranking: BM25 with title/description boost.