← Back to NadirClaw

How to Deploy & Use NadirClaw

NadirClaw Deployment & Usage Guide

1. Prerequisites

System Requirements

  • Python: 3.9+ (tested on 3.9-3.12)
  • Git: For cloning the repository
  • Port: 8856 (default) available on localhost
  • Memory: ~512MB RAM + overhead for embedding model
  • Disk: ~100MB for installation + space for logs/cache

Optional Dependencies

  • Dashboard: pip install nadirclaw[dashboard] (requires browser)
  • Telemetry: pip install nadirclaw[telemetry] (OpenTelemetry)
  • Ollama: If using local models, install Ollama and run ollama serve

API Provider Accounts (Choose at least one)


2. Installation

Method A: Install from PyPI (Recommended)

pip install nadirclaw

Method B: Install from Source

# Clone the repository
git clone https://github.com/doramirdor/NadirClaw.git
cd NadirClaw

# Install in editable mode with optional extras
pip install -e ".[dashboard,telemetry]"

Method C: Automated Install Script

curl -fsSL https://raw.githubusercontent.com/doramirdor/NadirClaw/main/install.sh | sh

This script installs via pip and adds nadirclaw to your PATH.


3. Configuration

First-Time Setup

Run the interactive wizard to configure providers and models:

nadirclaw setup

The wizard will:

  1. Detect existing API keys in your environment (.env or shell)
  2. Let you select which providers to enable
  3. Choose models for simple/complex routing tiers
  4. Configure fallback chains
  5. Set budget limits (optional)
  6. Test your configuration

Manual Configuration (Advanced)

Create a .env file in your working directory or set environment variables:

# Provider API keys (at least one required)
OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-...
GEMINI_API_KEY=AIza...
DEEPSEEK_API_KEY=sk-...

# Router settings
NADIRCLAW_PORT=8856
NADIRCLAW_SIMPLE_MODEL=gemini-3-flash-preview
NADIRCLAW_COMPLEX_MODEL=gpt-4.1
NADIRCLAW_LOG_RAW=false  # Set to true to log full requests
NADIRCLAW_CACHE_TTL=300  # Cache TTL in seconds (default: 300)
NADIRCLAW_CACHE_MAX_SIZE=1000  # Max cached responses (default: 1000)

# Budget tracking (optional)
NADIRCLAW_DAILY_BUDGET=10.00  # USD
NADIRCLAW_MONTHLY_BUDGET=100.00  # USD
NADIRCLAW_BUDGET_WEBHOOK=https://your-alert-hook.example.com

# Ollama local (if using)
OLLAMA_API_BASE=http://localhost:11434

Provider-Specific Notes

  • OAuth: Use nadirclaw auth <provider> login to authenticate via browser instead of API keys
    nadirclaw auth openai login
    nadirclaw auth anthropic login
    nadirclaw auth google login
    
  • Ollama: Ensure Ollama is running (ollama serve) and models are pulled (ollama pull llama3.2)

Model Aliases

Use short names in configuration:

  • flashgemini-3-flash-preview
  • progemini-2.5-pro
  • sonnetclaude-sonnet-4-5-20250929
  • gpt4gpt-4.1
  • gpt4minigpt-4.1-mini

4. Build & Run

Development Mode

# Install with dev dependencies
pip install -e ".[dev]"

# Run with hot-reload (if using custom code)
nadirclaw serve --verbose --log-raw

# In another terminal, test
curl http://localhost:8856/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "auto",
    "messages": [{"role": "user", "content": "What is 2+2?"}]
  }'

Production Mode

# Basic run
nadirclaw serve

# With custom port and models
nadirclaw serve --port 8856 --simple-model gemini-3-flash-preview --complex-model gpt-4.1

# Enable raw logging for debugging
nadirclaw serve --log-raw

# Run as daemon (Linux/macOS)
nohup nadirclaw serve > nadirclaw.log 2>&1 &

Verify Installation

# Check version
nadirclaw --version

# Test connectivity
curl http://localhost:8856/v1/models

# View dashboard (if installed)
nadirclaw dashboard
# Opens http://localhost:8856/dashboard in browser

5. Deployment

Option 1: Systemd Service (Linux)

Create /etc/systemd/system/nadirclaw.service:

[Unit]
Description=NadirClaw LLM Router
After=network.target

[Service]
Type=simple
User=youruser
WorkingDirectory=/path/to/NadirClaw
Environment="PATH=/usr/bin:/usr/local/bin"
Environment="HOME=/home/youruser"
ExecStart=/usr/local/bin/nadirclaw serve --port 8856
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target

Enable and start:

sudo systemctl daemon-reload
sudo systemctl enable nadirclaw
sudo systemctl start nadirclaw
sudo systemctl status nadirclaw

Option 2: Docker

Create Dockerfile:

FROM python:3.11-slim

WORKDIR /app
COPY . /app

RUN pip install --no-cache-dir nadirclaw[dashboard]

# Copy .env if needed
# COPY .env /app/.env

EXPOSE 8856

CMD ["nadirclaw", "serve", "--port", "8856"]

Build and run:

docker build -t nadirclaw .
docker run -d \
  -p 8856:8856 \
  -v $(pwd)/.env:/app/.env \
  -v $(pwd)/data:/app/data \
  --name nadirclaw \
  nadirclaw

Option 3: Cloud Platform (Any VPS/Cloud Instance)

Deploy on any VPS (DigitalOcean, Linode, AWS EC2, GCP Compute Engine):

