MCP Became The Integration Layer For AI - And Only 3% Of Financial Firms Run It In Production: A Developer's Guide To Market-Data And Trading MCP Servers
The Model Context Protocol won the integration argument in 2026: over 97 million monthly SDK downloads across Python and TypeScript by March, more than 10,000 public servers in the official registry, and a settled answer to how an agent reaches a tool. Financial services has not followed. Research puts just 3% of financial firms running MCP in production and 12% with a formal pilot - the laggards of every sector surveyed - while 28% rank it a top-five company initiative. That gap is not indecision; it is the absence of guardrails that the rest of the industry could afford to skip and finance cannot. This is how to build an MCP server that is actually deployable inside a financial firm: per-user entitlements, prompt-injection containment, cost control on unbounded market-data queries, and an audit trail per tool call.
AlchmAI Engineering13 min read
3%
Of financial services respondents run MCP in production; 12% have a formal pilot - behind every other sector surveyed
28%
Rank MCP adoption a top-five company-level initiative, rating it critical or high priority
97M
Monthly MCP SDK downloads across Python and TypeScript by March 2026, with 10,000+ public servers in the official registry
51% / 44%
Top financial use cases: fraud detection and prevention, then internal process automation
There is a particular kind of technology adoption curve where an industry looks like a laggard and is in fact being rational. MCP in financial services is that curve. The protocol has plainly won the general integration argument - by March 2026 the SDKs were logging over 97 million monthly downloads across Python and TypeScript, with more than 10,000 active public servers in the official registry - and the question of how an agent reaches a tool is now, for most of the industry, a solved problem with an obvious answer. Financial services sat it out. The research puts production usage at 3% of respondents and formal pilots at 12%, comfortably behind other sectors, while 28% simultaneously rate MCP adoption a top-five company priority. Firms want this. They are not shipping it.
The stated blockers are security concerns, legacy system complexity and data quality, and every one of those is legitimate. But having built integration layers for banks, brokers and trading firms, we would put it more sharply: the default MCP posture assumes a trust model that does not exist in a financial firm. The protocol was designed around a developer's laptop, where the person running the client is the person entitled to the data, the tool output is basically trustworthy, and nobody has to explain the resulting API calls to a regulator. Change those three assumptions and the engineering work is real but entirely tractable. This playbook is that work.
Design Rule One: The Server Never Holds The User's Authority
The pattern we deploy propagates the end-user identity through the agent to the server, and the server evaluates entitlements per call against that identity using the firm's existing entitlement service - the same one the trading UI and the research portal already use. This is more work than a service account, and it is not optional. Market data is licensed per user and per venue with real contractual consequences; positions and order flow sit behind information barriers; client data sits behind consent. A server that cannot express 'this user may see level 1 for LSE but not level 2, and may not see the institutional book at all' cannot be deployed, however elegant its tool schemas are.
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
const server = new McpServer({ name: "alchmai-market-data", version: "1.4.0" });
/**
* Every call carries the acting user's identity, forwarded by the agent
* runtime from the authenticated session. The server has NO standing
* entitlement of its own - it is a policy enforcement point, not a
* privileged actor.
*/
interface CallContext {
actingUserId: string;
sessionId: string;
purpose: string; // declared at session start, logged, and auditable
}
server.registerTool(
"get_quotes",
{
title: "Get quotes",
description:
"Return end-of-day or delayed quotes for instruments the acting user " +
"is entitled to. Does not return real-time level 2 depth.",
inputSchema: {
instruments: z.array(z.string().regex(/^[A-Z0-9.]{1,12}$/)).min(1).max(50),
asOf: z.string().date(), // required: no implicit "today"
depth: z.enum(["l1", "ohlc"]).default("l1"),
},
},
async ({ instruments, asOf, depth }, { _meta }) => {
const ctx = _meta as unknown as CallContext;
// 1. Entitlement per instrument, per user, against the firm's existing
// service. Denials are returned as data, not thrown - the model needs
// to know which symbols it cannot see so it stops asking.
const decisions = await entitlements.checkBatch({
userId: ctx.actingUserId,
resources: instruments.map((i) => ({ type: "quote", instrument: i, depth })),
});
const permitted = decisions.filter((d) => d.allowed).map((d) => d.instrument);
const denied = decisions.filter((d) => !d.allowed);
// 2. Bounded cost. The vendor bill is per request and per symbol, and an
// agent in a retry loop is an unbounded spend without this.
await quota.consume(ctx.actingUserId, permitted.length);
const rows = permitted.length
? await marketData.quotes({ instruments: permitted, asOf, depth })
: [];
// 3. One audit record per call, before the data leaves the process.
await audit.write({
kind: "mcp.tool_call",
tool: "get_quotes",
actingUserId: ctx.actingUserId,
sessionId: ctx.sessionId,
purpose: ctx.purpose,
requested: instruments,
permitted,
deniedCodes: denied.map((d) => d.reasonCode),
asOf,
at: new Date().toISOString(),
});
return {
content: [{ type: "text", text: JSON.stringify({ asOf, rows }) }],
structuredContent: {
asOf,
rows,
denied: denied.map((d) => ({ instrument: d.instrument, reason: d.reasonCode })),
},
};
},
);Design Rule Two: Treat Tool Output As Untrusted Input
The security problem that most concerns financial security teams, correctly, is that MCP tool results flow straight into a model's context and are treated with the same weight as instructions. If any tool in your registry can return attacker-influenced content - a news feed, a filing, a broker research note, an email, a web page, a counterparty's document - then you have an injection path directly into a system that can call other tools. In a documentation assistant that is embarrassing. In a system with an order tool in the registry, it is an incident.
- Classify every tool as trusted or untrusted at registration time, based on whether its output can be influenced by anyone outside your control. Be pessimistic: a filing is untrusted, a counterparty's settlement instruction is untrusted, your own reference data is trusted.
- Delimit untrusted content explicitly in the context and instruct the model that content inside those delimiters is data to be analysed and never instructions to be followed. This is necessary and not sufficient - it raises the cost of an attack, it does not eliminate it.
- Enforce the actual boundary in the tool layer: a session that has consumed untrusted content must not hold consequential tools. If the workflow genuinely needs both - read a filing, then act - split it into two agents with a structured, schema-validated handoff between them. The second agent never sees the filing text, only the extracted fields.
- Strip or neutralise markup, hidden text, and zero-width characters at the tool boundary. Instruction payloads hidden in white-on-white text and HTML comments remain a live technique because it keeps working.
- Alert on tool-call sequences that correlate with injection: an untrusted read immediately followed by an unusual write attempt is worth paging someone about, and it is trivially detectable in the audit stream you are already writing.
Design Rule Three: Bound The Cost, Because The Agent Will Not
Market data is metered, and agents are enthusiastic. An agent exploring a question can generate query patterns no human would - a thousand single-symbol calls where a human would have requested one batch, a full history fetch to answer a question about last week, the same call repeated because the first response did not obviously answer the question. Three controls, all cheap:
- 01Schema-level bounds. The get_quotes tool above caps instruments at 50 per call, and every history tool should cap the requested range. A bound expressed in the schema is enforced by validation before your code runs, and the model sees the limit in the tool description, which materially improves its behaviour.
- 02Per-user, per-session quota with a hard stop. Not a warning log - a refusal, returned as structured data so the agent understands the budget is exhausted rather than the service broken.
- 03A response cache keyed on the tuple that actually determines the answer, including the as-of date. Agents repeat themselves far more than humans, and in financial data a point-in-time query for a historical date is perfectly cacheable forever because the answer cannot change.
Resources Versus Tools: A Distinction Worth Getting Right
MCP distinguishes resources - addressable content the client can read - from tools, which are actions the model invokes. Teams building financial servers frequently make everything a tool because tools are what the model calls, and then discover their context is full of reference data that never changes. The better division is the obvious one once stated: stable context belongs in resources, and dynamic or parameterised lookups belong in tools.
- Resources: instrument reference data, the firm's trading policy, venue calendars, the schema documentation for your own data model, the definitions of the metrics in your research. Stable, cacheable, and part of the model's cacheable prefix rather than a per-turn tool round trip.
- Tools: quotes, history, positions, order status, anything parameterised by time or user, and anything with a side effect. Non-cacheable by nature, audited by necessity.
- The practical payoff is cost. Reference data promoted from repeated tool calls into a stable resource block stops being re-fetched and re-tokenised on every turn, which on a fan-out workload across an instrument universe is one of the largest single savings available.
Where The Early Value Is Landing
The survey data on use cases matches what we see in client work almost exactly. Fraud detection and prevention leads at 51%, internal process automation follows at 44%, and code generation and technical documentation is close behind. Data specialists are expected to be the primary users, with 86% of respondents identifying them as such. That pattern is telling: the winning early MCP use cases in finance are ones where the agent reads widely and writes narrowly, and where a human validates the output as part of an existing workflow.
Our practical recommendation for a firm starting now is to build one read-only server over the data your analysts already spend their days assembling - reference data, positions, historical quotes, internal research - with proper per-user entitlements from day one, and connect it to a single well-scoped workflow. It is a two-to-four week engagement, it produces immediate and measurable time savings, and critically it builds the entitlement, audit and quota infrastructure that every subsequent server will reuse. Firms that start with a consequential write tool because it demos better typically spend six months in security review and ship nothing.
The Bottom Line
MCP settled the question of how AI systems connect to tools, and financial services has held back for reasons that are sound but solvable. The protocol's default trust model assumes the server can act with its own authority, that tool output is trustworthy, and that nobody needs to explain the calls afterwards - and all three are false inside a financial firm. Invert them: propagate the acting user's identity and evaluate entitlements per call, classify tool output by trustworthiness and keep consequential tools out of any session that has consumed untrusted content, bound cost in the schema and by quota, put stable reference data in resources rather than tool calls, and write one audit record per call before the data leaves the process. None of that is exotic engineering. It is a fortnight of work that turns an undeployable integration into a deployable one, and it is the same fortnight whether you build one server or twenty. That is the integration layer we build for financial clients in London, and on current adoption numbers, building it this year is a lead rather than a catch-up.
References & Further Reading
- Stacklok - State of Model Context Protocol in Financial Services 2026. stacklok.com/resources/state-of-mcp-in-financial-services-2026
- Stacklok - MCP Maturity Model for Financial Services (2026). stacklok.com/resources/mcp-maturity-model-fsi
- Stacklok - State of Model Context Protocol in Software 2026 (research report PDF). stacklok.com/wp-content/uploads/2026/01/State-of-MCP-in-Software-2026_FINAL.pdf
- Model Context Protocol - official specification. modelcontextprotocol.io
- MCP Institute - State of MCP 2026. mcp.institute/research/state-of-mcp-2026
- Digital Applied - MCP adoption statistics 2026. digitalapplied.com/blog/mcp-adoption-statistics-2026-model-context-protocol
- Knit - Is MCP the future of AI integration? Roadmap, what shipped, and what's next (2026). getknit.dev/blog/the-future-of-mcp-roadmap-enhancements-and-whats-next
- OWASP - Top 10 for Large Language Model Applications (prompt injection guidance). owasp.org/www-project-top-10-for-large-language-model-applications
AlchmAI Engineering
Engineering, London
Written by the AlchmAI engineering team in Mayfair, London. We build trading platforms, real-time charts, market data pipelines and AI features for brokers, prop firms and fintech teams. The Playbook is where we explain how we approach these systems, with code you can run and sources you can check.
Code in this guide is illustrative and supplied without warranty. Review and test it before production use. Nothing here is investment advice. Important information