Key takeaways
Do I need a sign-in on it?
The rules say it is optional. So a server with no lock at all is still a correct server.
Can I reuse my app's token?
No. The rules say a server must not accept a token that was not issued for that server.
What broke in July 2026?
Sessions were removed. An ownership check moved out of the plumbing and into your tool code.
Is old advice still good?
Often not. Self sign-up for callers was retired, and it is one leg of a known attack.
Will a scanner catch it?
Mostly no, ours included. Each tool answers a different question from this one.
Fastest thing to do?
Call your own server with no token. If real data comes back, you have your answer.

A year ago, an MCP server was a thing you ran on your own laptop so your editor could reach your files. That is still the common picture. It is why nearly everything written about MCP safety is advice for the person installing one: do not run a server you do not trust.

That advice is fine. It is now aimed at the wrong half of the room.

The rules themselves have moved on. Almost all of the sign-in rules in MCP are written for servers reached over the web, and the rules say plainly that a laptop server should not use them at all. Web-reached servers are servers you host, on a public address, for other people's agents to call.

If you shipped one of those, or a coding tool shipped one for you, you did not add a feature. You opened a second front door to your data. And the rules that govern that door are not the rules you already know from your normal routes.

What changes the moment you host one

MCP splits servers by how they are reached, and the split does all the work.

A server that talks over plain input and output is the laptop kind. The rules tell it to skip the sign-in flow and take its keys from the environment. That is sound, because only the one program on that machine can talk to it. The wall around it is the machine itself.

A server reached over the web has no such wall. Anyone who learns the address can send it a request. The sign-in rules exist for exactly this case, and they are long, because there is a lot to get right.

Here is the part that catches people. You do not have to follow them.

The lock is optional, and the rules say so

This is the sentence, word for word:

Authorization is OPTIONAL for MCP implementations.

A server with no sign-in at all is still a correct server. Nothing is broken. It will answer every request it gets, from anyone, and no part of MCP will object.

That is not a mistake in the design. MCP has to cover the laptop case too, and the laptop case has no use for a sign-in flow. But the effect on a hosted product is direct, and it is the whole reason this page exists: the starting state is open, and closing it is your job alone.

Compare that to the rest of your stack. A database refuses you by default. A cloud bucket is private until you make it public. Your web framework has a login page in the first tutorial. Here the order is reversed. The working example works because there is nothing in the way.

This is the same pattern we see in the apps we score. A tool gives you something that runs, the safe setting is a later chapter nobody reaches, and the thing ships in the state the tool left it in. It is why the average Launch Readiness Score across the 700+ AI-built apps we have audited is 44 out of 100, and why missing access control keeps showing up near the top of the list.

The easy way to add a sign-in is the one thing the rules forbid

Say you decide to close the door. There is an obvious shortcut, and almost everyone reaches for it.

Your product already signs people in. You already hand every user a token. So let the agent send you that same token. You already have the code that checks it. This is an afternoon of work.

The rules have a name for that, and a hard line against it:

MCP servers MUST NOT accept any tokens that were not explicitly issued for the MCP server.

The name is token passthrough. To see why it matters, you need one idea that is easy to miss.

A token is not only proof of who someone is. It also carries who it was made for. The rules call that the audience. A token your web app handed out was made for your web app, and for nothing else. When your MCP server takes it anyway, it has answered the first question and skipped the second.

And the second question is the one that matters here, because the caller is not a person at a keyboard. It is an agent, holding tokens from many places at once, deciding on its own which one to send you.

The rules list four separate harms that follow. They are worth reading slowly, because only the first one is obvious.

What breaksWhy
Your controls stop applyingRate limits and request checks are often tied to who a token was made for. A token made for something else walks past them.
Your logs stop being trueThe service behind you records the request as coming from someone else. When you need to trace what happened, the trail points the wrong way.
You become the tunnelAnyone holding a stolen token can send it through your server to reach what sits behind it. Your server does the reaching, under your name.
You cannot add controls laterOnce callers rely on sending you any token they like, every control you add afterwards breaks them. The easy choice now removes the option later.

The fix is not hard, and it is not a product you buy. Your server gets an address of its own. Tokens are issued for that address. Your server checks that the token in front of it names that address, and returns a 401 when it does not. The rules spell this out: a server must confirm that a token was made for it, and must reject anything else.

Sessions are gone, and that moved a check into code you wrote

In July 2026 MCP changed in a way that quietly handed you a new job.

The old version had sessions. Your server handed out a session id, the caller sent it back in a header, and your server kept track of what belonged to whom. The July 2026 revision removed all of that. There is no session header now, and no opening handshake. Every request stands on its own.

The rules are clear about what takes its place. A server that needs to remember something between calls makes its own handle — a cart id, a job id, a draft id — and gets it back as an ordinary argument to a tool.

Read that line again with a security hat on. The thing that used to be a session is now just a value the caller types in, arriving in the same place as every other value they type in.

The people writing the rules saw it coming:

MCP servers MUST NOT treat possession of a state handle as authentication.

This is the oldest hole on the web wearing new clothes. If your tool takes a cart id and hands back that cart, and never asks whether the cart belongs to the caller, then anyone who can guess a cart id can read any cart. Change one number, get someone else's data.

The repair the rules give you is worth copying exactly. Store the handle against the user, not on its own. Take the user from the token you already checked, never from what the caller sent. Then a guessed handle is useless, because it is filed under a name the guesser cannot supply. Make the handles random rather than counted up, and give them an end date.

If that shape feels familiar, it should. It is the same missing ownership check we write up over and over in database rules on AI-built apps, where a table is readable by anyone who can name a row. Same flaw. New door. And this door is newer, so it gets read less.

Half the guidance you will find is now the wrong guidance

Search for how to put a sign-in on an MCP server and much of what comes back was written in 2025. A good deal of it will tell you to turn on dynamic client registration, which lets any caller sign itself up and collect an id with no human in the loop. For a while that was the normal answer.

The July 2026 revision retired it. It still works, kept alive only for older sign-in servers that cannot do the newer thing, and the rules say plainly that new builds should not reach for it.

There is a sharper reason to care than being out of date. That same feature is one of the four conditions for the confused deputy attack, which the rules describe at length. All four have to be true at once:

ConditionIn plain terms
One fixed id used with the service behind youEvery request you pass along looks like the same caller.
Callers can sign themselves upAn attacker can get an id, and name any address to send the reply to.
The service behind you remembers the first approvalIt drops a cookie and stops asking.
You do not ask on your own behalfNothing in your flow checks whether this caller was ever approved.

With all four in place, a user who clicks a link is never shown an approval screen, because their browser still carries the one from last time. The code comes back, goes to the address the attacker named, and the attacker walks in as them.

The repair is your own approval step, run before you hand anyone on. Keep a list of which callers this user has approved. Check it first. Show a screen that names the caller, names what it is asking for, and shows where the reply will be sent. Match the reply address to the one on file, character for character, and refuse anything else.

See what an outsider sees

Our free scan reads a live URL in about 30 seconds and returns a Launch Readiness Score out of 100 across security, reliability, performance and monitoring.

Run a free scan

What our own scan does and does not see here

We publish our method, so we will be exact rather than vague, including where it runs out.

Our scan reads a live URL and works from what it can reach. If your MCP door sits on an address that no page points at, we will not find it, because nothing on your site tells us it is there. A clean score from us is not a statement about a door we never knocked on.

The audience test is worse than that. To learn whether your server takes a token meant for something else, someone has to hold a token meant for something else and send it. We do not hold your tokens, and we would not want to. That one is yours to run, it takes about a minute, and it is step three below.

The same gap sits over the tools next to ours, and it is worth being concrete about why. A network scanner probes what your address exposes from outside. It will see a web port answering and has no way to know that what answers is a set of tools wired to your database. A code scanner reads your source, where a tool handler looks like any other function, and the rule being broken lives in a field on a token rather than in the code. A package scanner asks whether your libraries have known flaws, which is a third question again, and the one behind made-up package names. None of these tools are broken. Each answers the question it was built for, and none of those questions is whether this door is locked.

What we do see is the ground this sits on. We test rate limits live rather than reading config, on sign-in and sign-up and other routes, and no rate limit on the routes that check who you are is the second most common critical finding across our scans, at 71 percent. We look for keys left where a browser can read them, which sit at 67 percent. If your MCP door has no lock, these are the rooms behind it. Our paid audit puts a senior engineer on the same four areas, which is more depth on the same ground, not a different lens.

We would rather draw that line in public than let a score stand in for an answer it cannot give.

Six checks you can run today

