media-mcp
The media-mcp server provides a centralized interface to manage a self-hosted media stack (Sonarr, Radarr, qBittorrent via Qui, Prowlarr, Jellyfin).
Sonarr (TV): Check system status, health, disk space. List, search, add, delete TV series; manage quality profiles and root folders. View download queue with diagnostics, history (grabs, imports, deletions), upcoming episodes. Manage seasons: monitor/unmonitor, trigger searches; delete episode files, seasons, or entire series. Calendar of upcoming episodes.
Radarr (Movies): Check system status, health, disk space. List, search, add, delete movies; manage quality profiles and root folders. View download queue with diagnostics, history, upcoming releases. Manage movies: monitor/unmonitor, trigger searches; delete movie files or entire movies. Calendar of upcoming releases.
qBittorrent (via Qui): List instances, torrents (by name/hash), get details (bridging Sonarr/Radarr downloadId). Pause, resume, delete torrents (with optional file deletion).
Prowlarr: Check status/health, list indexers with health, test connectivity. Cross-search all indexers for any content (movies, ebooks, manga, software, etc.). Grab releases and send to download client.
Jellyfin: Server status, list movies. Manage collections: create, delete, list, add/remove movies, view contents. Set descriptions/lock overviews. Advanced movie resolution: match by tmdbId, Jellyfin id, or approximate title (with Radarr fallback).
Coordinated Purge: Delete TV season files or movie files from Sonarr/Radarr AND their associated torrents (including cross-seeds) from qBittorrent in one operation, with dry-run preview.
Safety: All destructive actions default to dry-run (
confirm=False) and require explicitconfirm=Trueto execute. Movie/collection references support fuzzy matching with ambiguity detection.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@media-mcpSearch for the movie 'Inception' and add it to Radarr"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
media-mcp
Serveur MCP pour piloter un stack média self-hosted : Sonarr + Radarr, qBittorrent via qui (autobrr), Prowlarr (indexeurs) et Jellyfin (collections curatives / BoxSets).
Deux transports : stdio (défaut, dev local / Claude Desktop) et HTTP (service Docker sur le homelab). Voir Déploiement.
Prérequis
Python 3.11+
uvinstallé
Related MCP server: MCP *arr Server
Installation
# Cloner / se placer dans le répertoire du projet
cd media-mcp
# Installer les dépendances
uv sync
# Copier et remplir les variables d'environnement
cp .env.example .env
# Éditer .env avec vos URLs et clés APILancement en développement
uv run python -m media_mcpLe serveur démarre en mode stdio (défaut) et attend des messages MCP sur stdin/stdout.
Pour le lancer en HTTP localement :
MCP_TRANSPORT=http PORT=8080 uv run python -m media_mcp
# endpoint MCP : http://127.0.0.1:8080/mcpConfiguration Claude Desktop
Ajouter dans ~/Library/Application Support/Claude/claude_desktop_config.json
(macOS) ou %APPDATA%\Claude\claude_desktop_config.json (Windows) :
{
"mcpServers": {
"media-mcp": {
"command": "uv",
"args": ["--directory", "/chemin/absolu/media-mcp", "run", "python", "-m", "media_mcp"],
"env": {
"SONARR_URL": "http://localhost:8989",
"SONARR_API_KEY": "xxx",
"RADARR_URL": "http://localhost:7878",
"RADARR_API_KEY": "xxx",
"QUI_URL": "https://qui.example.com",
"QUI_API_KEY": "xxx",
"QUI_INSTANCE": "",
"PROWLARR_URL": "http://localhost:9696",
"PROWLARR_API_KEY": "xxx"
}
}
}
}Remplacer /chemin/absolu/media-mcp par le chemin réel du projet.
Variables d'environnement
Variable | Description | Défaut |
| Transport : |
|
| Interface d'écoute (transports HTTP uniquement) |
|
| Port d'écoute (transports HTTP uniquement) |
|
| URL de base Sonarr |
|
| Clé API Sonarr | (requis) |
| URL de base Radarr |
|
| Clé API Radarr | (requis) |
| URL de base de l'instance qui | (requis pour qBit) |
| Clé API qui (Settings > API Keys) | (requis pour qBit) |
| Instance qBit ciblée (id ou nom) ; vide = auto si une seule | (optionnel) |
| URL de base Prowlarr | (requis pour Prowlarr) |
| Clé API Prowlarr | (requis pour Prowlarr) |
| URL de base Jellyfin (ex. | (requis pour Jellyfin) |
| Clé API Jellyfin (Dashboard > API Keys) | (requis pour Jellyfin) |
Tools disponibles
Sonarr
Tool | Type | Description |
| read | Statut et version de Sonarr |
| read | Liste des séries suivies |
| read | Recherche une série (pour ajout) |
| read | Profils de qualité disponibles |
| read | Dossiers racine configurés |
| read | File de téléchargement + diagnostic des items bloqués (voir ci-dessous) |
| read | Espace disque par volume, le plus plein en premier |
| read | Avertissements de santé de l'instance |
| read | Événements récents (grab/import/…) avec downloadId ; filtre |
| write | Retire un item (par |
| read | Épisodes à venir via calendrier |
| read | Détail saison par saison d'une série |
| read | Liste les épisodes d'une saison (E-num, titre, hasFile ✓/✗, monitored ✓/✗, id, fileId) |
| write | Ajoute une série |
| write | (Dé)monitore une saison précise |
| write | Lance la recherche d'une saison |
| destructive | Supprime tous les fichiers d'une saison |
| destructive | Supprime un fichier d'épisode |
| destructive | Supprime une série |
Radarr
Tool | Type | Description |
| read | Statut et version de Radarr |
| read | Liste des films suivis |
| read | Recherche un film (pour ajout) |
| read | Profils de qualité disponibles |
| read | Dossiers racine configurés |
| read | File de téléchargement + diagnostic des items bloqués (voir Sonarr) |
| read | Espace disque par volume, le plus plein en premier |
| read | Avertissements de santé de l'instance |
| read | Événements récents (grab/import/…) avec downloadId ; filtre |
| write | Retire un item (par |
| read | Films à venir via calendrier |
| write | Ajoute un film |
| write | (Dé)monitore un film |
| write | Lance la recherche d'un film |
| destructive | Supprime le fichier d'un film (garde le film suivi) |
| destructive | Supprime un film |
qBittorrent (via qui)
Accès uniquement via qui (le gestionnaire web multi-instance d'autobrr), jamais via l'API qBittorrent directe. Auth par header
X-API-Key. Les tools ciblent l'instance résolue depuisQUI_INSTANCE(id ou nom) ; si vide et qu'une seule instance existe, elle est choisie automatiquement ; si plusieurs, une erreur liste les instances disponibles.
Tool | Type | Description |
| read | Instances qBittorrent gérées par qui (id + nom) |
| read | Torrents de l'instance (nom, hash complet, état, %, taille, ratio, catégorie) ; |
| read | Détail d'un torrent par hash ou préfixe unique (pont avec le |
| control | Met un torrent en pause (réversible, pas de confirm) |
| control | Reprend un torrent (réversible, pas de confirm) |
| destructive | Retire un torrent de qBittorrent, avec option suppression des fichiers |
Les tools prenant un hash acceptent le hash complet (40 car., copiable depuis
qbit_list_torrents) ou un préfixe unique ; un préfixe ambigu liste les candidats sans
agir.
Le hash qBittorrent est la clé de liaison : c'est la valeur renvoyée par le downloadId
de l'historique Sonarr/Radarr. La comparaison est insensible à la casse (qBit renvoie le
hash en minuscules, les *arr souvent en majuscules).
Prowlarr (indexeurs)
Gestionnaire d'indexeurs Servarr — API en /api/v1 (et non v3), auth X-Api-Key.
Orienté diagnostic des indexeurs.
Tool | Type | Description |
| read | Version de Prowlarr |
| read | Indexeurs configurés (id, nom, activé ✓/✗, protocole, privacy, catégories, tags), triés par nom |
| read | Indexeurs en échec / désactivés temporairement (+ |
| read | Avertissements globaux Prowlarr (type/source/message) |
| action | Teste la connectivité d'un indexeur → PASS/FAIL + message (pas de confirm) |
| action | Teste tous les indexeurs → résumé pass/fail, échecs mis en avant |
| read | Recherche cross-indexeurs (tout contenu) triée par seeders ; affiche |
| acquisition | Envoie une release au download client de Prowlarr (dry-run/confirm) |
prowlarr_indexer_statusne porte pas de message textuel de raison (l'API/indexerstatusn'expose queindexerId+ horodatages) : il croise la liste des indexeurs pour le nom et affiche la date de reprise (disabledTill). Pour le « pourquoi » global, voirprowlarr_health.
Recherche & grab (contenu hors-*arr : ebooks, manga, logiciels…)
prowlarr_search interroge tous les indexeurs et renvoie, par release, la référence de grab
(guid + indexerId) à passer à prowlarr_grab. Les résultats sont triés par seeders
décroissant (le limit de Prowlarr n'étant pas un vrai plafond, la coupe est faite côté client).
prowlarr_grab envoie la release au download client configuré dans Prowlarr (dry-run par
défaut ; confirm=True pour exécuter). Aucune catégorie n'est passée par le MCP : le
classement final dans qBittorrent (ebook / logiciel / autre) est décidé par les Mapped
Categories du download client, à configurer dans l'UI Prowlarr (Settings → Download
Clients). S'il n'y a aucun download client, le grab renvoie un message clair (à ajouter d'abord
dans l'UI). La recherche/le grab avec catégorie explicite restent gérés côté Prowlarr, pas ici.
Jellyfin (collections curatives / BoxSets)
Serveur média Jellyfin — endpoints à la racine du serveur (pas de préfixe /api/vN),
auth par header Authorization: MediaBrowser Token="<clé>". Objectif : créer et gérer des
collections curatives (BoxSets) avec description, pilotables en langage naturel.
Client autonome (ne dérive PAS d'
ArrClient, commeQuiClient) : Jellyfin n'est pas une API *arr. LeuserIdrequis par les endpoints d'items est résolu une fois (premier comptePolicy.IsAdministratorviaGET /Users) puis mis en cache pour la durée du process.
Tool | Type | Description |
| read | Nom + version du serveur (valide la clé API) |
| read | Films de la bibliothèque (short id, titre, année, tmdbId) |
| read | Collections/BoxSets (short id, nom, nb d'items, description tronquée) |
| read | Contenu d'une collection (par nom ou id) |
| write | Crée une collection depuis une liste de films ; option description (verrouillée) |
| write | Ajoute des films à une collection |
| write | Retire des films d'une collection (les films restent en bibliothèque) |
| write | Écrit la description d'un item (collection ou film) ; |
| destructive | Supprime le conteneur collection (les films sont conservés) |
Résolution des films (movies) et références (collection_ref / item_ref)
Le paramètre movies accepte une liste mixte : tmdbId numériques, ids Jellyfin (ou
préfixe unique de 8 car.), ou titres approximatifs (casse/accents/articles/ponctuation
normalisés — « Le Solitaire » ≈ « solitaire »). La résolution est une cascade qui s'arrête
au premier niveau donnant un match unique :
tmdbIdexact (viaProviderIds.Tmdb)id Jellyfin, ou préfixe unique
NameJellyfin normaliséOriginalTitleJellyfin normalisérepli Radarr — Radarr connaît les titres localisés/alternatifs (
title,originalTitle,alternateTitles) que Jellyfin n'indexe parfois que sous un titre anglais. Le titre demandé y est matché, sontmdbIdrécupéré, puis rebranché sur Jellyfin partmdbId. Utilise le client Radarr interne (jamais un appel vers nos propres tools MCP) ; si Radarr n'est pas configuré ou est injoignable, le niveau 5 est simplement sauté (not_foundpropre, aucune exception).
La règle est identique à chaque niveau : un seul candidat → matched ; plusieurs → ambiguous (candidats remontés, jamais un choix arbitraire) ; aucun → niveau suivant.
Chaque movies déclenche au plus un fetch bibliothèque Jellyfin + au plus un fetch
Radarr (ce dernier uniquement si une référence atteint le niveau 5, en lazy). Les dry-runs
(confirm=False) affichent exactement les films matched / ambiguous / not found avant toute
écriture, avec une colonne indiquant le moyen de résolution (tmdb / id / title /
original-title / via-radarr) ; un match via-radarr (le plus faillible) affiche en clair le
titre Radarr ET le titre Jellyfin retenus. Sur confirm=True, une création/modification
refuse de procéder si des références restent non résolues (pas de collection partielle en
silence). ProviderIds.Tmdb est le pont fiable avec le tmdbId Radarr (jamais de match sur le
titre en interne quand un tmdbId existe).
Pièges Jellyfin gérés
POST /Items/{id}= GET-modify-POST du BaseItemDto complet (pas de PATCH). Un DTO partiel renvoie 400 et peut corrompre l'item jusqu'au prochain rescan (champs collectionnullpassés à.ToList()). Avant tout envoi, les champs tableau (Tags,Genres,Studios,People,LockedFields,GenreItems,TagItems…) sont normalisés en[](jamaisnull) etProviderIdsen{}(map, pas liste). Un test respx vérifie explicitement qu'aucunnullne part dans un champ tableau.Verrouillage : après écriture d'un
Overview,"Overview"est ajouté àLockedFields(verrou au niveau champ) pour qu'un refresh de métadonnées n'écrase pas la description. Comportement par défaut, désactivable vialock=False.Bibliothèque « Collections » absente :
POST /Collectionspeut renvoyer une 500 (Sequence contains no elements) ; c'est traduit en message actionnable (créer une première collection depuis l'UI web) plutôt qu'une erreur brute.
Cadrage : l'upload d'affiche (
jellyfin_set_collection_image) n'est pas dans cette itération — la place est prévue dans l'architecture (POST /Items/{id}/Images/Primary, corps base64 +Content-Typeréel), à ajouter ensuite.
Tools coordonnés — purge « partout »
Suppriment, en un geste avec aperçu et confirm, les fichiers bibliothèque (Sonarr/Radarr)
ET le(s) torrent(s) correspondants côté qBittorrent-via-qui, cross-seeds inclus.
Tool | Type | Description |
| destructive | Purge une saison partout (fichiers Sonarr + torrents + cross-seeds) |
| destructive | Purge un film partout (fichier Radarr + torrents + cross-seeds) |
Flux :
Lister les fichiers concernés côté *arr (saison / film) → nombre + taille.
Extraire les
downloadIddepuis l'historique *arr (/history/series,/history/movie) → ensemble des hash d'origine (dédupliqués ; un season pack partage un seuldownloadId).Côté qui, pour chaque origine : résoudre le torrent, puis
local-matches?strict=true→ cross-seeds (siblings).Ensemble à supprimer = origines présentes ∪ siblings, dédupliqué par hash.
include_loose_matches=Falseexclut les siblingsmatch_type ∈ {name, release}(garde les matchescontent_path) et indique combien ont été exclus.Dry-run (
confirm=False) : aperçu exhaustif des deux côtés, rien supprimé.confirm=True: suppression des fichiers *arr puis un seulbulk-action delete(avecdeleteFilesselondelete_torrent_files) sur tous les hash ; rapport combiné.
Cas limites gérés (sans planter) : aucun downloadId (historique purgé → suppression
biblio seule, torrents à gérer à la main) ; origine absente de qBit (ignorée, signalée) ;
saison/film sans fichier (torrents traités quand même) ; cross-seed indispo (repli sur les
origines seules).
Honnêteté sur l'espace disque : les tailles bibliothèque et torrents ne sont jamais additionnées — hardlinkées, ce sont généralement les mêmes octets. L'aperçu les montre séparément et rappelle que, comme on supprime les deux côtés (+ cross-seeds), l'espace de ce contenu sera cette fois réellement libéré (≈ la plus grande des deux tailles, pas la somme).
Pattern dry-run / confirm
Toutes les actions à effet de bord (add_*, delete_*, search_*) acceptent un paramètre confirm:
confirm=False(défaut) → aperçu sans exécution (dry-run)confirm=True→ exécution réelle
Note hardlink : les tools de suppression de fichiers (
sonarr_delete_season,sonarr_delete_episode_file,radarr_delete_movie_file) retirent les fichiers côté Sonarr/Radarr uniquement. Si les fichiers sont en hardlink avec un client torrent, l'espace disque n'est pas libéré tant que le torrent n'est pas aussi supprimé côté client. L'aperçu dry-run le rappelle.
Filtre event_type de *_history
L'API attend un entier pour son query param eventType, donc le filtrage est fait
côté client sur le champ texte eventType de chaque événement. event_type accepte :
Alias | Correspond à ( |
|
|
|
|
|
|
|
|
|
|
|
|
La chaîne canonique exacte est aussi acceptée (ex. event_type="downloadFolderImported").
Une valeur inconnue renvoie un message listant les valeurs valides, sans appel API.
Comme le filtrage est côté client sur une fenêtre élargie (une requête,
pageSize = max(limit*5, 100)), un résultat filtré partiel ajoute une note
showing N of up to {limit} (searched the {window} most recent events).
Diagnostic & regroupement de *_queue
sonarr_queue / radarr_queue surfacent, pour chaque item, pourquoi il est bloqué :
trackedDownloadStatus / trackedDownloadState (ex. warning / importBlocked), le texte
des statusMessages et l'errorMessage éventuel. Les messages par item sont bornés
((+N more)) pour rester lisibles ; un champ absent/null est géré sans erreur.
Les items partageant le même downloadId (un season pack = un torrent, N lignes) sont
regroupés en une entrée [×N] affichant le downloadId (le pont vers qBittorrent) et la
ligne ids: … (les queue IDs individuels du groupe, tronquée si trop longue). Les items sans
downloadId restent individuels et conservent taille/ETA.
*_delete_queue_item accepte exactement un de queue_id (un item) ou download_id
(tous les items du download, retirés en un seul DELETE /queue/bulk) ; en dry-run il liste
le nombre d'items, leur(s) titre(s) et les IDs ciblés avant toute suppression.
Déploiement
⚠️ Sécurité — l'image GHCR est PUBLIQUE
Ne jamais mettre de secret dans l'image, le
Dockerfile, un workflow ou un fichier suivi par git. Toutes les clés et URLs arrivent au runtime (env_file/environment/docker run -e). LeDockerfilene déclare queMCP_TRANSPORT,HOSTetPORT..dockerignoreexclut.env*,.git,tests/,.venv… : rien de sensible n'entre dans le build context..gitignoreexclut.env, ses variantes et le vraidocker-compose.yml. Seuls.env.exampleetdocker-compose.example.yml(placeholders) sont committés.Les URLs configurées doivent être les URLs INTERNES du homelab (
http://sonarr:8989,http://qui:7476…), jamais les URLs Cloudflare/publiques : elles ne doivent ni fuiter ni faire transiter le trafic par l'extérieur.Le serveur MCP n'a aucune authentification : ne pas publier son port hors du homelab.
Transports
| Transport FastMCP | Usage |
| stdio | Dev local, Claude Desktop |
| streamable-http | Service Docker — endpoint |
| sse | Clients MCP qui ne parlent que l'ancien transport — endpoint |
Le défaut reste stdio : la config Claude Desktop existante fonctionne sans changement.
Une valeur inconnue fait échouer le démarrage avec la liste des valeurs acceptées.
Build & run Docker
docker build -t media-mcp:local .
# L'image démarre en HTTP sur 8080 (MCP_TRANSPORT=http est le défaut DANS l'image)
docker run --rm -p 127.0.0.1:8080:8080 --env-file .env media-mcp:localL'image est multi-stage (deps résolues par uv, puis seul le venv est copié), tourne en
non-root (uid 10001) et n'embarque ni les tests, ni .env, ni .git.
docker-compose (homelab)
cp docker-compose.example.yml docker-compose.yml # le vrai compose est gitignoré
cp .env.example .env # puis remplir avec les URLs INTERNES
docker compose up -dRéseau : media-mcp doit être sur le même réseau Docker que les services
*arr / qui / Prowlarr / Jellyfin pour les joindre par nom de conteneur. Le compose
d'exemple s'attache à un réseau external — le remplacer par le réseau réel
(docker network ls). Si le client MCP (Hermes) tourne dans ce même réseau, il joint
http://media-mcp:8080/mcp directement : inutile de publier le port.
CI/CD (GitHub Actions)
Workflow | Déclencheur | Ce qu'il fait |
PR vers |
| |
push sur | build et push vers |
L'auth GHCR passe par le GITHUB_TOKEN intégré (permissions: packages: write) : aucun
PAT ni secret perso à stocker. Les workflows ne contiennent aucun secret applicatif — ils
buildent l'image, ils ne la font pas tourner.
Rendre le package public (une seule fois, après le premier push) : GitHub → onglet Packages →
media-mcp→ Package settings → Change visibility → Public. Les packages GHCR sont privés par défaut.
Développement
# Lint & format
uv run ruff check src tests
uv run ruff format src tests
# Tests
uv run pytestArchitecture
src/media_mcp/
config.py # pydantic-settings — lit les variables d'env
models.py # modèles pydantic pour les réponses simplifiées
coordinated.py # service d'orchestration purge (arr + qui), logique lourde
jellyfin_resolve.py # résolution en cascade (tmdbId/id/Name/OriginalTitle + repli Radarr injecté)
server.py # instancie FastMCP (host/port) et enregistre tous les tools
__main__.py # entrypoint: python -m media_mcp — résout MCP_TRANSPORT
clients/
base.py # ArrClient: httpx async, gestion des erreurs
sonarr.py # SonarrClient(ArrClient)
radarr.py # RadarrClient(ArrClient)
prowlarr.py # ProwlarrClient(ArrClient) — /api/v1
qui.py # QuiClient: httpx async, header X-API-Key (NE dérive PAS d'ArrClient)
jellyfin.py # JellyfinClient: root path, MediaBrowser Token (NE dérive PAS d'ArrClient)
tools/
sonarr_tools.py # @mcp.tool pour Sonarr
radarr_tools.py # @mcp.tool pour Radarr
qbit_tools.py # @mcp.tool pour qBittorrent via qui
prowlarr_tools.py # @mcp.tool pour Prowlarr (indexeurs)
coordinated_tools.py # @mcp.tool purge saison/film "partout" (arr + qui)
jellyfin_tools.py # @mcp.tool pour Jellyfin (collections curatives / BoxSets)Déploiement :
Dockerfile # image multi-stage (uv -> venv), non-root, http:8080
.dockerignore # garde secrets/tests/.git hors du build context
docker-compose.example.yml # modèle homelab (le vrai docker-compose.yml est gitignoré)
.github/workflows/
ci.yml # PR : lint + tests + build sans push
release.yml # main : build + push GHCR (latest + SHA)Ajouter un nouveau service (ex. Jellyseerr) : créer clients/jellyseerr.py et
tools/jellyseerr_tools.py, puis enregistrer dans server.py.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseBqualityDmaintenanceEnables AI assistants to manage TV series collections through Sonarr's API using natural language interactions. Supports searching, adding, updating, and deleting TV series with detailed control over quality profiles, season monitoring, and episode downloads.Last updated9
- AlicenseAqualityBmaintenanceEnables unified control of \*arr media management applications (Sonarr, Radarr, Lidarr, Readarr, Prowlarr) through natural language queries. Manage TV shows, movies, music, books, search for content, monitor downloads, and check upcoming releases across all services.Last updated66709184MIT
- Alicense-qualityDmaintenanceEnables interaction with Sonarr and Radarr APIs to query media libraries, check recent additions, view upcoming releases, manage download queues, and perform searches for TV shows and movies through natural language.Last updated1MIT
- Flicense-qualityDmaintenanceIntegrates with Radarr and Sonarr to manage your media library, enabling search, download requests, status checks, and system health monitoring.Last updated6
Related MCP Connectors
Trakt MCP — TV/movie metadata + watch tracking signals
Manage SRG+ hubs, channels, content, assets, users, and workspaces from any MCP-aware AI agent.
Personal assistant MCP server with search, execute, packages, jobs, secrets, and integrations.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/ava-hip/mcp-media-stack'
If you have feedback or need assistance with the MCP directory API, please join our Discord server