Skip to main content
Glama

mcp-medusa

MCP server that exposes Medusa anime automation tools.

Tools

add_anime

Adds an anime to Medusa using POST /api/v2/anime/add.

Common arguments:

{
  "anime_id": 62076,
  "source": "myanimelist",
  "root_dir": "/media/videos/Anime",
  "anime": true,
  "scene": false,
  "status": "wanted",
  "initial_release_group": "SubsPlease",
  "fallback_release_groups": ["SubsPlease", "Erai-raws"],
  "release_group_fallback_days": 7
}

Arguments:

Argument

Required

Default

Allowed values / notes

anime_id

yes

none

Source-specific anime ID. For myanimelist, this is the MAL anime ID.

root_dir

yes

none

Medusa root directory path for the new series.

source

no

myanimelist

Case-insensitive: myanimelist, livechart

anime

no

true

Usually keep true.

scene

no

false

Whether to enable scene numbering.

status

no

wanted

Medusa episode status string, commonly wanted, skipped, or ignored.

initial_release_group

no

none

First/active release group to whitelist, for example SubsPlease.

fallback_release_groups

no

none

Ordered list of release groups to rotate through. Include the initial group first for deterministic behavior.

release_group_fallback_days

no

7

Days after episode airdate before switching to the next fallback group.

directory_name

no

Medusa-generated

Optional series folder name override.

seasonal_anime

Queries Medusa seasonal anime using GET /api/v2/anime/seasonal.

{
  "year": 2026,
  "season": "SPRING",
  "source": "myanimelist",
  "source_sort": "anime_num_list_users",
  "page": 1,
  "limit": 10,
  "fields": ["animeId", "displayTitle", "year", "animeType", "genres", "score", "imageUrl"]
}

Minimal call using current anime season defaults:

{}

Arguments:

Argument

Required

Default

Allowed values / notes

year

no

current year

If omitted, calculated from the MCP server's current date.

season

no

current anime season

Case-insensitive: WINTER, SPRING, SUMMER, FALL or values like Summer. If omitted, calculated from the MCP server's current month.

source

no

myanimelist

Case-insensitive: myanimelist, livechart

source_sort

no

anime_num_list_users

Case-insensitive: anime_num_list_users, anime_score

page

no

1

Medusa result page number. Must be 1 or greater.

limit

no

10

Results per page. Medusa allows 1 through 1000; default is intentionally small to avoid MCP client truncation.

fields

no

null

Optional list of response fields to keep. If omitted/null, the full Medusa anime objects are returned.

Current anime season defaults use this month mapping:

Months

Season

January-March

WINTER

April-June

SPRING

July-September

SUMMER

October-December

FALL

Useful fields values include:

["animeId", "source", "displayTitle", "titleRomanji", "titleEnglish", "year", "season", "animeType", "status", "episodes", "episodeInfo", "genres", "studios", "score", "numListUsers", "imageUrl", "anidbId", "tvdbId", "malId", "url", "directoryName"]

resolve_anime_title

Resolves a title to enriched Medusa/MyAnimeList candidates using GET /api/v2/anime/search with source, includeDetails=true, and limit.

{
  "title": "Frieren",
  "source": "myanimelist",
  "limit": 10,
  "min_score": 88,
  "score_gap": 8
}

Returns decision as match, ambiguous, or no_match, plus scored candidates.

anime_info

Returns compact anime details and Medusa presence by title or MAL ID without adding anything.

{
  "title": "Frieren",
  "source": "myanimelist"
}

or:

{
  "mal_id": 52991,
  "source": "myanimelist"
}

seasonal_candidates

Fetches seasonal candidates using Medusa's server-side seasonal filters before applying residual OpenClaw-specific heuristics.

{
  "year": 2026,
  "season": "SUMMER",
  "source": "myanimelist",
  "limit": 25,
  "min_num_list_users": 3000,
  "fields": ["animeId", "displayTitle", "animeType", "genres", "numListUsers", "synopsis"]
}

The MCP tool sends Medusa filters such as animeType=TV, minNumListUsers, excludeGenres=Kids,Boys Love, matched=false, firstSeasonOnly=true, and fields to reduce payload size.

