handleBroadcastEvent handles broadcast request events by executing local handlers and responding via RPC. This implements the protocol v3 broadcast model where tool calls and permission requests are broadcast as session events to all clients. Handlers are executed in their own goroutine (not the JS
(event SessionEvent)
| 1395 | // event consumer loop) so that a stalled handler does not block event delivery or |
| 1396 | // cause RPC deadlocks. |
| 1397 | func (s *Session) handleBroadcastEvent(event SessionEvent) { |
| 1398 | switch d := event.Data.(type) { |
| 1399 | case *ExternalToolRequestedData: |
| 1400 | handler, ok := s.getToolHandler(d.ToolName) |
| 1401 | if !ok { |
| 1402 | return |
| 1403 | } |
| 1404 | var tp, ts string |
| 1405 | if d.Traceparent != nil { |
| 1406 | tp = *d.Traceparent |
| 1407 | } |
| 1408 | if d.Tracestate != nil { |
| 1409 | ts = *d.Tracestate |
| 1410 | } |
| 1411 | s.executeToolAndRespond(d.RequestID, d.ToolName, d.ToolCallID, d.Arguments, handler, tp, ts) |
| 1412 | |
| 1413 | case *PermissionRequestedData: |
| 1414 | if d.ResolvedByHook != nil && *d.ResolvedByHook { |
| 1415 | return // Already resolved by a permissionRequest hook; no client action needed. |
| 1416 | } |
| 1417 | handler := s.getPermissionHandler() |
| 1418 | if handler == nil { |
| 1419 | return |
| 1420 | } |
| 1421 | s.executePermissionAndRespond(d.RequestID, d.PermissionRequest, handler) |
| 1422 | |
| 1423 | case *MCPOauthRequiredData: |
| 1424 | handler := s.getMCPAuthHandler() |
| 1425 | if d.RequestID == "" { |
| 1426 | return |
| 1427 | } |
| 1428 | if handler == nil { |
| 1429 | log.Printf( |
| 1430 | "Received MCP OAuth request without a registered MCP auth handler. SessionId=%s, RequestId=%s", |
| 1431 | s.SessionID, |
| 1432 | d.RequestID, |
| 1433 | ) |
| 1434 | return |
| 1435 | } |
| 1436 | var staticClientConfig *MCPAuthStaticClientConfig |
| 1437 | if d.StaticClientConfig != nil { |
| 1438 | var grantType *string |
| 1439 | if d.StaticClientConfig.GrantType != nil { |
| 1440 | value := string(*d.StaticClientConfig.GrantType) |
| 1441 | grantType = &value |
| 1442 | } |
| 1443 | staticClientConfig = &MCPAuthStaticClientConfig{ |
| 1444 | ClientID: d.StaticClientConfig.ClientID, |
| 1445 | ClientSecret: d.StaticClientConfig.ClientSecret, |
| 1446 | GrantType: grantType, |
| 1447 | PublicClient: d.StaticClientConfig.PublicClient, |
| 1448 | } |
| 1449 | } |
| 1450 | request := MCPAuthRequest{ |
| 1451 | RequestID: d.RequestID, |
| 1452 | ServerName: d.ServerName, |
| 1453 | ServerURL: d.ServerURL, |
| 1454 | Reason: d.Reason, |