Quick Summary
- A working MCP server at home is not proof it’s safe in production
- Checking who someone is does not tell you what they can see
- Tool calls need hard limits, or they will be misused
- You only know it’s safe once you’ve actually tested it
You got your MCP server running. It works fine on your laptop, nobody else around, nothing to break. That’s good, but it’s not really the test that matters. MCP security in production means real users hitting your server, real company data sitting behind it, and real risk if something slips.
This isn’t one fix. It’s three things that have to hold together at the same time: knowing who’s actually calling, keeping one customer’s data away from another’s, and stopping a tool from being pushed into something it shouldn’t do. Miss one of these and the other two don’t really help much.
We’ll go through each piece below, what tends to break, what fixes it, and roughly how you’d check your own work before shipping. Nothing fancy here, just the parts people usually get wrong.
“Most teams get MCP working fast. The hard part is making sure one customer never sees another customer’s data once it’s live. That’s where the real engineering is.”
Jitendra Rathod, CEO, Tuvoc Technologies
1 : Why MCP Needs a Different Security Model in Production
Your server worked fine on your own machine, one process, one person, nothing else going on. Production doesn’t look anything like that. MCP production security means strangers calling in over the network, sometimes dozens at once, sometimes at odd hours you’re not watching.
MCP itself won’t sort this out for you. It moves messages back and forth, that’s roughly all it does at the protocol layer. Who gets let in, and what they’re allowed to touch after that, is for your team to decide.
1.1 : From Local stdio to Remote Streamable HTTP
Locally your server talks over stdio, one trusted process doing its thing. Move it to the cloud and now you’re on Streamable HTTP, sitting open on the internet, reachable by anyone who finds it.
That’s a bigger jump than it sounds. A closed, quiet process turns into a server fielding calls from strangers, possibly many at the same moment. Every one of those calls needs checking. Not just the first one.
- Network exposure replaces a closed local process
- Multiple callers can hit your server together, not one by one
- A shared setup means one bug reaches more than one user
1.2 : Where MCP Protocol Responsibilities End and Application Security Begins
Here’s where people trip up. They assume following the MCP spec means they’re covered on security. It doesn’t work that way. Model Context Protocol security is really about message format, not about who’s allowed to see what data.
Your access rules and your customer boundaries: none of that ships with the protocol. You build it. If you skip it thinking MCP already handles it somewhere, it hasn’t, and that gap is usually where the trouble starts.
- Protocol covers message format, nothing about permissions
- You own the authorization policy, always
- Isolation between customers has to be built by you
2 : MCP Authentication and Authorization: Verify Identity and Token Audience
Someone’s on the line, calling your server. First thing to settle: who are they, actually? MCP authentication handles that part. Separate question after that: what are they even allowed to do here? That’s authorization, and the two checks aren’t the same thing.
A token can be valid and still be used by the wrong server. If you miss that check, and if your request goes through where it shouldn’t, the signature alone will not be able to report that back to you.
2.1 : OAuth Protected-Resource Discovery and the Authorization Handshake
Before any tool gets called, your client has to figure out where to log in and how. That’s the discovery step: your client finds the server’s rules first, then follows them.
How OAuth authentication works for remote MCP servers is mostly this discovery step plus a fairly standard OAuth 2.1 flow after it. Skip discovery and clients end up guessing at the right endpoints, which rarely goes well.
- Client finds the server’s auth setup first
- A standard OAuth 2.1 flow handles the actual login
- Nothing runs before this step finishes
2.2 : RFC 8707 Resource Indicators: Why a Valid Token Is Not Enough
A token can be real. Signed correctly, not expired, everything checks out. And it can still be the wrong token for your particular server. Being valid and being meant for you aren’t the same thing.
MCP resource indicators close that gap. They tie a token to one exact resource at issue time. Your server needs to check that match, separately from checking the signature.
- A valid token might still be the wrong one
- Resource indicators tie a token to a single target
- Check the audience field, don’t stop at the signature
2.3 : Delegated User Identity Versus Autonomous Agent Credentials
Who makes the tool call; your user or your system? For MCP authorization, that choice is vital evidence. If the user begins to act, their identity may be required to go along the process. However, if the call is made by the system, you need to ascertain the account from which the call was made.
Delegated identity ties the call to the user. A service identity lets your system work on its own, useful for background tasks. But check its permissions. Give it too much access, and one wrong call can affect more than it should.
- Delegated identity keeps a trail back to the user
- Service identity is simpler, though riskier at scale
- The choice depends on what you’ll need to trace
3 : MCP Multi-Tenancy: Enforce Isolation Beyond Tool Arguments
Here’s something that catches teams off guard. A caller can pass every single authorization check you’ve set up, correctly authenticated, fully permitted, and still walk away with another company’s data. MCP multi-tenancy is the piece that’s supposed to stop exactly that.
Being allowed to call a tool and being allowed to see one particular record are two different questions. You need an answer for both, not just the first one.
| Checkpoint | Weak approach | Safer approach |
|---|---|---|
| Tenant identity | Trust the tenant ID in tool arguments | Derive it from verified server-side context |
| Data access | Rely only on application logic | Enforce tenant boundaries at the database too |
| Shared state | Assume caches and sessions are safe | Scope them to the correct tenant |
3.1 : The Cardinal Anti-Pattern: Trusting an LLM-Supplied Tenant Identifier
This is the mistake we keep running into. A tool handler just pulls the tenant ID straight out of whatever argument the model happened to send. Quick to build, and broken from the start.
Python: Vulnerable pattern
def get_records(tenant_id):
return database.get_records(tenant_id) Python: Safer pattern
def get_records(authenticated_context):
tenant_id = authenticated_context.tenant_id
return database.get_records(tenant_id) How to prevent cross-tenant data leakage in MCP begins with not doing that. We ran this ourselves: a made-up argument pulled another tenant’s records without much trouble, even though the caller was logged in correctly and allowed to call the tool.
- A model-supplied tenant ID can’t be trusted on its own
- Any caller could claim to be a different tenant
- Pull tenant context from the session, not the argument
3.2 : Trusted Context Propagation and Database-Level Isolation
So where should the tenant ID come from instead? From the server’s own session, set up when the user first logged in. Not from anything typed or generated into a tool argument afterward.
How to implement tenant isolation in an MCP server also means checking again at the database itself. If your application logic has a bug somewhere, row-level rules at the data layer can still catch it before damage is done.
- Tenant ID should come only from the verified session
- Carry that context through every layer, not just the first
- Database-level checks give you a backup if app logic fails
3.3 : Cross-Tenant Leakage Through Caches, Shared State, and Continuation Handles
Fixing the main data path isn’t quite the end of it. Caches, saved sessions, background jobs: these can leak across tenants too, and often nobody notices until a customer complains.
MCP tenant context has to follow the data wherever it travels, not just show up at the first query. This mostly applies if your setup uses stateful sessions somewhere. It’s worth checking whether yours actually does.
- Shared caches can quietly leak across tenants
- Session handles need the same tenant scoping
- Applies mainly where your deployment keeps state
4 : MCP Security Patterns: Constrain Tool Execution and Limit the Blast Radius
Okay, say identity checks pass and tenant walls hold. There’s a third gap people forget about: the model itself gets tricked into calling something it shouldn’t have. MCP access control is the piece that stops a trick from turning into actual loss.
Whatever the model wants to do, that’s just a suggestion. It’s not a green light. Your server still checks every call, no exceptions for how trusted a request looks.
4.1 : Indirect Prompt Injection and the Confused-Deputy Problem
A document somewhere has hidden text in it. Maybe a webpage does too. The model reads that text and, without anyone meaning for it to happen, picks a different tool than it should have. This is indirect MCP prompt injection, and honestly it’s harder to spot than it sounds.
Now if your server happens to be running with more access than this one moment needs, you’ve got what’s called a confused-deputy problem. Writing better prompts doesn’t fix this. Cutting the server’s privileges down does.
- Hidden text can nudge the model toward the wrong tool call
- Wide privileges are what turn a small trick into something costly
- Prompt filtering helps a little, but it’s not a real fix on its own
4.2 : Tool-Definition Integrity, Poisoning, and Malicious Changes
There’s another angle here, and it’s not about the call at all. It’s the tool’s own description, what it claims to do. Change that text, even slightly, or write it to mislead from day one, and the model’s already working off bad information before a single call happens.
So MCP tool security isn’t only about watching live traffic. Somebody has to watch the definitions too. A tool’s description changing is a code change, basically, and it should go through the same review one would get.
- A tool’s description can be edited or written to mislead
- Letting that slide is really a supply-chain gap
- Review definition changes the way you’d review any code
4.3 : Least Privilege, Input Validation, and Approval Gates
Three things, mostly. Each tool gets only the access it needs for its job, nothing spare sitting around. Every input gets checked on the server, no matter what the model insists is true about it. And when something has real consequences, a person has to approve it first, not a model.
That’s roughly what secure MCP server implementation comes down to. Drop just the approval step on one risky action, and having the other two in place won’t really save you from it.
- Narrow each tool’s access down to what the job needs
- Input checks run server-side, the model’s claims don’t count
- Approval matters most right where consequences are highest
5 : MCP Observability and Auditing: Trace Security Decisions
A control can sit there working fine for months, then fail once, quietly, and nobody notices right away. When that happens, can your team actually rebuild what happened? Or is it mostly guesswork pulled from scattered logs?
What’s worth saving isn’t a huge list. Who called in, which tenant they were tied to, what your server decided about the call. Enough to retrace the whole thing later, roughly, not a complete transcript of everything.
5.1 : Tenant-Aware Audit Events and Trace Correlation
Any call that touches security ought to leave a trace somewhere. Caller, the tenant claimed, the tool that ran, whether it got through or got blocked. That’s close to the minimum, not some extra nicety.
A correlation ID matters here too. MCP audit logging without one means the request’s trail stops wherever that first log sits. It doesn’t follow into whatever system gets touched next. Without it you’re stitching separate logs together by hand later, and that’s slow, and honestly easy to get wrong.
- Save caller identity, tenant, tool, and the outcome
- A correlation ID should ride along with the request
- This is usually where an investigation starts
5.2 : Redaction, Anomaly Detection, and Incident Investigation
Here’s something people miss. Logs themselves can become a liability. A token, or some sensitive field, sitting around in plain text inside a log file: that’s just one more spot data can leak from.
Pull that sensitive stuff out before it ever gets written, not afterward as cleanup. Keep log access scoped by tenant instead of leaving it open to everyone on the team. And it helps to notice when something looks off (a sudden spike of tenant mismatches, say) rather than waiting for a customer to be the one who catches it.
- Strip sensitive fields before the write happens, not after
- Tenant-scope your log access, skip the company-wide view
- Odd patterns are worth flagging early, manual review alone won’t catch everything
6 : MCP Production Readiness: Verify the Security Boundaries Before Release
Everything covered above is still just a claim until someone’s actually tested it. MCP security testing is what turns the design into something you can trust, because you watched it hold up under an actual attempt to break it.
Passing a test suite lowers your risk, it doesn’t erase it. Worth being upfront with your team about what the tests actually cover, and just as upfront about what they don’t.
6.1 : Automated Security Tests in CI/CD
Running this check by hand once isn’t really enough. Wrap the cross-tenant test into your pipeline so it runs on every build, automatically, before anything new goes out.
How to test MCP server security before deployment really means a failed build the moment something regresses, say a previously blocked tenant leak starts working again. Better to catch that in CI than find out from a customer later.
- Wrap the leak test into your pipeline directly
- Fail builds on any security regression, not just obvious ones
- Catch problems in CI, well before release
6.2 : The Production Approval Checklist for MCP Deployments
Before flipping the switch, there’s a short list worth running through. Identity checks working. Tenant isolation actually tested, not assumed. Tool execution kept in bounds. Logging in place and readable. Negative tests passing, not just the usual happy-path ones.
How to secure an MCP server in production comes down to whether each item on that list traces back to a real, working control, rather than something someone said out loud in a meeting once.
- Each checklist item should map to a real control
- Run the checklist before every release, every time
- A missing item is a blocker, not a footnote
Conclusion
Three things, and they need to hold together. Knowing who’s calling. Keeping each tenant’s data separate. Keeping tools from being pushed somewhere unsafe. MCP security best practices aren’t really a checklist you read once and move on from.
They’re something you keep testing, release after release. If you can’t actually prove a control works, it’s safer to assume it doesn’t yet. That’s a reasonable place to start.
Manoj Donga
Manoj Donga is the MD at Tuvoc Technologies, with 17+ years of experience in the industry. He has strong expertise in the AdTech industry, handling complex client requirements and delivering successful projects across diverse sectors. Manoj specializes in PHP, React, and HTML development, and supports businesses in developing smart digital solutions that scale as business grows.
Have an Idea? Let’s Shape It!
Kickstart your tech journey with a personalized development guide tailored to your goals.
Discover Your Tech Path →Share with your community!
Latest Articles
sellers.json, ads.txt, and SupplyChain Object: An Implementation Guide for SSP Teams
If you are running an SSP, you have probably got all three of these sitting somewhere already. ads.txt, sellers.json, and…
Vertical Embedded Finance: Adding Payments and Lending to Your SaaS (Build vs. BaaS)
Your SaaS already owns the workflow. Most people talking about embedded finance for SaaS skip right past that part, but…
When to Choose a White Label Real Estate App Development Company and Why?
Most real estate businesses we talk to aren't short on leads or deals. Even your search for a white-label real…