resolveExploreToolSnapshot computes the child chat's inherited MCP server snapshot from the spawning parent turn. The MCP set is filtered in two stages. First, filterExternalMCPConfigsForTurn applies the parent turn's plan-mode policy to the parent's MCP configs, producing visibleConfigs. Second, i
( ctx context.Context, parent database.Chat, )
| 872 | // re-escalate beyond the original grant. Non-Explore parents pass |
| 873 | // through the second stage unchanged. |
| 874 | func (p *Server) resolveExploreToolSnapshot( |
| 875 | ctx context.Context, |
| 876 | parent database.Chat, |
| 877 | ) ([]uuid.UUID, error) { |
| 878 | inheritedMCPServerIDs := []uuid.UUID{} |
| 879 | if len(parent.MCPServerIDs) > 0 { |
| 880 | configs, err := p.db.GetMCPServerConfigsByIDs(ctx, parent.MCPServerIDs) |
| 881 | if err != nil { |
| 882 | return nil, xerrors.Errorf("get parent MCP server configs for chat %s: %w", parent.ID, err) |
| 883 | } |
| 884 | |
| 885 | visibleConfigs, _ := filterExternalMCPConfigsForTurn( |
| 886 | configs, |
| 887 | parent.PlanMode, |
| 888 | parent.ParentChatID, |
| 889 | ) |
| 890 | // Empty means the parent is not Explore, so all plan-filtered |
| 891 | // configs remain eligible. Populated means the parent is |
| 892 | // Explore, so only its persisted snapshot can pass. |
| 893 | allowedParentIDs := map[uuid.UUID]struct{}{} |
| 894 | if isExploreSubagentMode(parent.Mode) { |
| 895 | for _, id := range parent.MCPServerIDs { |
| 896 | allowedParentIDs[id] = struct{}{} |
| 897 | } |
| 898 | } |
| 899 | for _, cfg := range visibleConfigs { |
| 900 | if len(allowedParentIDs) > 0 { |
| 901 | if _, ok := allowedParentIDs[cfg.ID]; !ok { |
| 902 | continue |
| 903 | } |
| 904 | } |
| 905 | inheritedMCPServerIDs = append(inheritedMCPServerIDs, cfg.ID) |
| 906 | } |
| 907 | } |
| 908 | |
| 909 | return inheritedMCPServerIDs, nil |
| 910 | } |
| 911 | |
| 912 | func (p *Server) delegatedAPIKeyIDForSubagent(ctx context.Context) (string, error) { |
| 913 | apiKeyID, ok := aibridge.DelegatedAPIKeyIDFromContext(ctx) |