server.ts
Publish Discovery Metadata
Hosts find your authorization server through standard metadata documents (RFC 9728).mcpAuthMetadataRouter serves them at /.well-known/oauth-protected-resource, so the host can perform the authentication flow.
server.ts
resourceServerUrl is this server’s public URL: localhost in development, the tunnel URL when testing in a host, your domain in production.
Verify Tokens with a Middleware
Once the user is signed in, every request carriesAuthorization: Bearer <token>. requireBearerAuth validates it before any handler runs: missing, invalid, or expired tokens get a 401, insufficient scopes a 403.
It takes a verifier you write, with one method: verifyAccessToken(token) resolves with an AuthInfo (handlers receive it as extra.authInfo) or throws InvalidTokenError (the middleware answers 401).
requireBearerAuth.
Mix Public and Authenticated Tools
Serving both anonymous and signed-in callers from one server takes three changes to the fully authenticated setup.Switch the Middleware
optionalBearerAuth validates the token when present, lets the request through when absent, and still rejects invalid tokens with a 401. Unauthenticated requests now reach your handlers.
server.ts
Declare Tool Visibility
Three declarations cover the combinations:securitySchemes | Meaning |
|---|---|
[{ type: "oauth2" }] | Requires sign-in |
[{ type: "noauth" }] | Works signed out |
[{ type: "noauth" }, { type: "oauth2" }] | Works signed out, does more when signed in |
server.ts
search-products lists both schemes: anonymous callers browse the public catalog, signed-in callers get results scoped to their account. extra.authInfo is set or undefined accordingly.
Guard the Handler
With unauthenticated requests reaching handlers, the scope check is no longer a formality: it’s the only gate on protected tools.server.ts
Go Further
Register Tools
Define what humans and agents can do
Create Views
Craft interactive UIs rendered in conversation
Manage State
Decide what the model sees