mcp-arr-server 1.5.2 → 1.5.4

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.
package/dist/index.js CHANGED
@@ -3,25 +3,23 @@
3
3
  * MCP Server for *arr Media Management Suite
4
4
  *
5
5
  * Provides tools for managing Sonarr (TV), Radarr (Movies), Lidarr (Music),
6
- * Readarr (Books), and Prowlarr (Indexers) through Claude Code.
6
+ * and Prowlarr (Indexers) through Claude Code.
7
7
  *
8
8
  * Environment variables:
9
9
  * - SONARR_URL, SONARR_API_KEY
10
10
  * - RADARR_URL, RADARR_API_KEY
11
11
  * - LIDARR_URL, LIDARR_API_KEY
12
- * - READARR_URL, READARR_API_KEY
13
12
  * - PROWLARR_URL, PROWLARR_API_KEY
14
13
  */
15
14
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
16
15
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
17
16
  import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
18
- import { SonarrClient, RadarrClient, LidarrClient, ReadarrClient, ProwlarrClient, } from "./arr-client.js";
17
+ import { SonarrClient, RadarrClient, LidarrClient, ProwlarrClient, } from "./arr-client.js";
19
18
  import { trashClient } from "./trash-client.js";
20
19
  const services = [
21
20
  { name: 'sonarr', displayName: 'Sonarr (TV)', url: process.env.SONARR_URL, apiKey: process.env.SONARR_API_KEY },
22
21
  { name: 'radarr', displayName: 'Radarr (Movies)', url: process.env.RADARR_URL, apiKey: process.env.RADARR_API_KEY },
23
22
  { name: 'lidarr', displayName: 'Lidarr (Music)', url: process.env.LIDARR_URL, apiKey: process.env.LIDARR_API_KEY },
24
- { name: 'readarr', displayName: 'Readarr (Books)', url: process.env.READARR_URL, apiKey: process.env.READARR_API_KEY },
25
23
  { name: 'prowlarr', displayName: 'Prowlarr (Indexers)', url: process.env.PROWLARR_URL, apiKey: process.env.PROWLARR_API_KEY },
26
24
  ];
27
25
  // Check which services are configured
@@ -45,9 +43,6 @@ for (const service of configuredServices) {
45
43
  case 'lidarr':
46
44
  clients.lidarr = new LidarrClient(config);
47
45
  break;
48
- case 'readarr':
49
- clients.readarr = new ReadarrClient(config);
50
- break;
51
46
  case 'prowlarr':
52
47
  clients.prowlarr = new ProwlarrClient(config);
53
48
  break;
@@ -135,8 +130,6 @@ if (clients.radarr)
135
130
  addConfigTools('radarr', 'Radarr (Movies)');
136
131
  if (clients.lidarr)
137
132
  addConfigTools('lidarr', 'Lidarr (Music)');
138
- if (clients.readarr)
139
- addConfigTools('readarr', 'Readarr (Books)');
140
133
  // Sonarr tools
141
134
  if (clients.sonarr) {
142
135
  TOOLS.push({
@@ -263,22 +256,6 @@ if (clients.sonarr) {
263
256
  },
264
257
  required: ["tvdbId", "title", "qualityProfileId", "rootFolderPath"],
265
258
  },
266
- }, {
267
- name: "sonarr_get_root_folders",
268
- description: "Get available root folders for Sonarr. Use this to find valid rootFolderPath values when adding a series.",
269
- inputSchema: {
270
- type: "object",
271
- properties: {},
272
- required: [],
273
- },
274
- }, {
275
- name: "sonarr_get_quality_profiles",
276
- description: "Get available quality profiles for Sonarr. Use this to find valid qualityProfileId values when adding a series.",
277
- inputSchema: {
278
- type: "object",
279
- properties: {},
280
- required: [],
281
- },
282
259
  });
283
260
  }
284
261
  // Radarr tools
@@ -377,22 +354,6 @@ if (clients.radarr) {
377
354
  },
378
355
  required: ["tmdbId", "title", "qualityProfileId", "rootFolderPath"],
379
356
  },