None of these need a new tool, a budget line, or anyone's permission. The first three take a minute between them.

  1. Call your own server with nothing attached. Send a plain request with no token at all. A closed server answers 401 and tells you where to go to sign in. If you get real data back, the door is open, and you have your answer in one command.
  2. Ask for the sign-in notice. A protected server has to publish a small file saying who issues its tokens, at a fixed address ending in /.well-known/oauth-protected-resource. Fetch it. Nothing there means nobody told the callers how to sign in.
  3. Send a token from somewhere else. Take a token your web app handed out, or one from any other service, and send it to your MCP address. It should be refused. If it is accepted, you have the exact thing the rules forbid, and you found it in a minute.
  4. Open one tool handler and find where the user comes from. Follow the value you use to decide what to return. If it came from the arguments the caller sent, that is the hole. It must come from the token you checked.
  5. Read your scopes out loud. If you see a star, or the word all, or anything named full access, one stolen token opens everything at once. The rules name those three as common mistakes by name. Start narrow and ask for more only when a step needs it.
  6. Put your MCP door on the same rate limit as your login. It is a route that reaches your data and it takes traffic from software, not from people. Ours is the check we run live, and it is the one most often missing.

If you want a fuller pass after that, the tools worth adding for routes like this are the ones that send real traffic rather than reading your code, because the whole question here is what your server does when someone sends it something odd. It belongs on the same list as the rest of your pre-launch checks, next to the checks you run on every build, and the wider set of audit tools is worth reading before you buy anything.

What we are not claiming

Four limits, stated here rather than buried.

We have not tested your server. Nothing on this page is a finding about your product. Every rule quoted comes from the published MCP rules, which anyone can read, and we link them at the bottom.

These are rules, not law. Nobody will fine you for ignoring a MUST NOT here. What you break instead is the promise the callers rely on, and a caller that trusts you to check will not check for you.

The text moves. The July 2026 revision is settled, but the working draft keeps changing, and some of it will change again. We quote the settled one and the safety notes that sit beside it. Check the version stamp on anything you read about MCP, including this.

We are not counting how common any of this is. We do not measure MCP doors across our scans, so we have no rate to give you, and we have not guessed at one. The 44 out of 100, the 71 percent and the 67 percent above are ours and are about the ground underneath, not about MCP.

If the words here are new, our plain-English glossary defines them, and our guide to auditing AI-written code covers the wider job this sits inside. For teams doing this at more than one desk, the checklist for AI editors and our notes on working with coding agents are where a rule like this gets written down, and agent-style tools are usually where the first MCP door gets opened.

The habit worth keeping. Before any new door goes live, send it one request with nothing attached and see what comes back. If it answers with your data, you have learned the most important thing about it in under a minute. Do it again after every deploy that touches the route.

Frequently asked questions

Does an MCP server need authorization?

Only if you want one. The MCP rules say in plain words that authorization is optional. A server that asks for nothing is still a correct server, and it will answer every request it receives from anyone who knows the address. That is fine for a server running on your own laptop, where the machine is the wall. For a server you host on a public address, it means the starting state is open and closing it is entirely your job.

Can I reuse my app's existing login token for my MCP server?

No, and this is the rule that catches most homemade servers. The MCP rules say a server must not accept any token that was not issued for that server. A token your web app handed out was made for your web app. Accepting it anyway is called token passthrough, and the rules name it as an anti-pattern. Your MCP server needs an address of its own, tokens issued for that address, and a check that the token in front of it names that address.

What changed for security in the 2026-07-28 MCP revision?

Sessions were removed. There is no session header and no opening handshake, so every request now stands on its own. A server that needs to remember something between calls mints its own handle and receives it back as an ordinary tool argument. That moves an ownership check out of the plumbing and into code you write. The rules are explicit that holding a handle is not proof of identity, so your tool has to check that the handle belongs to the caller. Dynamic client registration was also retired in favour of client id metadata documents.

Will my security scanner check my MCP endpoint?

Probably not, and that includes ours. A scanner that reads a live address works from what it can reach, so an MCP address that no page links to is never found. A code scanner reads your source, where a tool handler looks like any other function. A package scanner asks about your libraries. None of those questions is whether this particular door is locked. The checks in this article are ones you run yourself, and the first three take about a minute.

What is the fastest check I can run right now?

Send your own MCP address one request with no token attached and look at what comes back. A closed server answers 401 and points you at where to sign in. If you get real data instead, the door is open and you have learned the most important thing about it in a single command. The second fastest is to send it a token issued by some other service and confirm it is refused.

Is this only a problem for servers I host, or for ones I install too?

Both, but they are different problems. A server you install on your machine can run any command it likes with your privileges, so the risk there is what you chose to run. A server you host is reachable by strangers, so the risk is who can call it and what they can reach through it. This article is about the second one, because it is the one that gets written about least and the one that puts your users' data rather than your laptop on the line.

Research sources