AI & Architecture · 2026-09-07 · 4 min read
Broker Agent – MCP Server Proof of Concept
Objective
Experiment with MCP (Model Context Protocol) servers and data integration via a Claude Code agent. As technology moves on, we wanted to see what a new application structure—with chat effectively acting as the front end—would look like, and what the pitfalls, benefits, and trade-offs would be.
To that end, we built a "Broker" MCP that you can talk to directly, just as you would to your human broker.
The Problem: Understanding Investments Across Multiple Accounts
The money sits in four accounts across three providers—let's call them Platform A, Platform B, and Platform C. An ISA and a general investment account with the first, and one account with each of the others. Each has its own login, its own two-factor prompt, its own CSV export, and its own opinion about what cash means.
It is time-expensive to answer simple questions:
- How much cash could I actually deploy today, everything included?
- What percentage of the total is sitting in one name?
- Which account should this next purchase go in, given what each one pays on uninvested cash?
- Am I up or down since I bought, after costs?
None of that is hard. It is just three logins, three downloads, and a spreadsheet—every single time. Which means in practice you do it twice a year and guess the rest of the time.
Make the question cheap and you start asking it
Broker Agent is the piece that makes it cheap. It is an MCP server that Claude connects to over stdio. It knows how to log in to all three platforms, pull down accounts, cash, and positions, and normalise them into a single local store.
The answer to "total cash available to invest across all accounts" becomes a single prompt.
Architecture: Transport in the Middle, One Adapter per Platform
The server file itself is deliberately boring. broker_mcp_server.js declares the tools, validates their inputs with zod schemas, and serialises whatever comes back as one JSON file. It contains no broker logic at all.
Everything that actually knows about a broker lives in one module per platform, and all three modules expose the same four capabilities:
login · download · quote · buy
Why the uniform shape matters
Because the model on the other end of the pipe only has to learn one pattern. b_quote, c_quote, and a_quote all mean the same thing, even though one is a REST call, one is a local gateway call, and one is a headless browser clicking through a deal form. The differences that genuinely matter are pushed into the tool descriptions, where they belong.
Merging without clobbering
All three adapters write through one small helper, portfolio_store.js. Its writePlatform() reads the existing file, replaces a single top-level block, and writes it back—so refreshing Platform B at lunchtime never drops the Platform A data you pulled that morning. Accounts are grouped by platform rather than flattened, which keeps "what's my ISA worth" and "what's everything worth" both answerable from the same file.
Adapters: Three Platforms, Three Entirely Different Problems
The three modules look alike from the outside and share almost nothing underneath. Each broker forced a different answer to the same question: how do you get in?
Platform A: No API, so drive the website
Platform A has no public trading API. The only way in is to automate the GUI, so platform-a.js opens a visible Chromium window with Playwright and hands it to the user. The user types in credentials and clears the 2FA—nothing is stored in environment variables. The resulting cookies go to session-a.json and get reused until they expire.
Because Platform A's session dies when the window closes, the browser is created once and shared across calls, with a refresh loop pinging the page every 30 seconds to keep it alive.
Platform B: A proper REST API, and no browser at all
Platform B publishes a documented REST API, making this the cleanest of the three. platform-b.js authenticates with B_API_KEY, B_IDENTIFIER, and B_PASSWORD from environment variables, holds a pair of tokens in memory, and calls GET /accounts and GET /positions.
Platform C: Your own gateway, running on your own machine
Platform C's retail accounts go through its local Java gateway serving the broker's web API on localhost behind a self-signed certificate. platform-c.js talks to that after you authenticate once in the browser with 2FA, keeping the session warm with a 60-second tickle.
Example Prompts & Privacy Considerations
Registering the server with Claude Code takes four lines of MCP client config pointing node at broker_mcp_server.js. After that, you simply ask:
- "What share of the portfolio is my largest holding?"
- "Quote me £2,000 of Victrex in the ISA account."
- "Across all accounts, what's the current return on all investments in the UK housebuilder sector?"
On privacy and sharing data with the LLM
We minimised sensitive PII (such as names and raw account numbers) in portfolio_store.js by stripping those fields before writing portfolio.json, which is the file the LLM reads for analysis.
Enjoyed this technical breakdown?
Subscribe for occasional engineering field notes on load testing, synthetic data, and observability—or talk to us about your system.