Non-Interactive Mode Reference¶
Complete reference for Merlya's non-interactive (batch) execution mode.
Overview¶
Non-interactive mode (merlya run) executes commands without user interaction, making it ideal for:
- CI/CD pipelines (GitHub Actions, GitLab CI, Jenkins)
- Scheduled tasks (cron, systemd timers)
- Shell scripts and automation
- Docker containers
- Monitoring and alerting
Command Syntax¶
Arguments¶
| Argument | Description |
|---|---|
COMMAND | Natural language command or slash command to execute |
Options¶
| Option | Short | Description |
|---|---|---|
--file FILE | -f | Load tasks from YAML or text file |
--yes | -y | Skip confirmation prompts (auto-confirm) |
--format FORMAT | Output format: text (default) or json | |
--quiet | -q | Minimal output (errors only) |
--model ROLE | -m | Model role: brain (complex reasoning) or fast (quick tasks) |
--verbose | Enable verbose logging (use merlya --verbose run ...) | |
--help | Show help message |
Single Command Execution¶
Execute a single command:
With auto-confirmation (required for commands that modify systems):
With model selection:
# Use fast model for quick tasks
merlya run --model fast "List all hosts"
# Use brain model for complex analysis
merlya run -m brain "Analyze this incident and suggest remediation steps"
Slash Commands¶
Execute internal Merlya commands directly without AI processing:
Allowed Commands¶
Most read-only and diagnostic commands work in batch mode:
| Command | Description |
|---|---|
/health | Check system health |
/hosts list | List all hosts |
/hosts show <name> | Show host details |
/hosts import <file> | Import hosts from file |
/hosts export <file> | Export hosts to file |
/hosts tag <name> <tag> | Add tag to host |
/hosts untag <name> <tag> | Remove tag from host |
/scan <host> | Scan host for system info |
/model show | Show current model config |
/model provider <name> | Change LLM provider |
/model brain <name> | Set brain model (reasoning) |
/model fast <name> | Set fast model (routing) |
/log level <level> | Set log level |
/variable list | List variables |
/variable get <name> | Get variable value |
/secret list | List secret names |
Blocked Commands¶
These commands are not available in batch mode:
| Command | Reason |
|---|---|
/exit, /quit, /q | Session control (no session in batch) |
/new | Starts new conversation |
/conv, /conversation | Requires conversation context |
Interactive Commands¶
These commands require user input and cannot run in batch mode:
| Command | Reason |
|---|---|
/hosts add <name> | Prompts for hostname, port, username |
/ssh config <host> | Prompts for SSH configuration |
/secret set <name> | Requires secure input prompt |
Examples¶
# Quick health check
merlya run "/health"
# List all hosts with production tag
merlya run "/hosts list --tag=production"
# Scan a server
merlya run "/scan web-01 --quick"
# Full scan with JSON output
merlya run --format json "/scan web-01 --full"
# Import hosts from SSH config
merlya run "/hosts import ~/.ssh/config --format=ssh"
# Change model for subsequent commands
merlya run "/model provider anthropic"
Task File Execution¶
Execute multiple tasks from a file:
YAML Format¶
# tasks.yml
model: fast # Default model for all tasks (optional)
tasks:
- description: "Check disk space"
prompt: "Check disk usage on all servers, warn if above 80%"
- description: "Check memory"
prompt: "Check memory usage on all servers"
- description: "Analyze anomalies"
prompt: "Analyze any anomalies found and suggest fixes"
model: brain # Override for complex analysis
- prompt: "Verify nginx is running on web tier"
File-level fields¶
| Field | Required | Description |
|---|---|---|
model | No | Default model role for all tasks (brain or fast) |
tasks | Yes | List of tasks to execute |
Task-level fields¶
| Field | Required | Description |
|---|---|---|
prompt | Yes | The natural language command |
description | No | Human-readable task description |
model | No | Override model role for this task (brain or fast) |
Model selection priority¶
- CLI
--modelargument (highest priority) - Task-level
modelfield in YAML - File-level
modelfield in YAML - Default configured model (lowest priority)
Text Format¶
Simple one-command-per-line format:
# tasks.txt
Check disk space on all servers
List running services
Verify backup status from last 24h
Lines starting with # are treated as comments.
Output Formats¶
Text Output (Default)¶
Human-readable output:
Running health checks...
Executing: Check uptime on web-01
> ssh web-01 "uptime"
14:32:01 up 45 days, 3:21, 2 users, load average: 0.15, 0.10, 0.05
The server has been running for 45 days with low load average.
Completed: 1/1 tasks passed
JSON Output¶
Machine-parseable output for automation:
{
"success": true,
"total": 1,
"passed": 1,
"failed": 0,
"tasks": [
{
"task": "Check uptime on web-01",
"success": true,
"message": "The server has been running for 45 days with low load average.",
"actions": ["ssh_execute"]
}
]
}
Quiet Mode¶
Only errors are displayed:
Exit Codes¶
| Code | Meaning |
|---|---|
| 0 | All tasks succeeded |
| 1 | One or more tasks failed |
Use exit codes in scripts:
#!/bin/bash
if merlya run --quiet --yes "Check all servers healthy"; then
echo "All systems operational"
else
echo "Issues detected!"
exit 1
fi
Environment Variables¶
Configure Merlya via environment variables (useful in containers):
| Variable | Description |
|---|---|
OPENROUTER_API_KEY | OpenRouter API key |
ANTHROPIC_API_KEY | Anthropic API key |
OPENAI_API_KEY | OpenAI API key |
MERLYA_ROUTER_MODEL | Override local router model |
MERLYA_ROUTER_FALLBACK | LLM fallback model |
Example:
Use Cases¶
Cron Job¶
# /etc/cron.d/merlya-health
0 6 * * * root /usr/local/bin/merlya run --format json --yes \
"Run daily health checks" >> /var/log/merlya/daily.log 2>&1
Shell Script¶
#!/bin/bash
set -e
LOG_FILE="/var/log/merlya/deploy.log"
echo "$(date): Starting deployment" >> $LOG_FILE
# Pre-flight checks
RESULT=$(merlya run --format json --yes "Verify all servers healthy")
if echo "$RESULT" | jq -e '.success' > /dev/null; then
echo "$(date): Pre-flight passed" >> $LOG_FILE
merlya run --yes "Deploy version $VERSION to production"
else
echo "$(date): Pre-flight FAILED" >> $LOG_FILE
exit 1
fi
GitHub Actions¶
- name: Health Check
env:
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
run: |
pip install merlya
merlya run --format json --yes "Check all production servers"
Docker¶
Best Practices¶
- Always use
--yesin automation - Prompts will hang without TTY - Use
--format jsonfor parsing - Reliable structured output - Check exit codes - Handle failures gracefully
- Log output - Keep records of automated actions
- Test in staging first - Before automating production tasks
- Set timeouts - Wrap long-running commands with
timeout
# Example with timeout
timeout 300 merlya run --yes "Deploy to production" || {
echo "Deployment timed out after 5 minutes"
exit 1
}
Credential Requirements¶
When using --yes mode with commands that require elevated privileges (sudo, su), you must pre-configure credentials.
Why Credentials Can't Be Prompted¶
In non-interactive mode:
- No TTY available for password prompts
--yesauto-confirms but can't provide credentials- Agent will fail immediately with clear error message
Solutions¶
1. Store in Keyring (Recommended)¶
# Store sudo password for a specific host
merlya secret set sudo:192.168.1.7:password
# Store for multiple hosts
merlya secret set sudo:web-01:password
merlya secret set sudo:db-01:password
2. Configure NOPASSWD Sudo¶
On target hosts, add to /etc/sudoers.d/merlya:
# Allow specific user to run commands without password
cedric ALL=(ALL) NOPASSWD: ALL
# Or limit to specific commands
cedric ALL=(ALL) NOPASSWD: /usr/bin/systemctl, /usr/bin/journalctl
3. Use Interactive Mode¶
For one-off elevated commands, run without --yes:
Error Messages¶
When credentials are missing in --yes mode:
❌ Cannot obtain credentials in non-interactive mode.
Missing: password for [email protected]
To fix this, before running in --yes mode:
1. Store credentials in keyring:
merlya secret set sudo:192.168.1.7:password
2. Or configure NOPASSWD sudo on the target host
3. Or run in interactive mode (without --yes)
Troubleshooting¶
"Health checks failed"¶
The LLM provider is not configured or unreachable:
"Host not found"¶
The target host is not in the inventory:
# List available hosts
merlya run "List all hosts"
# Or add the host first (interactive mode)
merlya
/hosts add web-01
No output in JSON mode¶
Ensure you're capturing both stdout and stderr: