Skip to content

Commit 88c1e77

Browse files
committed
Add sendNotification in extra
1 parent 08a23a1 commit 88c1e77

File tree

2 files changed

+46
-43
lines changed

2 files changed

+46
-43
lines changed

example/server_simple_streamable_https.dart

Lines changed: 21 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -57,19 +57,13 @@ class InMemoryEventStore implements EventStore {
5757
}
5858
}
5959

60-
// Global server instance to be used by tool callbacks
61-
Server? globalServer;
62-
6360
// Create an MCP server with implementation details
6461
McpServer getServer() {
6562
// Create the McpServer with the implementation details and options
6663
final server = McpServer(
6764
Implementation(name: 'simple-streamable-http-server', version: '1.0.0'),
6865
);
6966

70-
// Save reference to underlying server for logging access
71-
globalServer = server.server;
72-
7367
// Register a simple tool that returns a greeting
7468
server.tool(
7569
'greet',
@@ -107,32 +101,29 @@ McpServer getServer() {
107101
Future<void> sleep(int ms) => Future.delayed(Duration(milliseconds: ms));
108102

109103
// Send debug notification
110-
if (globalServer != null) {
111-
await globalServer!.sendLoggingMessage(LoggingMessageNotificationParams(
112-
level: LoggingLevel.debug,
113-
data: 'Starting multi-greet for $name',
114-
));
115-
}
104+
await extra?.sendNotification(JsonRpcLoggingMessageNotification(
105+
logParams: LoggingMessageNotificationParams(
106+
level: LoggingLevel.debug,
107+
data: 'Starting multi-greet for $name',
108+
)));
116109

117110
await sleep(1000); // Wait 1 second before first greeting
118111

119112
// Send first info notification
120-
if (globalServer != null) {
121-
await globalServer!.sendLoggingMessage(LoggingMessageNotificationParams(
122-
level: LoggingLevel.info,
123-
data: 'Sending first greeting to $name',
124-
));
125-
}
113+
await extra?.sendNotification(JsonRpcLoggingMessageNotification(
114+
logParams: LoggingMessageNotificationParams(
115+
level: LoggingLevel.info,
116+
data: 'Sending first greeting to $name',
117+
)));
126118

127119
await sleep(1000); // Wait another second before second greeting
128120

129121
// Send second info notification
130-
if (globalServer != null) {
131-
await globalServer!.sendLoggingMessage(LoggingMessageNotificationParams(
132-
level: LoggingLevel.info,
133-
data: 'Sending second greeting to $name',
134-
));
135-
}
122+
await extra?.sendNotification(JsonRpcLoggingMessageNotification(
123+
logParams: LoggingMessageNotificationParams(
124+
level: LoggingLevel.info,
125+
data: 'Sending second greeting to $name',
126+
)));
136127

137128
return CallToolResult(
138129
content: [
@@ -196,14 +187,12 @@ McpServer getServer() {
196187
while (count == 0 || counter < count) {
197188
counter++;
198189
try {
199-
if (globalServer != null) {
200-
await globalServer!
201-
.sendLoggingMessage(LoggingMessageNotificationParams(
202-
level: LoggingLevel.info,
203-
data:
204-
'Periodic notification #$counter at ${DateTime.now().toIso8601String()}',
205-
));
206-
}
190+
await extra?.sendNotification(JsonRpcLoggingMessageNotification(
191+
logParams: LoggingMessageNotificationParams(
192+
level: LoggingLevel.info,
193+
data:
194+
'Periodic notification #$counter at ${DateTime.now().toIso8601String()}',
195+
)));
207196
} catch (error) {
208197
print('Error sending notification: $error');
209198
}

lib/src/shared/protocol.dart

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,23 @@ class RequestHandlerExtra {
5555
/// The session ID from the transport, if available.
5656
final String? sessionId;
5757

58+
final RequestId requestId;
59+
60+
final Future<void> Function(JsonRpcNotification notification)
61+
sendNotification;
62+
63+
final Future<T> Function<T extends BaseResultData>(
64+
JsonRpcRequest request,
65+
T Function(Map<String, dynamic> resultJson) resultFactory,
66+
RequestOptions options) sendRequest;
67+
5868
/// Creates extra data for request handlers.
59-
const RequestHandlerExtra({required this.signal, this.sessionId});
69+
const RequestHandlerExtra(
70+
{required this.signal,
71+
this.sessionId,
72+
required this.requestId,
73+
required this.sendNotification,
74+
required this.sendRequest});
6075
}
6176

6277
/// Internal class holding timeout state for a request.
@@ -394,9 +409,14 @@ abstract class Protocol {
394409
_requestHandlerAbortControllers[request.id] = abortController;
395410

396411
final extra = RequestHandlerExtra(
397-
signal: abortController.signal,
398-
sessionId: _transport?.sessionId,
399-
);
412+
signal: abortController.signal,
413+
sessionId: _transport?.sessionId,
414+
requestId: request.id,
415+
sendNotification: (notification) => this.notification(notification),
416+
sendRequest: <T extends BaseResultData>(JsonRpcRequest request,
417+
T Function(Map<String, dynamic>) resultFactory,
418+
RequestOptions options) =>
419+
this.request<T>(request, resultFactory, options));
400420

401421
Future.microtask(() => handler(request, extra)).then(
402422
(result) async {
@@ -753,13 +773,7 @@ abstract class Protocol {
753773
assertNotificationCapability(notificationData.method);
754774
}
755775

756-
final jsonrpcNotification = JsonRpcNotification(
757-
method: notificationData.method,
758-
params: notificationData.params,
759-
meta: notificationData.meta,
760-
);
761-
762-
await _transport!.send(jsonrpcNotification);
776+
await _transport!.send(notificationData);
763777
}
764778

765779
/// Registers a handler for requests with the given method.

0 commit comments

Comments
 (0)