prepare_seasonal_review

Compacts seasonal candidate items into an AI review packet with conservative review instructions.

{
  "items": [{"animeId": 62076, "displayTitle": "Example Title"}],
  "max_items": 25
}

resolve_and_add_anime

Resolves and dry-runs or executes a single add through Medusa's bulk-add endpoint. Writes require execute: true.

{
  "title": "Frieren",
  "root_dir": "/media/videos/Anime",
  "execute": false
}

scheduler_status

Returns Medusa scheduler thread health and queue state. Use when anime adds appear stuck or unverified.

{}

search_tvdb

Searches TVDB by show name for a TVDB ID. Use as fallback when an anime add fails due to AniDB-to-TVDB mapping issues.

{ "query": "Dorohedoro", "language": "en" }

add_series

Adds a series directly by TVDB ID via POST /api/v2/series. Bypasses anime resolution entirely. Use after search_tvdb when add_anime fails.

Arguments:

Argument

Required

Default

Notes

tvdb_id

yes

none

TVDB show ID (from search_tvdb).

root_dir

yes

none

Medusa root directory path.

anime

no

true

status

no

wanted

Accepts strings like wanted, skipped, ignored — converted to numeric internally.

language

no

none

Indexer language override.

show_dir

no

none

Custom series folder name override.

scene

no

false

paused

no

false

{ "tvdb_id": 370761, "root_dir": "/media/videos/Anime" }

set_episode_status

Sets episode statuses for a series via POST /api/v2/internal/updateEpisodeStatus. Use when TVDB metadata is out of sync and Medusa is not downloading episodes that should be available.

Arguments:

Argument

Required

Default

Notes

series_slug

yes

none

Series slug (e.g. tvdb370761).

episodes

yes

none

List of episode slugs (e.g. ["s01e01", "s01e02"]).

status

no

wanted

Target status: wanted, skipped, ignored.

{ "series_slug": "tvdb370761", "episodes": ["s01e01", "s01e02"], "status": "wanted" }

Force a manual search for specific episodes via PUT /api/v2/search/manual. Queues a provider search that actively queries enabled providers and snatches matching releases. Use after setting episodes to "wanted".

Arguments:

Argument

Required

Default

Notes

series_slug

yes

none

Series slug (e.g. tvdb370761).

episodes

yes

none

List of episode slugs (e.g. ["s01e01", "s01e02"]).

{ "series_slug": "tvdb370761", "episodes": ["s01e01"] }

update_series_quality

Update allowed or preferred qualities for an existing series via PATCH /api/v2/series/{slug}. Uses human-readable quality names. Omitted fields are left unchanged.

Arguments:

Argument

Required

Default

Notes

series_slug

yes

none

Series slug (e.g. tvdb370761).

allowed_qualities

no

none

Quality names for the allowed list.

preferred_qualities

no

none

Quality names for the preferred list.

Quality names: "SDTV", "SD DVD", "720p HDTV", "RawHD", "1080p HDTV", "720p WEB-DL", "1080p WEB-DL", "720p BluRay", "1080p BluRay", "4K UHD TV", "8K UHD TV", "4K UHD WEB-DL", "8K UHD WEB-DL", "4K UHD BluRay", "8K UHD BluRay".

{ "series_slug": "tvdb370761", "allowed_qualities": ["1080p BluRay", "720p HDTV"] }

organize_season_folders

Enable season folders and move episode files into Season XX/ subdirectories without renaming files. Calls POST /api/v2/series/{slug}/operation with type=ORGANIZE_SEASON_FOLDERS.

Use when a multi-season anime has all files in a flat directory and Plex is missing episodes due to poor multi-season-in-one-folder support.

Arguments:

Argument

Required

Default

Notes

series_slug

yes

none

Series slug (e.g. tvdb370761).

{ "series_slug": "tvdb370761" }

postprocess

Trigger Medusa manual post-processing on a directory. Scans a download/staging folder and moves matched episodes into their show folders. Reuses the MEDUSA_URL / MEDUSA_API_KEY credentials. Use this to clear files stranded in staging after a failed auto-post-process (e.g. a mis-named release the download handler bailed on). Calls POST /api/v2/postprocess.

