navidrome-mcp 1.0.1

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.
Files changed (195) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +397 -0
  3. package/dist/capabilities.d.ts +20 -0
  4. package/dist/capabilities.d.ts.map +1 -0
  5. package/dist/capabilities.js +25 -0
  6. package/dist/capabilities.js.map +1 -0
  7. package/dist/client/auth-manager.d.ts +27 -0
  8. package/dist/client/auth-manager.d.ts.map +1 -0
  9. package/dist/client/auth-manager.js +54 -0
  10. package/dist/client/auth-manager.js.map +1 -0
  11. package/dist/client/navidrome-client.d.ts +28 -0
  12. package/dist/client/navidrome-client.d.ts.map +1 -0
  13. package/dist/client/navidrome-client.js +84 -0
  14. package/dist/client/navidrome-client.js.map +1 -0
  15. package/dist/config.d.ts +41 -0
  16. package/dist/config.d.ts.map +1 -0
  17. package/dist/config.js +132 -0
  18. package/dist/config.js.map +1 -0
  19. package/dist/constants/defaults.d.ts +29 -0
  20. package/dist/constants/defaults.d.ts.map +1 -0
  21. package/dist/constants/defaults.js +37 -0
  22. package/dist/constants/defaults.js.map +1 -0
  23. package/dist/constants/timeouts.d.ts +66 -0
  24. package/dist/constants/timeouts.d.ts.map +1 -0
  25. package/dist/constants/timeouts.js +66 -0
  26. package/dist/constants/timeouts.js.map +1 -0
  27. package/dist/index.d.ts +20 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +70 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/resources/index.d.ts +21 -0
  32. package/dist/resources/index.d.ts.map +1 -0
  33. package/dist/resources/index.js +83 -0
  34. package/dist/resources/index.js.map +1 -0
  35. package/dist/schemas/common.d.ts +68 -0
  36. package/dist/schemas/common.d.ts.map +1 -0
  37. package/dist/schemas/common.js +69 -0
  38. package/dist/schemas/common.js.map +1 -0
  39. package/dist/schemas/index.d.ts +21 -0
  40. package/dist/schemas/index.d.ts.map +1 -0
  41. package/dist/schemas/index.js +24 -0
  42. package/dist/schemas/index.js.map +1 -0
  43. package/dist/schemas/pagination.d.ts +153 -0
  44. package/dist/schemas/pagination.d.ts.map +1 -0
  45. package/dist/schemas/pagination.js +93 -0
  46. package/dist/schemas/pagination.js.map +1 -0
  47. package/dist/schemas/validation.d.ts +147 -0
  48. package/dist/schemas/validation.d.ts.map +1 -0
  49. package/dist/schemas/validation.js +143 -0
  50. package/dist/schemas/validation.js.map +1 -0
  51. package/dist/tools/handlers/lastfm-handlers.d.ts +5 -0
  52. package/dist/tools/handlers/lastfm-handlers.d.ts.map +1 -0
  53. package/dist/tools/handlers/lastfm-handlers.js +143 -0
  54. package/dist/tools/handlers/lastfm-handlers.js.map +1 -0
  55. package/dist/tools/handlers/lyrics-handlers.d.ts +5 -0
  56. package/dist/tools/handlers/lyrics-handlers.d.ts.map +1 -0
  57. package/dist/tools/handlers/lyrics-handlers.js +51 -0
  58. package/dist/tools/handlers/lyrics-handlers.js.map +1 -0
  59. package/dist/tools/handlers/playlist-handlers.d.ts +5 -0
  60. package/dist/tools/handlers/playlist-handlers.d.ts.map +1 -0
  61. package/dist/tools/handlers/playlist-handlers.js +316 -0
  62. package/dist/tools/handlers/playlist-handlers.js.map +1 -0
  63. package/dist/tools/handlers/queue-handlers.d.ts +5 -0
  64. package/dist/tools/handlers/queue-handlers.d.ts.map +1 -0
  65. package/dist/tools/handlers/queue-handlers.js +135 -0
  66. package/dist/tools/handlers/queue-handlers.js.map +1 -0
  67. package/dist/tools/handlers/radio-handlers.d.ts +5 -0
  68. package/dist/tools/handlers/radio-handlers.d.ts.map +1 -0
  69. package/dist/tools/handlers/radio-handlers.js +323 -0
  70. package/dist/tools/handlers/radio-handlers.js.map +1 -0
  71. package/dist/tools/handlers/registry.d.ts +26 -0
  72. package/dist/tools/handlers/registry.d.ts.map +1 -0
  73. package/dist/tools/handlers/registry.js +77 -0
  74. package/dist/tools/handlers/registry.js.map +1 -0
  75. package/dist/tools/handlers/search-handlers.d.ts +5 -0
  76. package/dist/tools/handlers/search-handlers.d.ts.map +1 -0
  77. package/dist/tools/handlers/search-handlers.js +125 -0
  78. package/dist/tools/handlers/search-handlers.js.map +1 -0
  79. package/dist/tools/handlers/tag-handlers.d.ts +5 -0
  80. package/dist/tools/handlers/tag-handlers.d.ts.map +1 -0
  81. package/dist/tools/handlers/tag-handlers.js +155 -0
  82. package/dist/tools/handlers/tag-handlers.js.map +1 -0
  83. package/dist/tools/handlers/user-preferences-handlers.d.ts +5 -0
  84. package/dist/tools/handlers/user-preferences-handlers.d.ts.map +1 -0
  85. package/dist/tools/handlers/user-preferences-handlers.js +155 -0
  86. package/dist/tools/handlers/user-preferences-handlers.js.map +1 -0
  87. package/dist/tools/index.d.ts +19 -0
  88. package/dist/tools/index.d.ts.map +1 -0
  89. package/dist/tools/index.js +20 -0
  90. package/dist/tools/index.js.map +1 -0
  91. package/dist/tools/lastfm-discovery.d.ts +107 -0
  92. package/dist/tools/lastfm-discovery.d.ts.map +1 -0
  93. package/dist/tools/lastfm-discovery.js +238 -0
  94. package/dist/tools/lastfm-discovery.js.map +1 -0
  95. package/dist/tools/library.d.ts +31 -0
  96. package/dist/tools/library.d.ts.map +1 -0
  97. package/dist/tools/library.js +272 -0
  98. package/dist/tools/library.js.map +1 -0
  99. package/dist/tools/listening-history.d.ts +51 -0
  100. package/dist/tools/listening-history.d.ts.map +1 -0
  101. package/dist/tools/listening-history.js +126 -0
  102. package/dist/tools/listening-history.js.map +1 -0
  103. package/dist/tools/lyrics.d.ts +35 -0
  104. package/dist/tools/lyrics.d.ts.map +1 -0
  105. package/dist/tools/lyrics.js +222 -0
  106. package/dist/tools/lyrics.js.map +1 -0
  107. package/dist/tools/media-library.d.ts +46 -0
  108. package/dist/tools/media-library.d.ts.map +1 -0
  109. package/dist/tools/media-library.js +179 -0
  110. package/dist/tools/media-library.js.map +1 -0
  111. package/dist/tools/playlist-management.d.ts +80 -0
  112. package/dist/tools/playlist-management.d.ts.map +1 -0
  113. package/dist/tools/playlist-management.js +384 -0
  114. package/dist/tools/playlist-management.js.map +1 -0
  115. package/dist/tools/queue-management.d.ts +48 -0
  116. package/dist/tools/queue-management.d.ts.map +1 -0
  117. package/dist/tools/queue-management.js +83 -0
  118. package/dist/tools/queue-management.js.map +1 -0
  119. package/dist/tools/radio-discovery.d.ts +95 -0
  120. package/dist/tools/radio-discovery.d.ts.map +1 -0
  121. package/dist/tools/radio-discovery.js +352 -0
  122. package/dist/tools/radio-discovery.js.map +1 -0
  123. package/dist/tools/radio-validation.d.ts +49 -0
  124. package/dist/tools/radio-validation.d.ts.map +1 -0
  125. package/dist/tools/radio-validation.js +463 -0
  126. package/dist/tools/radio-validation.js.map +1 -0
  127. package/dist/tools/radio.d.ts +38 -0
  128. package/dist/tools/radio.d.ts.map +1 -0
  129. package/dist/tools/radio.js +315 -0
  130. package/dist/tools/radio.js.map +1 -0
  131. package/dist/tools/search.d.ts +54 -0
  132. package/dist/tools/search.d.ts.map +1 -0
  133. package/dist/tools/search.js +165 -0
  134. package/dist/tools/search.js.map +1 -0
  135. package/dist/tools/tags.d.ts +63 -0
  136. package/dist/tools/tags.d.ts.map +1 -0
  137. package/dist/tools/tags.js +260 -0
  138. package/dist/tools/tags.js.map +1 -0
  139. package/dist/tools/test.d.ts +50 -0
  140. package/dist/tools/test.d.ts.map +1 -0
  141. package/dist/tools/test.js +121 -0
  142. package/dist/tools/test.js.map +1 -0
  143. package/dist/tools/user-preferences.d.ts +73 -0
  144. package/dist/tools/user-preferences.d.ts.map +1 -0
  145. package/dist/tools/user-preferences.js +231 -0
  146. package/dist/tools/user-preferences.js.map +1 -0
  147. package/dist/transformers/song-transformer.d.ts +122 -0
  148. package/dist/transformers/song-transformer.d.ts.map +1 -0
  149. package/dist/transformers/song-transformer.js +232 -0
  150. package/dist/transformers/song-transformer.js.map +1 -0
  151. package/dist/types/core.d.ts +147 -0
  152. package/dist/types/core.d.ts.map +1 -0
  153. package/dist/types/core.js +19 -0
  154. package/dist/types/core.js.map +1 -0
  155. package/dist/types/index.d.ts +23 -0
  156. package/dist/types/index.d.ts.map +1 -0
  157. package/dist/types/index.js +19 -0
  158. package/dist/types/index.js.map +1 -0
  159. package/dist/types/lyrics.d.ts +58 -0
  160. package/dist/types/lyrics.d.ts.map +1 -0
  161. package/dist/types/lyrics.js +19 -0
  162. package/dist/types/lyrics.js.map +1 -0
  163. package/dist/types/playlists.d.ts +150 -0
  164. package/dist/types/playlists.d.ts.map +1 -0
  165. package/dist/types/playlists.js +19 -0
  166. package/dist/types/playlists.js.map +1 -0
  167. package/dist/types/radio.d.ts +192 -0
  168. package/dist/types/radio.d.ts.map +1 -0
  169. package/dist/types/radio.js +19 -0
  170. package/dist/types/radio.js.map +1 -0
  171. package/dist/types/tags.d.ts +72 -0
  172. package/dist/types/tags.d.ts.map +1 -0
  173. package/dist/types/tags.js +19 -0
  174. package/dist/types/tags.js.map +1 -0
  175. package/dist/utils/cache.d.ts +32 -0
  176. package/dist/utils/cache.d.ts.map +1 -0
  177. package/dist/utils/cache.js +84 -0
  178. package/dist/utils/cache.js.map +1 -0
  179. package/dist/utils/error-formatter.d.ts +108 -0
  180. package/dist/utils/error-formatter.d.ts.map +1 -0
  181. package/dist/utils/error-formatter.js +161 -0
  182. package/dist/utils/error-formatter.js.map +1 -0
  183. package/dist/utils/logger.d.ts +33 -0
  184. package/dist/utils/logger.d.ts.map +1 -0
  185. package/dist/utils/logger.js +52 -0
  186. package/dist/utils/logger.js.map +1 -0
  187. package/dist/utils/message-manager.d.ts +74 -0
  188. package/dist/utils/message-manager.d.ts.map +1 -0
  189. package/dist/utils/message-manager.js +134 -0
  190. package/dist/utils/message-manager.js.map +1 -0
  191. package/dist/utils/version.d.ts +5 -0
  192. package/dist/utils/version.d.ts.map +1 -0
  193. package/dist/utils/version.js +19 -0
  194. package/dist/utils/version.js.map +1 -0
  195. package/package.json +78 -0
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Navidrome MCP Server - Configuration Management
3
+ * Copyright (C) 2025
4
+ *
5
+ * This program is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU Affero General Public License as published
7
+ * by the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU Affero General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU Affero General Public License
16
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+ */
18
+ import { z } from 'zod';
19
+ declare const ConfigSchema: z.ZodObject<{
20
+ navidromeUrl: z.ZodString;
21
+ navidromeUsername: z.ZodString;
22
+ navidromePassword: z.ZodString;
23
+ debug: z.ZodDefault<z.ZodBoolean>;
24
+ cacheTtl: z.ZodDefault<z.ZodNumber>;
25
+ tokenExpiry: z.ZodDefault<z.ZodNumber>;
26
+ features: z.ZodObject<{
27
+ lastfm: z.ZodDefault<z.ZodBoolean>;
28
+ radioBrowser: z.ZodDefault<z.ZodBoolean>;
29
+ lyrics: z.ZodDefault<z.ZodBoolean>;
30
+ }, z.core.$strip>;
31
+ lastFmApiKey: z.ZodOptional<z.ZodString>;
32
+ radioBrowserUserAgent: z.ZodOptional<z.ZodString>;
33
+ radioBrowserBase: z.ZodDefault<z.ZodString>;
34
+ lyricsProvider: z.ZodOptional<z.ZodString>;
35
+ lrclibUserAgent: z.ZodOptional<z.ZodString>;
36
+ lrclibBase: z.ZodDefault<z.ZodString>;
37
+ }, z.core.$strip>;
38
+ export type Config = z.infer<typeof ConfigSchema>;
39
+ export declare function loadConfig(): Promise<Config>;
40
+ export {};
41
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AA4BxB,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;iBAwBhB,CAAC;AAEH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAElD,wBAAsB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CAsElD"}
package/dist/config.js ADDED
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Navidrome MCP Server - Configuration Management
3
+ * Copyright (C) 2025
4
+ *
5
+ * This program is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU Affero General Public License as published
7
+ * by the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU Affero General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU Affero General Public License
16
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+ */
18
+ import { z } from 'zod';
19
+ import { config as loadDotenv } from 'dotenv';
20
+ import { fileURLToPath } from 'url';
21
+ import { dirname, join } from 'path';
22
+ import { ErrorFormatter } from './utils/error-formatter.js';
23
+ import { logger } from './utils/logger.js';
24
+ // Safely load dotenv - it's optional since environment variables
25
+ // can be provided directly (e.g., by Claude MCP configuration)
26
+ try {
27
+ // Try to load from the project root directory
28
+ const __filename = fileURLToPath(import.meta.url);
29
+ const __dirname = dirname(__filename);
30
+ const projectRoot = join(__dirname, '..');
31
+ loadDotenv({
32
+ path: join(projectRoot, '.env'),
33
+ // Don't override existing environment variables
34
+ override: false
35
+ });
36
+ }
37
+ catch (error) {
38
+ // Silently ignore dotenv errors - environment variables may be
39
+ // provided by the MCP host (Claude) directly
40
+ if (process.env['DEBUG'] === 'true') {
41
+ logger.warn('Could not load .env file (this is normal when running as MCP server):', error);
42
+ }
43
+ }
44
+ const ConfigSchema = z.object({
45
+ navidromeUrl: z.string().url('NAVIDROME_URL must be a valid URL'),
46
+ navidromeUsername: z.string().min(1, 'NAVIDROME_USERNAME is required'),
47
+ navidromePassword: z.string().min(1, 'NAVIDROME_PASSWORD is required'),
48
+ debug: z.boolean().default(false),
49
+ cacheTtl: z.number().positive().default(300),
50
+ tokenExpiry: z.number().positive().default(86400), // Default 24 hours in seconds
51
+ // Feature Configuration
52
+ features: z.object({
53
+ lastfm: z.boolean().default(false),
54
+ radioBrowser: z.boolean().default(false),
55
+ lyrics: z.boolean().default(false),
56
+ }),
57
+ // API Keys and External Service Configuration
58
+ lastFmApiKey: z.string().optional(),
59
+ radioBrowserUserAgent: z.string().optional(),
60
+ radioBrowserBase: z.string().url().default('https://de1.api.radio-browser.info'),
61
+ // Lyrics Configuration
62
+ lyricsProvider: z.string().optional(),
63
+ lrclibUserAgent: z.string().optional(),
64
+ lrclibBase: z.string().url().default('https://lrclib.net'),
65
+ });
66
+ export async function loadConfig() {
67
+ // Try to safely load .env file only in development mode
68
+ // MCP servers get their environment from the host application
69
+ if (!process.env['NAVIDROME_URL']) {
70
+ // Only attempt to load .env if we're missing required environment variables
71
+ // This suggests we're in development mode
72
+ try {
73
+ // Use import.meta.url to get absolute path, avoiding process.cwd() entirely
74
+ const __filename = fileURLToPath(import.meta.url);
75
+ const __dirname = dirname(__filename);
76
+ const projectRoot = join(__dirname, '..');
77
+ const envPath = join(projectRoot, '.env');
78
+ // Check if we can actually access the file system
79
+ // This will fail gracefully if we can't
80
+ loadDotenv({
81
+ path: envPath,
82
+ // Don't override existing environment variables
83
+ override: false
84
+ });
85
+ }
86
+ catch {
87
+ // Silently ignore dotenv errors - environment variables should be
88
+ // provided by the MCP host (Claude Desktop) directly
89
+ if (process.env['DEBUG'] === 'true') {
90
+ logger.warn('Could not load .env file (this is expected when running as MCP server)');
91
+ }
92
+ }
93
+ }
94
+ // Centralized environment variable access
95
+ const lastFmApiKey = process.env['LASTFM_API_KEY'] || undefined;
96
+ const radioBrowserUserAgent = process.env['RADIO_BROWSER_USER_AGENT'] || undefined;
97
+ const lyricsProvider = process.env['LYRICS_PROVIDER'] || undefined;
98
+ const lrclibUserAgent = process.env['LRCLIB_USER_AGENT'] || undefined;
99
+ const rawConfig = {
100
+ navidromeUrl: process.env['NAVIDROME_URL'],
101
+ navidromeUsername: process.env['NAVIDROME_USERNAME'],
102
+ navidromePassword: process.env['NAVIDROME_PASSWORD'],
103
+ debug: process.env['DEBUG'] === 'true',
104
+ cacheTtl: process.env['CACHE_TTL'] ? parseInt(process.env['CACHE_TTL'], 10) : 300,
105
+ tokenExpiry: process.env['TOKEN_EXPIRY'] ? parseInt(process.env['TOKEN_EXPIRY'], 10) : 86400,
106
+ // Feature detection based on available configuration
107
+ features: {
108
+ lastfm: !!(lastFmApiKey && lastFmApiKey.trim()),
109
+ radioBrowser: !!(radioBrowserUserAgent && radioBrowserUserAgent.trim()),
110
+ lyrics: !!(lyricsProvider && lyricsProvider.trim() && lrclibUserAgent && lrclibUserAgent.trim()),
111
+ },
112
+ // API Keys and External Service Configuration
113
+ lastFmApiKey,
114
+ radioBrowserUserAgent,
115
+ radioBrowserBase: process.env['RADIO_BROWSER_BASE'] || 'https://de1.api.radio-browser.info',
116
+ // Lyrics Configuration
117
+ lyricsProvider,
118
+ lrclibUserAgent,
119
+ lrclibBase: process.env['LRCLIB_BASE'] || 'https://lrclib.net',
120
+ };
121
+ try {
122
+ return ConfigSchema.parse(rawConfig);
123
+ }
124
+ catch (error) {
125
+ if (error instanceof z.ZodError) {
126
+ const messages = error.issues.map((e) => `${e.path.join('.')}: ${e.message}`);
127
+ throw new Error(ErrorFormatter.configValidation(messages));
128
+ }
129
+ throw error;
130
+ }
131
+ }
132
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Default record counts for MCP server endpoints
3
+ *
4
+ * Centralized configuration for default result limits to make them easy to adjust.
5
+ * Higher defaults (100 instead of 20) help prevent missing results when building playlists or searching.
6
+ */
7
+ export declare const DEFAULT_VALUES: {
8
+ readonly SONGS_LIMIT: 100;
9
+ readonly ALBUMS_LIMIT: 100;
10
+ readonly PLAYLISTS_LIMIT: 100;
11
+ readonly SEARCH_LIMIT: 100;
12
+ readonly SEARCH_ALL_LIMIT: 100;
13
+ readonly PLAYLIST_TRACKS_LIMIT: 100;
14
+ readonly STARRED_ITEMS_LIMIT: 100;
15
+ readonly TOP_RATED_LIMIT: 100;
16
+ readonly RECENTLY_PLAYED_LIMIT: 100;
17
+ readonly MOST_PLAYED_LIMIT: 100;
18
+ readonly SIMILAR_ARTISTS_LIMIT: 100;
19
+ readonly SIMILAR_TRACKS_LIMIT: 100;
20
+ readonly TOP_TRACKS_BY_ARTIST_LIMIT: 100;
21
+ readonly TRENDING_MUSIC_LIMIT: 100;
22
+ readonly TAGS_LIMIT: 100;
23
+ readonly TAG_SEARCH_LIMIT: 100;
24
+ readonly TAG_DISTRIBUTION_LIMIT: 10;
25
+ readonly TAG_DISTRIBUTION_VALUES_LIMIT: 20;
26
+ readonly UNIQUE_TAGS_LIMIT: 100;
27
+ readonly RADIO_DISCOVERY_LIMIT: 15;
28
+ };
29
+ //# sourceMappingURL=defaults.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/constants/defaults.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;CAoCjB,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Default record counts for MCP server endpoints
3
+ *
4
+ * Centralized configuration for default result limits to make them easy to adjust.
5
+ * Higher defaults (100 instead of 20) help prevent missing results when building playlists or searching.
6
+ */
7
+ export const DEFAULT_VALUES = {
8
+ // Core list endpoints - increased from 20 to 100 to avoid missing results
9
+ SONGS_LIMIT: 100,
10
+ ALBUMS_LIMIT: 100,
11
+ PLAYLISTS_LIMIT: 100,
12
+ // Search endpoints - increased from 20 to 100 for better search coverage
13
+ SEARCH_LIMIT: 100,
14
+ SEARCH_ALL_LIMIT: 100, // for artistCount, albumCount, songCount in search_all
15
+ // Playlist endpoints
16
+ PLAYLIST_TRACKS_LIMIT: 100,
17
+ // Ratings and favorites
18
+ STARRED_ITEMS_LIMIT: 100,
19
+ TOP_RATED_LIMIT: 100,
20
+ // Activity tracking
21
+ RECENTLY_PLAYED_LIMIT: 100,
22
+ MOST_PLAYED_LIMIT: 100,
23
+ // External API integrations
24
+ SIMILAR_ARTISTS_LIMIT: 100,
25
+ SIMILAR_TRACKS_LIMIT: 100,
26
+ TOP_TRACKS_BY_ARTIST_LIMIT: 100,
27
+ TRENDING_MUSIC_LIMIT: 100,
28
+ // Tag management
29
+ TAGS_LIMIT: 100,
30
+ TAG_SEARCH_LIMIT: 100,
31
+ TAG_DISTRIBUTION_LIMIT: 10, // for analysis, keep reasonable
32
+ TAG_DISTRIBUTION_VALUES_LIMIT: 20, // max values per tag
33
+ UNIQUE_TAGS_LIMIT: 100,
34
+ // Radio discovery
35
+ RADIO_DISCOVERY_LIMIT: 15, // optimal for discovery without overwhelming
36
+ };
37
+ //# sourceMappingURL=defaults.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defaults.js","sourceRoot":"","sources":["../../src/constants/defaults.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,0EAA0E;IAC1E,WAAW,EAAE,GAAG;IAChB,YAAY,EAAE,GAAG;IACjB,eAAe,EAAE,GAAG;IAEpB,yEAAyE;IACzE,YAAY,EAAE,GAAG;IACjB,gBAAgB,EAAE,GAAG,EAAE,uDAAuD;IAE9E,qBAAqB;IACrB,qBAAqB,EAAE,GAAG;IAE1B,wBAAwB;IACxB,mBAAmB,EAAE,GAAG;IACxB,eAAe,EAAE,GAAG;IAEpB,oBAAoB;IACpB,qBAAqB,EAAE,GAAG;IAC1B,iBAAiB,EAAE,GAAG;IAEtB,4BAA4B;IAC5B,qBAAqB,EAAE,GAAG;IAC1B,oBAAoB,EAAE,GAAG;IACzB,0BAA0B,EAAE,GAAG;IAC/B,oBAAoB,EAAE,GAAG;IAEzB,iBAAiB;IACjB,UAAU,EAAE,GAAG;IACf,gBAAgB,EAAE,GAAG;IACrB,sBAAsB,EAAE,EAAE,EAAE,gCAAgC;IAC5D,6BAA6B,EAAE,EAAE,EAAE,qBAAqB;IACxD,iBAAiB,EAAE,GAAG;IAEtB,kBAAkB;IAClB,qBAAqB,EAAE,EAAE,EAAE,6CAA6C;CAChE,CAAC"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Timeout constants for radio stream validation operations
3
+ *
4
+ * Different timeout values based on operation context to balance
5
+ * thoroughness with performance and user experience.
6
+ */
7
+ /**
8
+ * Timeout for single, explicit validation operations
9
+ * Used when user specifically requests validation of a stream
10
+ * Higher timeout allows for more thorough testing
11
+ */
12
+ export declare const SINGLE_VALIDATION_TIMEOUT = 8000;
13
+ /**
14
+ * Timeout for batch validation operations
15
+ * Used when validating multiple streams in batch operations
16
+ * Balanced timeout to avoid excessive wait times for multiple validations
17
+ */
18
+ export declare const BATCH_VALIDATION_TIMEOUT = 3000;
19
+ /**
20
+ * Timeout for discovery validation operations
21
+ * Used when auto-validating discovered radio stations
22
+ * Lower timeout for quick feedback when validating many discovered stations
23
+ */
24
+ export declare const DISCOVERY_VALIDATION_TIMEOUT = 2000;
25
+ /**
26
+ * Maximum allowed timeout for any validation operation
27
+ * Hard limit to prevent excessively long waits
28
+ */
29
+ export declare const MAX_VALIDATION_TIMEOUT = 30000;
30
+ /**
31
+ * Minimum allowed timeout for any validation operation
32
+ * Ensures sufficient time for network operations
33
+ */
34
+ export declare const MIN_VALIDATION_TIMEOUT = 1000;
35
+ /**
36
+ * Radio stream validation timing and buffer constants
37
+ * Used internally by the validation process for optimal performance
38
+ */
39
+ export declare const RADIO_VALIDATION: {
40
+ /**
41
+ * Ratio of total timeout to allocate for HEAD request
42
+ * 60% of total timeout allows time for subsequent audio sampling
43
+ */
44
+ readonly HEAD_TIMEOUT_RATIO: 0.6;
45
+ /**
46
+ * Minimum timeout for audio sampling phase
47
+ * Ensures sufficient time to detect audio content even with slow connections
48
+ */
49
+ readonly MIN_SAMPLE_TIMEOUT: 2000;
50
+ /**
51
+ * Buffer size for audio content sampling
52
+ * 8KB provides good balance between detection accuracy and efficiency
53
+ */
54
+ readonly SAMPLE_BUFFER_SIZE: 8192;
55
+ /**
56
+ * Timeout for reading stream content during validation
57
+ * Prevents hanging on non-responsive streams during content analysis
58
+ */
59
+ readonly STREAM_READ_TIMEOUT: 3000;
60
+ /**
61
+ * Fallback HEAD timeout when calculated value would be too high
62
+ * Prevents excessive wait times for HEAD requests
63
+ */
64
+ readonly FALLBACK_HEAD_TIMEOUT: 4000;
65
+ };
66
+ //# sourceMappingURL=timeouts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeouts.d.ts","sourceRoot":"","sources":["../../src/constants/timeouts.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,OAAO,CAAC;AAE9C;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAE7C;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,OAAO,CAAC;AAEjD;;;GAGG;AACH,eAAO,MAAM,sBAAsB,QAAQ,CAAC;AAE5C;;;GAGG;AACH,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAE3C;;;GAGG;AACH,eAAO,MAAM,gBAAgB;IAC3B;;;OAGG;;IAGH;;;OAGG;;IAGH;;;OAGG;;IAGH;;;OAGG;;IAGH;;;OAGG;;CAEK,CAAC"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Timeout constants for radio stream validation operations
3
+ *
4
+ * Different timeout values based on operation context to balance
5
+ * thoroughness with performance and user experience.
6
+ */
7
+ /**
8
+ * Timeout for single, explicit validation operations
9
+ * Used when user specifically requests validation of a stream
10
+ * Higher timeout allows for more thorough testing
11
+ */
12
+ export const SINGLE_VALIDATION_TIMEOUT = 8000; // 8 seconds
13
+ /**
14
+ * Timeout for batch validation operations
15
+ * Used when validating multiple streams in batch operations
16
+ * Balanced timeout to avoid excessive wait times for multiple validations
17
+ */
18
+ export const BATCH_VALIDATION_TIMEOUT = 3000; // 3 seconds
19
+ /**
20
+ * Timeout for discovery validation operations
21
+ * Used when auto-validating discovered radio stations
22
+ * Lower timeout for quick feedback when validating many discovered stations
23
+ */
24
+ export const DISCOVERY_VALIDATION_TIMEOUT = 2000; // 2 seconds
25
+ /**
26
+ * Maximum allowed timeout for any validation operation
27
+ * Hard limit to prevent excessively long waits
28
+ */
29
+ export const MAX_VALIDATION_TIMEOUT = 30000; // 30 seconds
30
+ /**
31
+ * Minimum allowed timeout for any validation operation
32
+ * Ensures sufficient time for network operations
33
+ */
34
+ export const MIN_VALIDATION_TIMEOUT = 1000; // 1 second
35
+ /**
36
+ * Radio stream validation timing and buffer constants
37
+ * Used internally by the validation process for optimal performance
38
+ */
39
+ export const RADIO_VALIDATION = {
40
+ /**
41
+ * Ratio of total timeout to allocate for HEAD request
42
+ * 60% of total timeout allows time for subsequent audio sampling
43
+ */
44
+ HEAD_TIMEOUT_RATIO: 0.6,
45
+ /**
46
+ * Minimum timeout for audio sampling phase
47
+ * Ensures sufficient time to detect audio content even with slow connections
48
+ */
49
+ MIN_SAMPLE_TIMEOUT: 2000, // 2 seconds
50
+ /**
51
+ * Buffer size for audio content sampling
52
+ * 8KB provides good balance between detection accuracy and efficiency
53
+ */
54
+ SAMPLE_BUFFER_SIZE: 8192, // 8KB
55
+ /**
56
+ * Timeout for reading stream content during validation
57
+ * Prevents hanging on non-responsive streams during content analysis
58
+ */
59
+ STREAM_READ_TIMEOUT: 3000, // 3 seconds
60
+ /**
61
+ * Fallback HEAD timeout when calculated value would be too high
62
+ * Prevents excessive wait times for HEAD requests
63
+ */
64
+ FALLBACK_HEAD_TIMEOUT: 4000, // 4 seconds
65
+ };
66
+ //# sourceMappingURL=timeouts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timeouts.js","sourceRoot":"","sources":["../../src/constants/timeouts.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;GAIG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,IAAI,CAAC,CAAC,YAAY;AAE3D;;;;GAIG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,CAAC,CAAC,YAAY;AAE1D;;;;GAIG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,IAAI,CAAC,CAAC,YAAY;AAE9D;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,CAAC,CAAC,aAAa;AAE1D;;;GAGG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,IAAI,CAAC,CAAC,WAAW;AAEvD;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B;;;OAGG;IACH,kBAAkB,EAAE,GAAG;IAEvB;;;OAGG;IACH,kBAAkB,EAAE,IAAI,EAAE,YAAY;IAEtC;;;OAGG;IACH,kBAAkB,EAAE,IAAI,EAAE,MAAM;IAEhC;;;OAGG;IACH,mBAAmB,EAAE,IAAI,EAAE,YAAY;IAEvC;;;OAGG;IACH,qBAAqB,EAAE,IAAI,EAAE,YAAY;CACjC,CAAC"}
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Navidrome MCP Server
4
+ * Copyright (C) 2025
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU Affero General Public License as published
8
+ * by the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ * GNU Affero General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Affero General Public License
17
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
18
+ */
19
+ export {};
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;GAgBG"}
package/dist/index.js ADDED
@@ -0,0 +1,70 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Navidrome MCP Server
4
+ * Copyright (C) 2025
5
+ *
6
+ * This program is free software: you can redistribute it and/or modify
7
+ * it under the terms of the GNU Affero General Public License as published
8
+ * by the Free Software Foundation, either version 3 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ * GNU Affero General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Affero General Public License
17
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
18
+ */
19
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
20
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
21
+ import { loadConfig } from './config.js';
22
+ import { registerTools } from './tools/index.js';
23
+ import { registerResources } from './resources/index.js';
24
+ import { NavidromeClient } from './client/navidrome-client.js';
25
+ import { logger } from './utils/logger.js';
26
+ import { getPackageVersion } from './utils/version.js';
27
+ import { MCP_CAPABILITIES } from './capabilities.js';
28
+ async function main() {
29
+ try {
30
+ const config = await loadConfig();
31
+ logger.setDebug(config.debug);
32
+ // Add startup diagnostics for troubleshooting
33
+ logger.debug('Starting Navidrome MCP Server...');
34
+ logger.debug('Node version:', process.version);
35
+ logger.debug('Platform:', process.platform);
36
+ logger.debug('Environment variables present:', {
37
+ NAVIDROME_URL: !!process.env['NAVIDROME_URL'],
38
+ NAVIDROME_USERNAME: !!process.env['NAVIDROME_USERNAME'],
39
+ NAVIDROME_PASSWORD: !!process.env['NAVIDROME_PASSWORD'],
40
+ });
41
+ const server = new Server({
42
+ name: 'navidrome-mcp',
43
+ version: getPackageVersion(),
44
+ }, {
45
+ capabilities: MCP_CAPABILITIES,
46
+ });
47
+ const client = new NavidromeClient(config);
48
+ await client.initialize();
49
+ registerTools(server, client, config);
50
+ registerResources(server, client);
51
+ const transport = new StdioServerTransport();
52
+ await server.connect(transport);
53
+ logger.info('Navidrome MCP Server started successfully');
54
+ }
55
+ catch (error) {
56
+ // Provide detailed error information for debugging
57
+ logger.error('Failed to start Navidrome MCP Server');
58
+ logger.error('Error details:', error);
59
+ if (error instanceof Error) {
60
+ logger.error('Error message:', error.message);
61
+ logger.error('Stack trace:', error.stack);
62
+ }
63
+ throw error; // Re-throw to be caught by outer handler
64
+ }
65
+ }
66
+ main().catch((error) => {
67
+ logger.error('Failed to start server:', error);
68
+ process.exit(1);
69
+ });
70
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;QAClC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAE9B,8CAA8C;QAC9C,MAAM,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACjD,MAAM,CAAC,KAAK,CAAC,eAAe,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAC/C,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC5C,MAAM,CAAC,KAAK,CAAC,gCAAgC,EAAE;YAC7C,aAAa,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;YAC7C,kBAAkB,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;YACvD,kBAAkB,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;SACxD,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB;YACE,IAAI,EAAE,eAAe;YACrB,OAAO,EAAE,iBAAiB,EAAE;SAC7B,EACD;YACE,YAAY,EAAE,gBAAgB;SAC/B,CACF,CAAC;QAEF,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;QAC3C,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;QAE1B,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QACtC,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAElC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAEhC,MAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;IAC3D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,mDAAmD;QACnD,MAAM,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;QACrD,MAAM,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;QACtC,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,MAAM,CAAC,KAAK,CAAC,gBAAgB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;YAC9C,MAAM,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QAC5C,CAAC;QACD,MAAM,KAAK,CAAC,CAAC,yCAAyC;IACxD,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,MAAM,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;IAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Navidrome MCP Server - Resource Registry
3
+ * Copyright (C) 2025
4
+ *
5
+ * This program is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU Affero General Public License as published
7
+ * by the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU Affero General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU Affero General Public License
16
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+ */
18
+ import type { Server } from '@modelcontextprotocol/sdk/server/index.js';
19
+ import type { NavidromeClient } from '../client/navidrome-client.js';
20
+ export declare function registerResources(server: Server, client: NavidromeClient): void;
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAQrE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,IAAI,CA4E/E"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Navidrome MCP Server - Resource Registry
3
+ * Copyright (C) 2025
4
+ *
5
+ * This program is free software: you can redistribute it and/or modify
6
+ * it under the terms of the GNU Affero General Public License as published
7
+ * by the Free Software Foundation, either version 3 of the License, or
8
+ * (at your option) any later version.
9
+ *
10
+ * This program is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ * GNU Affero General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU Affero General Public License
16
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
17
+ */
18
+ import { ListResourcesRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
19
+ import { ErrorFormatter } from '../utils/error-formatter.js';
20
+ export function registerResources(server, client) {
21
+ // Define available resources
22
+ const resources = [
23
+ {
24
+ uri: 'navidrome://server/status',
25
+ name: 'Server Status',
26
+ description: 'Navidrome server connection status',
27
+ mimeType: 'application/json',
28
+ },
29
+ ];
30
+ // Register list resources handler
31
+ server.setRequestHandler(ListResourcesRequestSchema, async () => ({
32
+ resources,
33
+ }));
34
+ // Register read resource handler
35
+ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
36
+ const { uri } = request.params;
37
+ // Parse URI to handle query parameters
38
+ const baseUri = uri.split('?')[0];
39
+ if (baseUri === 'navidrome://server/status') {
40
+ try {
41
+ // Test connectivity using our working /song endpoint with minimal request
42
+ const queryParams = new URLSearchParams({
43
+ _start: '0',
44
+ _end: '1', // Just get 1 song to test connectivity
45
+ });
46
+ await client.request(`/song?${queryParams.toString()}`);
47
+ return {
48
+ contents: [
49
+ {
50
+ uri,
51
+ mimeType: 'application/json',
52
+ text: JSON.stringify({
53
+ status: 'connected',
54
+ server: 'Navidrome',
55
+ timestamp: new Date().toISOString(),
56
+ message: 'Successfully connected to Navidrome server',
57
+ }, null, 2),
58
+ },
59
+ ],
60
+ };
61
+ }
62
+ catch (error) {
63
+ return {
64
+ contents: [
65
+ {
66
+ uri,
67
+ mimeType: 'application/json',
68
+ text: JSON.stringify({
69
+ status: 'error',
70
+ server: 'Navidrome',
71
+ timestamp: new Date().toISOString(),
72
+ error: 'Failed to connect to Navidrome server',
73
+ message: error instanceof Error ? error.message : 'Unknown error',
74
+ }, null, 2),
75
+ },
76
+ ],
77
+ };
78
+ }
79
+ }
80
+ throw new Error(ErrorFormatter.unknownResource(baseUri || uri));
81
+ });
82
+ }
83
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,GAE1B,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAE7D,MAAM,UAAU,iBAAiB,CAAC,MAAc,EAAE,MAAuB;IACvE,6BAA6B;IAC7B,MAAM,SAAS,GAAe;QAC5B;YACE,GAAG,EAAE,2BAA2B;YAChC,IAAI,EAAE,eAAe;YACrB,WAAW,EAAE,oCAAoC;YACjD,QAAQ,EAAE,kBAAkB;SAC7B;KACF,CAAC;IAEF,kCAAkC;IAClC,MAAM,CAAC,iBAAiB,CAAC,0BAA0B,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QAChE,SAAS;KACV,CAAC,CAAC,CAAC;IAEJ,iCAAiC;IACjC,MAAM,CAAC,iBAAiB,CAAC,yBAAyB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACpE,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QAE/B,uCAAuC;QACvC,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAGlC,IAAI,OAAO,KAAK,2BAA2B,EAAE,CAAC;YAC5C,IAAI,CAAC;gBACH,0EAA0E;gBAC1E,MAAM,WAAW,GAAG,IAAI,eAAe,CAAC;oBACtC,MAAM,EAAE,GAAG;oBACX,IAAI,EAAE,GAAG,EAAE,uCAAuC;iBACnD,CAAC,CAAC;gBAEH,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;gBACxD,OAAO;oBACL,QAAQ,EAAE;wBACR;4BACE,GAAG;4BACH,QAAQ,EAAE,kBAAkB;4BAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;gCACE,MAAM,EAAE,WAAW;gCACnB,MAAM,EAAE,WAAW;gCACnB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gCACnC,OAAO,EAAE,4CAA4C;6BACtD,EACD,IAAI,EACJ,CAAC,CACF;yBACF;qBACF;iBACF,CAAC;YACJ,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO;oBACL,QAAQ,EAAE;wBACR;4BACE,GAAG;4BACH,QAAQ,EAAE,kBAAkB;4BAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;gCACE,MAAM,EAAE,OAAO;gCACf,MAAM,EAAE,WAAW;gCACnB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gCACnC,KAAK,EAAE,uCAAuC;gCAC9C,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;6BAClE,EACD,IAAI,EACJ,CAAC,CACF;yBACF;qBACF;iBACF,CAAC;YACJ,CAAC;QACH,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,eAAe,CAAC,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;AACL,CAAC"}