feat: add order history tool - #17
Merged
Merged
Conversation
Add `robinhood_get_order_history`, a read-only tool that wraps `robin_stocks.orders.get_all_stock_orders()` to surface executed buy/sell history — the trades that built the current positions. - Curated rows (symbol, side, state, quantity, filled quantity, average price, type, timestamps, per-fill executions), never a raw API dump. - Instrument-URL → ticker resolution via `get_symbol_by_url`, cached in a module-level `_symbol_url_cache` (instrument→symbol mappings are immutable, so no TTL). Distinct URLs resolve once per call; unresolvable instruments fall back to `symbol: None` rather than failing the whole response. - `state="executed"` (default) filters on a non-empty `executions` list, catching both `filled` and `partially_filled`; `state="all"` returns cancelled/queued/rejected rows too. - Optional `symbol` filter resolves ticker→URL first and matches on `instrument`, skipping per-row resolution. `start_date` passes through to the API for server-side trimming. `limit` slices most recent first. - Wraps only the read endpoint — the `cancel_*` siblings in `rh.orders` are never exposed, consistent with the no-trading rule. Lands the server at 14 tools, still within the comfort ceiling. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds a new read-only MCP tool to surface Robinhood stock order history (buys/sells) as curated, symbol-resolved rows with per-fill execution details, filling the gap between “current positions” and “how you got there”.
Changes:
- Implement
get_order_historyintools.py, including instrument-URL→symbol resolution with a module-level cache and filtering options (symbol,state,limit,start_date). - Register the new tool in the FastMCP server and expose it in
server.json, plus update README docs. - Add a dedicated
TestGetOrderHistorytest suite and related fixtures/helpers.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_tools.py | Adds TestGetOrderHistory plus cache-reset fixture and order-shaped test helpers. |
| src/robinhood_mcp/tools.py | Implements order history retrieval, curation, filtering, sorting, and symbol-resolution caching. |
| src/robinhood_mcp/server.py | Registers the new robinhood_get_order_history MCP tool and wires it to get_order_history. |
| server.json | Adds the new tool to published MCP server metadata. |
| README.md | Documents trade history usage and adds the tool to the tool table. |
| CLAUDE.md | Updates the architecture overview (tool count). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Addresses GitHub Copilot review on PR #17. - Add `_raw_executions()` helper that normalizes an order's `executions` field to a list of dicts, tolerating malformed (non-list) API data. Used by both `_order_payload` and the `state="executed"` filter so a non-list value can no longer crash `_order_payload` (it iterated the raw value directly) and no longer slips past the executed filter as a truthy non-list. One definition keeps filter and payload consistent. - server.json: add the missing `robinhood_get_position` entry so the published tool metadata matches the registered tool surface (14 tools). - CLAUDE.md: correct the architecture comment to 14 tool implementations. Adds a regression test for malformed `executions` values. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The module-level symbol cache only stores successful instrument->symbol lookups, so an unresolvable URL shared by many order rows re-hit the API once per row. Resolve each distinct instrument URL once per call via a local map, keeping the no-TTL module cache for successful lookups. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
robinhood_get_order_history, a read-only tool that wrapsrobin_stocks.orders.get_all_stock_orders()to surface executed buy/sell history — the trades that built the current positions. Fills a gap: the server could show what you hold now, but not what you bought or sold to get there.What it returns
Curated rows (newest first), never a raw API dump:
symbol,side,state,quantity,filled_quantity,average_price,type,created_at,last_transaction_atexecutions[]— per-fill price/quantity/timestamp detailDesign notes
get_symbol_by_url, cached in a module-level_symbol_url_cache(instrument→symbol mappings are immutable, so no TTL). Distinct URLs resolve once per call; an unresolvable instrument falls back tosymbol: Nonerather than failing the whole response.statefilter.state="executed"(default) filters on a non-emptyexecutionslist, catching bothfilledandpartially_filled— a literalstate == "filled"check would silently drop partial fills.state="all"returns cancelled/queued/rejected rows too.symbolfilter. When provided, resolves ticker→URL first via the existing_validate_symbol_instrumentand matches oninstrument, skipping per-row resolution.start_datepasses straight through to the API for server-side trimming;limitslices most-recent-first.cancel_*siblings inrh.ordersare never exposed.Lands the server at 14 tools, still within the comfort ceiling.
Tests
TestGetOrderHistory— 12 new tests, written test-first (TDD): curated rows, distinct-URL resolution dedup,executedvsallstate filtering, symbol filter, limit + ordering,start_datepassthrough, unresolvable instrument, empty/non-list responses, input validation.Verified locally:
ruff checkclean,ruff format --checkclean, 59 tests pass (47 existing + 12 new).