Building an AI investment analyst that follows a method
How InvestPal is built: written analysis procedures the agent must follow, five small services on your own machine, memory as structured state, and brokerage access designed around real money.
Ask a general-purpose AI whether a stock is worth buying and you get a fluent answer put together on the spot. It reads well. It is also different every time you ask, and nothing in it tells you how the conclusion was reached or what would change it.
InvestPal is built around the opposite idea: an analyst should follow a method. It works through written, step-by-step procedures for each kind of question, it runs on your own machine, and it plugs into the AI tools you already use. This post is about how it is built and why it is built that way. The product page covers what it does, and the code is on GitHub.
Three decisions shape everything below:
- Method over improvisation. The agent reaches for a written procedure before it reasons freehand.
- Local-first. No hosted backend, no account, no tenancy. Every service and all of your data stay on your machine; the only thing that leaves it is what the model you choose needs to see to answer.
- Client-agnostic. The backend speaks the Model Context Protocol (MCP), so any capable assistant can become the front-end.
The shape of it
InvestPal is five small services running on localhost, plus one database file.
The core is a Python FastAPI service. It exposes the same capabilities twice: as a REST API for ordinary applications, and as an MCP server for AI clients. It owns the agents, the analysis procedures and all of the user’s state.
The data and brokerage servers are separate MCP servers, one per source: a Go server for market data, and Python servers for Alpaca, Coinbase and Interactive Brokers. Each one is small, does one thing, and can be used on its own by any MCP client.
State lives in one Turso/SQLite file, created on first start. There is no database server to run. Syncing that file to Turso Cloud is possible, and deliberately manual: nothing syncs on startup, on shutdown or on a timer, so a second machine never overwrites the first by surprise.
The detail that matters most is the dotted line. Claude Code and Claude Desktop are already capable agents, so they connect to the market data and brokerage servers directly, as native MCP clients. The core only coordinates those servers on behalf of clients that cannot speak MCP themselves, such as the web app. MCP is the seam that lets one backend serve very different front-ends without a translation layer for each.
Skills: written procedures instead of improvisation
The heart of InvestPal is fifteen skills. A skill is a written analytical procedure: what to look at, in what order, which numbers to compute, how to interpret them, and when the method does not apply. Their lineage is explicit. Valuation and asset-based reasoning come from Graham and Dodd’s Security Analysis; cycles, sentiment and second-level thinking come from Howard Marks’ The Most Important Thing.
They are grouped by the question an investor is actually asking:
| Question | Skills |
|---|---|
| Is this a good business? | Competitive moat · Earnings quality · Cash generation · Balance sheet strength · Profitability and pricing power · What management is signalling |
| What is it worth? | Intrinsic value · Price against value · Against its peers |
| Should I act now? | Second-level thinking · Market temperature · Macro conditions · Testing a theme |
| How exposed am I? | Portfolio risk · Margin of safety |
How the agent reaches them
Skills are not pasted into the system prompt. Fifteen full procedures would crowd out the conversation, and most questions need one or two of them. Instead the core exposes two tools:
- List skills returns every skill with a one-line summary of what it is for and when to use it.
- Get skill returns the full written procedure for one of them.
The agent’s instructions are blunt about using them: always prefer a skill over ad-hoc analysis, and skipping a relevant skill is a defect. So a question like “does this company have a moat?” turns into a short, predictable sequence: list the skills, fetch the moat procedure, gather the data it asks for, and work through it step by step.
What a procedure looks like
The competitive moat skill is a good example of why this matters. A freehand answer to “does this company have a moat?” usually lists some reassuring adjectives: strong brand, loyal customers, network effects. The procedure asks for numbers instead.
It starts by comparing two independent estimates of value. The first is what it would cost to rebuild the company’s assets from scratch. The second is its earnings power: what its current, sustainable earnings are worth if they never grow. If earnings power is well above the cost of rebuilding the assets, competitors should have rushed in and competed the excess away. If they have not, something is stopping them, and that something is the moat. If the two values are roughly equal, the company is a commodity business, however good its brand looks.
Only then does the procedure look for the cause: customer captivity, cost advantages, economies of scale, network effects. It ends with an estimate of how long the advantage is likely to last. The answer comes out the same way every time, and you can check every step of it.
Why written procedures
- Consistency. The same question gets the same method, so two answers about two companies can actually be compared.
- Auditability. You can read the procedure the agent followed, disagree with a step, and see exactly where your view differs.
- Versioning. Procedures are code. They live in the repository, change through commits, and every change is reviewable.
- Model independence. The method lives outside the model. Swap the model and the analysis still follows the same steps.
Three agents with separate jobs
Inside the core, three agents share the same tools but have different jobs. Each is a LangChain agent that reaches its tools over MCP.
| Agent | Job |
|---|---|
| Investment manager | The advisor you talk to. Holds the persona, reaches for skills, calls the data and brokerage tools. |
| Memory manager | Runs in the background on a cheaper model. Reads the conversation and maintains your long-term memory, so the advisor never stops mid-answer to take notes. |
| Workflow executor | Has no conversation at all. Runs scheduled work when it comes due and stores the report. |
Keeping memory out of the conversation lets the advisor stay attentive without being slow. Note-taking is real work: deciding what changed, superseding old facts, filing things in the right place. Doing it inline either delays the answer or gets skipped. A background agent on a cheaper model does it properly and costs little.
The model and provider are configured per agent, and Anthropic, OpenAI and Google models are all supported. In the Claude Code cockpit, Claude Code itself is the model, so InvestPal’s own agent and its API key are not involved at all.
Memory as structured state
The easy way to give an agent memory is a pile of notes and a vector search. InvestPal keeps notes like that, but most of what matters to an investor has a shape, so most of its memory is structured.
| What | How it is kept |
|---|---|
| Your profile | Goals, risk tolerance, horizon and constraints, as notes that are superseded rather than deleted, so the history of how your situation changed is kept |
| Holdings | What you own, from a broker or recorded by hand. Every row says where it came from and when it was true. No prices and no P&L are stored, because they go stale immediately |
| Ticker records | One per name you care about: the thesis, the entry trigger, the falsifier (what would prove the thesis wrong), and whether it is watched, held, exited or rejected |
| Conversation notes | Free-form notes from past conversations, searchable by meaning |
| Reminders and workflows | Action items the advisor is tracking, and scheduled work with its reports |
The ticker record does the most work. Writing down the falsifier when you buy is the cheapest protection there is against falling in love with a position. When the advisor revisits a holding, it checks the current facts against the conditions you wrote down at the time, not against whatever the story has become since.
Semantic search over conversation notes uses embeddings computed locally, on the CPU, with a small open embedding model. The text of your notes is never sent anywhere to be embedded, which matters for something as personal as your finances.
Work that runs on a schedule
An analyst is useful partly because they keep watching after you leave the room. InvestPal does this with workflows: a name, a description of what to achieve, and a cron schedule. “Review my portfolio every Monday morning and tell me anything that changed” is one workflow.
When a workflow comes due, the workflow executor runs it with the same tools and skills as the advisor and stores the report, so it is waiting for you the next time you open InvestPal. A workflow is marked as running while a run is in flight, which works as a lock: two triggers firing close together cannot run the same review twice.
Each front-end picks up these reports where it makes sense. In the Claude Code cockpit, a session-start hook loads your profile and open reminders and runs any workflows that came due while you were away. The web app shows each workflow’s history of reports.
Brokerage access with real money attached
Connecting an AI to a brokerage account is the part where a design mistake costs money, so the rules here are strict and simple.
A credential lives in exactly one process. Brokerage keys sit in a separate secrets file with owner-only permissions. At startup, each key is handed to its own brokerage server and to nothing else. The keys never travel over an MCP connection and never pass through the model’s context. The Claude Code cockpit is explicitly denied access to the secrets file.
Read-only removes the order tools entirely. Each brokerage has a read-only switch. When it is on, the tools that place orders are not just refused at call time; they are never registered, so the agent cannot see them, ask for them or be talked into calling them.
Defaults are the safe option. Alpaca points at paper trading unless you explicitly configure the live endpoint. Interactive Brokers never accepts a trading warning on your behalf: an order that triggers a warning comes back as needing confirmation, with the warning text, and stays off the market until a separate confirm call.
None of this is needed to use InvestPal. Without any brokerage connected, it is a complete research tool, and you can record holdings by hand.
Data without a vendor
The market data server draws only on free, public sources and needs no API keys:
| Source | Used for |
|---|---|
| FRED | Economic indicators and commodities |
| ECB reference rates | Currency exchange rates |
| SEC EDGAR | Insider transactions |
| stockanalysis.com | Stocks, ETFs, sectors, financials and news |
| dataroma | What well-known value investors hold |
| CoinGecko | Cryptocurrency data |
| CoinDesk and CoinTelegraph | Crypto news |
| Polymarket | Prediction market odds |
The trade-off is that free sources come with their own rules. Some have rate limits, and the SEC expects automated clients to identify themselves with a real contact address. Keeping every source behind one MCP server means those details live in one place, and swapping a source does not touch the agents or the skills.
One backend, many front-ends
Because the core speaks both MCP and REST, the same InvestPal can be used in several ways:
| Front-end | Best for |
|---|---|
| Claude Code cockpit | Daily use. Run Claude Code inside the InvestPal folder and it becomes the advisor: it loads the persona, your profile and reminders, and runs due workflows |
| Claude Desktop | Occasional questions in an ordinary chat, no terminal needed |
| Any MCP client | Bringing InvestPal into whatever assistant you already use |
| Local web app | A browser view of conversations, workflows and their reports, and reminders |
| REST API | Building your own interface, or wiring InvestPal into something you already run |
None of them needs anything hosted. A single make setup installs the services, writes the configuration and starts the stack, and make doctor tells you what is missing.
Wrapping up
The goal behind every decision here is the same: an AI analyst you can trust with questions about your money. You should be able to see how it reached an answer, your records should stay on your own machine, and it should not be able to act on your accounts unless you deliberately allow it.
Everything is open source. Start with the InvestPal page for what it does, or go straight to the code on GitHub.