@thelord/mcp-arr 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,784 @@
1
+ /**
2
+ * *arr Suite API Client
3
+ *
4
+ * All *arr applications (Sonarr, Radarr, Lidarr, Readarr, Prowlarr) use
5
+ * the same REST API pattern with X-Api-Key header authentication.
6
+ */
7
+ export type ArrService = 'sonarr' | 'radarr' | 'lidarr' | 'readarr' | 'prowlarr';
8
+ export interface ArrConfig {
9
+ url: string;
10
+ apiKey: string;
11
+ }
12
+ export interface SystemStatus {
13
+ appName: string;
14
+ version: string;
15
+ buildTime: string;
16
+ isDebug: boolean;
17
+ isProduction: boolean;
18
+ isAdmin: boolean;
19
+ isUserInteractive: boolean;
20
+ startupPath: string;
21
+ appData: string;
22
+ osName: string;
23
+ isDocker: boolean;
24
+ isLinux: boolean;
25
+ isOsx: boolean;
26
+ isWindows: boolean;
27
+ }
28
+ export interface QueueItem {
29
+ id: number;
30
+ title: string;
31
+ status: string;
32
+ trackedDownloadStatus: string;
33
+ trackedDownloadState: string;
34
+ statusMessages: Array<{
35
+ title: string;
36
+ messages: string[];
37
+ }>;
38
+ downloadId: string;
39
+ protocol: string;
40
+ downloadClient: string;
41
+ outputPath: string;
42
+ sizeleft: number;
43
+ size: number;
44
+ timeleft: string;
45
+ estimatedCompletionTime: string;
46
+ }
47
+ export interface Series {
48
+ id: number;
49
+ title: string;
50
+ sortTitle: string;
51
+ status: string;
52
+ overview: string;
53
+ network: string;
54
+ airTime: string;
55
+ images: Array<{
56
+ coverType: string;
57
+ url: string;
58
+ }>;
59
+ seasons: Array<{
60
+ seasonNumber: number;
61
+ monitored: boolean;
62
+ }>;
63
+ year: number;
64
+ path: string;
65
+ qualityProfileId: number;
66
+ seasonFolder: boolean;
67
+ monitored: boolean;
68
+ runtime: number;
69
+ tvdbId: number;
70
+ tvRageId: number;
71
+ tvMazeId: number;
72
+ firstAired: string;
73
+ seriesType: string;
74
+ cleanTitle: string;
75
+ imdbId: string;
76
+ titleSlug: string;
77
+ genres: string[];
78
+ tags: number[];
79
+ added: string;
80
+ ratings: {
81
+ votes: number;
82
+ value: number;
83
+ };
84
+ statistics: {
85
+ seasonCount: number;
86
+ episodeFileCount: number;
87
+ episodeCount: number;
88
+ totalEpisodeCount: number;
89
+ sizeOnDisk: number;
90
+ percentOfEpisodes: number;
91
+ };
92
+ }
93
+ export interface Episode {
94
+ id: number;
95
+ seriesId: number;
96
+ tvdbId: number;
97
+ episodeFileId: number;
98
+ seasonNumber: number;
99
+ episodeNumber: number;
100
+ title: string;
101
+ airDate: string;
102
+ airDateUtc: string;
103
+ overview: string;
104
+ hasFile: boolean;
105
+ monitored: boolean;
106
+ absoluteEpisodeNumber: number;
107
+ unverifiedSceneNumbering: boolean;
108
+ episodeFile?: {
109
+ id: number;
110
+ relativePath: string;
111
+ path: string;
112
+ size: number;
113
+ dateAdded: string;
114
+ quality: {
115
+ quality: {
116
+ id: number;
117
+ name: string;
118
+ };
119
+ };
120
+ };
121
+ }
122
+ export interface Book {
123
+ id: number;
124
+ title: string;
125
+ authorId: number;
126
+ foreignBookId: string;
127
+ titleSlug: string;
128
+ overview: string;
129
+ releaseDate: string;
130
+ pageCount: number;
131
+ monitored: boolean;
132
+ grabbed: boolean;
133
+ ratings: {
134
+ votes: number;
135
+ value: number;
136
+ };
137
+ editions: Array<{
138
+ id: number;
139
+ bookId: number;
140
+ foreignEditionId: string;
141
+ title: string;
142
+ pageCount: number;
143
+ isEbook: boolean;
144
+ monitored: boolean;
145
+ }>;
146
+ statistics?: {
147
+ bookFileCount: number;
148
+ bookCount: number;
149
+ totalBookCount: number;
150
+ sizeOnDisk: number;
151
+ percentOfBooks: number;
152
+ };
153
+ }
154
+ export interface Movie {
155
+ id: number;
156
+ title: string;
157
+ sortTitle: string;
158
+ sizeOnDisk: number;
159
+ status: string;
160
+ overview: string;
161
+ inCinemas: string;
162
+ physicalRelease: string;
163
+ digitalRelease: string;
164
+ images: Array<{
165
+ coverType: string;
166
+ url: string;
167
+ }>;
168
+ website: string;
169
+ year: number;
170
+ hasFile: boolean;
171
+ youTubeTrailerId: string;
172
+ studio: string;
173
+ path: string;
174
+ qualityProfileId: number;
175
+ monitored: boolean;
176
+ minimumAvailability: string;
177
+ isAvailable: boolean;
178
+ folderName: string;
179
+ runtime: number;
180
+ cleanTitle: string;
181
+ imdbId: string;
182
+ tmdbId: number;
183
+ titleSlug: string;
184
+ genres: string[];
185
+ tags: number[];
186
+ added: string;
187
+ ratings: {
188
+ votes: number;
189
+ value: number;
190
+ };
191
+ movieFile?: {
192
+ id: number;
193
+ relativePath: string;
194
+ path: string;
195
+ size: number;
196
+ dateAdded: string;
197
+ quality: {
198
+ quality: {
199
+ id: number;
200
+ name: string;
201
+ };
202
+ };
203
+ };
204
+ }
205
+ export interface Album {
206
+ id: number;
207
+ title: string;
208
+ disambiguation: string;
209
+ overview: string;
210
+ artistId: number;
211
+ foreignAlbumId: string;
212
+ monitored: boolean;
213
+ anyReleaseOk: boolean;
214
+ profileId: number;
215
+ duration: number;
216
+ albumType: string;
217
+ genres: string[];
218
+ images: Array<{
219
+ coverType: string;
220
+ url: string;
221
+ }>;
222
+ links: Array<{
223
+ url: string;
224
+ name: string;
225
+ }>;
226
+ statistics?: {
227
+ trackFileCount: number;
228
+ trackCount: number;
229
+ totalTrackCount: number;
230
+ sizeOnDisk: number;
231
+ percentOfTracks: number;
232
+ };
233
+ releaseDate: string;
234
+ releases: Array<{
235
+ id: number;
236
+ albumId: number;
237
+ foreignReleaseId: string;
238
+ title: string;
239
+ status: string;
240
+ duration: number;
241
+ trackCount: number;
242
+ monitored: boolean;
243
+ }>;
244
+ grabbed: boolean;
245
+ }
246
+ export interface Artist {
247
+ id: number;
248
+ artistName: string;
249
+ sortName: string;
250
+ status: string;
251
+ overview: string;
252
+ artistType: string;
253
+ disambiguation: string;
254
+ links: Array<{
255
+ url: string;
256
+ name: string;
257
+ }>;
258
+ images: Array<{
259
+ coverType: string;
260
+ url: string;
261
+ }>;
262
+ path: string;
263
+ qualityProfileId: number;
264
+ metadataProfileId: number;
265
+ monitored: boolean;
266
+ monitorNewItems: string;
267
+ genres: string[];
268
+ cleanName: string;
269
+ foreignArtistId: string;
270
+ tags: number[];
271
+ added: string;
272
+ ratings: {
273
+ votes: number;
274
+ value: number;
275
+ };
276
+ statistics: {
277
+ albumCount: number;
278
+ trackFileCount: number;
279
+ trackCount: number;
280
+ totalTrackCount: number;
281
+ sizeOnDisk: number;
282
+ percentOfTracks: number;
283
+ };
284
+ }
285
+ export interface Author {
286
+ id: number;
287
+ authorName: string;
288
+ sortName: string;
289
+ status: string;
290
+ overview: string;
291
+ links: Array<{
292
+ url: string;
293
+ name: string;
294
+ }>;
295
+ images: Array<{
296
+ coverType: string;
297
+ url: string;
298
+ }>;
299
+ path: string;
300
+ qualityProfileId: number;
301
+ metadataProfileId: number;
302
+ monitored: boolean;
303
+ monitorNewItems: string;
304
+ genres: string[];
305
+ cleanName: string;
306
+ foreignAuthorId: string;
307
+ tags: number[];
308
+ added: string;
309
+ ratings: {
310
+ votes: number;
311
+ value: number;
312
+ popularity: number;
313
+ };
314
+ statistics: {
315
+ bookFileCount: number;
316
+ bookCount: number;
317
+ totalBookCount: number;
318
+ sizeOnDisk: number;
319
+ percentOfBooks: number;
320
+ };
321
+ }
322
+ export interface Indexer {
323
+ id: number;
324
+ name: string;
325
+ enableRss: boolean;
326
+ enableAutomaticSearch: boolean;
327
+ enableInteractiveSearch: boolean;
328
+ protocol: string;
329
+ priority: number;
330
+ added: string;
331
+ }
332
+ export interface QualityProfile {
333
+ id: number;
334
+ name: string;
335
+ upgradeAllowed: boolean;
336
+ cutoff: number;
337
+ items: Array<{
338
+ id?: number;
339
+ name?: string;
340
+ quality?: {
341
+ id: number;
342
+ name: string;
343
+ source: string;
344
+ resolution: number;
345
+ };
346
+ items?: Array<{
347
+ quality: {
348
+ id: number;
349
+ name: string;
350
+ };
351
+ }>;
352
+ allowed: boolean;
353
+ }>;
354
+ minFormatScore: number;
355
+ cutoffFormatScore: number;
356
+ formatItems: Array<{
357
+ format: number;
358
+ name: string;
359
+ score: number;
360
+ }>;
361
+ }
362
+ export interface QualityDefinition {
363
+ id: number;
364
+ quality: {
365
+ id: number;
366
+ name: string;
367
+ source: string;
368
+ resolution: number;
369
+ };
370
+ title: string;
371
+ weight: number;
372
+ minSize: number;
373
+ maxSize: number;
374
+ preferredSize: number;
375
+ }
376
+ export interface DownloadClient {
377
+ id: number;
378
+ name: string;
379
+ implementation: string;
380
+ implementationName: string;
381
+ configContract: string;
382
+ enable: boolean;
383
+ protocol: string;
384
+ priority: number;
385
+ removeCompletedDownloads: boolean;
386
+ removeFailedDownloads: boolean;
387
+ fields: Array<{
388
+ name: string;
389
+ value: unknown;
390
+ }>;
391
+ tags: number[];
392
+ }
393
+ export interface NamingConfig {
394
+ renameEpisodes?: boolean;
395
+ replaceIllegalCharacters: boolean;
396
+ colonReplacementFormat?: string;
397
+ standardEpisodeFormat?: string;
398
+ dailyEpisodeFormat?: string;
399
+ animeEpisodeFormat?: string;
400
+ seriesFolderFormat?: string;
401
+ seasonFolderFormat?: string;
402
+ specialsFolderFormat?: string;
403
+ multiEpisodeStyle?: number;
404
+ renameMovies?: boolean;
405
+ movieFolderFormat?: string;
406
+ standardMovieFormat?: string;
407
+ renameTracks?: boolean;
408
+ artistFolderFormat?: string;
409
+ albumFolderFormat?: string;
410
+ trackFormat?: string;
411
+ renameBooks?: boolean;
412
+ authorFolderFormat?: string;
413
+ bookFolderFormat?: string;
414
+ standardBookFormat?: string;
415
+ }
416
+ export interface MediaManagementConfig {
417
+ autoUnmonitorPreviouslyDownloadedEpisodes?: boolean;
418
+ autoUnmonitorPreviouslyDownloadedMovies?: boolean;
419
+ recycleBin: string;
420
+ recycleBinCleanupDays: number;
421
+ downloadPropersAndRepacks: string;
422
+ createEmptySeriesFolders?: boolean;
423
+ createEmptyMovieFolders?: boolean;
424
+ deleteEmptyFolders: boolean;
425
+ fileDate: string;
426
+ rescanAfterRefresh: string;
427
+ setPermissionsLinux: boolean;
428
+ chmodFolder: string;
429
+ chownGroup: string;
430
+ episodeTitleRequired?: string;
431
+ skipFreeSpaceCheckWhenImporting: boolean;
432
+ minimumFreeSpaceWhenImporting: number;
433
+ copyUsingHardlinks: boolean;
434
+ importExtraFiles: boolean;
435
+ extraFileExtensions: string;
436
+ enableMediaInfo: boolean;
437
+ }
438
+ export interface HealthCheck {
439
+ source: string;
440
+ type: string;
441
+ message: string;
442
+ wikiUrl: string;
443
+ }
444
+ export interface Tag {
445
+ id: number;
446
+ label: string;
447
+ }
448
+ export interface RootFolder {
449
+ id: number;
450
+ path: string;
451
+ accessible: boolean;
452
+ freeSpace: number;
453
+ unmappedFolders?: Array<{
454
+ name: string;
455
+ path: string;
456
+ }>;
457
+ }
458
+ export interface MetadataProfile {
459
+ id: number;
460
+ name: string;
461
+ minPopularity?: number;
462
+ skipMissingDate: boolean;
463
+ skipMissingIsbn: boolean;
464
+ skipPartsAndSets: boolean;
465
+ skipSeriesSecondary: boolean;
466
+ allowedLanguages?: string;
467
+ minPages?: number;
468
+ }
469
+ export interface SearchResult {
470
+ title: string;
471
+ sortTitle: string;
472
+ status: string;
473
+ overview: string;
474
+ year: number;
475
+ images: Array<{
476
+ coverType: string;
477
+ url: string;
478
+ }>;
479
+ remotePoster?: string;
480
+ tvdbId?: number;
481
+ tmdbId?: number;
482
+ imdbId?: string;
483
+ foreignArtistId?: string;
484
+ foreignAuthorId?: string;
485
+ }
486
+ export declare class ArrClient {
487
+ private config;
488
+ private serviceName;
489
+ protected apiVersion: string;
490
+ constructor(serviceName: ArrService, config: ArrConfig);
491
+ /**
492
+ * Make an API request
493
+ */
494
+ protected request<T>(endpoint: string, options?: RequestInit): Promise<T>;
495
+ /**
496
+ * Get system status
497
+ */
498
+ getStatus(): Promise<SystemStatus>;
499
+ /**
500
+ * Get download queue
501
+ */
502
+ getQueue(): Promise<{
503
+ records: QueueItem[];
504
+ totalRecords: number;
505
+ }>;
506
+ /**
507
+ * Get calendar items (upcoming releases)
508
+ */
509
+ getCalendar(start?: string, end?: string): Promise<unknown[]>;
510
+ /**
511
+ * Get all root folders
512
+ */
513
+ getRootFolders(): Promise<Array<{
514
+ id: number;
515
+ path: string;
516
+ freeSpace: number;
517
+ }>>;
518
+ /**
519
+ * Test connection
520
+ */
521
+ testConnection(): Promise<boolean>;
522
+ /**
523
+ * Get quality profiles
524
+ */
525
+ getQualityProfiles(): Promise<QualityProfile[]>;
526
+ /**
527
+ * Get quality definitions (size limits)
528
+ */
529
+ getQualityDefinitions(): Promise<QualityDefinition[]>;
530
+ /**
531
+ * Get download clients
532
+ */
533
+ getDownloadClients(): Promise<DownloadClient[]>;
534
+ /**
535
+ * Get naming configuration
536
+ */
537
+ getNamingConfig(): Promise<NamingConfig>;
538
+ /**
539
+ * Get media management configuration
540
+ */
541
+ getMediaManagement(): Promise<MediaManagementConfig>;
542
+ /**
543
+ * Get health check issues
544
+ */
545
+ getHealth(): Promise<HealthCheck[]>;
546
+ /**
547
+ * Get all tags
548
+ */
549
+ getTags(): Promise<Tag[]>;
550
+ /**
551
+ * Get detailed root folders
552
+ */
553
+ getRootFoldersDetailed(): Promise<RootFolder[]>;
554
+ /**
555
+ * Get indexers (per-app configuration, not Prowlarr)
556
+ */
557
+ getIndexers(): Promise<Indexer[]>;
558
+ }
559
+ export declare class SonarrClient extends ArrClient {
560
+ constructor(config: ArrConfig);
561
+ /**
562
+ * Get all series
563
+ */
564
+ getSeries(): Promise<Series[]>;
565
+ /**
566
+ * Get a specific series
567
+ */
568
+ getSeriesById(id: number): Promise<Series>;
569
+ /**
570
+ * Search for series
571
+ */
572
+ searchSeries(term: string): Promise<SearchResult[]>;
573
+ /**
574
+ * Add a series
575
+ */
576
+ addSeries(series: Partial<Series> & {
577
+ tvdbId: number;
578
+ rootFolderPath: string;
579
+ qualityProfileId: number;
580
+ }): Promise<Series>;
581
+ /**
582
+ * Trigger a search for missing episodes
583
+ */
584
+ searchMissing(seriesId: number): Promise<{
585
+ id: number;
586
+ }>;
587
+ /**
588
+ * Get episodes for a series, optionally filtered by season
589
+ */
590
+ getEpisodes(seriesId: number, seasonNumber?: number): Promise<Episode[]>;
591
+ /**
592
+ * Search for a specific episode
593
+ */
594
+ searchEpisode(episodeIds: number[]): Promise<{
595
+ id: number;
596
+ }>;
597
+ }
598
+ export declare class RadarrClient extends ArrClient {
599
+ constructor(config: ArrConfig);
600
+ /**
601
+ * Get all movies
602
+ */
603
+ getMovies(): Promise<Movie[]>;
604
+ /**
605
+ * Get a specific movie
606
+ */
607
+ getMovieById(id: number): Promise<Movie>;
608
+ /**
609
+ * Search for movies
610
+ */
611
+ searchMovies(term: string): Promise<SearchResult[]>;
612
+ /**
613
+ * Add a movie
614
+ */
615
+ addMovie(movie: Partial<Movie> & {
616
+ tmdbId: number;
617
+ rootFolderPath: string;
618
+ qualityProfileId: number;
619
+ }): Promise<Movie>;
620
+ /**
621
+ * Trigger a search for a movie
622
+ */
623
+ searchMovie(movieId: number): Promise<{
624
+ id: number;
625
+ }>;
626
+ }
627
+ export declare class LidarrClient extends ArrClient {
628
+ constructor(config: ArrConfig);
629
+ /**
630
+ * Get all artists
631
+ */
632
+ getArtists(): Promise<Artist[]>;
633
+ /**
634
+ * Get a specific artist
635
+ */
636
+ getArtistById(id: number): Promise<Artist>;
637
+ /**
638
+ * Search for artists
639
+ */
640
+ searchArtists(term: string): Promise<SearchResult[]>;
641
+ /**
642
+ * Add an artist
643
+ */
644
+ addArtist(artist: Partial<Artist> & {
645
+ foreignArtistId: string;
646
+ rootFolderPath: string;
647
+ qualityProfileId: number;
648
+ metadataProfileId: number;
649
+ }): Promise<Artist>;
650
+ /**
651
+ * Get all albums, optionally filtered by artist
652
+ */
653
+ getAlbums(artistId?: number): Promise<Album[]>;
654
+ /**
655
+ * Get a specific album
656
+ */
657
+ getAlbumById(id: number): Promise<Album>;
658
+ /**
659
+ * Search for missing albums for an artist
660
+ */
661
+ searchMissingAlbums(artistId: number): Promise<{
662
+ id: number;
663
+ }>;
664
+ /**
665
+ * Search for a specific album
666
+ */
667
+ searchAlbum(albumId: number): Promise<{
668
+ id: number;
669
+ }>;
670
+ /**
671
+ * Get calendar (upcoming album releases)
672
+ */
673
+ getCalendar(start?: string, end?: string): Promise<Album[]>;
674
+ /**
675
+ * Get metadata profiles
676
+ */
677
+ getMetadataProfiles(): Promise<MetadataProfile[]>;
678
+ }
679
+ export declare class ReadarrClient extends ArrClient {
680
+ constructor(config: ArrConfig);
681
+ /**
682
+ * Get all authors
683
+ */
684
+ getAuthors(): Promise<Author[]>;
685
+ /**
686
+ * Get a specific author
687
+ */
688
+ getAuthorById(id: number): Promise<Author>;
689
+ /**
690
+ * Search for authors
691
+ */
692
+ searchAuthors(term: string): Promise<SearchResult[]>;
693
+ /**
694
+ * Add an author
695
+ */
696
+ addAuthor(author: Partial<Author> & {
697
+ foreignAuthorId: string;
698
+ rootFolderPath: string;
699
+ qualityProfileId: number;
700
+ metadataProfileId: number;
701
+ }): Promise<Author>;
702
+ /**
703
+ * Get books for an author
704
+ */
705
+ getBooks(authorId?: number): Promise<Book[]>;
706
+ /**
707
+ * Get a specific book
708
+ */
709
+ getBookById(id: number): Promise<Book>;
710
+ /**
711
+ * Search for missing books for an author
712
+ */
713
+ searchMissingBooks(authorId: number): Promise<{
714
+ id: number;
715
+ }>;
716
+ /**
717
+ * Search for a specific book
718
+ */
719
+ searchBook(bookIds: number[]): Promise<{
720
+ id: number;
721
+ }>;
722
+ /**
723
+ * Get calendar (upcoming book releases)
724
+ */
725
+ getCalendar(start?: string, end?: string): Promise<Book[]>;
726
+ /**
727
+ * Get metadata profiles
728
+ */
729
+ getMetadataProfiles(): Promise<MetadataProfile[]>;
730
+ }
731
+ export interface IndexerStats {
732
+ id: number;
733
+ indexerId: number;
734
+ indexerName: string;
735
+ averageResponseTime: number;
736
+ numberOfQueries: number;
737
+ numberOfGrabs: number;
738
+ numberOfRssQueries: number;
739
+ numberOfAuthQueries: number;
740
+ numberOfFailedQueries: number;
741
+ numberOfFailedGrabs: number;
742
+ numberOfFailedRssQueries: number;
743
+ numberOfFailedAuthQueries: number;
744
+ }
745
+ export declare class ProwlarrClient extends ArrClient {
746
+ constructor(config: ArrConfig);
747
+ /**
748
+ * Get all indexers
749
+ */
750
+ getIndexers(): Promise<Indexer[]>;
751
+ /**
752
+ * Test all indexers
753
+ */
754
+ testAllIndexers(): Promise<Array<{
755
+ id: number;
756
+ isValid: boolean;
757
+ validationFailures: Array<{
758
+ propertyName: string;
759
+ errorMessage: string;
760
+ }>;
761
+ }>>;
762
+ /**
763
+ * Test a specific indexer
764
+ */
765
+ testIndexer(indexerId: number): Promise<{
766
+ id: number;
767
+ isValid: boolean;
768
+ validationFailures: Array<{
769
+ propertyName: string;
770
+ errorMessage: string;
771
+ }>;
772
+ }>;
773
+ /**
774
+ * Get indexer statistics
775
+ */
776
+ getIndexerStats(): Promise<{
777
+ indexers: IndexerStats[];
778
+ }>;
779
+ /**
780
+ * Search across all indexers
781
+ */
782
+ search(query: string, categories?: number[]): Promise<unknown[]>;
783
+ }
784
+ //# sourceMappingURL=arr-client.d.ts.map