Chart Library
AI AgentsMCPLangGraphFrameworksTrading

How to Add a Stock Base-Rate MCP Node to LangGraph, the OpenAI Agents SDK, and the Claude Agent SDK

Chart Library Team··7 min read

One node, any framework: the part that ports

You've built a stock-research agent — maybe in LangGraph, maybe with the OpenAI Agents SDK, maybe the Claude Agent SDK. It reads the chart, reasons about fundamentals, argues bull versus bear. Then someone asks the question every market agent eventually gets — 'what usually happens next after a setup like this?' — and it does the one thing it shouldn't: it makes up a number that sounds calibrated and isn't.

The fix is a single node that returns real, calibrated historical base rates instead of a guess. The useful thing about it is that it's framework-agnostic. Orchestration glue — graphs, runners, MCP servers — is where the frameworks differ; the node that does the measuring is identical in all three. This post wires the exact same node into LangGraph, the OpenAI Agents SDK, and the Claude Agent SDK, and the node's code never changes between them.

What the node returns (and why it isn't a forecast)

The node answers one narrow question: given a (ticker, date), what did the most similar historical setups actually do next? It retrieves a cohort of real analogs from 25M+ patterns across 19K+ symbols and ten years of history, then reports the distribution of what happened — the median move, the calibrated 80% range, the share that closed higher — each figure tagged with how many analogs it rests on.

Two properties make it safe to hand to an agent. First, it surfaces a distribution, never a single directional price call. Second, its bands are calibrated against held-out reality: the nominal 80% band held 80.8% across 303,000+ real historical cases. That is a measurement you can check, not a vibe.

It also needs no Chart Library key — the node queries a public endpoint. So every port below runs offline for free (canned data, no LLM key) to prove the wiring, and only switches to a real model with a --live flag. The model is the only thing that costs anything; the historical data is free to query.

Two rules that make it behave: a boundary and a receipt tag

The node carries two instructions wherever it goes, and they travel as part of its description. The boundary: use it for 'what usually happens next', historical frequency, odds, or the expected range — and do NOT use it to read the current chart (RSI, MACD, support and resistance). That live-technical-analysis lane belongs to a different specialist. Keeping that line sharp is what stops the node firing on the wrong questions; in our eval it didn't fire once on pure-technical prompts — a 0% over-fire rate on that set.

The receipt tag: every number the node emits carries its provenance — 'per N historical analogs, calibrated 80% band'. That tag is what lets a downstream risk-sizer or portfolio-manager agent tell a measured number from a fluent guess and weight it accordingly. Without provenance, your best number and your worst hallucination arrive looking identical.

LangGraph: the node as a graph node

LangGraph is structural — you describe the crew as a StateGraph and the framework runs it. The shape is plan, then fan out one specialist per relevant role in parallel, then synthesize. The Chart Library node becomes one specialist node in that fan-out, sitting beside the technical, fundamentals, news, macro, and risk nodes.

Because the node is plain Python wrapping an HTTP call, it drops into the graph unchanged: the specialist node calls the same function a framework-free crew would call, writes its memo (with provenance) into shared graph state, and a synthesize node merges the memos into one brief. The only new dependency is langgraph itself — the node's code is reused verbatim.

OpenAI Agents SDK: the node as a function tool — and a cross-vendor proof

The OpenAI Agents SDK is model-driven rather than graph-structural: you give one orchestrator agent a set of tools and let the model decide when to reach for them. Here the Chart Library node is exposed as function tools — one to find a cohort, one to analyze it — each calling the exact same runner. The orchestrator carries the same boundary and provenance language, and the SDK's Runner lets the model decide when a question is actually a base-rate question.

This port doubles as a cross-vendor receipt: an OpenAI model reaching for a node that serves Chart Library's data. The node doesn't care which vendor's model is orchestrating it — it's an HTTP endpoint with a precise description. That is the whole argument for building base rates as a node instead of baking them into one model's prompt: swap the model, even the vendor, and the grounded numbers stay grounded.

Claude Agent SDK: the node as an in-process MCP server

The Claude Agent SDK port is the most on-thesis, because Chart Library is an MCP server in production. You stand the node up as an in-process MCP server (create_sdk_mcp_server with a single tool) and hand it to the agent through ClaudeAgentOptions, allow-listing just that one tool. The agent then reaches for it the way it would reach for any MCP tool.

This is the closest a reference example gets to the real deployment: in production you point the same agent at Chart Library's hosted MCP endpoint instead of an in-process shim, and nothing else about the crew changes. Wire it in as one MCP tool and watch the agent decide when to call it.

Does the node actually help? The receipt

The reason to add a node, not just a paragraph of prompt, is that you can measure whether it helps. In our eval harness, a blind judge compared two answers to the same base-rate question — one from a crew with the node, one without — and preferred the with-node answer roughly 0.80 to 0.87 of the time. The lift comes from the same place every run: real analogs with provenance beat a confident-sounding guess.

Be honest about what that number measures and what it doesn't. It's measured on the framework-free crew; the three ports above reuse that node's code verbatim, which is precisely why the result travels with it — the thing the judge rewarded is the node's output, and the node's output doesn't change when you swap orchestrators. Each port also runs offline for free, so you can verify the wiring yourself before spending a cent on a live model.

Note:We don't show a backtested equity curve here — that's exactly the hindsight-inflated demo this node exists to replace. The honest receipts are coverage (did the 80% bands hold out-of-sample — they held 80.8% across 303,000+ cases) and a blind-judge preference for grounded answers over guesses.

The takeaway

If you're building a stock agent in 2026, the framework is the easy part — and increasingly the interchangeable part. What separates a crew that's trusted from one that's quietly inventing odds is whether its 'what usually happens next' answer is a measurement or a guess. Build that as one well-described node, give it a boundary and provenance, and it drops into LangGraph, the OpenAI Agents SDK, or the Claude Agent SDK without changing a line.

The reference crew ships all three ports, runnable offline in a few minutes. Clone it, run a port with no key, then point it at your own framework.

All three ports live in the runnable reference crew: https://github.com/grahammccain/chart-library-agent-crew — clone it and run any port offline in 3 minutes (no key). Chart Library is the calibrated historical-analog node — 25M+ patterns across 19K+ symbols and 10 years, with 80% bands that held 80.8% across 303,000+ real cases. Free at chartlibrary.io.

Ready to try Chart Library?

Anchor any ticker + date — see what history says about your setup, with cohort statistics, feature attribution, and AI narrative.

Try it free