| 3128 | } |
| 3129 | |
| 3130 | func (c *unixSocketClient) StreamHostedMCPProjection( |
| 3131 | ctx context.Context, |
| 3132 | bindID string, |
| 3133 | lastDigest string, |
| 3134 | handler mcppkg.HostedProjectionHandler, |
| 3135 | ) error { |
| 3136 | query := url.Values{} |
| 3137 | query.Set("bind_id", strings.TrimSpace(bindID)) |
| 3138 | if trimmed := strings.TrimSpace(lastDigest); trimmed != "" { |
| 3139 | query.Set("last_digest", trimmed) |
| 3140 | } |
| 3141 | return c.doSSE( |
| 3142 | ctx, |
| 3143 | http.MethodGet, |
| 3144 | "/api/internal/hosted-mcp/projection/stream", |
| 3145 | query, |
| 3146 | nil, |
| 3147 | "", |
| 3148 | func(event SSEEvent) error { |
| 3149 | if event.Event == clientErrorKey { |
| 3150 | return readAPIErrorBody(0, "", event.Data) |
| 3151 | } |
| 3152 | if event.Event != "projection" { |
| 3153 | return nil |
| 3154 | } |
| 3155 | var snapshot mcppkg.HostedProjectionResponse |
| 3156 | if err := json.Unmarshal(event.Data, &snapshot); err != nil { |
| 3157 | return fmt.Errorf("cli: decode hosted MCP projection event: %w", err) |
| 3158 | } |
| 3159 | if handler == nil { |
| 3160 | return nil |
| 3161 | } |
| 3162 | return handler(snapshot) |
| 3163 | }, |
| 3164 | ) |
| 3165 | } |
| 3166 | |
| 3167 | func (c *unixSocketClient) CallHostedMCP( |
| 3168 | ctx context.Context, |