380
- }, {
381
- name: "radarr_get_root_folders",
382
- description: "Get available root folders for Radarr. Use this to find valid rootFolderPath values when adding a movie.",
383
- inputSchema: {
384
- type: "object",
385
- properties: {},
386
- required: [],
387
- },
388
- }, {
389
- name: "radarr_get_quality_profiles",
390
- description: "Get available quality profiles for Radarr. Use this to find valid qualityProfileId values when adding a movie.",
391
- inputSchema: {
392
- type: "object",
393
- properties: {},
394
- required: [],
395
- },
396
357
  });
397
358
  }
398
359
  // Lidarr tools
@@ -542,154 +503,6 @@ if (clients.lidarr) {
542
503
  },
543
504
  });
544
505
  }
545
- // Readarr tools
546
- if (clients.readarr) {
547
- TOOLS.push({
548
- name: "readarr_get_authors",
549
- description: "Get all authors in Readarr library",
550
- inputSchema: {
551
- type: "object",
552
- properties: {},
553
- required: [],
554
- },
555
- }, {
556
- name: "readarr_search",
557
- description: "Search for authors by name. Returns results with foreignAuthorId needed for readarr_add_author.",
558
- inputSchema: {
559
- type: "object",
560
- properties: {
561
- term: {
562
- type: "string",
563
- description: "Search term (author name)",
564
- },
565
- },
566
- required: ["term"],
567
- },
568
- }, {
569
- name: "readarr_get_queue",
570
- description: "Get Readarr download queue",
571
- inputSchema: {
572
- type: "object",
573
- properties: {},
574
- required: [],
575
- },
576
- }, {
577
- name: "readarr_get_books",
578
- description: "Get books for an author in Readarr. Shows which books are available and which are missing.",
579
- inputSchema: {
580
- type: "object",
581
- properties: {
582
- authorId: {
583
- type: "number",
584
- description: "Author ID to get books for",
585
- },
586
- },
587
- required: ["authorId"],
588
- },
589
- }, {
590
- name: "readarr_search_book",
591
- description: "Trigger a search for a specific book to download",
592
- inputSchema: {
593
- type: "object",
594
- properties: {
595
- bookIds: {
596
- type: "array",
597
- items: { type: "number" },
598
- description: "Book ID(s) to search for",
599
- },
600
- },
601
- required: ["bookIds"],
602
- },
603
- }, {
604
- name: "readarr_search_missing",
605
- description: "Trigger a search for all missing books for an author",
606
- inputSchema: {
607
- type: "object",
608
- properties: {
609
- authorId: {
610
- type: "number",
611
- description: "Author ID to search missing books for",
612
- },
613
- },
614
- required: ["authorId"],
615
- },
616
- }, {
617
- name: "readarr_get_calendar",
618
- description: "Get upcoming book releases from Readarr",
619
- inputSchema: {
620
- type: "object",
621
- properties: {
622
- days: {
623
- type: "number",
624
- description: "Number of days to look ahead (default: 30)",
625
- },
626
- },
627
- required: [],
628
- },
629
- }, {
630
- name: "readarr_add_author",
631
- description: "Add an author to Readarr. Use readarr_search first to find the foreignAuthorId, and readarr_get_root_folders / readarr_get_quality_profiles / readarr_get_metadata_profiles to get valid values. Use readarr_get_tags to get valid tag IDs.",
632
- inputSchema: {
633
- type: "object",
634
- properties: {
635
- foreignAuthorId: {
636
- type: "string",
637
- description: "Foreign author ID from readarr_search results",
638
- },
639
- authorName: {
640
- type: "string",
641
- description: "Author name",
642
- },
643
- qualityProfileId: {
644
- type: "number",
645
- description: "Quality profile ID from readarr_get_quality_profiles",
646
- },
647
- metadataProfileId: {
648
- type: "number",
649
- description: "Metadata profile ID from readarr_get_metadata_profiles",
650
- },
651
- rootFolderPath: {
652
- type: "string",
653
- description: "Root folder path from readarr_get_root_folders",
654
- },
655
- monitored: {
656
- type: "boolean",
657
- description: "Whether to monitor the author (default: true)",
658
- },
659
- tags: {
660
- type: "array",
661
- items: { type: "number" },
662
- description: "Array of tag IDs from readarr_get_tags (optional)",
663
- },
664
- },
665
- required: ["foreignAuthorId", "authorName", "qualityProfileId", "metadataProfileId", "rootFolderPath"],
666
- },
667
- }, {
668
- name: "readarr_get_root_folders",
669
- description: "Get available root folders for Readarr. Use this to find valid rootFolderPath values when adding an author.",
670
- inputSchema: {
671
- type: "object",
672
- properties: {},
673
- required: [],
674
- },
675
- }, {
676
- name: "readarr_get_quality_profiles",
677
- description: "Get available quality profiles for Readarr. Use this to find valid qualityProfileId values when adding an author.",
678
- inputSchema: {
679
- type: "object",
680
- properties: {},
681
- required: [],
682
- },
683
- }, {
684
- name: "readarr_get_metadata_profiles",
685
- description: "Get available metadata profiles for Readarr. Use this to find valid metadataProfileId values when adding an author.",
686
- inputSchema: {
687
- type: "object",
688
- properties: {},
689
- required: [],
690
- },
691
- });
692
- }
693
506
  // Prowlarr tools
