1
1
package main
2
2
3
3
import (
4
+ "context"
5
+ "flag"
4
6
"fmt"
5
7
"log"
6
8
"time"
@@ -79,6 +81,12 @@ func NewMCPServer() *MCPServer {
79
81
mcp .Required (),
80
82
),
81
83
), s .handleEchoTool )
84
+
85
+ s .server .AddTool (
86
+ mcp .NewTool ("notify" ),
87
+ s .handleSendNotification ,
88
+ )
89
+
82
90
s .server .AddTool (mcp .NewTool (string (ADD ),
83
91
mcp .WithDescription ("Adds two numbers" ),
84
92
mcp .WithNumber ("a" ,
@@ -127,7 +135,7 @@ func NewMCPServer() *MCPServer {
127
135
mcp .WithDescription ("Returns the MCP_TINY_IMAGE" ),
128
136
), s .handleGetTinyImageTool )
129
137
130
- s .server .AddNotificationHandler (s .handleNotification )
138
+ s .server .AddNotificationHandler ("notification" , s .handleNotification )
131
139
132
140
go s .runUpdateInterval ()
133
141
@@ -177,6 +185,7 @@ func (s *MCPServer) runUpdateInterval() {
177
185
}
178
186
179
187
func (s * MCPServer ) handleReadResource (
188
+ ctx context.Context ,
180
189
request mcp.ReadResourceRequest ,
181
190
) ([]interface {}, error ) {
182
191
return []interface {}{
@@ -191,6 +200,7 @@ func (s *MCPServer) handleReadResource(
191
200
}
192
201
193
202
func (s * MCPServer ) handleResourceTemplate (
203
+ ctx context.Context ,
194
204
request mcp.ReadResourceRequest ,
195
205
) ([]interface {}, error ) {
196
206
return []interface {}{
@@ -205,7 +215,8 @@ func (s *MCPServer) handleResourceTemplate(
205
215
}
206
216
207
217
func (s * MCPServer ) handleSimplePrompt (
208
- arguments map [string ]string ,
218
+ ctx context.Context ,
219
+ request mcp.GetPromptRequest ,
209
220
) (* mcp.GetPromptResult , error ) {
210
221
return & mcp.GetPromptResult {
211
222
Description : "A simple prompt without arguments" ,
@@ -222,8 +233,10 @@ func (s *MCPServer) handleSimplePrompt(
222
233
}
223
234
224
235
func (s * MCPServer ) handleComplexPrompt (
225
- arguments map [string ]string ,
236
+ ctx context.Context ,
237
+ request mcp.GetPromptRequest ,
226
238
) (* mcp.GetPromptResult , error ) {
239
+ arguments := request .Params .Arguments
227
240
return & mcp.GetPromptResult {
228
241
Description : "A complex prompt with arguments" ,
229
242
Messages : []mcp.PromptMessage {
@@ -258,8 +271,10 @@ func (s *MCPServer) handleComplexPrompt(
258
271
}
259
272
260
273
func (s * MCPServer ) handleEchoTool (
261
- arguments map [string ]interface {},
274
+ ctx context.Context ,
275
+ request mcp.CallToolRequest ,
262
276
) (* mcp.CallToolResult , error ) {
277
+ arguments := request .Params .Arguments
263
278
message , ok := arguments ["message" ].(string )
264
279
if ! ok {
265
280
return nil , fmt .Errorf ("invalid message argument" )
@@ -275,8 +290,10 @@ func (s *MCPServer) handleEchoTool(
275
290
}
276
291
277
292
func (s * MCPServer ) handleAddTool (
278
- arguments map [string ]interface {},
293
+ ctx context.Context ,
294
+ request mcp.CallToolRequest ,
279
295
) (* mcp.CallToolResult , error ) {
296
+ arguments := request .Params .Arguments
280
297
a , ok1 := arguments ["a" ].(float64 )
281
298
b , ok2 := arguments ["b" ].(float64 )
282
299
if ! ok1 || ! ok2 {
@@ -293,35 +310,65 @@ func (s *MCPServer) handleAddTool(
293
310
}, nil
294
311
}
295
312
313
+ func (s * MCPServer ) handleSendNotification (
314
+ ctx context.Context ,
315
+ request mcp.CallToolRequest ,
316
+ ) (* mcp.CallToolResult , error ) {
317
+
318
+ server := server .ServerFromContext (ctx )
319
+
320
+ err := server .SendNotificationToClient (
321
+ "notifications/progress" ,
322
+ map [string ]interface {}{
323
+ "progress" : 10 ,
324
+ "total" : 10 ,
325
+ "progressToken" : 0 ,
326
+ },
327
+ )
328
+ if err != nil {
329
+ return nil , fmt .Errorf ("failed to send notification: %w" , err )
330
+ }
331
+
332
+ return & mcp.CallToolResult {
333
+ Content : []interface {}{
334
+ mcp.TextContent {
335
+ Type : "text" ,
336
+ Text : "notification sent successfully" ,
337
+ },
338
+ },
339
+ }, nil
340
+ }
341
+
342
+ func (s * MCPServer ) ServeSSE (addr string ) * server.SSEServer {
343
+ return server .NewSSEServer (s .server , fmt .Sprintf ("http://%s" , addr ))
344
+ }
345
+
346
+ func (s * MCPServer ) ServeStdio () error {
347
+ return server .ServeStdio (s .server )
348
+ }
349
+
296
350
func (s * MCPServer ) handleLongRunningOperationTool (
297
- arguments map [string ]interface {},
351
+ ctx context.Context ,
352
+ request mcp.CallToolRequest ,
298
353
) (* mcp.CallToolResult , error ) {
354
+ arguments := request .Params .Arguments
355
+ progressToken := request .Params .Meta .ProgressToken
299
356
duration , _ := arguments ["duration" ].(float64 )
300
357
steps , _ := arguments ["steps" ].(float64 )
301
358
stepDuration := duration / steps
302
- progressToken , _ := arguments [ "_meta" ].( map [ string ] interface {})[ "progressToken" ].(mcp. ProgressToken )
359
+ server := server . ServerFromContext ( ctx )
303
360
304
361
for i := 1 ; i < int (steps )+ 1 ; i ++ {
305
362
time .Sleep (time .Duration (stepDuration * float64 (time .Second )))
306
363
if progressToken != nil {
307
- // s.server.HandleMessage(
308
- // context.Background(),
309
- // mcp.JSONRPCNotification{
310
- // JSONRPC: mcp.JSONRPC_VERSION,
311
- // Notification: mcp.Notification{
312
- // Method: "progress",
313
- // Params: struct {
314
- // Meta map[string]interface{} `json:"_meta,omitempty"`
315
- // }{
316
- // Meta: map[string]interface{}{
317
- // "progress": i,
318
- // "total": int(steps),
319
- // "progressToken": progressToken,
320
- // },
321
- // },
322
- // },
323
- // },
324
- // )
364
+ server .SendNotificationToClient (
365
+ "notifications/progress" ,
366
+ map [string ]interface {}{
367
+ "progress" : i ,
368
+ "total" : int (steps ),
369
+ "progressToken" : progressToken ,
370
+ },
371
+ )
325
372
}
326
373
}
327
374
@@ -361,7 +408,8 @@ func (s *MCPServer) handleLongRunningOperationTool(
361
408
// }
362
409
363
410
func (s * MCPServer ) handleGetTinyImageTool (
364
- arguments map [string ]interface {},
411
+ ctx context.Context ,
412
+ request mcp.CallToolRequest ,
365
413
) (* mcp.CallToolResult , error ) {
366
414
return & mcp.CallToolResult {
367
415
Content : []interface {}{
@@ -382,7 +430,10 @@ func (s *MCPServer) handleGetTinyImageTool(
382
430
}, nil
383
431
}
384
432
385
- func (s * MCPServer ) handleNotification (notification mcp.JSONRPCNotification ) {
433
+ func (s * MCPServer ) handleNotification (
434
+ ctx context.Context ,
435
+ notification mcp.JSONRPCNotification ,
436
+ ) {
386
437
log .Printf ("Received notification: %s" , notification .Method )
387
438
}
388
439
@@ -391,9 +442,34 @@ func (s *MCPServer) Serve() error {
391
442
}
392
443
393
444
func main () {
445
+ var transport string
446
+ flag .StringVar (& transport , "t" , "stdio" , "Transport type (stdio or sse)" )
447
+ flag .StringVar (
448
+ & transport ,
449
+ "transport" ,
450
+ "stdio" ,
451
+ "Transport type (stdio or sse)" ,
452
+ )
453
+ flag .Parse ()
454
+
394
455
server := NewMCPServer ()
395
- if err := server .Serve (); err != nil {
396
- log .Fatalf ("Server error: %v" , err )
456
+
457
+ switch transport {
458
+ case "stdio" :
459
+ if err := server .ServeStdio (); err != nil {
460
+ log .Fatalf ("Server error: %v" , err )
461
+ }
462
+ case "sse" :
463
+ sseServer := server .ServeSSE ("localhost:8080" )
464
+ log .Printf ("SSE server listening on :8080" )
465
+ if err := sseServer .Start (":8080" ); err != nil {
466
+ log .Fatalf ("Server error: %v" , err )
467
+ }
468
+ default :
469
+ log .Fatalf (
470
+ "Invalid transport type: %s. Must be 'stdio' or 'sse'" ,
471
+ transport ,
472
+ )
397
473
}
398
474
}
399
475
0 commit comments