Skip to content

Commit 0dab3a1

Browse files
committed
feat: AI-native Robinhood trading interface for agents
TypeScript monorepo providing a standalone API client (@rh-for-agents/client) and MCP server with 18 tools for AI agents to interact with Robinhood. - Standalone client library with session caching, multi-account support, and proper error handling (AuthenticationError, APIError) - MCP server exposing tools for portfolio, trading, options, research, and account management via stdio transport - Claude Code skills with three-layer progressive disclosure (SKILL.md → reference.md → client-api.md) - Browser-based authentication via playwright-core: passive network interception of OAuth tokens (no DOM interaction, resilient to UI changes) - Token refresh flow with device_token and expires_in (matching pyrh) - AES-256-GCM encrypted token storage with OS keychain key management - Order placement safety checks — explicit parameters, user confirmation required - Full test suite with mocked HTTP layer (Vitest) - Biome v2 for linting/formatting, strict TypeScript, ESM-only
1 parent 0e26224 commit 0dab3a1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+2491
-338
lines changed

.github/FUNDING.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
github: kevin1chun

.github/ISSUE_TEMPLATE/bug_report.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ labels: bug
66

77
## Environment
88

9-
- **rh-agent-tools version**:
9+
- **rh-for-agents version**:
1010
- **Bun version** (`bun --version`):
1111
- **OS**:
1212
- **MCP client** (Claude Code / Claude Desktop / other):

.github/dependabot.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: npm
4+
directory: /
5+
schedule:
6+
interval: weekly
7+
groups:
8+
minor-and-patch:
9+
update-types: [minor, patch]
10+
- package-ecosystem: github-actions
11+
directory: /
12+
schedule:
13+
interval: weekly

.github/workflows/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@ name: CI
22

33
on:
44
push:
5-
branches: [master]
5+
branches: [main]
66
pull_request:
7-
branches: [master]
7+
branches: [main]
88

99
jobs:
1010
check:
1111
runs-on: ubuntu-latest
1212
steps:
13-
- uses: actions/checkout@v4
13+
- uses: actions/checkout@v6
1414
- uses: oven-sh/setup-bun@v2
1515
- run: bun install --frozen-lockfile
1616
- run: bun run check

.github/workflows/release.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Release
2+
on:
3+
push:
4+
tags: ["v*"]
5+
6+
jobs:
7+
release:
8+
runs-on: ubuntu-latest
9+
permissions:
10+
contents: write # create GitHub Release
11+
id-token: write # npm provenance
12+
steps:
13+
- uses: actions/checkout@v6
14+
- uses: actions/setup-node@v4
15+
with:
16+
node-version: "22"
17+
registry-url: "https://registry.npmjs.org"
18+
- uses: oven-sh/setup-bun@v2
19+
- run: bun install --frozen-lockfile
20+
- run: bun run check
21+
- run: bun run typecheck
22+
- run: npx vitest run
23+
- run: cd packages/client && npm publish --provenance --access public
24+
env:
25+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
26+
- run: cd packages/server && npm publish --provenance --access public
27+
env:
28+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
29+
- uses: softprops/action-gh-release@v2
30+
with:
31+
generate_release_notes: true

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ dist/
77
.DS_Store
88
*~
99
coverage/
10+
.claude/

CHANGELOG.md

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,39 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8-
## [0.3.0] - 2025-03-10
8+
## [0.2.0] - 2026-03-10
9+
10+
### Added
11+
12+
- **Token refresh flow** using `refresh_token` + `device_token` with `expires_in: 734000` (~8.5 days, matching pyrh). Sessions last significantly longer before requiring browser re-login.
13+
- Detailed encrypt/decrypt flow diagrams in `ARCHITECTURE.md`
14+
- Authentication section in `CLAUDE.md` documenting browser auth mechanism
15+
16+
### Fixed
17+
18+
- **device_token capture** in browser login — Robinhood's frontend sends OAuth requests as JSON, not form-urlencoded. The interceptor now parses JSON first, correctly capturing `device_token`.
19+
- **Release workflow** — added `setup-node` with `registry-url` for npm authentication
20+
21+
### Changed
22+
23+
- README prerequisites clarified: Google Chrome is required by `playwright-core` (no bundled browser)
24+
- Removed `robin_stocks` migration context from `ARCHITECTURE.md`
25+
- Removed OpenClaw MCP bridge references from README
26+
27+
## [0.1.0] - 2026-03-10
928

1029
### Added
1130

