@@ -5,11 +5,17 @@ import {
5
5
ListToolsRequestSchema ,
6
6
ListPromptsRequestSchema ,
7
7
GetPromptRequestSchema ,
8
+ ListResourcesRequestSchema ,
9
+ ReadResourceRequestSchema ,
10
+ SubscribeRequestSchema ,
11
+ UnsubscribeRequestSchema ,
8
12
} from "@modelcontextprotocol/sdk/types.js" ;
9
13
import { ToolLoader } from "./toolLoader.js" ;
10
14
import { PromptLoader } from "./promptLoader.js" ;
15
+ import { ResourceLoader } from "./resourceLoader.js" ;
11
16
import { ToolProtocol } from "../tools/BaseTool.js" ;
12
17
import { PromptProtocol } from "../prompts/BasePrompt.js" ;
18
+ import { ResourceProtocol } from "../resources/BaseResource.js" ;
13
19
import { readFileSync } from "fs" ;
14
20
import { join , dirname } from "path" ;
15
21
import { logger } from "./Logger.js" ;
@@ -30,14 +36,19 @@ export type ServerCapabilities = {
30
36
prompts ?: {
31
37
enabled : true ;
32
38
} ;
39
+ resources ?: {
40
+ enabled : true ;
41
+ } ;
33
42
} ;
34
43
35
44
export class MCPServer {
36
45
private server : Server ;
37
46
private toolsMap : Map < string , ToolProtocol > = new Map ( ) ;
38
47
private promptsMap : Map < string , PromptProtocol > = new Map ( ) ;
48
+ private resourcesMap : Map < string , ResourceProtocol > = new Map ( ) ;
39
49
private toolLoader : ToolLoader ;
40
50
private promptLoader : PromptLoader ;
51
+ private resourceLoader : ResourceLoader ;
41
52
private serverName : string ;
42
53
private serverVersion : string ;
43
54
private basePath : string ;
@@ -53,6 +64,7 @@ export class MCPServer {
53
64
54
65
this . toolLoader = new ToolLoader ( this . basePath ) ;
55
66
this . promptLoader = new PromptLoader ( this . basePath ) ;
67
+ this . resourceLoader = new ResourceLoader ( this . basePath ) ;
56
68
57
69
this . server = new Server (
58
70
{
@@ -63,6 +75,7 @@ export class MCPServer {
63
75
capabilities : {
64
76
tools : { enabled : true } ,
65
77
prompts : { enabled : false } ,
78
+ resources : { enabled : false } ,
66
79
} ,
67
80
}
68
81
) ;
@@ -162,6 +175,66 @@ export class MCPServer {
162
175
messages : await prompt . getMessages ( request . params . arguments ) ,
163
176
} ;
164
177
} ) ;
178
+
179
+ this . server . setRequestHandler ( ListResourcesRequestSchema , async ( ) => {
180
+ return {
181
+ resources : Array . from ( this . resourcesMap . values ( ) ) . map (
182
+ ( resource ) => resource . resourceDefinition
183
+ ) ,
184
+ } ;
185
+ } ) ;
186
+
187
+ this . server . setRequestHandler (
188
+ ReadResourceRequestSchema ,
189
+ async ( request ) => {
190
+ const resource = this . resourcesMap . get ( request . params . uri ) ;
191
+ if ( ! resource ) {
192
+ throw new Error (
193
+ `Unknown resource: ${
194
+ request . params . uri
195
+ } . Available resources: ${ Array . from ( this . resourcesMap . keys ( ) ) . join (
196
+ ", "
197
+ ) } `
198
+ ) ;
199
+ }
200
+
201
+ return {
202
+ contents : await resource . read ( ) ,
203
+ } ;
204
+ }
205
+ ) ;
206
+
207
+ this . server . setRequestHandler ( SubscribeRequestSchema , async ( request ) => {
208
+ const resource = this . resourcesMap . get ( request . params . uri ) ;
209
+ if ( ! resource ) {
210
+ throw new Error ( `Unknown resource: ${ request . params . uri } ` ) ;
211
+ }
212
+
213
+ if ( ! resource . subscribe ) {
214
+ throw new Error (
215
+ `Resource ${ request . params . uri } does not support subscriptions`
216
+ ) ;
217
+ }
218
+
219
+ await resource . subscribe ( ) ;
220
+ return { } ;
221
+ } ) ;
222
+
223
+ this . server . setRequestHandler ( UnsubscribeRequestSchema , async ( request ) => {
224
+ const resource = this . resourcesMap . get ( request . params . uri ) ;
225
+ if ( ! resource ) {
226
+ throw new Error ( `Unknown resource: ${ request . params . uri } ` ) ;
227
+ }
228
+
229
+ if ( ! resource . unsubscribe ) {
230
+ throw new Error (
231
+ `Resource ${ request . params . uri } does not support subscriptions`
232
+ ) ;
233
+ }
234
+
235
+ await resource . unsubscribe ( ) ;
236
+ return { } ;
237
+ } ) ;
165
238
}
166
239
167
240
private async detectCapabilities ( ) : Promise < ServerCapabilities > {
@@ -170,15 +243,16 @@ export class MCPServer {
170
243
if ( await this . toolLoader . hasTools ( ) ) {
171
244
capabilities . tools = { enabled : true } ;
172
245
logger . debug ( "Tools capability enabled" ) ;
173
- } else {
174
- logger . debug ( "No tools found, tools capability disabled" ) ;
175
246
}
176
247
177
248
if ( await this . promptLoader . hasPrompts ( ) ) {
178
249
capabilities . prompts = { enabled : true } ;
179
250
logger . debug ( "Prompts capability enabled" ) ;
180
- } else {
181
- logger . debug ( "No prompts found, prompts capability disabled" ) ;
251
+ }
252
+
253
+ if ( await this . resourceLoader . hasResources ( ) ) {
254
+ capabilities . resources = { enabled : true } ;
255
+ logger . debug ( "Resources capability enabled" ) ;
182
256
}
183
257
184
258
return capabilities ;
@@ -196,30 +270,37 @@ export class MCPServer {
196
270
prompts . map ( ( prompt : PromptProtocol ) => [ prompt . name , prompt ] )
197
271
) ;
198
272
199
- this . detectCapabilities ( ) ;
273
+ const resources = await this . resourceLoader . loadResources ( ) ;
274
+ this . resourcesMap = new Map (
275
+ resources . map ( ( resource : ResourceProtocol ) => [ resource . uri , resource ] )
276
+ ) ;
277
+
278
+ await this . detectCapabilities ( ) ;
200
279
201
280
const transport = new StdioServerTransport ( ) ;
202
281
await this . server . connect ( transport ) ;
203
282
204
- if ( tools . length > 0 || prompts . length > 0 ) {
283
+ logger . info ( `Started ${ this . serverName } @${ this . serverVersion } ` ) ;
284
+
285
+ if ( tools . length > 0 ) {
205
286
logger . info (
206
- `Started ${ this . serverName } @${ this . serverVersion } with ${ tools . length } tools and ${ prompts . length } prompts`
287
+ `Tools (${ tools . length } ): ${ Array . from ( this . toolsMap . keys ( ) ) . join (
288
+ ", "
289
+ ) } `
207
290
) ;
208
- if ( tools . length > 0 ) {
209
- logger . info (
210
- `Available tools: ${ Array . from ( this . toolsMap . keys ( ) ) . join ( ", " ) } `
211
- ) ;
212
- }
213
- if ( prompts . length > 0 ) {
214
- logger . info (
215
- `Available prompts: ${ Array . from ( this . promptsMap . keys ( ) ) . join (
216
- ", "
217
- ) } `
218
- ) ;
219
- }
220
- } else {
291
+ }
292
+ if ( prompts . length > 0 ) {
293
+ logger . info (
294
+ `Prompts (${ prompts . length } ): ${ Array . from (
295
+ this . promptsMap . keys ( )
296
+ ) . join ( ", " ) } `
297
+ ) ;
298
+ }
299
+ if ( resources . length > 0 ) {
221
300
logger . info (
222
- `Started ${ this . serverName } @${ this . serverVersion } with no tools or prompts`
301
+ `Resources (${ resources . length } ): ${ Array . from (
302
+ this . resourcesMap . keys ( )
303
+ ) . join ( ", " ) } `
223
304
) ;
224
305
}
225
306
} catch ( error ) {
0 commit comments