Back to skills
SkillHub ClubShip Full StackFull Stack

sonarr-fixed

Search and add TV shows to Sonarr. Supports monitor options, search-on-add. FORK of jordyvandomselaar/sonarr with fixed metadata.

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
3,030
Hot score
99
Updated
March 20, 2026
Overall rating
C5.0
Composite score
5.0
Best-practice grade
B80.4

Install command

npx @skill-hub/cli install openclaw-skills-sonarr-fixed

Repository

openclaw/skills

Skill path: skills/frannunpal/sonarr-fixed

Search and add TV shows to Sonarr. Supports monitor options, search-on-add. FORK of jordyvandomselaar/sonarr with fixed metadata.

Open repository

Best for

Primary workflow: Ship Full Stack.

Technical facets: Full Stack.

Target audience: everyone.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: openclaw.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install sonarr-fixed into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/openclaw/skills before adding sonarr-fixed to shared team environments
  • Use sonarr-fixed for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: sonarr-fixed
version: 1.0.2
description: Search and add TV shows to Sonarr. Supports monitor options, search-on-add. FORK of jordyvandomselaar/sonarr with fixed metadata.
metadata:
  openclaw:
    emoji: "πŸ“Ί"
    requires:
      bins:
        - curl
        - jq
      config:
        - path: ~/.openclaw/credentials/sonarr/config.json
          description: "Sonarr API configuration with url, apiKey, and defaultQualityProfile"
      env:
        - name: SONARR_URL
          optional: true
          description: "Sonarr instance URL (overrides config file)"
        - name: SONARR_API_KEY
          optional: true
          description: "Sonarr API key (overrides config file)"
    fork:
      original: jordyvandomselaar/sonarr
      original_url: https://clawhub.com/jordyvandomselaar/sonarr
      reason: "Fixed metadata to properly declare required credentials and config paths"
---

# Sonarr (Fixed)

