@ravi-hq/ravi
v0.6.3
Published
OpenClaw plugin for Ravi — identity provider for AI agents. Email channels + full agent toolbox.
Downloads
2,047
Readme
@ravi-hq/openclaw-plugin
OpenClaw plugin for Ravi -- identity provider for AI agents. Gives your agent a real email address, phone number, password manager, and encrypted secrets store through a single plugin.
Features
- 2 messaging channels -- real-time email via cursor-based polling (owner, trusted)
- 28 agent tools -- manage identities, inboxes, passwords, secrets, contacts, and more
- E2E encryption -- PIN-based Argon2id + NaCl SealedBox, compatible with Ravi CLI
- DM policy controls -- allowlist or open policy per channel account
- Lazy crypto -- encryption keys derived on first use, not at startup
Installation
openclaw plugins install @ravi-hq/raviQuick Start
openclaw plugins install @ravi-hq/ravi
openclaw ravi onboardonboard authenticates (device-code flow + E2E encryption PIN), selects an
identity, auto-configures OpenClaw, and sets up the ravi-secrets provider.
Credentials are stored in ~/.ravi/auth.json and identityUuid is set via
openclaw config set. No manual config editing needed.
The auth flow matches the Ravi Go CLI exactly:
- Verification URL displayed immediately (copy-paste friendly for headless VMs)
- First-time users: choose and confirm a 6-digit encryption PIN
- Returning users: enter PIN (3 attempts) to unlock existing keypair
- Multiple identities: interactive numbered selection prompt
Use openclaw ravi login to re-authenticate without changing identity or config.
Configuration
Authentication is stored in ~/.ravi/auth.json (written by openclaw ravi login or onboard).
The identityUuid is set automatically by openclaw ravi onboard via openclaw config set.
Manual plugin config is only needed for multi-agent setups where different agents use different identities, or to customize channel DM policies.
plugins:
ravi:
# Ravi API base URL (default: https://ravi.app)
apiUrl: "https://ravi.app"
# Identity UUID -- set automatically by 'openclaw ravi onboard'.
# Override here only for multi-agent setups.
identityUuid: "identity-uuid-here"
# Channel accounts (from 'openclaw ravi onboard')
channels:
ravi-email-owner:
accounts:
"identity-uuid-here":
identityUuid: "identity-uuid-here"
identityName: "My Agent"
email: "[email protected]"
dm:
policy: "allowlist" # "allowlist" or "open"
allowFrom:
- "[email protected]"
Channels
Ravi Email
Real-time email channel powered by cursor-based polling from the Ravi backend.
- Threading model: Each email thread maps 1:1 to an OpenClaw session. A new
thread_idcreates a new session; subsequent messages in that thread resume it. - Session key format:
agent:{agentId}:ravi-email-owner:{accountId}:thread:{threadId} - DM policy: Set
policy: "allowlist"to restrict incoming email to specific sender addresses, or"open"to accept all senders. - Outbound: Replies are sent via the Ravi API and threaded correctly in the original email conversation.
Agent Tools
The plugin registers 28 tools that agents can invoke.
Identity
| Tool | Description | Parameters |
|------|-------------|------------|
| ravi_identity_list | List all identities for the authenticated user | -- |
| ravi_identity_create | Create a new identity (provisions email + phone + secrets) | name (string, required), email (string, optional) |
| ravi_get_info | Get the active identity's email and phone number | -- |
Email Inbox
| Tool | Description | Parameters |
|------|-------------|------------|
| ravi_inbox_email | List email threads, optionally unread only | unread (boolean) |
| ravi_read_email | Read all messages in an email thread | thread_id (string, required) |
| ravi_email_compose | Compose and send a new email | to, subject, body (all required) |
| ravi_email_reply | Reply to an existing email | message_id (number, required), body (required), reply_all |
| ravi_email_forward | Forward an email to a new recipient | message_id (number, required), to, subject, body (all required) |
SMS
| Tool | Description | Parameters |
|------|-------------|------------|
| ravi_inbox_sms | List SMS conversations, optionally unread only | unread (boolean) |
| ravi_read_sms | Read all messages in an SMS conversation | conversation_id (string, required) |
| ravi_sms_send | Send an SMS from the active identity's phone | to_number (E.164, required), body (required) |
Passwords
| Tool | Description | Parameters |
|------|-------------|------------|
| ravi_passwords_list | List all saved passwords (passwords hidden in list view) | -- |
| ravi_passwords_get | Get a specific password entry with decrypted password | uuid (string, required) |
| ravi_passwords_create | Create a new password (encrypted) | domain (required), username, password, notes |
| ravi_passwords_update | Update an existing password entry | uuid (required), domain, username, password, notes |
| ravi_generate_password | Generate a random password without storing it | length, special, digits |
| ravi_passwords_delete | Delete a password entry | uuid (string, required) |
Secrets
| Tool | Description | Parameters |
|------|-------------|------------|
| ravi_secrets_list | List all secret keys | -- |
| ravi_secrets_get | Get a secret by key (auto-decrypted) | key (string, required) |
| ravi_secrets_set | Store a secret (auto-encrypted) | key (string, required), value (string, required) |
| ravi_secrets_delete | Delete a secret by UUID | uuid (string, required) |
Feedback
| Tool | Description | Parameters |
|------|-------------|------------|
| ravi_feedback | Submit feedback about Ravi | message (required), category (bug/feature/positive/friction/other) |
Contacts
| Tool | Description | Parameters |
|------|-------------|------------|
| ravi_contacts_list | List all contacts for the active identity | -- |
| ravi_contacts_search | Fuzzy search contacts by name, nickname, or email | query (string, required) |
| ravi_contacts_get | Get a specific contact by UUID | uuid (string, required) |
| ravi_contacts_create | Create a new contact | email, phone_number, display_name, nickname |
| ravi_contacts_update | Update an existing contact | uuid (required), email, phone_number, display_name, nickname |
| ravi_contacts_delete | Delete a contact | uuid (string, required) |
CLI Commands
Run these via openclaw ravi <command>:
| Command | Description |
|---------|-------------|
| login | Authenticate via device-code flow and set up E2E encryption PIN |
| onboard | Full setup: auth + identity selection + OpenClaw config + secrets provider |
| status | Show auth status and list available identities |
E2E Encryption
All sensitive data (passwords, secrets, email content at rest) is encrypted end-to-end using a 6-digit PIN.
- Key derivation: PIN + server-stored salt -> Argon2id (time=3, mem=64MB, threads=1) -> 32-byte seed
- Encryption: NaCl SealedBox (ephemeral X25519 keypair + Poly1305 MAC)
- Ciphertext format:
e2e::<base64>-- same format used by the Ravi CLI - First-time setup: Choose + confirm 6-digit PIN, derive keypair, upload public key to server
- Returning login: Enter PIN (3 attempts), verify against server verifier + public key match
- Recovery key: Saved to
~/.ravi/recovery-key.txtduring first-time setup
After login, the derived keypair is stored in ~/.ravi/auth.json. Subsequent operations
use the stored keypair directly — no PIN re-entry needed.
Secrets Provider
The plugin ships a ravi-secrets binary that implements the OpenClaw exec
secrets protocol, letting you use the Ravi secrets store as a secrets provider.
The binary is installed automatically with the package.
Configuration
Add the provider to your OpenClaw config:
secrets:
providers:
ravi:
source: exec
command: ravi-secretsThen reference secrets anywhere a secret is accepted:
{ source: "exec", provider: "ravi", id: "my-api-key" }Requirements
- You must run
openclaw ravi onboard(orlogin) first -- the binary reads credentials from~/.ravi/auth.json. - Secrets are decrypted automatically using the E2E keypair stored during login. If no keypair is found, raw (encrypted) values are returned.
Architecture
Agent (OpenClaw runtime)
|
+-- Channels (ravi-email-owner, ravi-email-trusted)
| '-- Polling --> GET /api/email-messages/?direction=incoming&created_after=...
| Events arrive in plaintext (server decrypts before dispatch)
|
+-- Tools (28 agent tools)
| '-- REST calls --> GET/POST/DELETE /api/...
| Identity-scoped via bound JWT claims (identity_uuid in token)
| Returns MCP-style content arrays
|
'-- Crypto layer (lazy-initialized)
PIN + salt --> Argon2id --> NaCl SealedBox
Decrypts historical data from REST ("e2e::<base64>" fields)
Encrypts secrets/password writes before sending to serverKey points:
- Polling responses are plaintext -- the server decrypts before dispatch. No client-side decryption needed for real-time channel messages.
- REST data may be encrypted -- historical email content, passwords, and
secrets can contain
"e2e::<base64>"ciphertext that the plugin decrypts client-side using the PIN-derived keypair. - Tool responses return MCP-style content arrays (e.g.
[{ type: "text", text: "..." }]), letting the runtime render structured results natively. - Authentication uses bound JWTs with
identity_uuidclaim baked into the token. Identity is resolved from JWT claims.
Development
Prerequisites
- Node.js 18+
- npm
Setup
npm installBuild Targets
make build # Local dev build (reads .env.local for API URL)
make build-prod # Production build (always uses https://ravi.app)
make test # Run all tests
make lint # Type-check without emitting (tsc --noEmit)Publishing to npm happens only via GitHub Actions -- there is no local publish target.
npm Scripts
npm run build # Compile TypeScript to dist/
npm test # Run tests (vitest, single run)
npm run test:watch # Run tests in watch mode
npm run lint # Type-check without emitting (tsc --noEmit)Project structure
src/
index.ts # Plugin entry point and registration
types.ts # TypeScript interfaces for API responses and polling events
client.ts # RaviClient -- typed HTTP client for all REST endpoints
polling.ts # RaviPollingClient -- cursor-based polling for email events
crypto.ts # E2E encryption (Argon2id + NaCl SealedBox)
polling-pool.ts # Polling connection pool (ref-counted, one client per identity)
cli.ts # CLI commands (login, onboard, status)
bin/
ravi-secrets.ts # OpenClaw exec secrets provider binary
channels/
email.ts # ravi-email-owner channel
email-trusted.ts # ravi-email-trusted channel
tools/
identity.ts # Identity management tools
inbox.ts # Email and SMS inbox tools
email-send.ts # Email compose and reply tools
sms-send.ts # SMS send tool
passwords.ts # Password manager tools
secrets.ts # Secret management tools
contacts.ts # Contact management tools
feedback.ts # Feedback tool
__tests__/ # Test files (*.test.ts)License
MIT
