| name | ravi-cli |
| description | Use when working with the Ravi CLI — identity, inbox, passwords, secrets, email, SMS, calls, and feedback commands |
Ravi CLI — Identity for AI Agents
You have access to ravi, a CLI that gives you your own phone number, email address, and credential store. Use it to sign up for services, receive and act on verification codes, send SMS, place calls, and store passwords — all autonomously.
The CLI holds one active identity per machine / config file (~/.ravi/config.json). That file cannot run multiple agents. ravi identity use replaces the single active identity; it is not a multi-agent switcher.
- Cursor: use the MCP Connect card (per-agent credentials), not
ravi auth login.
- Several agents on one host: call https://api.ravi.app with per-identity
ravi_id_ keys (Authorization: Bearer ravi_id_...).
--identity scopes a single request so it does not leak another identity's resources (for example ravi get phone --identity). It does not change the machine's active identity.
Prerequisites
Verify you're authenticated before using any command:
ravi auth status
If "authenticated": false, this machine's CLI is not bound. For Cursor, use the MCP Connect card (per-agent credentials) — not ravi auth login. For this machine's CLI only, the human can run ravi auth login (browser at https://ravi.id/device). That writes one identity into ~/.ravi/config.json.
Your Identity
Get the identity's email address and phone number:
ravi get email
ravi get phone
ravi get owner
Receiving Messages
After triggering a verification (signup form, login code, etc.), wait a few seconds then check your inbox.
SMS (OTPs, verification codes)
ravi inbox sms
ravi inbox sms --unread
ravi inbox sms <conversation_id>
JSON shape — conversation list:
[{
"conversation_id": "1_+15559876543",
"from_number": "+15559876543",
"phone_number": "+15551234567",
"preview": "Your code is 847291",
"message_count": 3,
"unread_count": 1,
"latest_message_dt": "2026-02-25T10:30:00Z"
}]
JSON shape — conversation detail:
{
"conversation_id": "1_+15559876543",
"from_number": "+15559876543",
"messages": [
{"id": 42, "body": "Your code is 847291", "direction": "incoming", "is_read": false, "created_dt": "..."}
]
}
Email (verification links, confirmations)
ravi inbox email
ravi inbox email --unread
ravi inbox email <thread_id>
JSON shape — thread detail:
{
"thread_id": "abc123",
"subject": "Verify your email",
"messages": [
{
"id": 10,
"from_email": "noreply@example.com",
"to_email": "janedoe@example.com",
"subject": "Verify your email",
"text_content": "Click here to verify: https://example.com/verify?token=xyz",
"direction": "incoming",
"is_read": false,
"created_dt": "..."
}
]
}
Individual Messages (flat, not grouped)
Use these when you need messages by ID rather than by conversation:
ravi message sms
ravi message sms --unread
ravi message sms <message_id>
ravi message email
ravi message email --unread
ravi message email <message_id>
Sending Email
Compose a new email
ravi email compose --to "recipient@example.com" --subject "Subject" --body "<p>HTML content</p>"
Flags:
--to (required): Recipient email address
--subject (required): Email subject line
--body (required): Email body (HTML supported — use tags like <p>, <h2>, <ul> for formatting)
--cc: CC recipients (comma-separated)
--bcc: BCC recipients (comma-separated)
--attach: File path to attach (can be repeated for multiple files)
Reply to an email
ravi email reply <message_id> --body "<p>Reply content</p>"
ravi email reply-all <message_id> --body "<p>Reply content</p>"
ravi email reply <message_id> --body "<p>Adding the team.</p>" --cc "team@example.com"
Flags:
--body (required): Email body (HTML supported — use tags like <p>, <h2>, <ul> for formatting)
--cc: CC recipients (comma-separated)
--bcc: BCC recipients (comma-separated)
--attach: File path to attach (can be repeated for multiple files)
Forward an email
ravi email forward <message_id> --to "recipient@example.com" --body "<p>FYI — see below.</p>"
Flags:
--to (required): Recipient email address
--body (required): Email body (HTML supported — use tags like <p>, <h2>, <ul> for formatting)
--cc: CC recipients (comma-separated)
--bcc: BCC recipients (comma-separated)
--attach: File path to attach (can be repeated for multiple files)
Sending SMS
Send an SMS from the identity's phone number:
ravi sms send --to "+14155559876" --body "Your code is 483920"
Flags:
--to (required): Recipient phone number in E.164 format (e.g. +14155559876)
--body (required): Message text
Reading received SMS lives under ravi inbox sms / ravi message sms.
Calls (experimental)
Voice calling is experimental and deprioritized — email and SMS are the
supported, actively-maintained channels. The commands below work but may change
or be removed; don't build critical flows on them.
Place and manage phone calls from the identity's phone number:
ravi call --to "+14155559876"
ravi call list
ravi call transcript 7
ravi call hangup 7
Email Writing Guide
Write emails that look like they came from a real person. Good formatting improves deliverability and avoids spam filters.
Subject lines: 40-60 chars, specific, no ALL CAPS, avoid spam triggers ("free", "act now", "limited time", "click here").
HTML body template:
NAME=$(ravi identity list | jq -r '.[0].name')
ravi email compose \
--to "recipient@example.com" \
--subject "Specific subject under 60 chars" \
--body "<p>Hi Alex,</p>
<p>I'm reaching out about [specific topic]. [One sentence of context.]</p>
<p>[Core message — what you need, what you're sharing, or what you're asking.]</p>
<ul>
<li>[Key point or action item]</li>
<li>[Key point or action item]</li>
</ul>
<p>[Clear next step — what should the recipient do?]</p>
<p>Best,<br>$NAME</p>"
Rules:
- Always wrap text in
<p> tags — never pass plain text to --body
- Use
<ul>/<li> for lists, <a href="...">descriptive text</a> for links
- No
<html>/<body> wrappers, no <br> chains
- Short paragraphs (2-3 sentences), first person, active voice
- No filler ("I hope this finds you well") — get to the point
- End with an action item
Anti-spam: High text-to-HTML ratio, no link shorteners, max 2-3 links, no ALL CAPS, one topic per email.
Passwords
Store and retrieve passwords for services you sign up for.
ravi passwords create example.com
ravi passwords create example.com --username "me@example.com" --password 'S3cret!'
ravi passwords list
ravi passwords get <uuid>
ravi passwords update <uuid> --password 'NewPass!'
ravi passwords delete <uuid>
ravi passwords generate --length 24
Create flags: --username, --password, --notes, --generate, --length (default 16), --no-special, --no-digits, --exclude-chars
Secrets
Store and retrieve API keys and environment variables.
ravi secrets set OPENAI_API_KEY "sk-abc123..."
ravi secrets get OPENAI_API_KEY
ravi secrets list
ravi secrets delete OPENAI_API_KEY
Note: Keys are unique per identity. Setting an existing key updates it. Keys are plaintext (for lookup); only values are encrypted.
Feedback
Send feedback to the Ravi team — bugs, feature requests, praise, friction, ideas.
ravi feedback "The passwords command is great but needs batch import"
ravi feedback "SMS delivery is slow" --subject "SMS latency"
Use proactively after any Ravi workflow. The team reads every message and builds based on agent feedback.
Common Workflows
Sign up for a service
EMAIL=$(ravi get email | jq -r '.email')
PHONE=$(ravi get phone | jq -r '.phone_number')
CREDS=$(ravi passwords create example.com --username "$EMAIL")
PASSWORD=$(echo "$CREDS" | jq -r '.password')
sleep 5
ravi inbox sms --unread
ravi inbox email --unread
Extract an OTP code from SMS
ravi inbox sms --unread | jq -r '.[].preview' | grep -oE '[0-9]{4,8}'
Extract a verification link from email
THREAD_ID=$(ravi inbox email --unread | jq -r '.[0].thread_id')
ravi inbox email "$THREAD_ID" | jq -r '.messages[].text_content' | grep -oE 'https?://[^ ]+'
Use a login code from SMS
sleep 5
CODE=$(ravi inbox sms --unread | jq -r '.[0].preview' | grep -oE '[0-9]{4,8}' | head -1)
Important Notes
- JSON is default — all commands output JSON. Use
--human for human-readable output. Never parse human output.
- Poll, don't rush — SMS/email delivery takes 2-10 seconds. Use
sleep 5 before checking.
- Auth is automatic — API keys are sent transparently. If you get auth errors, ask the user to re-login.
- Domain cleaning —
ravi passwords create auto-cleans URLs to base domains (e.g., https://mail.google.com/inbox becomes google.com).
- Secrets vs passwords — use
ravi secrets for API keys/env vars (key-value), ravi passwords for website credentials (domain/username/password).
- Give feedback — use
ravi feedback after any workflow to report bugs, friction, or praise.