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.
- package/LICENSE +661 -0
- package/README.md +397 -0
- package/dist/capabilities.d.ts +20 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/capabilities.js +25 -0
- package/dist/capabilities.js.map +1 -0
- package/dist/client/auth-manager.d.ts +27 -0
- package/dist/client/auth-manager.d.ts.map +1 -0
- package/dist/client/auth-manager.js +54 -0
- package/dist/client/auth-manager.js.map +1 -0
- package/dist/client/navidrome-client.d.ts +28 -0
- package/dist/client/navidrome-client.d.ts.map +1 -0
- package/dist/client/navidrome-client.js +84 -0
- package/dist/client/navidrome-client.js.map +1 -0
- package/dist/config.d.ts +41 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +132 -0
- package/dist/config.js.map +1 -0
- package/dist/constants/defaults.d.ts +29 -0
- package/dist/constants/defaults.d.ts.map +1 -0
- package/dist/constants/defaults.js +37 -0
- package/dist/constants/defaults.js.map +1 -0
- package/dist/constants/timeouts.d.ts +66 -0
- package/dist/constants/timeouts.d.ts.map +1 -0
- package/dist/constants/timeouts.js +66 -0
- package/dist/constants/timeouts.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +70 -0
- package/dist/index.js.map +1 -0
- package/dist/resources/index.d.ts +21 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +83 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/schemas/common.d.ts +68 -0
- package/dist/schemas/common.d.ts.map +1 -0
- package/dist/schemas/common.js +69 -0
- package/dist/schemas/common.js.map +1 -0
- package/dist/schemas/index.d.ts +21 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +24 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/pagination.d.ts +153 -0
- package/dist/schemas/pagination.d.ts.map +1 -0
- package/dist/schemas/pagination.js +93 -0
- package/dist/schemas/pagination.js.map +1 -0
- package/dist/schemas/validation.d.ts +147 -0
- package/dist/schemas/validation.d.ts.map +1 -0
- package/dist/schemas/validation.js +143 -0
- package/dist/schemas/validation.js.map +1 -0
- package/dist/tools/handlers/lastfm-handlers.d.ts +5 -0
- package/dist/tools/handlers/lastfm-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/lastfm-handlers.js +143 -0
- package/dist/tools/handlers/lastfm-handlers.js.map +1 -0
- package/dist/tools/handlers/lyrics-handlers.d.ts +5 -0
- package/dist/tools/handlers/lyrics-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/lyrics-handlers.js +51 -0
- package/dist/tools/handlers/lyrics-handlers.js.map +1 -0
- package/dist/tools/handlers/playlist-handlers.d.ts +5 -0
- package/dist/tools/handlers/playlist-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/playlist-handlers.js +316 -0
- package/dist/tools/handlers/playlist-handlers.js.map +1 -0
- package/dist/tools/handlers/queue-handlers.d.ts +5 -0
- package/dist/tools/handlers/queue-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/queue-handlers.js +135 -0
- package/dist/tools/handlers/queue-handlers.js.map +1 -0
- package/dist/tools/handlers/radio-handlers.d.ts +5 -0
- package/dist/tools/handlers/radio-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/radio-handlers.js +323 -0
- package/dist/tools/handlers/radio-handlers.js.map +1 -0
- package/dist/tools/handlers/registry.d.ts +26 -0
- package/dist/tools/handlers/registry.d.ts.map +1 -0
- package/dist/tools/handlers/registry.js +77 -0
- package/dist/tools/handlers/registry.js.map +1 -0
- package/dist/tools/handlers/search-handlers.d.ts +5 -0
- package/dist/tools/handlers/search-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/search-handlers.js +125 -0
- package/dist/tools/handlers/search-handlers.js.map +1 -0
- package/dist/tools/handlers/tag-handlers.d.ts +5 -0
- package/dist/tools/handlers/tag-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/tag-handlers.js +155 -0
- package/dist/tools/handlers/tag-handlers.js.map +1 -0
- package/dist/tools/handlers/user-preferences-handlers.d.ts +5 -0
- package/dist/tools/handlers/user-preferences-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/user-preferences-handlers.js +155 -0
- package/dist/tools/handlers/user-preferences-handlers.js.map +1 -0
- package/dist/tools/index.d.ts +19 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +20 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/lastfm-discovery.d.ts +107 -0
- package/dist/tools/lastfm-discovery.d.ts.map +1 -0
- package/dist/tools/lastfm-discovery.js +238 -0
- package/dist/tools/lastfm-discovery.js.map +1 -0
- package/dist/tools/library.d.ts +31 -0
- package/dist/tools/library.d.ts.map +1 -0
- package/dist/tools/library.js +272 -0
- package/dist/tools/library.js.map +1 -0
- package/dist/tools/listening-history.d.ts +51 -0
- package/dist/tools/listening-history.d.ts.map +1 -0
- package/dist/tools/listening-history.js +126 -0
- package/dist/tools/listening-history.js.map +1 -0
- package/dist/tools/lyrics.d.ts +35 -0
- package/dist/tools/lyrics.d.ts.map +1 -0
- package/dist/tools/lyrics.js +222 -0
- package/dist/tools/lyrics.js.map +1 -0
- package/dist/tools/media-library.d.ts +46 -0
- package/dist/tools/media-library.d.ts.map +1 -0
- package/dist/tools/media-library.js +179 -0
- package/dist/tools/media-library.js.map +1 -0
- package/dist/tools/playlist-management.d.ts +80 -0
- package/dist/tools/playlist-management.d.ts.map +1 -0
- package/dist/tools/playlist-management.js +384 -0
- package/dist/tools/playlist-management.js.map +1 -0
- package/dist/tools/queue-management.d.ts +48 -0
- package/dist/tools/queue-management.d.ts.map +1 -0
- package/dist/tools/queue-management.js +83 -0
- package/dist/tools/queue-management.js.map +1 -0
- package/dist/tools/radio-discovery.d.ts +95 -0
- package/dist/tools/radio-discovery.d.ts.map +1 -0
- package/dist/tools/radio-discovery.js +352 -0
- package/dist/tools/radio-discovery.js.map +1 -0
- package/dist/tools/radio-validation.d.ts +49 -0
- package/dist/tools/radio-validation.d.ts.map +1 -0
- package/dist/tools/radio-validation.js +463 -0
- package/dist/tools/radio-validation.js.map +1 -0
- package/dist/tools/radio.d.ts +38 -0
- package/dist/tools/radio.d.ts.map +1 -0
- package/dist/tools/radio.js +315 -0
- package/dist/tools/radio.js.map +1 -0
- package/dist/tools/search.d.ts +54 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +165 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/tags.d.ts +63 -0
- package/dist/tools/tags.d.ts.map +1 -0
- package/dist/tools/tags.js +260 -0
- package/dist/tools/tags.js.map +1 -0
- package/dist/tools/test.d.ts +50 -0
- package/dist/tools/test.d.ts.map +1 -0
- package/dist/tools/test.js +121 -0
- package/dist/tools/test.js.map +1 -0
- package/dist/tools/user-preferences.d.ts +73 -0
- package/dist/tools/user-preferences.d.ts.map +1 -0
- package/dist/tools/user-preferences.js +231 -0
- package/dist/tools/user-preferences.js.map +1 -0
- package/dist/transformers/song-transformer.d.ts +122 -0
- package/dist/transformers/song-transformer.d.ts.map +1 -0
- package/dist/transformers/song-transformer.js +232 -0
- package/dist/transformers/song-transformer.js.map +1 -0
- package/dist/types/core.d.ts +147 -0
- package/dist/types/core.d.ts.map +1 -0
- package/dist/types/core.js +19 -0
- package/dist/types/core.js.map +1 -0
- package/dist/types/index.d.ts +23 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +19 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/lyrics.d.ts +58 -0
- package/dist/types/lyrics.d.ts.map +1 -0
- package/dist/types/lyrics.js +19 -0
- package/dist/types/lyrics.js.map +1 -0
- package/dist/types/playlists.d.ts +150 -0
- package/dist/types/playlists.d.ts.map +1 -0
- package/dist/types/playlists.js +19 -0
- package/dist/types/playlists.js.map +1 -0
- package/dist/types/radio.d.ts +192 -0
- package/dist/types/radio.d.ts.map +1 -0
- package/dist/types/radio.js +19 -0
- package/dist/types/radio.js.map +1 -0
- package/dist/types/tags.d.ts +72 -0
- package/dist/types/tags.d.ts.map +1 -0
- package/dist/types/tags.js +19 -0
- package/dist/types/tags.js.map +1 -0
- package/dist/utils/cache.d.ts +32 -0
- package/dist/utils/cache.d.ts.map +1 -0
- package/dist/utils/cache.js +84 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/error-formatter.d.ts +108 -0
- package/dist/utils/error-formatter.d.ts.map +1 -0
- package/dist/utils/error-formatter.js +161 -0
- package/dist/utils/error-formatter.js.map +1 -0
- package/dist/utils/logger.d.ts +33 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +52 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/message-manager.d.ts +74 -0
- package/dist/utils/message-manager.d.ts.map +1 -0
- package/dist/utils/message-manager.js +134 -0
- package/dist/utils/message-manager.js.map +1 -0
- package/dist/utils/version.d.ts +5 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +19 -0
- package/dist/utils/version.js.map +1 -0
- package/package.json +78 -0
package/dist/config.d.ts
ADDED
|
@@ -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"}
|
package/dist/index.d.ts
ADDED
|
@@ -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"}
|