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/cliFrom npm (Using npx)
No installation required — run commands directly:
npx @modelriver/cli listen --printFrom Source
git clone https://github.com/modelriver/modelriver-cli.gitcd modelriver-clinpm installnpm link # Makes `modelriver` command available globallyQuick Start
Step 1: Login (One-Time Setup)
Run the interactive login command to configure your API key and forward URL:
modelriver loginYou'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/modelriverStep 2: Start Forwarding
After login, simply run:
modelriver forwardThat'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 --printmodelriver f # Same as: modelriver forwardmodelriver t -w my-workflow -m "Hello" # Same as: modelriver trigger ...Configuration
Interactive Setup (Recommended)
modelriver loginThis saves your configuration to ~/.modelriver/config.json.
Environment Variables
Set these environment variables for convenience:
export MODELRIVER_API_KEY=mr_live_YOUR_API_KEYexport MODELRIVER_API_URL=https://api.modelriver.com # Optional, defaults to productionConfig File
Create a config file at ~/.modelriver/config.json or .modelriverrc in your project:
1{2 "api_key": "mr_live_YOUR_API_KEY",3 "api_url": "https://api.modelriver.com",4 "forward_url": "http://localhost:4000/webhook/modelriver"5}Priority: CLI arguments > Environment variables > Config file > Defaults
Commands
modelriver login - Interactive Setup
Configure your API key and forward URL interactively.
Usage:
modelriver loginWhat 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 loginmodelriver forward # Override portmodelriver forward --port 4001 # Verbose outputmodelriver forward --verboseOptions:
--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 servermodelriver listen --port 3001 --print # With custom API keymodelriver listen --api-key mr_live_YOUR_KEY --print # Forward to external server (without starting local server)modelriver listen --port 3002 --forward --printHow 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 workflowmodelriver websocket --workflow my-workflow --message "Hello from CLI" # With custom payloadmodelriver websocket --workflow my-workflow --payload '{"messages": [{"role": "user", "content": "Test"}]}' # Connect to existing channelmodelriver websocket --channel-id abc-123 --project-id xyz-789 # Verbose outputmodelriver websocket --workflow my-workflow --message "Test" --verboseExample 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 triggermodelriver trigger --workflow my-workflow --message "Test message" # With custom payloadmodelriver trigger --workflow my-workflow --payload '{"messages": [...]}' # Create webhook to receive responsemodelriver trigger --workflow my-workflow --message "Test" --webhook-url https://webhook.site/your-id # Print channel detailsmodelriver trigger --workflow my-workflow --message "Test" --print-channelExample 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 responsesOptions:
--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 webhooksmodelriver webhook list # Verbose outputmodelriver webhook list --verbosemodelriver webhook verify - Verify Signature
Verify a webhook signature locally.
Usage:
# From filemodelriver webhook verify \ --payload webhook.json \ --signature abc123... \ --timestamp 1234567890 \ --secret your-webhook-secret # From JSON stringmodelriver webhook verify \ --payload '{"channel_id": "...", "data": {...}}' \ --signature abc123... \ --timestamp 1234567890 \ --secret your-webhook-secretOptions:
--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 WebSocketexport MODELRIVER_API_KEY=mr_live_YOUR_KEYmodelriver 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_KEYmodelriver websocket --workflow my-workflow --message "Hello from CLI" --verboseExample 3: Send Test Request and Get Channel Info
export MODELRIVER_API_KEY=mr_live_YOUR_KEYmodelriver trigger --workflow my-workflow --message "Test" --print-channelExample 4: Forward Webhooks to Localhost
# One-time setupmodelriver login # Start forwardingmodelriver forward # Or with custom portmodelriver listen --port 3000 --forward --printWebhook Payload Format
Webhooks are sent as HTTP POST requests with the following format:
Body:
1{2 "channel_id": "uuid",3 "timestamp": 1234567890,4 "data": {5 "status": "success|error",6 "data": { ... },7 "meta": { ... }8 }9}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:
1{2 "api_key": "mr_live_YOUR_API_KEY",3 "api_url": "https://api.modelriver.com",4 "forward_url": "http://localhost:4000/webhook/modelriver"5}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 testTests 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