# On remote server
git clone https://github.com/doramirdor/NadirClaw.git
cd NadirClaw
python -m venv venv
source venv/bin/activate
pip install -e ".[dashboard]"

# Configure
nadirclaw setup  # Enter your API keys

# Run with screen/tmux or systemd
screen -S nadirclaw
nadirclaw serve
# Ctrl+A, D to detach

Option 4: Kubernetes

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nadirclaw
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nadirclaw
  template:
    metadata:
      labels:
        app: nadirclaw
    spec:
      containers:
      - name: nadirclaw
        image: nadirclaw:latest
        ports:
        - containerPort: 8856
        envFrom:
        - configMapRef:
            name: nadirclaw-config
        - secretRef:
            name: nadirclaw-secrets
        volumeMounts:
        - name: data
          mountPath: /app/data
        resources:
          requests:
            memory: "512Mi"
            cpu: "250m"
          limits:
            memory: "1Gi"
            cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
  name: nadirclaw
spec:
  selector:
    app: nadirclaw
  ports:
  - port: 8856
    targetPort: 8856

6. Usage

Basic Proxy Usage

Configure your AI tool (Claude Code, Cursor, Continue, OpenClaw) to use:

http://localhost:8856/v1

as the OpenAI API base URL. No API key needed for NadirClaw itself.

CLI Commands

Start the router

nadirclaw serve [OPTIONS]

Options:

  • --port PORT: Port to listen on (default: 8856)
  • --simple-model MODEL: Override simple tier model
  • --complex-model MODEL: Override complex tier model
  • --verbose: Enable debug logging
  • --log-raw: Log full requests/responses to JSONL

Interactive setup

nadirclaw setup [--reconfigure]

View dashboard

nadirclaw dashboard
# Opens http://localhost:8856/dashboard

Analyze usage logs

# Generate report for last 24 hours
nadirclaw report --since 24h

# Filter by model
nadirclaw report --since 7d --model gpt-4.1

# Show cost breakdown
nadirclaw report --since 30d --costs

# Export to JSON
nadirclaw report --since 7d --format json > report.json

View savings

nadirclaw savings --since 30d

Manage budget alerts

nadirclaw budget --status
nadirclaw budget --set-daily 10.00
nadirclaw budget --set-monthly 100.00

Monitor cache

nadirclaw cache --stats

OAuth authentication

nadirclaw auth openai login
nadirclaw auth anthropic login
nadirclaw auth google login

Direct API Calls

# Simple prompt (routes to cheap model)
curl http://localhost:8856/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "auto",
    "messages": [{"role": "user", "content": "Read file main.py"}]
  }'

# Force premium model
curl http://localhost:8856/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4.1",
    "messages": [{"role": "user", "content": "Design a distributed system"}]
  }'

# Use reasoning profile
curl http://localhost:8856/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "reasoning",
    "messages": [{"role": "user", "content": "Solve: A train leaves station A..."}]
  }'

# Streaming
curl http://localhost:8856/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "auto",
    "messages": [{"role": "user", "content": "Write a Python function"}],
    "stream": true
  }'

Routing Profiles

  • auto (default): Smart classification
  • eco: Always use cheapest available model
  • premium: Always use best model
  • free: Use only free/local models (Ollama)
  • reasoning: Force reasoning-optimized models

Integration Examples

Claude Code

# In your project directory
export CLAUDE_API_BASE=http://localhost:8856/v1
claude-code

Cursor IDE

Settings → Features → AI Provider → Custom OpenAI-Compatible:

  • API Base: http://localhost:8856/v1
  • API Key: Any non-empty string (NadirClaw ignores it)

Continue.dev

// config.json
{
  "models": [
    {
      "title": "NadirClaw Auto",
      "model": "auto",
      "apiBase": "http://localhost:8856/v1",
      "apiKey": "dummy"
    }
  ]
}

7. Troubleshooting

Common Issues

"No configuration found" on first run

Solution: Run nadirclaw setup and complete the wizard, or set environment variables in .env.

Port 8856 already in use

Solution:

# Find process using port
lsof -i :8856
# Kill it or use different port
nadirclaw serve --port 8857

OAuth fails with "redirect_uri_mismatch"

Solution: The local callback server runs on port 1455. Ensure no firewall blocks http://localhost:1455/auth/callback. Some providers require pre-registered redirect URIs — use API keys instead.

"Model not found" errors

Solution:

  1. Check provider's available models: curl https://api.openai.com/v1/models (with your key)
  2. Update MODEL_REGISTRY in nadirclaw/routing.py if using custom models
  3. Use model aliases: flash, sonnet, gpt4 instead of full IDs

High latency (>100ms)

Possible causes:

  • Classification model download on first run (~500MB). Wait for it to cache.
  • Network issues to provider APIs. Check with curl https://api.openai.com/v1/models
  • Ollama not running: ollama serve

Dashboard not loading

Solution: Install dashboard extras: pip install nadirclaw[dashboard]. Access http://localhost:8856/dashboard directly.

Logs not appearing in reports

Solution: Ensure --log-raw is enabled or check data/requests.db (SQLite). Reports read from this database.

Cache not working

Solution:

  • Cache only works for identical messages (same content, model, temperature)
  • Check cache stats: nadirclaw cache --stats
  • Adjust TTL: export NADIRCLAW_CACHE_TTL=600

Budget alerts not triggering

Solution:

  • Budgets track actual costs from provider pricing in routing.py
  • Ensure --log-raw is