Where MCP is now.

In March I called MCP an architectural pattern worth understanding, not a product worth buying. Six months in, that framing still holds — but the specifics have shifted enough to warrant an update.

The adoption curve has continued. MCP is now governed by the Agentic AI Foundation under the Linux Foundation umbrella. The connector count keeps climbing. Every major AI platform speaks the protocol natively. The tooling has matured — FastMCP is stable, the SDK story has consolidated, and building a read-only MCP server is now genuinely a one-week project for a competent engineer.

What's changed most is the conversation among hospitality operators. In March, the question was "should we look at this?" In July, it's "we're building it — here are our five problems." The projects have moved from evaluation to production, which means the problems have shifted from theoretical to operational. Internal adoption. Guardrails around what users can ask for and what the model gives back. Training staff who've never used an AI tool at work. Token budgets that don't blow past forecast when usage picks up. Auth that maps to a real org chart. Rate limits — the thing everyone worried about — turn out to be the least of it.

None of this shows up in the vendor decks. What follows is what I've learned building these systems for hospitality clients over the last six months — pattern-level, not case-study. Where a specific technology drives the point — MCP, Entra, Cloudflare — I'll name it. Where the pattern applies regardless of what you're using, I'll stay generic.

On scope

This is what I've seen. I don't claim to speak for every deployment. Where my experience diverges from what a vendor claims about their product, I'll flag it. Where the two agree, that's your signal that whatever you're building has more than one production reference.

Where the pattern held out of the box.

Before the criticism, the credit.

Read-only tool exposure is genuinely straightforward. The core MCP contract — expose a tool, describe what it does, let the model call it with typed parameters, return structured results — works the way the spec promises. Wiring a PMS lookup, an availability check, a rate quote is a matter of hours, not weeks. If you have a JSON API on the other side and someone who can write a schema, you're a day from having Claude answer "is unit 812 available July 3–6" against real data.

The connector story got dramatically simpler. In March, "which SDK, which language, which framework" was a live debate. That debate has resolved. Python shops land on FastMCP, Node shops on the TypeScript SDK — and Cloudflare Workers wins as the deploy target for anything that needs to sit at the edge. The choice-fatigue that slowed early adopters has mostly resolved into two or three defensible stacks.

Rate limiting turned out to be a non-issue. Hospitality PMS platforms cap API calls tightly, and AI queries are bursty by nature — one complex question can trigger five tool calls in ten seconds. That should have been a constant source of failure. It isn't. The MCP server sits between the model and the PMS: it caches what can be cached, queues what can't, and the PMS only ever sees a steady trickle.

Model behavior around tools is broadly correct. When the tool description is clear and the parameters are typed, the model calls the right tool with the right arguments. It doesn't hallucinate function names. It doesn't invent parameters. It occasionally passes bad values — usually because the underlying question was ambiguous — but the failure mode is "the tool errors out and the model tries again," not "the model makes something up."

Bottom line: the parts that vendors said would work do work. Half of what you build ships smoothly. If your project is stuck in evaluation because "the technology isn't ready," that's not why. The technology is ready. What's not ready is everything that wraps around it.

That's the rest of this piece.

Four patterns I've had to iterate on.

Pattern 1 — The reporting trap.

Every deployment I've done follows the same trajectory. Week one: staff uses the AI for what it's obviously good at — quick lookups, guest-facing answers, availability checks. Week three: someone asks the AI "give me daily occupancy across all units for the last six months." Week five: the AI is being used as a de facto reporting engine, and the token bill is up 10x.

The failure mode is subtle. The tool call succeeds. The model dutifully pulls the data. The response is 40,000 tokens of tabular information, which the model then reformats into a human-readable summary, which the user then screenshots part of. Each step is technically correct. The cost of that pattern, at scale, will surprise you.

What I now build in from day one: any tool that could return more than a bounded number of rows returns a URL, not data. The URL is short-lived — signed, TTL of 15 minutes, single-use — and points at a browser-rendered report. The model gets a one-line summary and the URL. The user gets a clickable link to the real report. The data never touches the LLM context.

The economics change immediately. A "six months of daily occupancy" query costs 200 tokens instead of 40,000. The user gets a better artifact — an actual report they can filter, sort, and export — instead of a chat window full of markdown. And the operator's token bill stays flat as usage scales.

Watch-out: users will find the pattern and try to game it — asking for progressively larger data pulls to bypass the row limit. Enforce the limit at the tool level (return the URL, not the data, above N rows regardless of the request) or build a second tier of URLs with longer TTLs and audit logging for genuinely large exports. Don't rely on prompt-level guidance; it will fail.

Pattern 2 — The PII bypass.

This is the same pattern with sharper teeth. Every hospitality system holds guest dates of birth — captured at check-in, on loyalty profiles, sometimes on staff and owner records too. Sooner or later — probably sooner — a user will ask a question whose honest answer requires the model to see one.

