romarr-mcp: indexer + download-client write tools (credentials by reference) #22

Open
hermes-agent wants to merge 1 commits from feat/romarr-mcp-indexers into main
pull from: feat/romarr-mcp-indexers
Collaborator

Four tools, so indexer and download-client setup stops being a UI click I cannot make.

  • indexer_schema / download_client_schema (read): the types and the fields each needs, straight from ROMarr's own INDEXER_TYPES / CLIENT_TYPES.
  • indexer_save (write): POST /api/v1/indexer with type, name, url, enable, id (update), plus extra for anything else the type needs.
  • download_client_save (write): POST /api/v1/downloadclient with type, name, host, port, use_ssl, url_base, username, category, id, plus extra.

Credentials by reference. Both pass api_key_env / password_env instead of the literal: the server resolves the variable from its own environment and never echoes it. That is why this works despite the agent not being able to read the gateway's keys — PROWLARR_API_KEY and SABNZBD_API_KEY are already in the rendered env the gateway consumes, so naming the variable is the whole handshake. Inline api_key / password still exist for cases with no variable, and are the only paths that would put a secret in a transcript.

Verified against a live ROMarr 1.8.0 (throwaway instance, ROMARR_API_KEY=testkey):

  • tools/list → 25 tools
  • indexer_schema → prowlarr, jackett, nzbhydra2, cardigann, bitmagnet, torznab, newznab, torrentrss…
  • indexer_save {type: prowlarr, url: http://127.0.0.1:9696, api_key_env: PROWLARR_API_KEY} → {"type":"prowlarr","url":…,"api_key":"********","id":"27b678f082ed"}; indexers then lists exactly that entry, key masked
  • indexer_save with an unset variable → error: NOT_SET_ANYWHERE is not set in this server's environment (no traceback, nothing stored)
  • download_client_save {type: qbittorrent, host: 127.0.0.1, port: 8080, username: luis, password_env: QBIT_PASS} → stored, and download_clients reports it as {name: qBittorrent, url: http://127.0.0.1:8080, category: romarr, configured: true, ok: false} — ok: false because the fake client refuses the connection, which is ROMarr's own validation doing its job

Gateway side (adding PROWLARR_API_KEY / SABNZBD_API_KEY to the romarr backend env, and the lock bump) is a separate config PR once this merges.

Four tools, so indexer and download-client setup stops being a UI click I cannot make. - `indexer_schema` / `download_client_schema` (read): the types and the fields each needs, straight from ROMarr's own `INDEXER_TYPES` / `CLIENT_TYPES`. - `indexer_save` (write): `POST /api/v1/indexer` with `type`, `name`, `url`, `enable`, `id` (update), plus `extra` for anything else the type needs. - `download_client_save` (write): `POST /api/v1/downloadclient` with `type`, `name`, `host`, `port`, `use_ssl`, `url_base`, `username`, `category`, `id`, plus `extra`. **Credentials by reference.** Both pass `api_key_env` / `password_env` instead of the literal: the server resolves the variable from its own environment and never echoes it. That is why this works despite the agent not being able to read the gateway's keys — `PROWLARR_API_KEY` and `SABNZBD_API_KEY` are already in the rendered env the gateway consumes, so naming the variable is the whole handshake. Inline `api_key` / `password` still exist for cases with no variable, and are the only paths that would put a secret in a transcript. Verified against a live ROMarr 1.8.0 (throwaway instance, `ROMARR_API_KEY=testkey`): - `tools/list` → 25 tools - `indexer_schema` → `prowlarr, jackett, nzbhydra2, cardigann, bitmagnet, torznab, newznab, torrentrss…` - `indexer_save {type: prowlarr, url: http://127.0.0.1:9696, api_key_env: PROWLARR_API_KEY}` → `{"type":"prowlarr","url":…,"api_key":"********","id":"27b678f082ed"}`; `indexers` then lists exactly that entry, key masked - `indexer_save` with an unset variable → `error: NOT_SET_ANYWHERE is not set in this server's environment` (no traceback, nothing stored) - `download_client_save {type: qbittorrent, host: 127.0.0.1, port: 8080, username: luis, password_env: QBIT_PASS}` → stored, and `download_clients` reports it as `{name: qBittorrent, url: http://127.0.0.1:8080, category: romarr, configured: true, ok: false}` — `ok: false` because the fake client refuses the connection, which is ROMarr's own validation doing its job Gateway side (adding `PROWLARR_API_KEY` / `SABNZBD_API_KEY` to the `romarr` backend env, and the lock bump) is a separate config PR once this merges.
hermes-agent added 1 commit 2026-11-05 23:30:38 +01:00
romarr-mcp: indexer and download-client write tools
NixOS Configuration CI / Nix Flake Check (pull_request) Successful in 20s
34b6e36787
All checks were successful
NixOS Configuration CI / Nix Flake Check (pull_request) Successful in 20s
You are not authorized to merge this pull request.
This pull request can be merged automatically.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin feat/romarr-mcp-indexers:feat/romarr-mcp-indexers
git checkout feat/romarr-mcp-indexers
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: luis/mcp-servers#22