IMPORTANT: the directory argument is interpreted by Medusa core, so it must be the path as seen inside the Medusa container (e.g. /data/medusa), NOT the path visible from a separate Hermes container.

Arguments:

Argument

Required

Default

Notes

directory

no

/data/medusa

Medusa-container path to scan. Must match Medusa core's view, not the Hermes mount.

process_type

no

auto

auto, manual, or failed.

force_replace

no

false

Overwrite existing episode files.

process_method

no

copy

copy or move.

{ "proc_dir": "/data/medusa", "proc_type": "auto" }

bulk_add_anime

Dry-runs or executes multiple anime adds through POST /api/v2/anime/bulk-add. Writes require execute: true.

{
  "items": [{"animeId": 62076, "displayTitle": "Example Title", "aiDecision": "add"}],
  "decision_field": "aiDecision",
  "allowed_decisions": ["add"],
  "execute": false
}

Related MCP server: MyAnimeList MCP Server

Configuration

Environment variables:

Variable

Required

Description

MEDUSA_URL

yes

Base URL for Medusa, for example http://medusa:8081

MEDUSA_API_KEY

recommended

Medusa API key sent as X-Api-Key

MEDUSA_WEB_ROOT

no

Web root if Medusa is hosted below a path

MEDUSA_TIMEOUT

no

HTTP timeout in seconds, default 30

MCP_TRANSPORT

no

stdio or sse, default stdio

MCP_HOST

no

SSE bind host, default 0.0.0.0

MCP_PORT

no

SSE bind port, default 8000

MCP_DNS_REBINDING_PROTECTION

no

Enable MCP SDK Host/Origin validation, default false

MCP_ALLOWED_HOSTS

no

Comma-separated allowed Host headers when DNS rebinding protection is enabled, for example daniel-nas.localdomain:3001,localhost:3001

MCP_ALLOWED_ORIGINS

no

Comma-separated allowed Origin headers when DNS rebinding protection is enabled

For container/SSE deployments, keep MCP_HOST=0.0.0.0 or set it explicitly. DNS rebinding protection is disabled by default because mapped ports, reverse proxies, and LAN hostnames otherwise commonly cause 421 Misdirected Request errors. If you enable it, include the externally visible host and port in MCP_ALLOWED_HOSTS.

Run locally

pip install -e .
MEDUSA_URL=http://localhost:8081 MEDUSA_API_KEY=... mcp-medusa

For SSE:

MEDUSA_URL=http://localhost:8081 MEDUSA_API_KEY=... mcp-medusa --transport sse --port 8000

Docker

The image defaults to SSE on port 8000.

docker build -t mcp-medusa .
docker run --rm -p 8000:8000 \
  -e MEDUSA_URL=http://medusa:8081 \
  -e MEDUSA_API_KEY=... \
  mcp-medusa

For stdio instead:

docker run --rm -i \
  -e MEDUSA_URL=http://medusa:8081 \
  -e MEDUSA_API_KEY=... \
  mcp-medusa --transport stdio

CI/CD

The repo uses a fully automated pipeline (no manual release steps):

  1. Open a PR against main. The ci.yml workflow runs tests/test_boot.py, which actually starts the server (stdio + SSE) and asserts FastMCP constructs, the expected tools register, and both transports bind. This is the gate that catches boot/import crashes before they ship.

  2. Auto-merge. Once the boot test passes, the enable-auto-merge job merges the PR (squash) using the ACTIONS_PAT repo secret (the default GITHUB_TOKEN cannot merge PRs in this repo).

  3. Auto-release + build. Pushing to main triggers merge-release.yml, which re-runs the boot test, creates a patch-bumped release (v0.0.N+1) off main, and builds + pushes the Docker image in the same workflow (the build is folded into merge-release.yml rather than a separate release-triggered workflow, because GitHub suppresses the release: published event when the release is created by a workflow via GITHUB_TOKEN).

Running the tests locally

uv venv
uv pip install -e ".[test]"
uv run pytest tests/ -v