You cannot solve this at the prompt layer. "Never include PII in your responses" is a suggestion, not a guarantee. The right fix is structural: PII never enters the tool response payload. When a tool needs to expose access to sensitive data, it returns a URL bound to the current authenticated user's session — same TTL pattern as the reporting case — that renders the sensitive fields in the browser, behind whatever access control your identity layer already enforces.

The AI knows the record exists. It knows how to answer questions about the surrounding context. When the user asks for the actual PII field, the AI hands them a link to the browser-rendered view. The sensitive data never crosses the model boundary.

Watch-out: audit is now on the URL, not on the conversation. Every PII-accessing URL needs to log who requested it, who opened it, and when. The link is short-lived by design, but you also need the after-the-fact record. If your identity layer doesn't already produce that log, add it before you deploy this pattern. Otherwise you've built a bypass that leaves less trail than the thing it replaced.

Pattern 3 — Auth isn't a bolt-on.

The MCP spec doesn't take a strong position on authentication. The examples in the docs typically use a static bearer token. That works for a demo. It does not work for a real deployment.

The first serious client will need per-role tool visibility — a front-desk agent should see availability queries, an accounting lead should see billing tools, a general manager should see both. The second client will need multi-tenant separation. The third will want SSO into whatever identity system they already run. By the time you've hit those three, you've either built a serious identity layer or you've discovered that your MCP server is stuck at "one static token, one shape of user."

The right call is to skip the bearer-token phase entirely and stand up Microsoft Entra (or Okta, or your equivalent enterprise identity provider) from day one. Every MCP server registers as an application. Every tool exposure is scoped by role assignment. Every user session carries a signed token that the MCP server verifies before serving any tool.

Watch-out: the deploy story is now more complex. Redirect URI management, app registration, secret rotation, role assignments — all of it becomes part of the delivery. Build it into your project template so it's a fifteen-minute setup, not a two-week detour on client three.

Pattern 4 — Feedback has to be in-context.

Every AI deployment I've been involved with has a feedback problem. The default playbook — "put a Contact Support link on the page, users will find it" — does not work for AI. Users don't take screenshots of a bad conversation and email them to IT. They shrug, close the chat, and mention it to a colleague in the hallway two weeks later. By then no one can reproduce it, no one remembers exactly what was asked, and the bug is invisible to the people who could fix it.

The dynamic gets worse over time. Users who quietly abandon the tool aren't complaining — they've concluded it's unreliable and are routing around it. The signal you needed to keep the deployment healthy disappears at exactly the point you needed it most.

