1m
Exercise 1: Auth in the schema (⏳ 8 min)
Disable the require_authentication config in the router.yaml file.
router.yaml
authorization:require_authentication: falsedirectives:enabled: truereject_unauthorized: false
We'll be more specific about what requires authentication in the listings schema.
Schema directives: @authenticated and @requiresScopes
The @authenticated directive is used to indicate that a field requires authentication.
Example for @authenticated
type Query {publicInfo: InformationsecretInfo: SecretInfo @authenticated}type Information {name: Stringmoney: Int @authenticated}
The @requiresScopes directive marks fields and types as restricted based on required scopes. It checks the scopes attached to the JWT claim.
Example for @requiresScopes
type Query {publicInfo: InformationadminOnly: AdminInfo @requiresScopes(scopes: [["admin:view"]])}type Information {name: Stringmoney: Int @requiresScopes(scopes: [["admin:view"]])}
Exercise 1 Goal
🎯 Goal: Configure authentication in the schema using @authenticated and @requiresScopes.
- Use
@authenticatedto require authentication for theListing.amenitiesfield. - Use
@requiresScopesto require thecost:viewscope for theListing.costPerNightfield. Thehost@example.comaccount has this scope. (Note: This is a new scope, not related to thehost:viewscope.)
Task!
💭 Hints
Check your work
As an authenticated and authorized host:
- Log in as a
host@example.comaccount (password:host123!). - Run the
GetListingDetailstool, giving it alistingIdoflisting-1. - You should see all the details for a listing.
Task!
Clear out the OAuth token in MCP Inspector by clicking Open Auth Settings and Clear OAuth State. You may also want to open up a new incognito tab, in case the refresh token for the last login is still valid.
As an authenticated and authorized guest:
- Log in as a
guest@example.comaccount (password:guest456!). - Run the
GetListingDetailstool, giving it alistingIdoflisting-1. - You should see the listing's amenities but not the listing's cost per night.
Task!
✅ Solution
listings-schema.graphql
type Listing {# ...other fieldscostPerNight: Float @requiresScopes(scopes: [["cost:view"]])amenities: [Amenity]! @authenticated}
mcp.yaml
transport:type: streamable_httpauth:servers:- https://dev-4gnj48muikmjespc.us.auth0.comaudiences:- https://airlock-api.demoresource: http://127.0.0.1:5000/mcpscopes:- openid- host:view- guest:booking- cost:view