The boot test spawns the real server, so it needs no Docker. If you change anything in server.py startup path, run this before pushing — CI will block the merge if the server fails to boot.

Required secrets

  • ACTIONS_PAT — a fine-grained PAT (or classic repo token) with Contents: read+write and Pull requests: read+write, stored as a repo secret. Used by ci.yml to merge PRs. (The default GITHUB_TOKEN lacks merge capability here.)

  • DOCKER_USERNAME / DOCKER_PASSWORD — used by docker-release.yml to push the image.

Available Tools

21 tools
add_animeA

Add an anime series to Medusa via /api/v2/anime/add.

Note: Some anime may fail with "no name on TVDBv2" due to AniDB→TVDB ID mapping issues. As a workaround, use search_tvdb to find the correct TVDB ID, then add_series to add it directly.

Inputs: anime_id (required), root_dir (required), anime, scene, +7 more.

add_seriesA

Add a series to Medusa directly by TVDB ID via POST /api/v2/series.

Use this as a fallback when add_anime fails due to AniDB-to-TVDB mapping issues. First find the correct TVDB ID with search_tvdb, then add it here. This bypasses anime resolution entirely and adds via the standard series endpoint.

quality values: "N/A", "Unknown", "SDTV", "SD DVD", "720p HDTV", "RawHD", "1080p HDTV", "720p WEB-DL", "1080p WEB-DL", "720p BluRay", "1080p BluRay", "4K UHD TV", "8K UHD TV", "4K UHD WEB-DL", "8K UHD WEB-DL", "4K UHD BluRay", "8K UHD BluRay". When omitted, Medusa's global quality defaults are used.

Inputs: tvdb_id (required), root_dir (required), anime, scene, +6 more.

anime_infoA

Return compact anime details and Medusa presence by title or MAL ID. Does not add anime.

Inputs: limit, title, mal_id, source, +3 more. Returns: object

bulk_add_animeA

Dry-run or add multiple anime items. Skips filterDecision=skip; execute must be true for writes.

Inputs: items (required), source, execute, root_dir, +9 more. Returns: object

create_aliasA

Create a local scene exception (alias) for a series.

This enables Medusa to recognize an alternative release title when searching, allowing it to match releases that use a different naming scheme. Only local (user-managed) scene exceptions can be created via this tool.

Inputs: name (required), series_slug (required), season. Returns: object

delete_aliasB

Delete a scene exception (alias) by ID.

Inputs: alias_id (required). Returns: result

diagnose_release_groupsA

Diagnose release group issues for a series by comparing config vs available releases.

Checks provider cache first; if empty, triggers a manual search and retries. Returns a structured diagnosis with recommendation.

Inputs: series_slug (required), season, episode, max_retries, +1 more. Returns: object

get_aliasesA

List scene exceptions (aliases) for a series.

Scene exceptions are alternative episode/release titles that Medusa recognizes when searching. This tool reads them; use create_alias to add new ones.

Inputs: series_slug (required), season. Returns: result

organize_season_foldersA

Move episodes into Season XX/ subdirectories without renaming files.

Enables season folders on the series and moves all downloaded episode files into Season XX/ subdirectories, preserving original filenames. Also moves associated files (subtitles, etc.).

Use this when:

  • A multi-season anime has all files in a flat directory

  • Plex is missing episodes due to poor multi-season-in-one-folder support

  • A second season was added years later to a show originally added flat

Calls POST /api/v2/series/{slug}/operation with type=ORGANIZE_SEASON_FOLDERS.

Inputs: series_slug (required). Returns: object

postprocessA

Trigger Medusa manual post-processing on a directory.

Scans directory (a download/staging folder) and moves matched episodes into their show folders. Reuses Medusa credentials from MEDUSA_URL / MEDUSA_API_KEY. Use this to clear files stranded in staging after a failed auto-post-process (e.g. a mis-named release that the download handler bailed on).

IMPORTANT: directory is interpreted by MEDUSA CORE, so it must be the path as seen inside the Medusa container (e.g. /data/medusa), NOT the path visible from the Hermes container.

Inputs: directory, process_type, force_replace, process_method. Returns: object

prepare_seasonal_reviewC

Compact seasonal candidates into an AI review packet.

