Skip to content

Commit ccb5cdb

Browse files
committed
Fixes
1 parent 1d95aa0 commit ccb5cdb

File tree

1 file changed

+43
-11
lines changed

1 file changed

+43
-11
lines changed

server/session.go

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -98,14 +98,16 @@ func (s *MCPServer) SendNotificationToAllClients(
9898
// Channel is blocked, if there's an error hook, use it
9999
if s.hooks != nil && len(s.hooks.OnError) > 0 {
100100
err := ErrNotificationChannelBlocked
101-
go func(sessionID string) {
101+
// Copy hooks pointer to local variable to avoid race condition
102+
hooks := s.hooks
103+
go func(sessionID string, hooks *Hooks) {
102104
ctx := context.Background()
103105
// Use the error hook to report the blocked channel
104-
s.hooks.onError(ctx, nil, "notification", map[string]interface{}{
106+
hooks.onError(ctx, nil, "notification", map[string]interface{}{
105107
"method": method,
106108
"sessionID": sessionID,
107109
}, fmt.Errorf("notification channel blocked for session %s: %w", sessionID, err))
108-
}(session.SessionID())
110+
}(session.SessionID(), hooks)
109111
}
110112
}
111113
}
@@ -141,13 +143,15 @@ func (s *MCPServer) SendNotificationToClient(
141143
// Channel is blocked, if there's an error hook, use it
142144
if s.hooks != nil && len(s.hooks.OnError) > 0 {
143145
err := ErrNotificationChannelBlocked
144-
go func(sessionID string) {
146+
// Copy hooks pointer to local variable to avoid race condition
147+
hooks := s.hooks
148+
go func(sessionID string, hooks *Hooks) {
145149
// Use the error hook to report the blocked channel
146-
s.hooks.onError(ctx, nil, "notification", map[string]interface{}{
150+
hooks.onError(ctx, nil, "notification", map[string]interface{}{
147151
"method": method,
148152
"sessionID": sessionID,
149153
}, fmt.Errorf("notification channel blocked for session %s: %w", sessionID, err))
150-
}(session.SessionID())
154+
}(session.SessionID(), hooks)
151155
}
152156
return ErrNotificationChannelBlocked
153157
}
@@ -187,13 +191,15 @@ func (s *MCPServer) SendNotificationToSpecificClient(
187191
if s.hooks != nil && len(s.hooks.OnError) > 0 {
188192
err := ErrNotificationChannelBlocked
189193
ctx := context.Background()
190-
go func(sID string) {
194+
// Copy hooks pointer to local variable to avoid race condition
195+
hooks := s.hooks
196+
go func(sID string, hooks *Hooks) {
191197
// Use the error hook to report the blocked channel
192-
s.hooks.onError(ctx, nil, "notification", map[string]interface{}{
198+
hooks.onError(ctx, nil, "notification", map[string]interface{}{
193199
"method": method,
194200
"sessionID": sID,
195201
}, fmt.Errorf("notification channel blocked for session %s: %w", sID, err))
196-
}(sessionID)
202+
}(sessionID, hooks)
197203
}
198204
return ErrNotificationChannelBlocked
199205
}
@@ -236,7 +242,20 @@ func (s *MCPServer) AddSessionTools(sessionID string, tools ...ServerTool) error
236242
session.SetSessionTools(newSessionTools)
237243

238244
// Send notification only to this session
239-
s.SendNotificationToSpecificClient(sessionID, "notifications/tools/list_changed", nil)
245+
if err := s.SendNotificationToSpecificClient(sessionID, "notifications/tools/list_changed", nil); err != nil {
246+
// Log the error but don't fail the operation
247+
// The tools were successfully added, but notification failed
248+
if s.hooks != nil && len(s.hooks.OnError) > 0 {
249+
hooks := s.hooks
250+
go func(sID string, hooks *Hooks) {
251+
ctx := context.Background()
252+
hooks.onError(ctx, nil, "notification", map[string]interface{}{
253+
"method": "notifications/tools/list_changed",
254+
"sessionID": sID,
255+
}, fmt.Errorf("failed to send notification after adding tools: %w", err))
256+
}(sessionID, hooks)
257+
}
258+
}
240259

241260
return nil
242261
}
@@ -274,7 +293,20 @@ func (s *MCPServer) DeleteSessionTools(sessionID string, names ...string) error
274293
session.SetSessionTools(newSessionTools)
275294

276295
// Send notification only to this session
277-
s.SendNotificationToSpecificClient(sessionID, "notifications/tools/list_changed", nil)
296+
if err := s.SendNotificationToSpecificClient(sessionID, "notifications/tools/list_changed", nil); err != nil {
297+
// Log the error but don't fail the operation
298+
// The tools were successfully deleted, but notification failed
299+
if s.hooks != nil && len(s.hooks.OnError) > 0 {
300+
hooks := s.hooks
301+
go func(sID string, hooks *Hooks) {
302+
ctx := context.Background()
303+
hooks.onError(ctx, nil, "notification", map[string]interface{}{
304+
"method": "notifications/tools/list_changed",
305+
"sessionID": sID,
306+
}, fmt.Errorf("failed to send notification after deleting tools: %w", err))
307+
}(sessionID, hooks)
308+
}
309+
}
278310

279311
return nil
280312
}

0 commit comments

Comments
 (0)