MCP Authorization Checklist (Spec 2026-07-28) + Endpoint Test

What the 2026-07-28 MCP specification asks of a server that guards your app data, a table of checks, and a read-only way to test your own endpoint.

Timothy Lindblom

Founder, Newly

Published Last updated

An MCP server that reaches your app's data should answer a request without a token with HTTP 401 and a pointer to its resource metadata, and accept only tokens issued for it. The 2026-07-28 specification builds this on OAuth 2.1. Request the server's endpoint yourself, read what comes back, and mark each item detected, unknown or confirmed by owner evidence.

QuestionWhat the 2026-07-28 spec saysLevel
Is authorization required?Optional. HTTP transports that support it should follow the spec; stdio servers should read credentials from the environment.OPTIONAL / SHOULD
What is the server's role?An OAuth 2.1 resource server that publishes Protected Resource Metadata (RFC 9728) naming at least one authorization server.MUST
What answers a call with no token?HTTP 401 with a WWW-Authenticate header carrying resource_metadata, or metadata at the well-known address.MUST (one of the two)
Which tokens may it accept?Only tokens issued for this server. It may not accept or pass on any other token.MUST
What about the Origin header?Servers on Streamable HTTP validate it and answer 403 when it is present and invalid.MUST

Checked against the published specification on 24 October 2026.

Do I need authorization on an MCP server at all?

An MCP server is a door that lets an AI assistant call tools or read data in your backend. Your Expo app is not that door. If you or an AI tool added an MCP endpoint next to your normal API, it is a second way into the same data, and it needs its own sign-in and its own access rules.

The authorization specification calls authorization optional, so an open server is not a spec violation. It is still your decision about who may read what. The Streamable HTTP section says servers should implement authentication for all connections, and a local server should bind to 127.0.0.1 and not to every network interface. A public server that holds nothing private can reasonably stay open. One that touches user records, keys or paid AI calls should not.

How does the sign-in flow work?

Your server never asks for a password. It sends the client to an authorization server, then checks the token that comes back. Steps 2 and 6 below are yours. Step 4 sets the audience: the client names your server in a resource parameter, as RFC 8707 defines, so the token is meant for you and for nobody else.

Request path between an AI client, your MCP server and the authorization serverAI clientan assistant or agentYour MCP serverthe resource serverAuthorization serverissues the tokens1. request, no token2. 401 + resource_metadata3. fetch your metadata4. sign in with PKCE and resource = your server URL5. access token issued for your server6. request with tokenyour server checks audience, then answers
Pink arrows mark the two steps your server owns. Based on the flow in the 2026-07-28 authorization specification.

The metadata in step 3 is a JSON document from RFC 9728. Its required field is resource, and the spec adds a requirement that authorization_servers lists at least one issuer. The sign-in step uses PKCE, a one-time proof that stops a stolen authorization code from being reused.

What should my server check?

Nine items, each tied to a requirement in the security considerations or the best practices page.

CheckWhat to look forWhat a miss means
1. 401 on no tokenA request without a token returns 401, not 200 or an empty list.Detected: the door is open.
2. Challenge headerWWW-Authenticate: Bearer with a resource_metadata URL.Clients cannot find your sign-in; unknown if the well-known path works.
3. Metadata documentresource equals your canonical URL; authorization_servers is not empty.A mismatched resource value breaks the spec's impersonation check.
4. Audience checkYour code verifies the token was issued for your server URL, in addition to checking its signature.Tokens meant for another service work on yours.
5. No passthroughCalls to upstream APIs use a separate token your server obtained itself.Your server forwards a client's credential to a service that trusts it.
6. Narrow scopesEach tool maps to one small scope; a token without it gets 403 with error=insufficient_scope.One stolen token reaches every tool.
7. Origin and bindingBad Origin gets 403; a local server listens on 127.0.0.1 only.A web page in the user's browser can reach a local server.
8. HTTPS everywhereAuthorization server endpoints use HTTPS; redirect URIs are HTTPS or localhost.Codes and tokens cross the network in the clear.
9. Token hygieneTokens stay out of query strings, logs and error messages; access tokens are short-lived.A log file becomes a key store.

One rule behind items 4 and 5

The best practices page lists the damage when audience checks are missing: rate limits and audit trails stop meaning anything, and logs downstream show requests from the wrong source. Its mitigation is one sentence: a server must not accept tokens that were not explicitly issued for it.

How do I test my own endpoint?

Only test servers you run. Each probe below is read-only and asks one question. Save the raw response with the date, because that file is your owner evidence.

  1. Send a request to the MCP URL with no token. Expect 401 and a WWW-Authenticate header. A 200 means check 1 failed.
  2. Open the resource_metadata URL from that header. The discovery rules also allow /.well-known/oauth-protected-resource. Confirm the JSON matches check 3.
  3. Send a request with a made-up token. Expect 401. Receiving data here is the failure the spec calls out most clearly.
  4. Send a request with a wrong Origin header and expect 403.

A third-party tool can run steps like these for you. mcp-authcheck (MIT license, one maintainer, not part of the MCP project) grades the 401 challenge, the metadata documents, PKCE discovery, rejection of an invalid token and origin handling, and gives a letter grade. Its own notes say a public server is graded N/A, not failed. A good grade is detected conformance on those points. Your tool permissions, scope mapping and logs stay unknown until you read them.

What goes wrong in practice, and who handles it?

