Exposing your app to an AI agent over MCP is basically handing someone a master keyring and trusting them to only open the doors they're supposed to. That trust is a bug waiting to happen. This week I wired up a batch of MCP tools over a multi-tenant Laravel app, and the whole exercise was really about one question: how do I let an agent drive the app without letting it drive someone else's data?

Here's the thing about MCP tools — each one is an endpoint. An agent calls list_events, publish_event, check_in_participant, and your server runs code on the caller's behalf. The moment you have more than one tenant, every single tool needs to answer two questions before it does anything: are you allowed to do this, and are you allowed to do it *here*. Authorization and scope. Skip either and you've built a confused deputy.

The trap: ambient scope doesn't exist under token auth

In a normal web request, multi-tenancy is comfortable. You've got a logged-in user, a global scope on the model that quietly appends where organization_id = ?, and you mostly forget it's there. Everything Just Works because there's an ambient "current organization" sitting in the session.

MCP tools don't have that. The caller authenticates with a token, there's no session, no middleware stack that set up a current-tenant context. If you lean on a global OrganizationScope that reads "the current org" from somewhere, it reads nothing — and a query you assumed was fenced returns every tenant's rows. That's the kind of bug that doesn't throw an error; it just silently leaks.