Skip to main content
Glama

lidarr_review_setup

Analyze Lidarr music management configuration to identify issues and optimize settings for quality profiles, download clients, naming, storage, and indexers.

Instructions

Get comprehensive configuration review for Lidarr (Music). Returns all settings for analysis: quality profiles, download clients, naming, storage, indexers, health warnings, and more. Use this to analyze the setup and suggest improvements.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault

No arguments

Implementation Reference

  • Main handler logic for 'lidarr_review_setup' tool. Dynamically handles all *_review_setup tools by fetching comprehensive config data (status, health, profiles, clients, naming, folders, tags, indexers, metadata for Lidarr) from LidarrClient and compiling a detailed JSON review object.
    case "sonarr_review_setup": case "radarr_review_setup": case "lidarr_review_setup": case "readarr_review_setup": { const serviceName = name.split('_')[0] as keyof typeof clients; const client = clients[serviceName]; if (!client) throw new Error(`${serviceName} not configured`); // Gather all configuration data const [status, health, qualityProfiles, qualityDefinitions, downloadClients, naming, mediaManagement, rootFolders, tags, indexers] = await Promise.all([ client.getStatus(), client.getHealth(), client.getQualityProfiles(), client.getQualityDefinitions(), client.getDownloadClients(), client.getNamingConfig(), client.getMediaManagement(), client.getRootFoldersDetailed(), client.getTags(), client.getIndexers(), ]); // For Lidarr/Readarr, also get metadata profiles let metadataProfiles = null; if (serviceName === 'lidarr' && clients.lidarr) { metadataProfiles = await clients.lidarr.getMetadataProfiles(); } else if (serviceName === 'readarr' && clients.readarr) { metadataProfiles = await clients.readarr.getMetadataProfiles(); } const review = { service: serviceName, version: status.version, appName: status.appName, platform: { os: status.osName, isDocker: status.isDocker, }, health: { issueCount: health.length, issues: health, }, storage: { rootFolders: rootFolders.map(f => ({ path: f.path, accessible: f.accessible, freeSpace: formatBytes(f.freeSpace), freeSpaceBytes: f.freeSpace, unmappedFolderCount: f.unmappedFolders?.length || 0, })), }, qualityProfiles: qualityProfiles.map(p => ({ id: p.id, name: p.name, upgradeAllowed: p.upgradeAllowed, cutoff: p.cutoff, allowedQualities: p.items .filter(i => i.allowed) .map(i => i.quality?.name || i.name || (i.items?.map(q => q.quality.name).join(', '))) .filter(Boolean), customFormatsWithScores: p.formatItems?.filter(f => f.score !== 0).length || 0, minFormatScore: p.minFormatScore, })), qualityDefinitions: qualityDefinitions.map(d => ({ quality: d.quality.name, minSize: d.minSize + ' MB/min', maxSize: d.maxSize === 0 ? 'unlimited' : d.maxSize + ' MB/min', preferredSize: d.preferredSize + ' MB/min', })), downloadClients: downloadClients.map(c => ({ name: c.name, type: c.implementationName, protocol: c.protocol, enabled: c.enable, priority: c.priority, })), indexers: indexers.map(i => ({ name: i.name, protocol: i.protocol, enableRss: i.enableRss, enableAutomaticSearch: i.enableAutomaticSearch, enableInteractiveSearch: i.enableInteractiveSearch, priority: i.priority, })), naming: naming, mediaManagement: { recycleBin: mediaManagement.recycleBin || 'not set', recycleBinCleanupDays: mediaManagement.recycleBinCleanupDays, downloadPropersAndRepacks: mediaManagement.downloadPropersAndRepacks, deleteEmptyFolders: mediaManagement.deleteEmptyFolders, copyUsingHardlinks: mediaManagement.copyUsingHardlinks, importExtraFiles: mediaManagement.importExtraFiles, extraFileExtensions: mediaManagement.extraFileExtensions, }, tags: tags.map(t => t.label), ...(metadataProfiles && { metadataProfiles }), }; return { content: [{ type: "text", text: JSON.stringify(review, null, 2), }], }; }
  • src/index.ts:163-170 (registration)
    Tool definition and registration in addConfigTools function. Pushes 'lidarr_review_setup' to TOOLS array when serviceName='lidarr'.
    name: `${serviceName}_review_setup`, description: `Get comprehensive configuration review for ${displayName}. Returns all settings for analysis: quality profiles, download clients, naming, storage, indexers, health warnings, and more. Use this to analyze the setup and suggest improvements.`, inputSchema: { type: "object" as const, properties: {}, required: [], }, }
  • src/index.ts:177-178 (registration)
    Conditional registration call for Lidarr tools, including lidarr_review_setup, only if Lidarr client is configured.
    if (clients.lidarr) addConfigTools('lidarr', 'Lidarr (Music)'); if (clients.readarr) addConfigTools('readarr', 'Readarr (Books)');
  • Input schema for lidarr_review_setup tool: empty object (no parameters required).
    inputSchema: { type: "object" as const, properties: {}, required: [], },
  • LidarrClient class providing all API methods called by the review_setup handler (getStatus, getHealth, etc.).
    export class LidarrClient extends ArrClient { constructor(config: ArrConfig) { super('lidarr', config); this.apiVersion = 'v1'; } /** * Get all artists */ async getArtists(): Promise<Artist[]> { return this['request']<Artist[]>('/artist'); } /** * Get a specific artist */ async getArtistById(id: number): Promise<Artist> { return this['request']<Artist>(`/artist/${id}`); } /** * Search for artists */ async searchArtists(term: string): Promise<SearchResult[]> { return this['request']<SearchResult[]>(`/artist/lookup?term=${encodeURIComponent(term)}`); } /** * Add an artist */ async addArtist(artist: Partial<Artist> & { foreignArtistId: string; rootFolderPath: string; qualityProfileId: number; metadataProfileId: number }): Promise<Artist> { return this['request']<Artist>('/artist', { method: 'POST', body: JSON.stringify({ ...artist, monitored: artist.monitored ?? true, addOptions: { searchForMissingAlbums: true, }, }), }); } /** * Get all albums, optionally filtered by artist */ async getAlbums(artistId?: number): Promise<Album[]> { const url = artistId ? `/album?artistId=${artistId}` : '/album'; return this['request']<Album[]>(url); } /** * Get a specific album */ async getAlbumById(id: number): Promise<Album> { return this['request']<Album>(`/album/${id}`); } /** * Search for missing albums for an artist */ async searchMissingAlbums(artistId: number): Promise<{ id: number }> { return this['request']<{ id: number }>('/command', { method: 'POST', body: JSON.stringify({ name: 'ArtistSearch', artistId, }), }); } /** * Search for a specific album */ async searchAlbum(albumId: number): Promise<{ id: number }> { return this['request']<{ id: number }>('/command', { method: 'POST', body: JSON.stringify({ name: 'AlbumSearch', albumIds: [albumId], }), }); } /** * Get calendar (upcoming album releases) */ async getCalendar(start?: string, end?: string): Promise<Album[]> { const params = new URLSearchParams(); if (start) params.append('start', start); if (end) params.append('end', end); const query = params.toString() ? `?${params.toString()}` : ''; return this['request']<Album[]>(`/calendar${query}`); } /** * Get metadata profiles */ async getMetadataProfiles(): Promise<MetadataProfile[]> { return this['request']<MetadataProfile[]>('/metadataprofile'); } }

Latest Blog Posts

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/aplaceforallmystuff/mcp-arr'

If you have feedback or need assistance with the MCP directory API, please join our Discord server