feat: add MCP enums, ToolError, and Caller

This commit is contained in:
2026-09-01 11:26:23 -05:00
parent 7d549fda58
commit e80095525d
5 changed files with 128 additions and 0 deletions
+18
View File
@@ -0,0 +1,18 @@
package client
import (
"context"
"encoding/json"
)
// Caller invokes an MCP tool by name and returns its JSON result.
type Caller interface {
Call(ctx context.Context, name string, args map[string]any) (json.RawMessage, error)
}
// Func adapts a function to Caller so tests can inject a stub.
type Func func(ctx context.Context, name string, args map[string]any) (json.RawMessage, error)
func (f Func) Call(ctx context.Context, name string, args map[string]any) (json.RawMessage, error) {
return f(ctx, name, args)
}
+41
View File
@@ -0,0 +1,41 @@
package client
// Side is an order side. Values are Robinhood wire strings.
type Side string
const (
Buy Side = "buy"
Sell Side = "sell"
)
// OrderType is an order type. Values are Robinhood wire strings.
type OrderType string
const (
Market OrderType = "market"
Limit OrderType = "limit"
Stop OrderType = "stop_market" // equity + options; crypto uses StopLoss
StopLimit OrderType = "stop_limit"
StopLoss OrderType = "stop_loss" // crypto only
)
// TimeInForce is an order duration. Values are Robinhood wire strings.
type TimeInForce string
const (
GFD TimeInForce = "gfd"
GTC TimeInForce = "gtc"
GFW TimeInForce = "gfw" // crypto
GFM TimeInForce = "gfm" // crypto
)
// MarketHours is a trading-session window. Values are Robinhood wire strings.
type MarketHours string
const (
RegularHours MarketHours = "regular_hours"
ExtendedHours MarketHours = "extended_hours"
AllDayHours MarketHours = "all_day_hours"
RegularCurbHours MarketHours = "regular_curb_hours"
RegularCurbOvernightHours MarketHours = "regular_curb_overnight_hours"
)
+17
View File
@@ -0,0 +1,17 @@
package client_test
import (
"testing"
"s1d3sw1ped/robinhood-agentic-mcp/client"
)
func TestEnums_wireValues(t *testing.T) {
t.Parallel()
if client.Buy != "buy" || client.Stop != "stop_market" || client.StopLoss != "stop_loss" {
t.Fatal("side/type")
}
if client.GFD != "gfd" || client.RegularHours != "regular_hours" {
t.Fatal("tif/hours")
}
}
+28
View File
@@ -0,0 +1,28 @@
package client
import "fmt"
// ToolError is a failed MCP tool call or a parse of its result.
type ToolError struct {
Name string // MCP tool name
Message string
Err error // transport/SDK/parse cause; may be nil
}
func (e *ToolError) Error() string {
return "mcp " + e.Name + ": " + e.Message
}
func (e *ToolError) Unwrap() error {
return e.Err
}
// ToolErrorf builds a ToolError. format may use %w so Unwrap works.
func ToolErrorf(name, format string, args ...any) *ToolError {
err := fmt.Errorf(format, args...)
return &ToolError{
Name: name,
Message: err.Error(),
Err: err,
}
}
+24
View File
@@ -0,0 +1,24 @@
package client_test
import (
"errors"
"testing"
"s1d3sw1ped/robinhood-agentic-mcp/client"
)
func TestToolError_formatAndAs(t *testing.T) {
t.Parallel()
inner := errors.New("boom")
err := client.ToolErrorf("get_accounts", "parse quotes: %w", inner)
if err.Error() != "mcp get_accounts: parse quotes: boom" {
t.Fatalf("%q", err.Error())
}
var te *client.ToolError
if !errors.As(err, &te) || te.Name != "get_accounts" {
t.Fatalf("%v", err)
}
if !errors.Is(err, inner) {
t.Fatal("unwrap")
}
}