feat: add rh Connect facade and tool coverage
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
# robinhood-agentic-mcp
|
||||
|
||||
Go library for the [Robinhood Agentic MCP](https://agent.robinhood.com/mcp/trading).
|
||||
|
||||
**Module:** `s1d3sw1ped/robinhood-agentic-mcp`
|
||||
**Go:** 1.25
|
||||
**Default MCP URL:** `https://agent.robinhood.com/mcp/trading` (`rh.DefaultURL`)
|
||||
|
||||
This moves **real money** in a Robinhood Agentic account. Not investment advice. The caller is responsible for every fill.
|
||||
|
||||
There is no CLI. `Login` is a library function. tradey is not wired to this module yet.
|
||||
|
||||
## Identity
|
||||
|
||||
Set `Config.Name` and `Config.Version` **before** `Login` or `Connect`. They are the MCP `Implementation` name/version and the OAuth client name. After a session exists they cannot be changed.
|
||||
|
||||
Empty `Name` / `Version` / `URL` become `robinhood-agentic-mcp` / `0.1.0` / `rh.DefaultURL`. Apps that need a distinct Robinhood OAuth client (tradey, another bot) pass their own `Name`.
|
||||
|
||||
```go
|
||||
cfg := rh.Config{
|
||||
TokenFile: "tokens.json",
|
||||
Name: "my-bot", // MCP identity and OAuth ClientName
|
||||
Version: "0.1.0",
|
||||
}
|
||||
```
|
||||
|
||||
Daemon/headless callers must not call `Login` (no browser). They call `Connect` with an existing token file (mode `0600`).
|
||||
|
||||
## Example
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
|
||||
decimal "github.com/alpacahq/alpacadecimal"
|
||||
rh "s1d3sw1ped/robinhood-agentic-mcp"
|
||||
"s1d3sw1ped/robinhood-agentic-mcp/equity"
|
||||
)
|
||||
|
||||
func main() {
|
||||
ctx := context.Background()
|
||||
cfg := rh.Config{
|
||||
TokenFile: "tokens.json",
|
||||
Name: "my-bot",
|
||||
}
|
||||
|
||||
if _, err := rh.Login(ctx, cfg); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
api, err := rh.Connect(ctx, cfg)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
qty := decimal.RequireFromString("1")
|
||||
limit := decimal.RequireFromString("100")
|
||||
_, err = api.Equity.PlaceOrder(ctx, equity.PlaceOrderRequest{
|
||||
Symbol: "MU",
|
||||
Side: rh.Buy,
|
||||
Type: rh.Limit,
|
||||
Qty: &qty,
|
||||
LimitPrice: &limit,
|
||||
TimeInForce: rh.GFD,
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`Login` writes tokens when `ROBINHOOD_ACCESS_TOKEN` is set, otherwise it runs a browser OAuth dance. `Connect` opens a streamable MCP session as `cfg.Name`/`cfg.Version`, or falls back to JSON-RPC `tools/call` with a bearer token.
|
||||
|
||||
Subpackages (`accounts`, `equity`, `options`, `crypto`, `watchlists`, `market`, `scanner`) also export `New(c client.Caller) *Client` for use without the facade. `api.Client.Call` is the escape hatch for any MCP tool by name.
|
||||
Reference in New Issue
Block a user