In the CVE record for CVE-2026-27826, the MCP server mcp-atlassian before version 0.17.0 let an unauthenticated caller steer the server into making outbound requests, rated 8.2 by the CVE record's CVSS 3.1 vector, published 10 March 2026. The record traces it to request headers that were never validated, which is a different flaw from a missing OAuth step. It still shows what an open MCP endpoint adds to your exposure. Update the version you run and put the endpoint behind sign-in.

If you use a managed login service, split the work this way:

TaskYour auth providerYou
Issue and sign tokensYes. Supabase documents turning on its OAuth 2.1 server for MCP clients.Turn it on and build the consent screen.
Register clientsOffers manual and dynamic registration; Supabase says to use dynamic registration cautiously.Review which clients exist and their redirect URIs.
Verify audience and expiryGives you the keys to verify with.Run the verification in your MCP server on every request.
Decide what each tool may touchNo.Map scopes to tools and keep row level rules on the data.

The Supabase MCP authentication guide also notes that row level security policies still apply to what the server reads. If a tool behind your server calls an AI model, each anonymous call spends your provider balance or, in a Newly app, credits. The 15-minute app check and the leaked key guide cover the keys behind those calls.

Dates matter here. The 2026-07-28 changelog deprecates Dynamic Client Registration in favor of Client ID Metadata Documents, and asks authorization servers to include the iss parameter in responses. Re-read the spec when your MCP library updates.

Where do you stand?

Everything starts as unknown, because that is what an untested item is. Move an item to confirmed only when you hold the evidence listed under it. A scan from outside can move some items to detected. Only you can confirm the rest.

Your MCP authorization check

  • Detected: You found the problem.
  • Unknown: Not checked yet, or the check could not tell.
  • Confirmed by owner evidence: You checked and kept the proof.
  1. 1. A request with no token gets HTTP 401 and a WWW-Authenticate header that names a resource_metadata URL.

    Evidence: the raw response headers from the no-token request, saved with the date.

  2. 2. The protected resource metadata document loads, its resource value is your server's canonical URL, and it lists at least one authorization server.

    Evidence: the JSON document and the URL it was fetched from.

  3. 3. Your server rejects a token issued for a different audience, and never forwards a client's token to another API.

    Evidence: the validation code or middleware setting plus the 401 from a made-up token.

  4. 4. Each tool needs the narrowest scope that covers it, and a token without it gets 403.

    Evidence: the scope-to-tool mapping and one 403 response.

  5. 5. Requests with an unexpected Origin header are refused with 403, and a local server binds to 127.0.0.1 only.

    Evidence: the server config and the 403 response.

  6. 6. Access tokens do not appear in logs, URLs or error messages, and the tools cannot reach more data than the signed-in user can.

    Evidence: a log search with no token strings and the tool permission list.

0 detected6 unknown0 confirmed by owner evidence

Your answers stay in this browser tab. Nothing is saved or sent.

The same outside view applies to the website around your app. The 30-second check for exposed .env and .git files is a good companion, and the security hub lists the other checks.

Frequently asked questions

Is OAuth required for every MCP server?

No. The 2026-07-28 specification calls authorization optional. If you support it over an HTTP transport, the spec says to follow its OAuth 2.1 profile. Servers that run locally over stdio should read credentials from the environment instead. A server that exposes private data over HTTP needs some form of authentication in practice, and the transport section says servers should implement it for all connections.

Can I use my existing login provider as the authorization server?

Often yes. The spec leaves the authorization server's internals open, and it may be a separate service from your MCP server. Supabase, for example, documents how its Auth service can act as the OAuth server for an MCP server. Your MCP server still has to publish its metadata and still has to check every token it receives was issued for it.

What is the difference between a 401 and a 403 here?

A 401 means authorization is required or the token is invalid or expired, and it carries the pointer to your resource metadata. A 403 means the caller is known but lacks permission, and the spec says a server should answer a token with too few scopes with 403 and error=insufficient_scope. Returning 200 with data for a bad token is the failure to look for.

Does a good grade from a checker mean my server is fine?

No. A checker such as mcp-authcheck reads what your endpoint says from outside and compares it with the spec. It cannot see how your code validates a real token, what your tools can reach, or what your logs store. Treat a good grade as detected conformance on the points it tested and everything else as unknown.

Is Dynamic Client Registration still allowed?

It remains in the specification for backwards compatibility but is marked deprecated in the 2026-07-28 revision. New servers should prefer Client ID Metadata Documents. If you leave open registration on, review which clients have registered and which redirect URIs they were given.

Does my Expo app need any of this?

Only if your backend exposes an MCP server for AI assistants to call. The app on the phone talks to your normal API. An MCP endpoint is a separate door into the same data, so it needs its own authentication and its own access rules.

Sources

All pages checked on 24 October 2026.

  1. Model Context Protocol specification 2026-07-28: Authorization, modelcontextprotocol.io
  2. Authorization Server Discovery (2026-07-28), modelcontextprotocol.io
  3. Client Registration (2026-07-28), modelcontextprotocol.io
  4. Authorization Security Considerations (2026-07-28), modelcontextprotocol.io
  5. Security Best Practices (2026-07-28), modelcontextprotocol.io
  6. Streamable HTTP transport (2026-07-28), modelcontextprotocol.io
  7. Key Changes in 2026-07-28, modelcontextprotocol.io
  8. RFC 9728: OAuth 2.0 Protected Resource Metadata, IETF
  9. RFC 8707: Resource Indicators for OAuth 2.0, IETF
  10. CVE-2026-27826, mcp-atlassian before 0.17.0, CVE Program
  11. Use Supabase Auth as the OAuth server for an MCP server, Supabase docs
  12. mcp-authcheck (third-party read-only checker), GitHub, tstanmay13/mcp-authcheck

Continue Learning