Inputs: items (required), max_items. Returns: object

resolve_and_add_animeB

Resolve and optionally add one anime. Dry-run unless execute is true.

Inputs: limit, title, mal_id, source, +10 more. Returns: object

resolve_anime_titleB

Resolve an anime title to MAL candidates with match/ambiguous/no_match decision.

Inputs: title (required), limit, fields, source, +2 more. Returns: object

scheduler_statusA

Return Medusa scheduler and queue status.

Shows whether each scheduler thread is alive, enabled, and currently active. Useful for diagnosing stuck queues.

Inputs: no named parameters. Returns: object

search_tvdbA

Search TVDB for a show by name and return matching TVDB IDs.

Use this when an anime add fails due to AniDB-to-TVDB mapping issues. Find the correct TVDB ID here, then add the show with add_series.

Inputs: query (required), language. Returns: result

seasonal_animeB

Query a paginated seasonal anime page from Medusa, optionally returning only selected fields.

Season, source, and source_sort are case-insensitive.

Inputs: page, year, limit, fields, +3 more.

seasonal_candidatesC

Fetch server-filtered seasonal anime candidates and apply residual preference heuristics.

Inputs: year, limit, fields, season, +5 more. Returns: object

set_episode_statusA

Set episode statuses for a series via PATCH /api/v2/episodes/{series_slug}.

Use when TVDB metadata is out of sync with actual episode status and Medusa is not downloading episodes that should be available. Set affected episodes to "wanted" to force Medusa to search for them.

Uses the same PATCH endpoint as the Medusa Web UI, so it can change UNAIRED episodes to WANTED unlike the internal bulk-update endpoint.

Inputs: episodes (required), series_slug (required), status. Returns: object

update_release_groupsA

Update release group configuration for a series.

Sends PATCH /api/v2/series/{slug} with the specified config.release.* fields. Only the provided fields are changed; omitted fields are left as-is.

Inputs: series_slug (required), blacklist, whitelist, fallback_days, +1 more. Returns: object

update_series_qualityA

Update allowed and/or preferred qualities for an existing series.

Sends PATCH /api/v2/series/{slug} with config.qualities.* fields. Only the provided fields are changed; omitted fields are left as-is.

quality values: "N/A", "Unknown", "SDTV", "SD DVD", "720p HDTV", "RawHD", "1080p HDTV", "720p WEB-DL", "1080p WEB-DL", "720p BluRay", "1080p BluRay", "4K UHD TV", "8K UHD TV", "4K UHD WEB-DL", "8K UHD WEB-DL", "4K UHD BluRay", "8K UHD BluRay".

Inputs: series_slug (required), allowed_qualities, preferred_qualities.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.3/5.0

    Scored across 21 tools

    Disambiguation3/5

    The core Medusa operations (aliases, release groups, searches, postprocessing) are clearly separated, but the anime-related tools have overlapping boundaries: seasonal_anime, seasonal_candidates, prepare_seasonal_review, resolve_anime_title, and resolve_and_add_anime all seem to cover similar discovery/dedup/resolution steps. Add flows are also split across add_series, add_anime, resolve_and_add_anime, and bulk_add_anime, so an agent may struggle to pick the right one without careful reading.

    Naming Consistency4/5

    Tool naming is overwhelmingly snake_case with a verb_noun pattern (create_alias, set_episode_status, update_series_quality, bulk_add_anime). Only a few tools deviate into noun-first or adjective-first forms such as anime_info and seasonal_anime, but the convention is still predictable overall.

    Tool Count3/5

    At 21 tools, the surface is on the upper edge of comfort and feels heavy for a cohesive server. The count is justifiable given the two intertwined domains of TV-series management and anime seasonal workflows, but some tools appear to cover niche pipeline stages that a smaller set could absorb.

    Completeness3/5

    The set covers many operational needs: adding series, adjusting statuses, searching, postprocessing, quality, season folders, aliases, scheduler status, and anime fetching. However, it lacks a general way to list or retrieve an existing series' slug/config, and there is no update path for aliases—only create/delete—so agents cannot fully reconcile or inspect existing state before modifying it.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers