Overview
The ModelRiver CLI is a command-line tool for testing webhooks and WebSockets from live/production ModelRiver, similar to Stripe CLI. It allows you to:
- Listen for webhooks via WebSocket (no public URL required)
- Forward webhooks to localhost for development
- Test WebSocket connections and receive real-time AI responses
- Trigger async requests from the command line
- Verify webhook signatures locally
Installation
From npm (Global Installation)
npm install -g @modelriver/cli
From npm (Using npx)
No installation required — run commands directly:
npx @modelriver/cli listen --print
From Source
git clone https://github.com/modelriver/modelriver-cli.git
cd modelriver-cli
npm install
npm link # Makes `modelriver` command available globally
Quick Start
Step 1: Login (One-Time Setup)
Run the interactive login command to configure your API key and forward URL:
modelriver login
You'll be prompted for:
- API Key: Your ModelRiver API key (starts with
mr_live_ormr_test_) - Forward URL: Where to forward webhooks (e.g.,
http://localhost:4000)
The URL will be automatically normalized to include /webhook/modelriver.
Example session:
ModelRiver CLI Login
─────────────────────
Configure your ModelRiver CLI credentials.
Enter your ModelRiver API key: mr_live_abc123...
Enter your webhook forward URL (e.g. http://localhost:4000/webhook/modelriver): http://localhost:4000
✓ Configuration saved!
Saved Configuration
───────────────────
✓ API Key: mr_live_abc123...
✓ Forward URL: http://localhost:4000/webhook/modelriver
Step 2: Start Forwarding
After login, simply run:
modelriver forward
That's it! Webhooks will be forwarded to your configured URL.
Command Aliases
For convenience, the CLI supports short aliases:
| Command | Alias | Description |
|---|---|---|
| listen | l | Listen for webhooks |
| forward | f | Forward using saved config |
| trigger | t | Send async request |
| websocket | ws | Test WebSocket connection |
Example:
modelriver l --print # Same as: modelriver listen --print
modelriver f # Same as: modelriver forward
modelriver t -w my-workflow -m "Hello" # Same as: modelriver trigger ...
Configuration
Interactive Setup (Recommended)
modelriver login
This saves your configuration to ~/.modelriver/config.json.
Environment Variables
Set these environment variables for convenience:
export MODELRIVER_API_KEY=mr_live_YOUR_API_KEY
export MODELRIVER_API_URL=https://api.modelriver.com # Optional, defaults to production
Config File
Create a config file at ~/.modelriver/config.json or .modelriverrc in your project:
{
"api_key": "mr_live_YOUR_API_KEY",
"api_url": "https://api.modelriver.com",
"forward_url": "http://localhost:4000/webhook/modelriver"
}
Priority: CLI arguments > Environment variables > Config file > Defaults
Commands
modelriver login - Interactive Setup
Configure your API key and forward URL interactively.
Usage:
modelriver login
What it does:
- Prompts for API key
- Prompts for webhook forward URL
- Saves configuration to
~/.modelriver/config.json - Displays saved configuration
modelriver forward - Quick Webhook Forwarding
Forward webhooks using your saved configuration.
Usage:
# Simple - uses saved config from login
modelriver forward
# Override port
modelriver forward --port 4001
# Verbose output
modelriver forward --verbose
Options:
--port <number>- Override the port in forward URL--verbose- Show detailed logging--api-key <key>- Override saved API key
modelriver listen - Receive Webhooks via WebSocket
Like Stripe CLI, receive webhook events directly via WebSocket - no public URL needed.
Usage:
# Start listening for webhooks (like `stripe listen`)
modelriver listen --print
# Or use alias: modelriver l --print
# Forward to local server
modelriver listen --port 3001 --print
# With custom API key
modelriver listen --api-key mr_live_YOUR_KEY --print
# Forward to external server (without starting local server)
modelriver listen --port 3002 --forward --print
How it works (like Stripe CLI):
- Authenticates with your API key
- Gets a secure WebSocket token (valid for 24 hours)
- Connects to ModelRiver via WebSocket
- Receives webhook events in real-time - no public URL or ngrok required!
- Optionally forwards to local server
Example Output:
✓ Connecting to ModelRiver...
✓ WebSocket connected
✓ Joined webhook channel
> Ready! Listening for webhook events
> User ID: user-id-123
> Channel: cli_webhooks:user-id-123
> Local port: 3001
> Press Ctrl+C to stop
[2026-01-07 15:20:30] Webhook received via WebSocket:
Channel ID: abc-123-def
Status: success
Data: {"result": "..."}
Options:
--print- Print received webhooks to console--port <number>- Local server port to forward to--forward- Enable forwarding to local server--api-key <key>- ModelRiver API key--verbose- Show detailed logs
modelriver websocket - Test WebSocket Connection
Test WebSocket connections to production and receive real-time responses.
Usage:
# Test with workflow
modelriver websocket --workflow my-workflow --message "Hello from CLI"
# With custom payload
modelriver websocket --workflow my-workflow --payload '{"messages": [{"role": "user", "content": "Test"}]}'
# Connect to existing channel
modelriver websocket --channel-id abc-123 --project-id xyz-789
# Verbose output
modelriver websocket --workflow my-workflow --message "Test" --verbose
Example Output:
✓ Making async request...
✓ Request queued: abc-123-def
> Channel ID: abc-123-def
> Project ID: xyz-789
✓ Connecting to WebSocket...
✓ WebSocket connected
✓ Channel joined
> Waiting for response...
✅ Response received:
{
"status": "success",
"data": { ... },
"meta": { ... }
}
Options:
--workflow <name>- Workflow to test--message <text>- Simple text message--payload <json>- Custom JSON payload--channel-id <id>- Existing channel ID--project-id <id>- Project ID--verbose- Show detailed logs
modelriver trigger - Send Async Request
Send a test async request and get channel details.
Usage:
# Basic trigger
modelriver trigger --workflow my-workflow --message "Test message"
# With custom payload
modelriver trigger --workflow my-workflow --payload '{"messages": [...]}'
# Create webhook to receive response
modelriver trigger --workflow my-workflow --message "Test" --webhook-url https://webhook.site/your-id
# Print channel details
modelriver trigger --workflow my-workflow --message "Test" --print-channel
Example Output:
✓ Async request created
Channel Details
{
"channel_id": "abc-123-def",
"project_id": "xyz-789",
"websocket_url": "wss://api.modelriver.com/socket",
"websocket_channel": "ai_response:xyz-789:abc-123-def",
"status": "pending"
}
> Use --webhook-url to automatically receive responses via webhook
> Or use "modelriver websocket" to connect and receive responses
Options:
--workflow <name>- Workflow name--message <text>- Simple text message--payload <json>- Custom JSON payload--webhook-url <url>- Webhook URL for responses--print-channel- Print channel details--verbose- Show detailed logs
modelriver webhook list - List Webhooks
List all webhooks for your project.
Usage:
# List webhooks
modelriver webhook list
# Verbose output
modelriver webhook list --verbose
modelriver webhook verify - Verify Signature
Verify a webhook signature locally.
Usage:
# From file
modelriver webhook verify \
--payload webhook.json \
--signature abc123... \
--timestamp 1234567890 \
--secret your-webhook-secret
# From JSON string
modelriver webhook verify \
--payload '{"channel_id": "...", "data": {...}}' \
--signature abc123... \
--timestamp 1234567890 \
--secret your-webhook-secret
Options:
--payload <file|json>- Webhook payload--signature <sig>- Signature to verify--timestamp <ts>- Unix timestamp--secret <secret>- Webhook secret
Usage Examples
Example 1: Listen for Webhooks (like Stripe CLI)
# Terminal 1: Start listening for webhooks via WebSocket
export MODELRIVER_API_KEY=mr_live_YOUR_KEY
modelriver listen --print
# Terminal 2: Trigger an async AI request
# Webhook events will appear in Terminal 1 via WebSocket (no public URL needed!)
Example 2: Test WebSocket Connection
export MODELRIVER_API_KEY=mr_live_YOUR_KEY
modelriver websocket --workflow my-workflow --message "Hello from CLI" --verbose
Example 3: Send Test Request and Get Channel Info
export MODELRIVER_API_KEY=mr_live_YOUR_KEY
modelriver trigger --workflow my-workflow --message "Test" --print-channel
Example 4: Forward Webhooks to Localhost
# One-time setup
modelriver login
# Start forwarding
modelriver forward
# Or with custom port
modelriver listen --port 3000 --forward --print
Webhook Payload Format
Webhooks are sent as HTTP POST requests with the following format:
Body:
{
"channel_id": "uuid",
"timestamp": 1234567890,
"data": {
"status": "success|error",
"data": { ... },
"meta": { ... }
}
}
Headers:
X-ModelRiver-Signature: HMAC-SHA256 hex signatureX-ModelRiver-Timestamp: Unix timestamp stringX-ModelRiver-Webhook-Id: Webhook UUIDContent-Type: application/json
WebSocket Protocol
The CLI connects to ModelRiver WebSockets using the Phoenix protocol:
- Connect to
wss://api.modelriver.com/socket?token={ws_token} - Join channel:
ai_response:{project_id}:{channel_id} - Listen for response event containing the AI response
Troubleshooting
"API key is required"
Set the API key via:
- Environment variable:
export MODELRIVER_API_KEY=mr_live_YOUR_KEY - CLI flag:
--api-key mr_live_YOUR_KEY - Config file:
~/.modelriver/config.json
"WebSocket connection failed"
- Verify the API URL is correct
- Check that the
ws_tokenhasn't expired (24-hour limit for CLI tokens) - Check network connectivity
- If using production, ensure you're using
wss://(secure WebSocket)
"Webhook signature verification failed"
- Ensure the secret matches exactly (no extra spaces)
- Verify timestamp is recent (within 5 minutes)
- Check that payload structure matches expected format
Note: The CLI does not support creating permanent webhooks. Use the ModelRiver dashboard to create webhooks for production use. The CLI only creates temporary webhooks for testing (via
listenandtest-webhookcommands), which are automatically cleaned up.
API Endpoints
The CLI uses these ModelRiver API endpoints:
POST /v1/ai/async- Create async requestPOST /v1/ai- Create sync requestGET /v1/webhooks- List webhooks- WebSocket connection at
wss://api.modelriver.com/socket
Configuration File Format
The CLI looks for configuration in these locations (in order):
.modelriverrcin current directory~/.modelriver/config.jsonin home directory
Example ~/.modelriver/config.json:
{
"api_key": "mr_live_YOUR_API_KEY",
"api_url": "https://api.modelriver.com",
"forward_url": "http://localhost:4000/webhook/modelriver"
}
Security
- API keys are stored locally in
~/.modelriver/config.json - WebSocket tokens are short-lived (24 hours for CLI usage)
- Never commit config files with API keys to version control
- Add
~/.modelriverrcand.modelriverrcto your.gitignore
Development
Running Tests
The CLI includes a Jest test suite. To run the tests:
npm test
Tests cover critical components including:
- Webhook signature verification
- Configuration loading
- API client validation
- Output formatting
Next Steps
- Review the Webhooks documentation to understand webhook integration
- Explore Client SDK for frontend WebSocket connections
- Check API documentation for async request details