@@ -9,7 +9,12 @@ import { Telemetry } from "./telemetry/telemetry.js";
9
9
import { UserConfig } from "./common/config.js" ;
10
10
import { type ServerEvent } from "./telemetry/types.js" ;
11
11
import { type ServerCommand } from "./telemetry/types.js" ;
12
- import { CallToolRequestSchema , CallToolResult } from "@modelcontextprotocol/sdk/types.js" ;
12
+ import {
13
+ CallToolRequestSchema ,
14
+ CallToolResult ,
15
+ SubscribeRequestSchema ,
16
+ UnsubscribeRequestSchema ,
17
+ } from "@modelcontextprotocol/sdk/types.js" ;
13
18
import assert from "assert" ;
14
19
import { ToolBase } from "./tools/tool.js" ;
15
20
@@ -27,6 +32,7 @@ export class Server {
27
32
public readonly userConfig : UserConfig ;
28
33
public readonly tools : ToolBase [ ] = [ ] ;
29
34
private readonly startTime : number ;
35
+ private readonly subscriptions = new Set < string > ( ) ;
30
36
31
37
constructor ( { session, mcpServer, userConfig, telemetry } : ServerOptions ) {
32
38
this . startTime = Date . now ( ) ;
@@ -42,7 +48,7 @@ export class Server {
42
48
this . registerResources ( ) ;
43
49
await this . validateConfig ( ) ;
44
50
45
- this . mcpServer . server . registerCapabilities ( { logging : { } , resources : { listChanged : true } } ) ;
51
+ this . mcpServer . server . registerCapabilities ( { logging : { } , resources : { listChanged : true , subscribe : true } } ) ;
46
52
47
53
// TODO: Eventually we might want to make tools reactive too instead of relying on custom logic.
48
54
this . registerTools ( ) ;
@@ -70,6 +76,26 @@ export class Server {
70
76
return existingHandler ( request , extra ) ;
71
77
} ) ;
72
78
79
+ this . mcpServer . server . setRequestHandler ( SubscribeRequestSchema , ( { params } ) => {
80
+ this . subscriptions . add ( params . uri ) ;
81
+ this . session . logger . debug ( {
82
+ id : LogId . serverInitialized ,
83
+ context : "resources" ,
84
+ message : `Client subscribed to resource: ${ params . uri } ` ,
85
+ } ) ;
86
+ return { } ;
87
+ } ) ;
88
+
89
+ this . mcpServer . server . setRequestHandler ( UnsubscribeRequestSchema , ( { params } ) => {
90
+ this . subscriptions . delete ( params . uri ) ;
91
+ this . session . logger . debug ( {
92
+ id : LogId . serverInitialized ,
93
+ context : "resources" ,
94
+ message : `Client unsubscribed from resource: ${ params . uri } ` ,
95
+ } ) ;
96
+ return { } ;
97
+ } ) ;
98
+
73
99
this . mcpServer . server . oninitialized = ( ) : void => {
74
100
this . session . setAgentRunner ( this . mcpServer . server . getClientVersion ( ) ) ;
75
101
@@ -101,6 +127,16 @@ export class Server {
101
127
await this . mcpServer . close ( ) ;
102
128
}
103
129
130
+ public sendResourceListChanged ( ) : void {
131
+ this . mcpServer . sendResourceListChanged ( ) ;
132
+ }
133
+
134
+ public sendResourceUpdated ( uri : string ) : void {
135
+ if ( this . subscriptions . has ( uri ) ) {
136
+ void this . mcpServer . server . sendResourceUpdated ( { uri } ) ;
137
+ }
138
+ }
139
+
104
140
/**
105
141
* Emits a server event
106
142
* @param command - The server command (e.g., "start", "stop", "register", "deregister")
0 commit comments