694
507
  if (clients.prowlarr) {
695
508
  TOOLS.push({
@@ -931,8 +744,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
931
744
  // Quality Profiles
932
745
  case "sonarr_get_quality_profiles":
933
746
  case "radarr_get_quality_profiles":
934
- case "lidarr_get_quality_profiles":
935
- case "readarr_get_quality_profiles": {
747
+ case "lidarr_get_quality_profiles": {
936
748
  const serviceName = name.split('_')[0];
937
749
  const client = clients[serviceName];
938
750
  if (!client)
@@ -966,8 +778,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
966
778
  // Health checks
967
779
  case "sonarr_get_health":
968
780
  case "radarr_get_health":
969
- case "lidarr_get_health":
970
- case "readarr_get_health": {
781
+ case "lidarr_get_health": {
971
782
  const serviceName = name.split('_')[0];
972
783
  const client = clients[serviceName];
973
784
  if (!client)
@@ -992,8 +803,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
992
803
  // Root folders
993
804
  case "sonarr_get_root_folders":
994
805
  case "radarr_get_root_folders":
995
- case "lidarr_get_root_folders":
996
- case "readarr_get_root_folders": {
806
+ case "lidarr_get_root_folders": {
997
807
  const serviceName = name.split('_')[0];
998
808
  const client = clients[serviceName];
999
809
  if (!client)
@@ -1019,8 +829,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1019
829
  // Download clients
1020
830
  case "sonarr_get_download_clients":
1021
831
  case "radarr_get_download_clients":
1022
- case "lidarr_get_download_clients":
1023
- case "readarr_get_download_clients": {
832
+ case "lidarr_get_download_clients": {
1024
833
  const serviceName = name.split('_')[0];
1025
834
  const client = clients[serviceName];
1026
835
  if (!client)
@@ -1049,8 +858,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1049
858
  // Naming config
1050
859
  case "sonarr_get_naming":
1051
860
  case "radarr_get_naming":
1052
- case "lidarr_get_naming":
1053
- case "readarr_get_naming": {
861
+ case "lidarr_get_naming": {
1054
862
  const serviceName = name.split('_')[0];
1055
863
  const client = clients[serviceName];
1056
864
  if (!client)
@@ -1066,8 +874,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1066
874
  // Tags
1067
875
  case "sonarr_get_tags":
1068
876
  case "radarr_get_tags":
1069
- case "lidarr_get_tags":
1070
- case "readarr_get_tags": {
877
+ case "lidarr_get_tags": {
1071
878
  const serviceName = name.split('_')[0];
1072
879
  const client = clients[serviceName];
1073
880
  if (!client)
@@ -1086,8 +893,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1086
893
  // Comprehensive setup review
1087
894
  case "sonarr_review_setup":
1088
895
  case "radarr_review_setup":
1089
- case "lidarr_review_setup":
1090
- case "readarr_review_setup": {
896
+ case "lidarr_review_setup": {
1091
897
  const serviceName = name.split('_')[0];
1092
898
  const client = clients[serviceName];
1093
899
  if (!client)
@@ -1105,14 +911,11 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1105
911
  client.getTags(),
1106
912
  client.getIndexers(),
1107
913
  ]);
1108
- // For Lidarr/Readarr, also get metadata profiles
914
+ // For Lidarr, also get metadata profiles
1109
915
  let metadataProfiles = null;
1110
916
  if (serviceName === 'lidarr' && clients.lidarr) {
1111
917
  metadataProfiles = await clients.lidarr.getMetadataProfiles();
1112
918
  }
1113
- else if (serviceName === 'readarr' && clients.readarr) {
1114
- metadataProfiles = await clients.readarr.getMetadataProfiles();
1115
- }
1116
919
  const review = {
1117
920
  service: serviceName,
1118
921
  version: status.version,
@@ -1338,28 +1141,6 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1338
1141
  }],
1339
1142
  };
1340
1143
  }
1341
- case "sonarr_get_root_folders": {
1342
- if (!clients.sonarr)
1343
- throw new Error("Sonarr not configured");
1344
- const folders = await clients.sonarr.getRootFolders();
1345
- return {
1346
- content: [{
1347
- type: "text",
1348
- text: JSON.stringify(folders, null, 2),
1349
- }],
1350
- };
1351
- }
1352
- case "sonarr_get_quality_profiles": {
1353
- if (!clients.sonarr)
1354
- throw new Error("Sonarr not configured");
1355
- const profiles = await clients.sonarr.getQualityProfiles();
1356
- return {
1357
- content: [{
1358
- type: "text",
1359
- text: JSON.stringify(profiles.map(p => ({ id: p.id, name: p.name })), null, 2),
1360
- }],
1361
- };
1362
- }
1363
1144
  // Radarr handlers
1364
1145
  case "radarr_get_movies": {
1365
1146
  if (!clients.radarr)
@@ -1472,28 +1253,6 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1472
1253
  }],
1473
1254
  };
1474
1255
  }
1475
- case "radarr_get_root_folders": {
1476
- if (!clients.radarr)
1477
- throw new Error("Radarr not configured");
1478
- const folders = await clients.radarr.getRootFolders();
1479
- return {
1480
- content: [{
1481
- type: "text",
1482
- text: JSON.stringify(folders, null, 2),
1483
- }],
1484
- };
1485
- }
1486
- case "radarr_get_quality_profiles": {
1487
- if (!clients.radarr)
1488
- throw new Error("Radarr not configured");
1489
- const profiles = await clients.radarr.getQualityProfiles();
1490
- return {
1491
- content: [{
1492
- type: "text",
1493
- text: JSON.stringify(profiles.map(p => ({ id: p.id, name: p.name })), null, 2),
1494
- }],
1495
- };
1496
- }
1497
1256
  // Lidarr handlers
1498
1257
  case "lidarr_get_artists": {
1499
1258
  if (!clients.lidarr)
@@ -1520,7 +1279,10 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1520
1279
  case "lidarr_search": {
1521
1280
  if (!clients.lidarr)
1522
1281
  throw new Error("Lidarr not configured");
1523
- const term = args.term;
1282
+ const a = args;
1283
+ const term = a.term ?? a.query ?? a.artist ?? a.name;
1284
+ if (!term)
1285
+ throw new Error("term required (artist name)");
1524
1286
  const results = await clients.lidarr.searchArtists(term);
1525
1287
  return {
1526
1288
  content: [{
@@ -1528,9 +1290,10 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1528
1290
  text: JSON.stringify({
1529
1291
  count: results.length,
1530
1292
  results: results.slice(0, 10).map(r => ({
1531
- title: r.title,
1293
+ artistName: r.artistName ?? r.title,
1294
+ disambiguation: r.disambiguation,
1532
1295
  foreignArtistId: r.foreignArtistId,
1533
- overview: r.overview?.substring(0, 200) + (r.overview && r.overview.length > 200 ? '...' : ''),
1296
+ overview: r.overview ? (r.overview.substring(0, 200) + (r.overview.length > 200 ? '...' : '')) : undefined,
1534
1297
  })),
1535
1298
  }, null, 2),
1536
1299
  }],
@@ -1690,199 +1453,6 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1690
1453
  }],
1691
1454
  };
1692
1455
  }
1693
- // Readarr handlers
1694
- case "readarr_get_authors": {
1695
- if (!clients.readarr)
1696
- throw new Error("Readarr not configured");
1697
- const authors = await clients.readarr.getAuthors();
1698
- return {
1699
- content: [{
1700
- type: "text",
1701
- text: JSON.stringify({
1702
- count: authors.length,
1703
- authors: authors.map(a => ({
1704
- id: a.id,
1705
- authorName: a.authorName,
1706
- status: a.status,
1707
- books: a.statistics?.bookFileCount + '/' + a.statistics?.totalBookCount,
1708
- sizeOnDisk: formatBytes(a.statistics?.sizeOnDisk || 0),
1709
- monitored: a.monitored,
1710
- })),
1711
- }, null, 2),
1712
- }],
1713
- };
1714
- }
1715
- case "readarr_search": {
1716
- if (!clients.readarr)
1717
- throw new Error("Readarr not configured");
1718
- const term = args.term;
1719
- const results = await clients.readarr.searchAuthors(term);
1720
- return {
1721
- content: [{
1722
- type: "text",
1723
- text: JSON.stringify({
1724
- count: results.length,
1725
- results: results.slice(0, 10).map(r => ({
1726
- title: r.title,
1727
- foreignAuthorId: r.foreignAuthorId,
1728
- overview: r.overview?.substring(0, 200) + (r.overview && r.overview.length > 200 ? '...' : ''),
1729
- })),
1730
- }, null, 2),
1731
- }],
1732
- };
1733
- }
1734
- case "readarr_get_queue": {
1735
- if (!clients.readarr)
1736
- throw new Error("Readarr not configured");
1737
- const queue = await clients.readarr.getQueue();
1738
- return {
1739
- content: [{
1740
- type: "text",
1741
- text: JSON.stringify({
1742
- totalRecords: queue.totalRecords,
1743
- items: queue.records.map(q => ({
1744
- title: q.title,
1745
- status: q.status,
1746
- progress: ((1 - q.sizeleft / q.size) * 100).toFixed(1) + '%',
1747
- timeLeft: q.timeleft,
1748
- downloadClient: q.downloadClient,
1749
- })),
1750
- }, null, 2),
1751
- }],
1752
- };
1753
- }
1754
- case "readarr_get_books": {
1755
- if (!clients.readarr)
1756
- throw new Error("Readarr not configured");
1757
- const authorId = args.authorId;
1758
- const books = await clients.readarr.getBooks(authorId);
1759
- return {
1760
- content: [{
1761
- type: "text",
1762
- text: JSON.stringify({
1763
- count: books.length,
1764
- books: books.map(b => ({
1765
- id: b.id,
1766
- title: b.title,
1767
- releaseDate: b.releaseDate,
1768
- pageCount: b.pageCount,
1769
- monitored: b.monitored,
1770
- hasFile: b.statistics ? b.statistics.bookFileCount > 0 : false,
1771
- sizeOnDisk: formatBytes(b.statistics?.sizeOnDisk || 0),
1772
- grabbed: b.grabbed,
1773
- })),
1774
- }, null, 2),
1775
- }],
1776
- };
1777
- }
1778
- case "readarr_search_book": {
1779
- if (!clients.readarr)
1780
- throw new Error("Readarr not configured");
1781
- const bookIds = args.bookIds;
1782
- const result = await clients.readarr.searchBook(bookIds);
1783
- return {
1784
- content: [{
1785
- type: "text",
1786
- text: JSON.stringify({
1787
- success: true,
1788
- message: `Search triggered for ${bookIds.length} book(s)`,
1789
- commandId: result.id,
1790
- }, null, 2),
1791
- }],
1792
- };
1793
- }
1794
- case "readarr_search_missing": {
1795
- if (!clients.readarr)
1796
- throw new Error("Readarr not configured");
1797
- const authorId = args.authorId;
1798
- const result = await clients.readarr.searchMissingBooks(authorId);
1799
- return {
1800
- content: [{
1801
- type: "text",
1802
- text: JSON.stringify({
1803
- success: true,
1804
- message: `Search triggered for missing books`,
1805
- commandId: result.id,
1806
- }, null, 2),
1807
- }],
1808
- };
1809
- }
1810
- case "readarr_get_calendar": {
1811
- if (!clients.readarr)
1812
- throw new Error("Readarr not configured");
1813
- const days = args?.days || 30;
1814
- const start = new Date().toISOString().split('T')[0];
1815
- const end = new Date(Date.now() + days * 24 * 60 * 60 * 1000).toISOString().split('T')[0];
1816
- const calendar = await clients.readarr.getCalendar(start, end);
1817
- return {
1818
- content: [{
1819
- type: "text",
1820
- text: JSON.stringify({
1821
- count: calendar.length,
1822
- books: calendar.map(b => ({
1823
- id: b.id,
1824
- title: b.title,
1825
- authorId: b.authorId,
1826
- releaseDate: b.releaseDate,
1827
- monitored: b.monitored,
1828
- })),
1829
- }, null, 2),
1830
- }],
1831
- };
1832
- }
1833
- case "readarr_add_author": {
1834
- if (!clients.readarr)
1835
- throw new Error("Readarr not configured");
1836
- const { foreignAuthorId, authorName, qualityProfileId, metadataProfileId, rootFolderPath, monitored, tags } = args;
1837
- const added = await clients.readarr.addAuthor({
1838
- foreignAuthorId, authorName, qualityProfileId, metadataProfileId, rootFolderPath, monitored, tags: tags ?? [],
1839
- });
1840
- return {
1841
- content: [{
1842
- type: "text",
1843
- text: JSON.stringify({
1844
- success: true,
1845
- message: `Added "${added.authorName}" to Readarr`,
1846
- id: added.id,
1847
- path: added.path,
1848
- monitored: added.monitored,
1849
- }, null, 2),
1850
- }],
1851
- };
1852
- }
1853
- case "readarr_get_root_folders": {
1854
- if (!clients.readarr)
1855
- throw new Error("Readarr not configured");
1856
- const folders = await clients.readarr.getRootFolders();
1857
- return {
1858
- content: [{
1859
- type: "text",
1860
- text: JSON.stringify(folders, null, 2),
1861
- }],
1862
- };
1863
- }
1864
- case "readarr_get_quality_profiles": {
1865
- if (!clients.readarr)
1866
- throw new Error("Readarr not configured");
1867
- const profiles = await clients.readarr.getQualityProfiles();
1868
- return {
1869
- content: [{
1870
- type: "text",
1871
- text: JSON.stringify(profiles.map(p => ({ id: p.id, name: p.name })), null, 2),
1872
- }],
1873
- };
1874
- }
1875
- case "readarr_get_metadata_profiles": {
1876
- if (!clients.readarr)
1877
- throw new Error("Readarr not configured");
1878
- const profiles = await clients.readarr.getMetadataProfiles();
1879
- return {
1880
- content: [{
1881
- type: "text",
1882
- text: JSON.stringify(profiles.map(p => ({ id: p.id, name: p.name })), null, 2),
1883
- }],
1884
- };
1885
- }
1886
1456
  // Prowlarr handlers
1887
1457
  case "prowlarr_get_indexers": {
1888
1458
  if (!clients.prowlarr)
@@ -1996,15 +1566,6 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1996
1566
  results.lidarr = { error: e instanceof Error ? e.message : String(e) };
1997
1567
  }
1998
1568
  }
1999
- if (clients.readarr) {
2000
- try {
2001
- const readarrResults = await clients.readarr.searchAuthors(term);
2002
- results.readarr = { count: readarrResults.length, results: readarrResults.slice(0, 5) };
2003
- }
2004
- catch (e) {
2005
- results.readarr = { error: e instanceof Error ? e.message : String(e) };
2006
- }
2007
- }
2008
1569
  return {
2009
1570
  content: [{ type: "text", text: JSON.stringify(results, null, 2) }],
2010
1571
  };