I built Ledgerly to answer one question:
what should an AI agent be allowed to do with real money?
My answer is that it should propose and explain, and it should never be the one that decides.
Ledgerly is a treasury agent live on Robinhood Chain mainnet, powered by
@openservai's SERV Reasoning.
It has four jobs: DCA into tokenized stocks, portfolio rebalancing, contractor payroll, and bill payments.
Investors get the first two, and a crypto company's treasury gets the last two. All four go through the same rule engine.
One trade, start to finish
A DCA plan comes due for NVDA. SERV Reasoning looks at where the price sits in today's range, sees it near the top, and proposes buying at 0.5x.
The code clamps every proposal to a fixed 0.5x to 1.5x band, so a bad answer can't inflate a buy.
Then a plain function checks the trade against a per-transaction cap, a daily cap, and an approval threshold.
If it passes, the trade goes to Uniswap v3 on Robinhood Chain. Before sending, the quote is compared across fee tiers and against Robinhood's own price API, and a pool more than 3% off is rejected as broken.
If the trade is above the approval line, it waits for a human, and the caps are checked again at the moment of approval.
The ledger then records two things for that trade, kept as separate fields on purpose:
Rule: "Within the per-transaction cap, the daily cap and the approval threshold."
SERV's explanation: "The price is near the top of today's range, so I would keep the scheduled DCA purchase but at a reduced size."
The rule is the fact that decided it, and the explanation is commentary. An auditor can point at one and read the other.
Selling and rebalancing
I've also run the other direction on mainnet. NVDA had drifted past its target, so the rebalancer proposed selling about $1.37. That was above my approval line, so it was held.
I approved it, the caps were re-checked, and it executed: about 0.006086 NVDA through the 0.05% pool at $225.26 against a $225.10 bid. SERV's note on it was that the sale reduces an oversized NVDA position and moves the portfolio toward its targets.
Transaction:
robinhoodchain.blockscout.co…
This is how is used SERV Reasoning:
Prompt Guard is always on. Payee names and memos are typed by users and end up in the prompt, so that's a real injection surface. A blocked prompt is never retried without it.
Shadow Agent checks every DCA reply against a strict JSON shape and regenerates weak ones.
Multipath is on through the model name, on a small model. A cheap model is enough when the model has no authority.
Kronos is off on purpose, because it rewrites the prompt and could break the JSON we parse.
If reasoning is unavailable, a DCA run falls back to a plain scheduled buy, and the guardrails still apply.
Once the model also replied "I can't share that." as a normal answer, and it was logged as if it were an explanation. Now replies that are too short or read like refusals are dropped, and the ledger keeps the plain facts.
Robinhood MCP
There's a read-only connector for Robinhood's Agentic Trading MCP. Any tool that looks like trading, transferring, or staking is refused by name before it can run, and it's off by default.
Against Robinhood's live server I verified OAuth discovery, dynamic client registration, and a PKCE authorization request, and I built a login tool on top of that.
But Robinhood brokerage account is restricted on my region so i couldn’t signed in and I was unable to call the MCP tools yet.
Live:
ledgerly.guru/
Repo:
github.com/firmino0/Ledgerly
Real funds, small caps, not financial advice. Tell me what to break next.
Built for the
#SERV Hackathon, Mainnet & MCP track.
#BuildonSERV #SERV’ing.