[ INTRODUCTION ]
What Oddysey is
Oddysey is a supervision layer for portfolio agents. It watches tokenized equities around the clock, drafts the move when something trips, and then stops — because the next step belongs to a person.
The problem it solves
Agents that can trade are easy to build and very hard to trust. Agents that can only look are trustworthy and useless. Oddysey takes the third option: an agent does the watching and the writing, a human does the deciding, and the record of who did which is not optional.
Markets move while you sleep. Reading every position every hour is exactly the sort of work an agent should absorb — but the moment that same agent can place an order, you have handed a probabilistic system a withdrawal right. Most products resolve this with guardrails: position caps, allow-lists, confirmation prompts. Guardrails constrain a capability that still exists. Oddysey removes the capability.
What it refuses to do
These are structural properties of the system, not settings you can turn off:
It never places an order.
There is no execution endpoint anywhere in the codebase. A proposal marked executed got there because someone reported a fill that happened somewhere else.
It holds no brokerage credentials.
A full OAuth connection layer was built, tested, and then unmounted. Because Oddysey does not execute, holding a refresh token that could place real orders would be custody risk purchased for nothing.
No agent can approve its own work.
The MCP server exposes nine tools and not one of them approves or rejects. An agent that could sign off on its own drafts would hollow out the entire product.
It never invents a price.
Every quote carries its source. When any symbol falls back to fictional prices, market.live is false everywhere the number appears — on the deck and over MCP.
How the pieces fit
market data your own agent
│ │ (Claude, Cursor, a script)
▼ ▼
┌───────────────┐ ┌──────────────┐
│ quote service │ │ MCP server │ /api/mcp
│ + D1 cache │ │ 9 tools │ bearer: odsy_…
└───────┬───────┘ └──────┬───────┘
│ │
▼ ▼
┌──────────────────────────────────────────────┐
│ Cloudflare D1 │
│ watches · proposals · ledger · quotes │
└───────┬──────────────────────────────┬───────┘
│ │
▼ ▼
┌────────────────┐ ┌───────────────┐
│ cron sweep │ drafts → │ Command Deck │
│ */15 · agent │ │ a human │
│ loop (LLM) │ │ approves │
└────────────────┘ └───────────────┘Everything runs on Cloudflare Workers. Persistence is D1, the sweep is a Cron Trigger, and drafting calls a language model through OpenRouter. The deck is a Next.js app; your agent talks to the same data through a remote MCP server at /api/mcp.
Who it is for
- Operators who already run an agent that can execute, and want a reviewed queue of work instead of an autonomous trader.
- Desks that need an audit trail where every action is attributable to either a named agent or a named human.
- Builders who want a worked example of an MCP server whose tool surface was designed around what an agent must not be able to do.
What is real and what is still a fixture
Being straight about this matters more than the demo looking finished.
| PART | STATUS |
|---|---|
| Watches, proposals, ledger | Real. Persisted in D1, scoped to your session address, editable. |
| Prices | Real when FINNHUB_API_KEY is set — live quotes on the underlying equities, cached for 120s. Fictional and labelled otherwise. |
| Drafting | Real. A language model writes the title, rationale, and target allocation; the arithmetic is computed in code. |
| The sweep | Real. A Cron Trigger runs every 15 minutes in production. |
| Token quantities | Fixture. There is no account to read balances from, because Oddysey deliberately connects to none. |
| Fleet roster and chain stats | Fixture. Presentation only — no agent process is running behind those rows. |
Next
Go to the quickstart to run the loop yourself, or read concepts for the vocabulary the rest of these docs assume. The reasoning behind the design lives in the whitepaper.