**⚠️ FORK NOTICE:** This is a fork of [jordyvandomselaar/sonarr](https://clawhub.com/jordyvandomselaar/sonarr) with corrected metadata declarations.

Add TV shows to your Sonarr library.

## Setup

Create `~/.openclaw/credentials/sonarr/config.json`:
```json
{
  "url": "http://localhost:8989",
  "apiKey": "your-api-key",
  "defaultQualityProfile": 1
}
```
- `defaultQualityProfile`: Quality profile ID (run `config` to see options)

### Alternative: Environment Variables
Instead of config file, you can use:
- `SONARR_URL` - Sonarr instance URL
- `SONARR_API_KEY` - Sonarr API key

## Workflow

1. **Search**: `search "Show Name"` - returns numbered list
2. **Present results with TVDB links** - always show clickable links
3. **Check**: User picks a number
4. **Add**: Add show and start search

## Important
- **Always include TVDB links** when presenting search results to user
- Format: `[Title (Year)](https://thetvdb.com/series/SLUG)`
- Uses `defaultQualityProfile` from config; can override per-add

## Commands

### Search for shows
```bash
bash scripts/sonarr.sh search "Breaking Bad"
```

### Check if show exists in library
```bash
bash scripts/sonarr.sh exists <tvdbId>
```

### Add a show (searches immediately by default)
```bash
bash scripts/sonarr.sh add <tvdbId>              # searches right away
bash scripts/sonarr.sh add <tvdbId> --no-search  # don't search
```

### Remove a show
```bash
bash scripts/sonarr.sh remove <tvdbId>                # keep files
bash scripts/sonarr.sh remove <tvdbId> --delete-files # delete files too
```
**Always ask user if they want to delete files when removing!**

### Get root folders & quality profiles (for config)
```bash
bash scripts/sonarr.sh config
```

---
*Original skill by [jordyvandomselaar](https://clawhub.com/jordyvandomselaar). Fork maintained with permission under open source principles.*


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### scripts/sonarr.sh

```bash
#!/bin/bash
set -e

# Sonarr API wrapper
# Credentials: ~/.openclaw/credentials/sonarr/config.json

CONFIG_FILE="$HOME/.openclaw/credentials/sonarr/config.json"

if [ -f "$CONFIG_FILE" ]; then
  SONARR_URL=$(jq -r '.url' "$CONFIG_FILE")
  SONARR_API_KEY=$(jq -r '.apiKey' "$CONFIG_FILE")
  DEFAULT_QUALITY_PROFILE=$(jq -r '.defaultQualityProfile // empty' "$CONFIG_FILE")
fi

if [ -z "$SONARR_URL" ] || [ -z "$SONARR_API_KEY" ]; then
  echo "Error: Sonarr not configured. Create $CONFIG_FILE with {\"url\": \"...\", \"apiKey\": \"...\"}"
  exit 1
fi

API="$SONARR_URL/api/v3"
AUTH="X-Api-Key: $SONARR_API_KEY"

cmd="$1"
shift || true

case "$cmd" in
  search)
    query="$1"
    curl -s -H "$AUTH" "$API/series/lookup?term=$(echo "$query" | jq -sRr @uri)" | jq -r '
      to_entries | .[:10] | .[] | 
      "\(.key + 1). \(.value.title) (\(.value.year)) - https://thetvdb.com/dereferrer/series/\(.value.tvdbId)"
    '
    ;;
    
  search-json)
    query="$1"
    curl -s -H "$AUTH" "$API/series/lookup?term=$(echo "$query" | jq -sRr @uri)"
    ;;
    
  exists)
    tvdbId="$1"
    result=$(curl -s -H "$AUTH" "$API/series?tvdbId=$tvdbId")
    if [ "$result" = "[]" ]; then
      echo "not_found"
    else
      echo "exists"
      echo "$result" | jq -r '.[0] | "ID: \(.id), Title: \(.title), Seasons: \(.statistics.seasonCount)"'
    fi
    ;;
    
  config)
    echo "=== Root Folders ==="
    curl -s -H "$AUTH" "$API/rootfolder" | jq -r '.[] | "\(.id): \(.path)"'
    echo ""
    echo "=== Quality Profiles ==="
    curl -s -H "$AUTH" "$API/qualityprofile" | jq -r '.[] | "\(.id): \(.name)"'
    ;;
    
  add)
    tvdbId="$1"
    qualityProfileId="$2"
    searchFlag="true"
    
    # Check for --no-search flag
    for arg in "$@"; do
      if [ "$arg" = "--no-search" ]; then
        searchFlag="false"
      fi
    done
    
    # Get series details from lookup
    series=$(curl -s -H "$AUTH" "$API/series/lookup?term=tvdb:$tvdbId" | jq '.[0]')
    
    if [ "$series" = "null" ] || [ -z "$series" ]; then
      echo "❌ Show not found with TVDB ID: $tvdbId"
      exit 1
    fi
    
    # Get default root folder
    rootFolder=$(curl -s -H "$AUTH" "$API/rootfolder" | jq -r '.[0].path')
    
    # Use provided quality profile ID, config default, or first available
    if [ -z "$qualityProfileId" ] || [ "$qualityProfileId" = "--no-search" ]; then
      if [ -n "$DEFAULT_QUALITY_PROFILE" ]; then
        qualityProfile="$DEFAULT_QUALITY_PROFILE"
      else
        qualityProfile=$(curl -s -H "$AUTH" "$API/qualityprofile" | jq -r '.[0].id')
      fi
    else
      qualityProfile="$qualityProfileId"
    fi
    
    # Build add request
    addRequest=$(echo "$series" | jq --arg rf "$rootFolder" --argjson qp "$qualityProfile" --argjson search "$searchFlag" '
      . + {
        rootFolderPath: $rf,
        qualityProfileId: $qp,
        monitored: true,
        seasonFolder: true,
        addOptions: {
          monitor: "all",
          searchForMissingEpisodes: $search,
          searchForCutoffUnmetEpisodes: false
        }
      }
    ')
    
    result=$(curl -s -X POST -H "$AUTH" -H "Content-Type: application/json" -d "$addRequest" "$API/series")
    
    if echo "$result" | jq -e '.id' > /dev/null 2>&1; then
      title=$(echo "$result" | jq -r '.title')
      year=$(echo "$result" | jq -r '.year')
      seasons=$(echo "$result" | jq -r '.statistics.seasonCount // "?"')
      echo "βœ… Added: $title ($year) - $seasons seasons"
      if [ "$searchFlag" = "true" ]; then
        echo "πŸ” Search started"
      fi
    else
      echo "❌ Failed to add show"
      echo "$result" | jq -r '.message // .'
    fi
    ;;
    
  remove)
    tvdbId="$1"
    deleteFiles="false"
    if [ "$2" = "--delete-files" ]; then
      deleteFiles="true"
    fi
    
    # Get series ID from library
    series=$(curl -s -H "$AUTH" "$API/series?tvdbId=$tvdbId")
    
    if [ "$series" = "[]" ]; then
      echo "❌ Show not found in library"
      exit 1
    fi
    
    seriesId=$(echo "$series" | jq -r '.[0].id')
    title=$(echo "$series" | jq -r '.[0].title')
    year=$(echo "$series" | jq -r '.[0].year')
    
    curl -s -X DELETE -H "$AUTH" "$API/series/$seriesId?deleteFiles=$deleteFiles" > /dev/null
    
    if [ "$deleteFiles" = "true" ]; then
      echo "πŸ—‘οΈ Removed: $title ($year) + deleted files"
    else
      echo "πŸ—‘οΈ Removed: $title ($year) (files kept)"
    fi
    ;;
    
  *)
    echo "Usage: sonarr.sh <command> [args]"
    echo ""
    echo "Commands:"
    echo "  search <query>              Search for TV shows"
    echo "  search-json <query>         Search (JSON output)"
    echo "  exists <tvdbId>             Check if show is in library"
    echo "  config                      Show root folders & quality profiles"
    echo "  add <tvdbId> [profileId] [--no-search]  Add a show (searches by default)"
    echo "  remove <tvdbId> [--delete-files]  Remove a show from library"
    ;;
esac

```



---

## Skill Companion Files

> Additional files collected from the skill directory layout.

### _meta.json

```json
{
  "owner": "frannunpal",
  "slug": "sonarr-fixed",
  "displayName": "Sonarr Fixed",
  "latest": {
    "version": "1.0.2",
    "publishedAt": 1771933701406,
    "commit": "https://github.com/openclaw/skills/commit/a9f6a719f28a7f2d13041fa6e4edff8b86b34dae"
  },
  "history": []
}

```