Key takeaways
- Remote MCP servers are reached over streamable HTTP at a URL, so users connect without installing anything.
- Authentication uses OAuth 2.1 with PKCE and, in most clients, dynamic client registration.
- The MCP server is a protected resource: unauthenticated requests must return 401 plus metadata pointing at the authorization server.
- Every tool call should execute as the signed-in user, with the same permissions and quotas as the dashboard.
- Never ship a shared admin token in an MCP server; scope tokens per user and meter usage per account.
A local MCP server is easy to secure: it runs as you, on your machine. A remote MCP server is a public HTTP endpoint that any AI client can reach, so authentication is the whole design problem. This guide explains the model and the pitfalls.
The protected resource model
In MCP terms, your server is a protected resource. The rules are simple and strict:
- An unauthenticated request must return 401, not data and not a generic error.
- The 401 response, plus a well-known metadata document, tells the client where the authorization server lives.
- The client then runs an OAuth 2.1 authorization-code flow with PKCE.
- The resulting access token is presented on every subsequent tool call.
This ordering matters. If your metadata is wrong, clients cannot discover how to authenticate and the connection silently fails with "unauthorized" — the single most common bug in remote MCP deployments.
Why OAuth rather than an API key
You could accept a static key in a header, and a few clients support it. It is still the weaker choice:
- Keys pasted into a chat client end up in logs, screenshots and shared conversations.
- A key rarely identifies a person, only an account, so you cannot audit who did what.
- Revoking a key breaks every device at once.
- There is no consent screen, so the user never sees which permissions they granted.
OAuth solves all four. The user signs in to your product, sees exactly what they are authorising, and can revoke a single connection later.
Dynamic client registration
Traditional OAuth assumes the developer pre-registers an application and gets a client ID and secret. That does not work when thousands of individual users connect arbitrary assistants.
Dynamic client registration lets the AI client register itself with your authorization server on the fly, receive credentials, and continue the flow. From the user's point of view, they paste a URL and land on a sign-in page. Enabling it is usually a single configuration switch on a managed auth provider.
What the user actually experiences
- They add your server URL in Claude, ChatGPT, Cursor or another MCP client.
- The client fetches metadata, discovers your authorization server, and opens a browser tab.
- Signed-out users hit your login screen first, then bounce back to the consent screen.
- The consent screen names the application and the scopes it requests.
- On approval, the client stores the token and the tool list appears in the assistant.
Keep the consent screen on your own domain and in your own brand. It is the moment a user decides whether to trust the connection.
Scoping every tool call to the user
Once the token arrives, resolve it to an internal user on every call, and then behave exactly as your dashboard would:
- Apply the same row-level security. A tool must never read another tenant's records.
- Check plan entitlements before doing work, and return a structured error if the feature is not included.
- Deduct credits atomically so a burst of parallel calls cannot overdraw an account.
- Log the call with the user ID for auditing.
The mental model: an MCP tool call is just another authenticated request from that user, arriving through a different door.
Defending against prompt injection
An AI agent may read untrusted content — a web page, an email, a pasted document — and that content can try to instruct it to call your tools maliciously. You cannot fix this in the model; you fix it at the boundary:
- Keep destructive tools out of the catalogue, or require an explicit confirmation parameter.
- Enforce hard limits server-side: batch sizes, rate limits, spend caps per hour.
- Never widen permissions because a tool argument asks you to.
- Treat tool arguments as untrusted user input, including in any query you build from them.
Operational details people forget
- Token expiry and refresh. Long agent sessions will outlive short-lived tokens; support refresh properly.
- Revocation. Give users a place to see and disconnect active connections.
- Rate limiting per user, not per IP. Assistants share IP ranges.
- Timeouts. Tools that take minutes should return a job ID and let a second tool poll it.
- Observability. Track tool call volume, error rates and which tool the model picks; wrong-tool selection is a documentation problem you can measure.
How VeriMailX does it
Our MCP endpoint is a protected resource with OAuth and dynamic client registration enabled. Unauthenticated calls return 401 with resource metadata; authorised calls run as the signed-in VeriMailX user with their own plan limits and credit balance. Verification tools deduct credits atomically, and free tools such as the disposable-domain lookup cost nothing.
If you are building your own, start with how to build an MCP server, or read what an MCP server is for the fundamentals.
Frequently asked questions
Ready to clean your list?
Verify your emails with VeriMailX and send your next campaign with more confidence, fewer bounces and better results. Unlimited free single email verification — no card required.
