@ravi-hq/openclaw-plugin
v0.1.0
Published
OpenClaw plugin for Ravi — identity provider for AI agents. Email & SMS channels + full agent toolbox.
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 vault through a single plugin.
Features
- 2 messaging channels -- real-time email and SMS via Server-Sent Events
- 17 agent tools -- manage identities, inboxes, passwords, vault secrets, 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/openclaw-pluginQuick Start
1. Install and authenticate
openclaw plugins install @ravi-hq/openclaw-plugin
openclaw ravi loginThis opens a browser for device-code authentication. Copy the access token from the output.
2. Add your token and PIN to the plugin config
# In your OpenClaw config
plugins:
ravi:
token: "eyJhbGciOiJIUzI1NiIs..." # From 'openclaw ravi login'
pin: "123456" # Your 6-digit E2E encryption PIN3. Run setup to configure channels
openclaw ravi setupThis lists your identities and generates a channel configuration snippet you can paste into your OpenClaw config.
Configuration
plugins:
ravi:
# Ravi API base URL (default: https://ravi.app)
apiUrl: "https://ravi.app"
# JWT access token (required)
token: "your-access-token"
# 6-digit E2E encryption PIN (required)
pin: "123456"
# Channel accounts (from 'openclaw ravi setup')
channels:
ravi-email:
accounts:
"identity-uuid-here":
identityUuid: "identity-uuid-here"
identityName: "My Agent"
email: "[email protected]"
dm:
policy: "allowlist" # "allowlist" or "open"
allowFrom:
- "[email protected]"
ravi-sms:
accounts:
"identity-uuid-here":
identityUuid: "identity-uuid-here"
identityName: "My Agent"
phone: "+15551234567"
dm:
policy: "allowlist" # "allowlist" or "open"
allowFrom:
- "+15559876543"Channels
Ravi Email
Real-time email channel powered by SSE events 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:{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.
Ravi SMS
Real-time SMS channel powered by the same SSE stream.
- Threading model: All messages from one phone number form a single session.
A new
from_numbercreates a new session; subsequent messages from that number resume it. - Session key format:
agent:{agentId}:ravi-sms:{accountId}:dm:{phoneNumber} - DM policy: Set
policy: "allowlist"to restrict incoming SMS to specific phone numbers (E.164 format), or"open"to accept all senders. - Outbound: Replies are sent via the Ravi API as plain-text SMS.
Agent Tools
The plugin registers 17 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 + vault) | name (string, required) |
| 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 |
SMS Inbox
| 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) |
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_delete | Delete a password entry | uuid (string, required) |
Vault
| Tool | Description | Parameters |
|------|-------------|------------|
| ravi_vault_list | List all secret keys in the vault | -- |
| ravi_vault_get | Get a secret by key (auto-decrypted) | key (string, required) |
| ravi_vault_set | Store a secret (auto-encrypted) | key (string, required), value (string, required) |
Feedback
| Tool | Description | Parameters |
|------|-------------|------------|
| ravi_feedback | Submit feedback about Ravi | message (required), category (bug/feature/help/other) |
CLI Commands
Run these via openclaw ravi <command>:
| Command | Description |
|---------|-------------|
| login | Authenticate via device-code flow (opens browser) |
| status | Show auth status and list available identities |
| setup | Generate channel configuration from your identities |
E2E Encryption
All sensitive data (passwords, vault 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 - PIN verification: On first use, the plugin derives the keypair and verifies it against the server's stored verifier before proceeding
The crypto layer is lazy-initialized: keys are only derived when a tool actually needs encryption or decryption.
Architecture
Agent (OpenClaw runtime)
|
+-- Channels (ravi-email, ravi-sms)
| '-- SSE stream --> GET /api/events/stream/
| Events arrive in plaintext (server decrypts before dispatch)
|
+-- Tools (17 agent tools)
| '-- REST calls --> GET/POST/DELETE /api/...
| Identity-scoped via X-Ravi-Identity header
|
'-- Crypto layer (lazy-initialized)
PIN + salt --> Argon2id --> NaCl SealedBox
Decrypts historical data from REST ("e2e::<base64>" fields)
Encrypts vault/password writes before sending to serverKey points:
- SSE events are plaintext -- the server decrypts before pushing to the stream. No client-side decryption needed for real-time channel messages.
- REST data may be encrypted -- historical email content, passwords, and vault
secrets can contain
"e2e::<base64>"ciphertext that the plugin decrypts client-side using the PIN-derived keypair. - Authentication uses unbound JWTs. The
X-Ravi-Identityheader scopes each API request to a specific identity.
Development
Prerequisites
- Node.js 18+
- npm
Setup
npm installScripts
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 SSE events
client.ts # RaviClient -- typed HTTP client for all REST endpoints
sse.ts # RaviSSEClient -- SSE with auto-reconnect and heartbeat
crypto.ts # E2E encryption (Argon2id + NaCl SealedBox)
service.ts # Background listener service (manages SSE connections)
cli.ts # CLI commands (login, status, setup)
channels/
email.ts # ravi-email channel definition
sms.ts # ravi-sms channel definition
tools/
identity.ts # Identity management tools
inbox.ts # Email and SMS inbox tools
email-send.ts # Email compose and reply tools
passwords.ts # Password manager tools
vault.ts # Vault secret tools
feedback.ts # Feedback tool
__tests__/ # Test files (*.test.ts)License
MIT