1231
- **MCP Server** with 18 structured tools for any MCP-compatible AI agent
13-
- **Standalone client library** (`@rh-agent-tools/client`) with ~50 async methods
32+
- **Standalone client library** (`@rh-for-agents/client`) with ~50 async methods
1433
- **5 Claude Code skills**: setup, portfolio, research, trade, options
1534
- Browser-based authentication via Playwright (Chrome)
1635
- AES-256-GCM encrypted session storage with OS keychain key management
1736
- Multi-account support (first-class across all account-scoped methods)
18-
- Interactive onboarding TUI (`rh-agent-tools onboard`)
19-
- One-command install for Claude Code (`rh-agent-tools install`)
37+
- Interactive onboarding TUI (`rh-for-agents onboard`)
38+
- One-command install for Claude Code (`rh-for-agents install`)
2039
- Safety controls: blocked fund transfers, blocked bulk cancels, explicit order parameters
2140
- Support for Claude Code, Codex, and OpenClaw agents
2241

23-
[0.3.0]: https://github.com/kevin1chun/rh-agent-tools/releases/tag/v0.3.0
42+
[0.2.0]: https://github.com/kevin1chun/rh-for-agents/compare/v0.1.0...v0.2.0
43+
[0.1.0]: https://github.com/kevin1chun/rh-for-agents/releases/tag/v0.1.0

CLAUDE.md

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
# rh-agent-tools
1+
# rh-for-agents
22

33
AI-native Robinhood trading interface — TypeScript monorepo with a standalone API client and MCP server.
44

55
## Project Structure
6-
- `packages/client/``@rh-agent-tools/client`: Standalone Robinhood API client
7-
- `packages/server/``rh-agent-tools`: MCP server with 18 tools
6+
- `packages/client/``@rh-for-agents/client`: Standalone Robinhood API client
7+
- `packages/server/``rh-for-agents`: MCP server with 18 tools
88
- `.claude/skills/` — Claude Code skills for interactive use (SKILL.md only, no scripts)
99
- `docs/` — Architecture, access controls, use cases, contributing
1010

@@ -15,12 +15,12 @@ AI-native Robinhood trading interface — TypeScript monorepo with a standalone
1515
- **Validation**: Zod v3.24 (API responses + MCP tool schemas)
1616
- **Testing**: Vitest (not `bun test` — module isolation matters)
1717
- **Linting**: Biome v2
18-
- **Browser Auth**: playwright-core (browser auth)
18+
- **Browser Auth**: playwright-core (drives system Chrome, no bundled browser)
1919

2020
## Running the MCP Server
2121
```bash
2222
bun install
23-
bun packages/server/bin/rh-agent-tools.ts
23+
bun packages/server/bin/rh-for-agents.ts
2424
```
2525

2626
## Development
@@ -33,7 +33,7 @@ npx vitest run # all tests (use vitest, NOT bun test)
3333
## Skills
3434
Canonical skill source is `packages/server/skills/`. Local `.claude/skills/` contains symlinks for development.
3535

36-
Install MCP server + skills: `bun packages/server/bin/rh-agent-tools.ts install`
36+
Install MCP server + skills: `bun packages/server/bin/rh-for-agents.ts install`
3737

3838
Skills use three-layer progressive disclosure:
3939
1. **SKILL.md** — MCP tool orchestration (default)
@@ -49,7 +49,7 @@ Available skills:
4949

5050
## Client Patterns
5151
```typescript
52-
import { RobinhoodClient, getClient } from "@rh-agent-tools/client";
52+
import { RobinhoodClient, getClient } from "@rh-for-agents/client";
5353

5454
// Class-based
5555
const client = new RobinhoodClient();
@@ -62,10 +62,18 @@ await rh.restoreSession();
6262
```
6363
- All methods are `async` (native `fetch` under the hood)
6464
- Multi-account is first-class: every account-scoped method accepts `accountNumber`
65-
- Session cached to `~/.rh-agent-tools/session.enc` (AES-256-GCM, key in OS keychain)
65+
- Session cached to `~/.rh-for-agents/session.enc` (AES-256-GCM, key in OS keychain)
66+
- Token refresh via `refresh_token` + `device_token` when access token expires
6667
- Proper exceptions: `AuthenticationError`, `APIError`
6768
- **Do NOT use `phoenix.robinhood.com`** — it rejects TLS. Use `api.robinhood.com` endpoints only.
6869

70+
## Authentication
71+
- Browser login (`robinhood_browser_login`) opens system Chrome via playwright-core
72+
- Purely passive — Playwright intercepts `/oauth2/token` network traffic, never interacts with the DOM
73+
- Request body (JSON) → captures `device_token`; Response → captures `access_token` + `refresh_token`
74+
- Tokens encrypted with AES-256-GCM, key stored in OS keychain (never on disk)
75+
- `restoreSession()` validates cached token, falls back to refresh, then directs to browser login
76+
6977
## Safety Rules
7078
- **NEVER** place bulk cancel operations
7179
- **NEVER** call fund transfer functions

0 commit comments

Comments
 (0)