What I now build in from day one: an in-response feedback affordance — thumbs up, thumbs down, and a one-click "flag this." When a user flags an interaction, the system captures the full conversation state (every turn, every tool call, every response, the user's identity and role assignments) and posts it to a queue the dev team already watches. No screenshots. No ticket forms. No re-explaining what happened.

Two things change on both sides. Users stay engaged, because giving feedback is a click, not a chore — they can voice a complaint without leaving the tool, they see it acknowledged, and the tool feels responsive instead of opaque. Developers inherit full reproduction context in that same click: exact tool sequence, exact model responses, exact permissions, exact user intent. Bugs that would have taken a week of triage close in an afternoon. Enhancement requests arrive with the actual usage that motivated them attached, so prioritization is grounded in real behavior instead of survey guesses.

Watch-out: those flagged payloads contain conversation history, which will contain sensitive queries even after you've done the PII bypass work above. Route them to a store with the same access controls as the underlying data — not to your general error tracker or Sentry-style tool. Otherwise you've built a bypass around the bypass.

The parts that break aren't the parts vendors warned you about. They're the parts that only surface once the system is in real use.

Three gotchas the vendor decks don't mention.

Token budgeting is a governance requirement.

You will not accurately predict how much your users cost you. Usage patterns emerge that you didn't anticipate. Someone will build a bookmark that runs a specific query fifty times a day. Someone will paste a spreadsheet into the chat and ask for analysis. Someone will discover the reporting pattern (see above) before you do.

Per-user-per-day token budgets aren't a nice-to-have. They're the thing that stands between a well-adopted deployment and an unexpected quarterly bill. Set them at deploy time. Wire alerts at 60% and 90% of budget. Review actual usage against budget monthly for the first quarter, then quarterly forever.

The specific mechanism matters less than the practice. A single Cloudflare Worker sitting in front of the model API can count tokens per authenticated user. So can a policy at your identity provider. So can billing telemetry from the model vendor. Pick one and instrument it before the deployment goes to more than a handful of users.

One MCP server per system fragments authorization.

The tempting architecture: one MCP server for the PMS, one for accounting, one for the messaging platform. Clean separation. Each server owns its domain.

The problem: the same user has different roles across those systems. A property manager who's read-write on the PMS is read-only on accounting is unauthorized on the payment platform. Each server needs to know that user's role in its own context. If you've stood each server up with its own app registration, you now have three places to manage that user's permissions — and three places to forget when their role changes.

One to watch

Microsoft is developing an Entra feature that could collapse this into a single agent-scoped identity spanning multiple resources — closer to how a service account works, but with per-tool policy. If it ships as described, "one auth scope per MCP server" stops being the ceiling. Worth tracking for anyone planning multi-server deployments in the next twelve months.

Until it lands, the pragmatic workaround is a shared identity layer that all your MCP servers consult — one app registration, one role model, one place to add or remove a user. Slightly more upfront work, dramatically simpler operations.

Tool naming travels further than you think.

The tool named get_guest_details will get called when a user asks "who's the guest in unit 812?" — great. It'll also get called when a user asks "I need the guest's insurance info for a claim." Not great. The model reads the tool name, matches it to intent, and calls what looks like the right thing.

Two lessons. First: tool names should describe the tool's contract, not its subject. get_guest_summary and get_guest_contact_details and get_guest_billing_scope will all get called correctly. get_guest_details will get called for anything guest-related. Second: the tool description matters as much as the name. The description is what the model uses to decide which of two overlapping tools to call. Write it as if a new employee were reading it, not as if a compiler were parsing it.

The reach problem — and the Academy answer.

Every one of the patterns above assumes users who know what they're doing. Most of them don't. That's not a failure of the users; it's a failure of the deployment.

The gap between "we built the MCP server" and "our staff uses it well" is education, not technology. An operations manager who's never used a coding assistant will not intuit what an MCP-connected chat can do — or, more importantly, what it can't. They'll ask "show me all owner statements" (the reporting trap). They'll try to paste a guest's date of birth into the chat to disambiguate a lookup (the PII bypass). They'll expect the AI to know things it doesn't. And they'll conclude the tool is bad when the actual problem is they don't know what to ask.

The fix I've settled on is what I've been calling an Academy — a small, in-context learning layer attached to the MCP deployment. The mechanism is simple: a Claude skill (or equivalent instruction bundle) that teaches users, in the same interface they'll use the tool from, what the tool can do, how to phrase questions, what the pitfalls are, and where to escalate.

The Academy sits alongside the MCP server, not on top of it. When a user asks the AI "how do I use this?" the Academy skill fires and walks them through the actual capabilities of their deployment — not a generic AI tutorial, not a vendor-authored explainer. The specific tools their organization has enabled, the queries those tools support, the guardrails around what not to ask.

The effect is competency compounding. A user who spent thirty minutes with the Academy asks better questions six months later. The team's collective query quality rises. The reporting trap gets diagnosed by users, not by the operator's dashboard. And the education layer is versioned with the MCP layer — when a new tool ships, the Academy learns about it, and users learn about it through the Academy.

Watch-out: the Academy is only as good as the specificity of its content. A generic "how to use AI" course won't do this job. It has to be built with your actual deployment as the reference, updated when the deployment changes, and treated as first-class engineering effort. If it's ghostwritten in a week and never touched again, users will notice and stop trusting it.

What I now do differently than the March version of me.

In March I called MCP an architectural pattern to understand and build toward. That was accurate but incomplete. What I now believe: MCP is one of five layers, and shipping only one of them is what produces the "MCP didn't work for us" stories that are starting to circulate.

The five layers:

  1. Auth. Enterprise identity from day one. Not a bolt-on.
  2. Tools. MCP proper — connectors, schemas, rate management. Mature.
  3. Guardrails. TTL URLs for anything that would push large data or PII through the model context.
  4. Education. An Academy layer so users can operate the deployment competently.
  5. Feedback. An in-context loop that captures full conversation state on a single click, so users stay engaged and developers stay informed.

Skipping any one of them is where the deployments I've seen struggle. Skipping auth turns into a security review that stalls the project. Skipping guardrails turns into a surprise bill or a compliance incident. Skipping education turns into a well-built system nobody uses well. Skipping feedback turns into a deployment that quietly decays without anyone noticing.

MCP is table stakes. What differentiates a deployment is what you build around it.

If you're evaluating whether to invest in MCP for your operation, the question isn't "does the technology work." It does. The question is "are we willing to build all five layers." That's the real project.

Attribution and sources This is a practitioner update, not independent research. It reflects six months of building MCP integrations for hospitality operators, plus ongoing conversations with peers doing the same work. Where specific mechanisms (TTL URLs, Entra app registrations, Academy skills) are described, they reflect what I've built or seen built in production — not what a vendor spec sheet claims. Named products and technologies (MCP, FastMCP, Cloudflare Workers, Microsoft Entra) are described as they behaved in the deployments I worked on; if your experience diverges, that's information worth having.
On process This piece was drafted with AI assistance from a Claude session, working from my project notes, ongoing client work, and iterative back-and-forth over the actual claims. The experiences, opinions, and judgment calls are mine; the words were shaped in conversation and then reviewed and finalized by me. If a technical claim doesn't match your experience, that's on me, not the tool — I'd rather know.