Identify the exact FHIR resource types and operations the app requires and construct granular scope strings using the format [context]/[ResourceType].[cruds] where c=create, r=read, u=update, d=delete, s=search
Include the granular scopes in the scope parameter of the OAuth authorization request alongside openid, fhirUser, launch, or launch/patient as applicable
Initiate the SMART authorization code flow; the authorization server will present the granular scope list to the user for approval
Exchange the authorization code for tokens; inspect the scope field in the token response to confirm which scopes were actually granted — the server may downscope
Use the granted access token to make FHIR API calls; restrict operations to those covered by the granted scopes to avoid authorization errors
If a required scope was not granted, surface a clear error to the user rather than attempting the restricted operation
Known gotchas
Granular scopes use a period before the cruds suffix (e.g., patient/Observation.rs), not a slash; malformed scope strings will be rejected or ignored
The authorization server may grant a broader scope than requested (e.g., patient/Observation.read instead of patient/Observation.r); treat the token response scope as authoritative
SMART v2 granular scopes are not universally supported; verify server support via the scopes_supported field in the .well-known/smart-configuration before requesting fine-grained scopes
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp