Claude Code

Overview

The Ravi Claude Code plugin teaches Claude Code how to use the ravi CLI. Once installed, Claude Code can autonomously sign up for services, receive OTPs, manage credentials, and send email on behalf of your agent.

Ravi works in two distinct Claude Code contexts — and they require different patterns:

ContextHow Ravi is calledPattern to use
Direct — Claude Code is the agent, running tasks itselfCLI subprocess via Bash toolPlugin skill file (this page)
Orchestrator — Claude Code is a skill/plugin managing subagentsMCP tools (preferred) or Bash(ravi ...) callsMCP Server or in-session CLI

Prerequisites

Install the Ravi CLI first — the plugin teaches Claude Code how to use it but doesn’t include the CLI itself.

brew install ravi-hq/tap/ravi
ravi auth login

Install the plugin

claude plugin marketplace add ravi-hq/claude-code-plugin
claude plugin install ravi@ravi

What it does

The plugin provides a skill file that tells Claude Code:

  • What commands are available (ravi get email, ravi inbox sms, ravi passwords create, etc.)
  • JSON output shapes for each command
  • Common workflows (signup, OTP extraction, 2FA completion)
  • Conventions (always use --json; poll with a retry loop rather than a bare sleep)

After installation, Claude Code will automatically use ravi when tasks involve identity, email, phone, or credentials.

Agent skills

The plugin uses skills from ravi-skills:

SkillWhat Claude Code learns
raviOverview — when to use each capability
ravi-identityCheck auth, get email/phone, switch Identities
ravi-inboxRead SMS and email — OTPs, verification links
ravi-email-sendCompose, reply, reply-all with HTML and attachments
ravi-loginSignup/login workflows with 2FA and credential storage
ravi-passwordsWebsite credentials (domain + username + password)
ravi-vaultKey-value secrets (API keys, env vars)

Example session

Once the plugin is installed, you can ask Claude Code to:

“Sign up for a Notion account using my Ravi identity”

Claude Code will:

  1. Get your agent’s email and phone via ravi get email --json and ravi get phone --json
  2. Generate and store credentials via ravi passwords create notion.so --json
  3. Fill out the signup form
  4. Poll the inbox for the verification code:
    for i in $(seq 1 10); do
      CODE=$(ravi inbox email --unread --json | jq -r '.[0].body // empty')
      [ -n "$CODE" ] && break
      sleep 2
    done
  5. Complete the signup

Claude Code as an orchestrator (skill-based parallel pattern)

When Claude Code is used as an orchestrator — via a skill like Subtask, a custom Claude Code plugin, or any workflow that spawns subagents inside the same Claude Code session — Ravi needs to be callable from within the running session, not just from a setup script run before launch.

This is a different problem from the pre-launch config injection approach used by wrapper orchestrators like amux or Claude Squad.

Pre-launch vs. in-session: when each pattern applies

Pre-launch config injection works when the orchestrator controls the agent’s startup environment — a shell script, a Makefile, or a .aperant/setup.sh that runs before the agent process starts. You write a .ravi/config.json into each worktree root and the agent finds it automatically via CWD resolution.

# Pre-launch: orchestrator setup script writes config before agent starts
mkdir -p "$WORKTREE/.ravi"
cat > "$WORKTREE/.ravi/config.json" <<EOF
{ "identity": "task-$TASK_ID" }
EOF

In-session provisioning is needed when the orchestrator is itself a Claude Code plugin or skill — spawning subagents via tool calls like Bash(subtask draft ...) rather than via subprocess launch. In this case, Ravi must be accessible as a callable tool from within the session.

Option 1: Ravi MCP server (preferred for in-session use)

The Ravi MCP server exposes all ravi_* tools natively. When registered in Claude Code’s MCP config, Ravi calls become first-class tool invocations — no subprocess, no shell dependency.

Add to ~/.claude/mcp.json:

{
  "mcpServers": {
    "ravi": {
      "command": "npx",
      "args": ["-y", "@ravi-hq/mcp-server"],
      "env": {
        "RAVI_ACCESS_TOKEN": "${RAVI_ACCESS_TOKEN}"
      }
    }
  }
}

Once registered, Claude Code can call ravi_identity_create, ravi_inbox_sms, ravi_secrets_get, and all other Ravi tools directly — making in-session provisioning identical to any other tool use.

For per-agent scoping in a parallel workflow, pass X-Ravi-Identity: <identity-name> in the env or set RAVI_CONFIG_DIR per subagent launch:

{
  "env": {
    "RAVI_ACCESS_TOKEN": "${RAVI_ACCESS_TOKEN}",
    "RAVI_CONFIG_DIR": "/tmp/ravi-agent-${TASK_ID}"
  }
}

See MCP server reference for the full tool list and auth options.

Option 2: Bash(ravi ...) tool invocation (fallback)

If MCP registration is not available (e.g., the Claude Code version in use doesn’t support MCP, or you’re inside a sandboxed skill context), Bash(ravi ...) calls work as a fallback — as long as the ravi binary is on PATH in the agent’s shell environment.

# Inside a Claude Code skill, orchestrator provisions identity for a subtask:
Bash("RAVI_CONFIG_DIR=/tmp/ravi-$TASK_ID ravi identity create --name task-$TASK_ID --json")

Limitations of the Bash fallback:

  • Requires ravi binary accessible in the shell PATH within the Claude Code context
  • Each invocation spawns a subprocess; slower than native MCP tool calls
  • Shell escaping can be tricky in skill prompts — prefer --json output and jq for parsing

In-session lifecycle: provision → use → revoke

For orchestrators that create identities per task (subtask hook, custom skill, etc.), the full lifecycle from inside a Claude Code session looks like:

# 1. Provision at task start (via MCP tool call)
ravi_identity_create(name="task-{TASK_ID}")

# 2. Inject into subagent worktree (before dispatching the subagent)
# Write .ravi/config.json into the worktree, or pass RAVI_CONFIG_DIR as env

# 3. Subagent uses identity autonomously during its task
# (inbox reads, OTP extraction, service signups)

# 4. Revoke or archive on task close/merge
ravi_identity_delete(name="task-{TASK_ID}")

This maps to the pre-dispatch and post-merge hooks described in Subtask + Ravi. If your orchestrator doesn’t have hooks, call the provision step at the start of the subagent’s system prompt (pass it as context) and the revoke step from the orchestrator after the subagent finishes.


Next steps