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
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
import { DEFAULT_VALUES } from '../../constants/defaults.js';
|
|
2
|
+
import { ErrorFormatter } from '../../utils/error-formatter.js';
|
|
3
|
+
// Import tool functions
|
|
4
|
+
import { listRadioStations, createRadioStation, deleteRadioStation, getRadioStation, playRadioStation, getCurrentRadioInfo, batchCreateRadioStations, } from '../radio.js';
|
|
5
|
+
import { validateRadioStream } from '../radio-validation.js';
|
|
6
|
+
import { discoverRadioStations, getRadioFilters, getStationByUuid, clickStation, voteStation, } from '../radio-discovery.js';
|
|
7
|
+
// Helper function to get radio tools based on config
|
|
8
|
+
function getRadioTools(config) {
|
|
9
|
+
const baseTools = [
|
|
10
|
+
{
|
|
11
|
+
name: 'list_radio_stations',
|
|
12
|
+
description: 'List all internet radio stations from Navidrome',
|
|
13
|
+
inputSchema: {
|
|
14
|
+
type: 'object',
|
|
15
|
+
properties: {},
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
name: 'create_radio_station',
|
|
20
|
+
description: 'Create a new internet radio station in Navidrome',
|
|
21
|
+
inputSchema: {
|
|
22
|
+
type: 'object',
|
|
23
|
+
properties: {
|
|
24
|
+
name: {
|
|
25
|
+
type: 'string',
|
|
26
|
+
description: 'Station name (required)',
|
|
27
|
+
},
|
|
28
|
+
streamUrl: {
|
|
29
|
+
type: 'string',
|
|
30
|
+
description: 'Stream URL (required) - must be valid HTTP/HTTPS URL',
|
|
31
|
+
},
|
|
32
|
+
homePageUrl: {
|
|
33
|
+
type: 'string',
|
|
34
|
+
description: 'Optional homepage URL for the station',
|
|
35
|
+
},
|
|
36
|
+
validateBeforeAdd: {
|
|
37
|
+
type: 'boolean',
|
|
38
|
+
description: 'Validate stream URL before adding (default: false)',
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
required: ['name', 'streamUrl'],
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: 'delete_radio_station',
|
|
46
|
+
description: 'Delete an internet radio station by ID',
|
|
47
|
+
inputSchema: {
|
|
48
|
+
type: 'object',
|
|
49
|
+
properties: {
|
|
50
|
+
id: {
|
|
51
|
+
type: 'string',
|
|
52
|
+
description: 'The unique ID of the radio station to delete',
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
required: ['id'],
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: 'get_radio_station',
|
|
60
|
+
description: 'Get detailed information about a specific radio station by ID',
|
|
61
|
+
inputSchema: {
|
|
62
|
+
type: 'object',
|
|
63
|
+
properties: {
|
|
64
|
+
id: {
|
|
65
|
+
type: 'string',
|
|
66
|
+
description: 'The unique ID of the radio station',
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
required: ['id'],
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: 'play_radio_station',
|
|
74
|
+
description: 'Start playing a radio station by setting it in the playback queue',
|
|
75
|
+
inputSchema: {
|
|
76
|
+
type: 'object',
|
|
77
|
+
properties: {
|
|
78
|
+
id: {
|
|
79
|
+
type: 'string',
|
|
80
|
+
description: 'The unique ID of the radio station to play',
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
required: ['id'],
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
name: 'get_current_radio_info',
|
|
88
|
+
description: 'Get information about currently playing radio station and stream metadata',
|
|
89
|
+
inputSchema: {
|
|
90
|
+
type: 'object',
|
|
91
|
+
properties: {},
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
name: 'batch_create_radio_stations',
|
|
96
|
+
description: 'Batch create multiple internet radio stations in Navidrome',
|
|
97
|
+
inputSchema: {
|
|
98
|
+
type: 'object',
|
|
99
|
+
properties: {
|
|
100
|
+
stations: {
|
|
101
|
+
type: 'array',
|
|
102
|
+
description: 'Array of radio stations to create',
|
|
103
|
+
items: {
|
|
104
|
+
type: 'object',
|
|
105
|
+
properties: {
|
|
106
|
+
name: {
|
|
107
|
+
type: 'string',
|
|
108
|
+
description: 'Station name (required)',
|
|
109
|
+
},
|
|
110
|
+
streamUrl: {
|
|
111
|
+
type: 'string',
|
|
112
|
+
description: 'Stream URL (required)',
|
|
113
|
+
},
|
|
114
|
+
homePageUrl: {
|
|
115
|
+
type: 'string',
|
|
116
|
+
description: 'Optional homepage URL',
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
required: ['name', 'streamUrl'],
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
validateBeforeAdd: {
|
|
123
|
+
type: 'boolean',
|
|
124
|
+
description: 'Validate all stream URLs before adding (default: false)',
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
required: ['stations'],
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
name: 'validate_radio_stream',
|
|
132
|
+
description: 'Tests if a radio stream URL is valid, accessible, and streams audio content. Checks HTTP response, content type, streaming headers, and attempts to verify audio data.',
|
|
133
|
+
inputSchema: {
|
|
134
|
+
type: 'object',
|
|
135
|
+
properties: {
|
|
136
|
+
url: {
|
|
137
|
+
type: 'string',
|
|
138
|
+
format: 'uri',
|
|
139
|
+
description: 'The radio stream URL to validate (required)',
|
|
140
|
+
},
|
|
141
|
+
timeout: {
|
|
142
|
+
type: 'number',
|
|
143
|
+
description: 'Timeout in milliseconds (default: 8000, max: 30000)',
|
|
144
|
+
minimum: 1000,
|
|
145
|
+
maximum: 30000,
|
|
146
|
+
default: 8000,
|
|
147
|
+
},
|
|
148
|
+
followRedirects: {
|
|
149
|
+
type: 'boolean',
|
|
150
|
+
description: 'Follow HTTP redirects (default: true)',
|
|
151
|
+
default: true,
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
required: ['url'],
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
];
|
|
158
|
+
// Add radio discovery tools if Radio Browser is enabled
|
|
159
|
+
if (config.features.radioBrowser) {
|
|
160
|
+
baseTools.push({
|
|
161
|
+
name: 'discover_radio_stations',
|
|
162
|
+
description: 'Discover internet radio stations worldwide via Radio Browser API. Search by genre/tag, country, language, quality, and more. Returns validated streams with metadata, sorted by popularity by default.',
|
|
163
|
+
inputSchema: {
|
|
164
|
+
type: 'object',
|
|
165
|
+
properties: {
|
|
166
|
+
query: {
|
|
167
|
+
type: 'string',
|
|
168
|
+
description: 'Search query for station names (e.g., "BBC", "Classic FM", "Jazz FM")',
|
|
169
|
+
},
|
|
170
|
+
tag: {
|
|
171
|
+
type: 'string',
|
|
172
|
+
description: 'Filter by music genre/tag (e.g., "jazz", "rock", "classical", "electronic", "hip-hop", "country", "reggae", "latin")',
|
|
173
|
+
},
|
|
174
|
+
countryCode: {
|
|
175
|
+
type: 'string',
|
|
176
|
+
description: 'ISO 2-letter country code (e.g., "US"=United States, "GB"=United Kingdom, "FR"=France, "DE"=Germany, "JP"=Japan, "AU"=Australia)',
|
|
177
|
+
},
|
|
178
|
+
language: {
|
|
179
|
+
type: 'string',
|
|
180
|
+
description: 'Broadcast language (e.g., "english", "spanish", "french", "german", "japanese", "portuguese", "italian")',
|
|
181
|
+
},
|
|
182
|
+
codec: {
|
|
183
|
+
type: 'string',
|
|
184
|
+
description: 'Audio codec preference (e.g., "MP3" for best compatibility, "AAC" for better quality, "OGG" for open standard)',
|
|
185
|
+
},
|
|
186
|
+
bitrateMin: {
|
|
187
|
+
type: 'number',
|
|
188
|
+
description: 'Minimum audio quality in kbps (e.g., 128 for standard quality, 256 for high quality, 320 for maximum quality)',
|
|
189
|
+
minimum: 0,
|
|
190
|
+
},
|
|
191
|
+
isHttps: {
|
|
192
|
+
type: 'boolean',
|
|
193
|
+
description: 'Require secure HTTPS streams (recommended for security)',
|
|
194
|
+
},
|
|
195
|
+
order: {
|
|
196
|
+
type: 'string',
|
|
197
|
+
description: 'Sort results by: "votes"=popularity, "name"=alphabetical, "clickcount"=most played, "bitrate"=quality, "lastcheckok"=reliability, "random"=shuffle',
|
|
198
|
+
enum: ['name', 'votes', 'clickcount', 'bitrate', 'lastcheckok', 'random'],
|
|
199
|
+
default: 'votes',
|
|
200
|
+
},
|
|
201
|
+
reverse: {
|
|
202
|
+
type: 'boolean',
|
|
203
|
+
description: 'Reverse sort order (true=descending/best first, false=ascending)',
|
|
204
|
+
default: true,
|
|
205
|
+
},
|
|
206
|
+
offset: {
|
|
207
|
+
type: 'number',
|
|
208
|
+
description: 'Skip first N results for pagination',
|
|
209
|
+
minimum: 0,
|
|
210
|
+
},
|
|
211
|
+
limit: {
|
|
212
|
+
type: 'number',
|
|
213
|
+
description: 'Maximum number of stations to return (15=quick discovery, 50=extensive search, 500=maximum)',
|
|
214
|
+
minimum: 1,
|
|
215
|
+
maximum: 500,
|
|
216
|
+
default: DEFAULT_VALUES.RADIO_DISCOVERY_LIMIT,
|
|
217
|
+
},
|
|
218
|
+
hideBroken: {
|
|
219
|
+
type: 'boolean',
|
|
220
|
+
description: 'Hide stations that failed recent connectivity checks (recommended: true)',
|
|
221
|
+
default: true,
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
}, {
|
|
226
|
+
name: 'get_radio_filters',
|
|
227
|
+
description: 'Get available filter options for radio station discovery (tags, countries, languages, codecs)',
|
|
228
|
+
inputSchema: {
|
|
229
|
+
type: 'object',
|
|
230
|
+
properties: {
|
|
231
|
+
kinds: {
|
|
232
|
+
type: 'array',
|
|
233
|
+
description: 'Filter types to retrieve',
|
|
234
|
+
items: {
|
|
235
|
+
type: 'string',
|
|
236
|
+
enum: ['tags', 'countries', 'languages', 'codecs'],
|
|
237
|
+
},
|
|
238
|
+
default: ['tags', 'countries', 'languages', 'codecs'],
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
},
|
|
242
|
+
}, {
|
|
243
|
+
name: 'get_station_by_uuid',
|
|
244
|
+
description: 'Get detailed information about a specific radio station by its UUID',
|
|
245
|
+
inputSchema: {
|
|
246
|
+
type: 'object',
|
|
247
|
+
properties: {
|
|
248
|
+
stationUuid: {
|
|
249
|
+
type: 'string',
|
|
250
|
+
description: 'The unique UUID of the radio station',
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
required: ['stationUuid'],
|
|
254
|
+
},
|
|
255
|
+
}, {
|
|
256
|
+
name: 'click_station',
|
|
257
|
+
description: 'Register a play click for a radio station (helps with popularity metrics). Call this when starting playback.',
|
|
258
|
+
inputSchema: {
|
|
259
|
+
type: 'object',
|
|
260
|
+
properties: {
|
|
261
|
+
stationUuid: {
|
|
262
|
+
type: 'string',
|
|
263
|
+
description: 'The unique UUID of the radio station',
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
required: ['stationUuid'],
|
|
267
|
+
},
|
|
268
|
+
}, {
|
|
269
|
+
name: 'vote_station',
|
|
270
|
+
description: 'Vote for a radio station to increase its popularity',
|
|
271
|
+
inputSchema: {
|
|
272
|
+
type: 'object',
|
|
273
|
+
properties: {
|
|
274
|
+
stationUuid: {
|
|
275
|
+
type: 'string',
|
|
276
|
+
description: 'The unique UUID of the radio station',
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
required: ['stationUuid'],
|
|
280
|
+
},
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
return baseTools;
|
|
284
|
+
}
|
|
285
|
+
// Factory function for creating radio tool category with dependencies
|
|
286
|
+
export function createRadioToolCategory(client, config) {
|
|
287
|
+
return {
|
|
288
|
+
tools: getRadioTools(config),
|
|
289
|
+
async handleToolCall(name, args) {
|
|
290
|
+
switch (name) {
|
|
291
|
+
case 'list_radio_stations':
|
|
292
|
+
return await listRadioStations(config, args);
|
|
293
|
+
case 'create_radio_station':
|
|
294
|
+
return await createRadioStation(config, args);
|
|
295
|
+
case 'delete_radio_station':
|
|
296
|
+
return await deleteRadioStation(config, args);
|
|
297
|
+
case 'get_radio_station':
|
|
298
|
+
return await getRadioStation(config, args);
|
|
299
|
+
case 'play_radio_station':
|
|
300
|
+
return await playRadioStation(config, args);
|
|
301
|
+
case 'get_current_radio_info':
|
|
302
|
+
return await getCurrentRadioInfo(config, args);
|
|
303
|
+
case 'batch_create_radio_stations':
|
|
304
|
+
return await batchCreateRadioStations(config, args);
|
|
305
|
+
case 'validate_radio_stream':
|
|
306
|
+
return await validateRadioStream(client, args);
|
|
307
|
+
case 'discover_radio_stations':
|
|
308
|
+
return await discoverRadioStations(config, client, args);
|
|
309
|
+
case 'get_radio_filters':
|
|
310
|
+
return await getRadioFilters(config, args);
|
|
311
|
+
case 'get_station_by_uuid':
|
|
312
|
+
return await getStationByUuid(config, args);
|
|
313
|
+
case 'click_station':
|
|
314
|
+
return await clickStation(config, args);
|
|
315
|
+
case 'vote_station':
|
|
316
|
+
return await voteStation(config, args);
|
|
317
|
+
default:
|
|
318
|
+
throw new Error(ErrorFormatter.toolUnknown(`radio ${name}`));
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
//# sourceMappingURL=radio-handlers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"radio-handlers.js","sourceRoot":"","sources":["../../../src/tools/handlers/radio-handlers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
2
|
+
import type { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import type { NavidromeClient } from '../../client/navidrome-client.js';
|
|
4
|
+
import type { Config } from '../../config.js';
|
|
5
|
+
export interface ToolCategory {
|
|
6
|
+
tools: Tool[];
|
|
7
|
+
handleToolCall(name: string, args: unknown): Promise<unknown>;
|
|
8
|
+
}
|
|
9
|
+
export interface ToolHandler {
|
|
10
|
+
(client: NavidromeClient, config: Config, name: string, args: unknown): Promise<unknown>;
|
|
11
|
+
}
|
|
12
|
+
export declare class ToolRegistry {
|
|
13
|
+
private categories;
|
|
14
|
+
private allTools;
|
|
15
|
+
register(categoryName: string, category: ToolCategory): void;
|
|
16
|
+
getAllTools(): Tool[];
|
|
17
|
+
handleToolCall(name: string, args: unknown): Promise<unknown>;
|
|
18
|
+
}
|
|
19
|
+
export declare function createToolResponse(result: unknown): {
|
|
20
|
+
content: {
|
|
21
|
+
type: 'text';
|
|
22
|
+
text: string;
|
|
23
|
+
}[];
|
|
24
|
+
};
|
|
25
|
+
export declare function registerTools(server: Server, client: NavidromeClient, config: Config): void;
|
|
26
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/tools/handlers/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACxE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAG/D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAG9C,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC/D;AAED,MAAM,WAAW,WAAW;IAC1B,CAAC,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC1F;AAGD,qBAAa,YAAY;IACvB,OAAO,CAAC,UAAU,CAAwC;IAC1D,OAAO,CAAC,QAAQ,CAAc;IAE9B,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI;IAK5D,WAAW,IAAI,IAAI,EAAE;IAIf,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;CASpE;AAGD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,OAAO,GAAG;IAAE,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,CASjG;AAeD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAoC3F"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
// Registry for all tool categories
|
|
3
|
+
export class ToolRegistry {
|
|
4
|
+
categories = new Map();
|
|
5
|
+
allTools = [];
|
|
6
|
+
register(categoryName, category) {
|
|
7
|
+
this.categories.set(categoryName, category);
|
|
8
|
+
this.allTools.push(...category.tools);
|
|
9
|
+
}
|
|
10
|
+
getAllTools() {
|
|
11
|
+
return [...this.allTools];
|
|
12
|
+
}
|
|
13
|
+
async handleToolCall(name, args) {
|
|
14
|
+
for (const category of this.categories.values()) {
|
|
15
|
+
const tool = category.tools.find(t => t.name === name);
|
|
16
|
+
if (tool) {
|
|
17
|
+
return category.handleToolCall(name, args);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
// Utility function to create consistent tool responses
|
|
24
|
+
export function createToolResponse(result) {
|
|
25
|
+
return {
|
|
26
|
+
content: [
|
|
27
|
+
{
|
|
28
|
+
type: 'text',
|
|
29
|
+
text: JSON.stringify(result, null, 2),
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
// Import category factory functions
|
|
35
|
+
import { createTestToolCategory } from '../test.js';
|
|
36
|
+
import { createLibraryToolCategory } from '../library.js';
|
|
37
|
+
import { createPlaylistToolCategory } from './playlist-handlers.js';
|
|
38
|
+
import { createSearchToolCategory } from './search-handlers.js';
|
|
39
|
+
import { createUserPreferencesToolCategory } from './user-preferences-handlers.js';
|
|
40
|
+
import { createQueueToolCategory } from './queue-handlers.js';
|
|
41
|
+
import { createRadioToolCategory } from './radio-handlers.js';
|
|
42
|
+
import { createLastFmToolCategory } from './lastfm-handlers.js';
|
|
43
|
+
import { createLyricsToolCategory } from './lyrics-handlers.js';
|
|
44
|
+
import { createTagsToolCategory } from './tag-handlers.js';
|
|
45
|
+
// Main registration function
|
|
46
|
+
export function registerTools(server, client, config) {
|
|
47
|
+
const registry = new ToolRegistry();
|
|
48
|
+
// Use feature flags from config for conditional tools
|
|
49
|
+
const hasLastFm = config.features.lastfm;
|
|
50
|
+
const hasLyrics = config.features.lyrics;
|
|
51
|
+
// Register all tool categories
|
|
52
|
+
registry.register('test', createTestToolCategory(client, config));
|
|
53
|
+
registry.register('library', createLibraryToolCategory(client, config));
|
|
54
|
+
registry.register('playlist-management', createPlaylistToolCategory(client, config));
|
|
55
|
+
registry.register('search', createSearchToolCategory(client, config));
|
|
56
|
+
registry.register('user-preferences', createUserPreferencesToolCategory(client, config));
|
|
57
|
+
registry.register('queue-management', createQueueToolCategory(client, config));
|
|
58
|
+
registry.register('radio', createRadioToolCategory(client, config));
|
|
59
|
+
registry.register('tags', createTagsToolCategory(client, config));
|
|
60
|
+
// Add conditional tools based on configuration
|
|
61
|
+
if (hasLastFm) {
|
|
62
|
+
registry.register('lastfm-discovery', createLastFmToolCategory(client, config));
|
|
63
|
+
}
|
|
64
|
+
if (hasLyrics) {
|
|
65
|
+
registry.register('lyrics', createLyricsToolCategory(client, config));
|
|
66
|
+
}
|
|
67
|
+
// Register MCP handlers
|
|
68
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
69
|
+
tools: registry.getAllTools(),
|
|
70
|
+
}));
|
|
71
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
72
|
+
const { name, arguments: args } = request.params;
|
|
73
|
+
const result = await registry.handleToolCall(name, args ?? {});
|
|
74
|
+
return createToolResponse(result);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/tools/handlers/registry.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAenG,mCAAmC;AACnC,MAAM,OAAO,YAAY;IACf,UAAU,GAA8B,IAAI,GAAG,EAAE,CAAC;IAClD,QAAQ,GAAW,EAAE,CAAC;IAE9B,QAAQ,CAAC,YAAoB,EAAE,QAAsB;QACnD,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;QAC5C,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxC,CAAC;IAED,WAAW;QACT,OAAO,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,IAAY,EAAE,IAAa;QAC9C,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;YAChD,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;YACvD,IAAI,IAAI,EAAE,CAAC;gBACT,OAAO,QAAQ,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC7C,CAAC;QACH,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;IAC3C,CAAC;CACF;AAED,uDAAuD;AACvD,MAAM,UAAU,kBAAkB,CAAC,MAAe;IAChD,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAe;gBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;aACtC;SACF;KACF,CAAC;AACJ,CAAC;AAED,oCAAoC;AACpC,OAAO,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,iCAAiC,EAAE,MAAM,gCAAgC,CAAC;AACnF,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,wBAAwB,EAAE,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAE3D,6BAA6B;AAC7B,MAAM,UAAU,aAAa,CAAC,MAAc,EAAE,MAAuB,EAAE,MAAc;IACnF,MAAM,QAAQ,GAAG,IAAI,YAAY,EAAE,CAAC;IAEpC,sDAAsD;IACtD,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;IACzC,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;IAEzC,+BAA+B;IAC/B,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAClE,QAAQ,CAAC,QAAQ,CAAC,SAAS,EAAE,yBAAyB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACxE,QAAQ,CAAC,QAAQ,CAAC,qBAAqB,EAAE,0BAA0B,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACrF,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,wBAAwB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACtE,QAAQ,CAAC,QAAQ,CAAC,kBAAkB,EAAE,iCAAiC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACzF,QAAQ,CAAC,QAAQ,CAAC,kBAAkB,EAAE,uBAAuB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC/E,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,uBAAuB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACpE,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAElE,iDAAiD;IACjD,IAAI,SAAS,EAAE,CAAC;QACd,QAAQ,CAAC,QAAQ,CAAC,kBAAkB,EAAE,wBAAwB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAClF,CAAC;IAED,IAAI,SAAS,EAAE,CAAC;QACd,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,wBAAwB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,wBAAwB;IACxB,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QAC5D,KAAK,EAAE,QAAQ,CAAC,WAAW,EAAE;KAC9B,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,iBAAiB,CAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAChE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QACjD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;QAC/D,OAAO,kBAAkB,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { NavidromeClient } from '../../client/navidrome-client.js';
|
|
2
|
+
import type { Config } from '../../config.js';
|
|
3
|
+
import type { ToolCategory } from './registry.js';
|
|
4
|
+
export declare function createSearchToolCategory(_client: NavidromeClient, config: Config): ToolCategory;
|
|
5
|
+
//# sourceMappingURL=search-handlers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-handlers.d.ts","sourceRoot":"","sources":["../../../src/tools/handlers/search-handlers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAkHlD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY,CAkB/F"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { DEFAULT_VALUES } from '../../constants/defaults.js';
|
|
2
|
+
// Import tool functions
|
|
3
|
+
import { searchAll, searchSongs, searchAlbums, searchArtists, } from '../search.js';
|
|
4
|
+
// Tool definitions for search category
|
|
5
|
+
const tools = [
|
|
6
|
+
{
|
|
7
|
+
name: 'search_all',
|
|
8
|
+
description: 'Search across all content types (artists, albums, songs) using a single query',
|
|
9
|
+
inputSchema: {
|
|
10
|
+
type: 'object',
|
|
11
|
+
properties: {
|
|
12
|
+
query: {
|
|
13
|
+
type: 'string',
|
|
14
|
+
description: 'Search terms to look for',
|
|
15
|
+
},
|
|
16
|
+
artistCount: {
|
|
17
|
+
type: 'number',
|
|
18
|
+
description: 'Maximum number of artists to return',
|
|
19
|
+
minimum: 0,
|
|
20
|
+
maximum: 100,
|
|
21
|
+
default: DEFAULT_VALUES.SEARCH_ALL_LIMIT,
|
|
22
|
+
},
|
|
23
|
+
albumCount: {
|
|
24
|
+
type: 'number',
|
|
25
|
+
description: 'Maximum number of albums to return',
|
|
26
|
+
minimum: 0,
|
|
27
|
+
maximum: 100,
|
|
28
|
+
default: DEFAULT_VALUES.SEARCH_ALL_LIMIT,
|
|
29
|
+
},
|
|
30
|
+
songCount: {
|
|
31
|
+
type: 'number',
|
|
32
|
+
description: 'Maximum number of songs to return',
|
|
33
|
+
minimum: 0,
|
|
34
|
+
maximum: 100,
|
|
35
|
+
default: DEFAULT_VALUES.SEARCH_ALL_LIMIT,
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
required: ['query'],
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: 'search_songs',
|
|
43
|
+
description: 'Search for songs by title, artist, or album',
|
|
44
|
+
inputSchema: {
|
|
45
|
+
type: 'object',
|
|
46
|
+
properties: {
|
|
47
|
+
query: {
|
|
48
|
+
type: 'string',
|
|
49
|
+
description: 'Search terms to look for in song titles, artists, or albums',
|
|
50
|
+
},
|
|
51
|
+
limit: {
|
|
52
|
+
type: 'number',
|
|
53
|
+
description: 'Maximum number of songs to return',
|
|
54
|
+
minimum: 1,
|
|
55
|
+
maximum: 100,
|
|
56
|
+
default: 100,
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
required: ['query'],
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: 'search_albums',
|
|
64
|
+
description: 'Search for albums by name or artist',
|
|
65
|
+
inputSchema: {
|
|
66
|
+
type: 'object',
|
|
67
|
+
properties: {
|
|
68
|
+
query: {
|
|
69
|
+
type: 'string',
|
|
70
|
+
description: 'Search terms to look for in album names or artists',
|
|
71
|
+
},
|
|
72
|
+
limit: {
|
|
73
|
+
type: 'number',
|
|
74
|
+
description: 'Maximum number of albums to return',
|
|
75
|
+
minimum: 1,
|
|
76
|
+
maximum: 100,
|
|
77
|
+
default: 100,
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
required: ['query'],
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: 'search_artists',
|
|
85
|
+
description: 'Search for artists by name',
|
|
86
|
+
inputSchema: {
|
|
87
|
+
type: 'object',
|
|
88
|
+
properties: {
|
|
89
|
+
query: {
|
|
90
|
+
type: 'string',
|
|
91
|
+
description: 'Search terms to look for in artist names',
|
|
92
|
+
},
|
|
93
|
+
limit: {
|
|
94
|
+
type: 'number',
|
|
95
|
+
description: 'Maximum number of artists to return',
|
|
96
|
+
minimum: 1,
|
|
97
|
+
maximum: 100,
|
|
98
|
+
default: 100,
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
required: ['query'],
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
];
|
|
105
|
+
// Factory function for creating search tool category with dependencies
|
|
106
|
+
export function createSearchToolCategory(_client, config) {
|
|
107
|
+
return {
|
|
108
|
+
tools,
|
|
109
|
+
async handleToolCall(name, args) {
|
|
110
|
+
switch (name) {
|
|
111
|
+
case 'search_all':
|
|
112
|
+
return await searchAll(config, args);
|
|
113
|
+
case 'search_songs':
|
|
114
|
+
return await searchSongs(config, args);
|
|
115
|
+
case 'search_albums':
|
|
116
|
+
return await searchAlbums(config, args);
|
|
117
|
+
case 'search_artists':
|
|
118
|
+
return await searchArtists(config, args);
|
|
119
|
+
default:
|
|
120
|
+
throw new Error(`Unknown search tool: ${name}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=search-handlers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-handlers.js","sourceRoot":"","sources":["../../../src/tools/handlers/search-handlers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { NavidromeClient } from '../../client/navidrome-client.js';
|
|
2
|
+
import type { Config } from '../../config.js';
|
|
3
|
+
import type { ToolCategory } from './registry.js';
|
|
4
|
+
export declare function createTagsToolCategory(client: NavidromeClient, _config: Config): ToolCategory;
|
|
5
|
+
//# sourceMappingURL=tag-handlers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tag-handlers.d.ts","sourceRoot":"","sources":["../../../src/tools/handlers/tag-handlers.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC9C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AA+IlD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,GAAG,YAAY,CAoB7F"}
|