5. Exercise 1: Auth in the schema
1m

Exercise 1: Auth in the schema ( 8 min)

Disable the require_authentication config in the router.yaml file.

router.yaml
authorization:
require_authentication: false
directives:
enabled: true
reject_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 requires authentication.

Example for @authenticated
type Query {
publicInfo: Information
secretInfo: SecretInfo @authenticated
}
type Information {
name: String
money: Int @authenticated
}

The @requiresScopes directive marks and types as restricted based on required scopes. It checks the scopes attached to the JWT claim.

Example for @requiresScopes
type Query {
publicInfo: Information
adminOnly: AdminInfo @requiresScopes(scopes: [["admin:view"]])
}
type Information {
name: String
money: Int @requiresScopes(scopes: [["admin:view"]])
}

Exercise 1 Goal

🎯 Goal: Configure authentication in the schema using @authenticated and @requiresScopes.

  • Use @authenticated to require authentication for the Listing.amenities .
  • Use @requiresScopes to require the cost:view scope for the Listing.costPerNight . The host@example.com account has this scope. (Note: This is a new scope, not related to the host:view scope.)
Task!

💭 Hints

Check your work

As an authenticated and authorized host:

  1. Log in as a host@example.com account (password: host123!).
  2. Run the GetListingDetails tool, giving it a listingId of listing-1.
  3. 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:

  1. Log in as a guest@example.com account (password: guest456!).
  2. Run the GetListingDetails tool, giving it a listingId of listing-1.
  3. You should see the listing's amenities but not the listing's cost per night.
Task!

Solution

listings-schema.graphql
type Listing {
# ...other fields
costPerNight: Float @requiresScopes(scopes: [["cost:view"]])
amenities: [Amenity]! @authenticated
}
mcp.yaml
transport:
type: streamable_http
auth:
servers:
- https://dev-4gnj48muikmjespc.us.auth0.com
audiences:
- https://airlock-api.demo
resource: http://127.0.0.1:5000/mcp
scopes:
- openid
- host:view
- guest:booking
- cost:view
Previous