fix: parse MCP result payloads and drop place idempotency_key

Typed result structs replace empty envelopes. Equity place sends
ref_id only so live additionalProperties:false schemas accept the call.
This commit is contained in:
2026-09-01 14:18:39 -05:00
parent f52a19181d
commit a6bf8632ce
22 changed files with 2225 additions and 74 deletions
+55
View File
@@ -0,0 +1,55 @@
package watchlists
import (
"encoding/json"
"s1d3sw1ped/robinhood-agentic-mcp/internal/wire"
)
func (r *OptionListResult) UnmarshalJSON(b []byte) error {
type row struct {
OptionID string `json:"option_id"`
ID string `json:"id"`
Symbol string `json:"symbol"`
Title string `json:"title"`
PositionType string `json:"position_type"`
}
rows, _, err := wire.UnmarshalRows[row](b, "items", "results", "options")
if err != nil {
return err
}
r.Items = make([]OptionWatchItem, 0, len(rows))
for _, row := range rows {
id := row.OptionID
if id == "" {
id = row.ID
}
r.Items = append(r.Items, OptionWatchItem{
OptionID: id, Symbol: row.Symbol, Title: row.Title, PositionType: row.PositionType,
})
}
return nil
}
func (r *PopularResult) UnmarshalJSON(b []byte) error {
type row struct {
ID string `json:"id"`
Title string `json:"title"`
Name string `json:"name"`
}
rows, _, err := wire.UnmarshalRows[row](b, "watchlists", "results")
if err != nil {
return err
}
r.Watchlists = make([]Watchlist, 0, len(rows))
for _, row := range rows {
title := row.Title
if title == "" {
title = row.Name
}
r.Watchlists = append(r.Watchlists, Watchlist{ID: row.ID, Title: title})
}
return nil
}
var _ json.Unmarshaler = (*OptionListResult)(nil)
+14 -2
View File
@@ -63,14 +63,26 @@ type ItemsResult struct {
// OptionListRequest is the argument set for get_option_watchlist (none).
type OptionListRequest struct{}
// OptionWatchItem is one contract on the options watchlist.
type OptionWatchItem struct {
OptionID string
Symbol string
Title string
PositionType string
}
// OptionListResult is the parsed get_option_watchlist payload.
type OptionListResult struct{}
type OptionListResult struct {
Items []OptionWatchItem
}
// PopularRequest is the argument set for get_popular_watchlists (none).
type PopularRequest struct{}
// PopularResult is the parsed get_popular_watchlists payload.
type PopularResult struct{}
type PopularResult struct {
Watchlists []Watchlist
}
// CreateRequest is the argument set for create_watchlist.
type CreateRequest struct {