This is a demo MCP server that acts as an OAuth resource server. It accepts JWT access tokens issued by a single external authorization server, and uses the scopes and roles in those tokens to decide which tools the caller may use.
You can use it to test out building an MCP client that does OAuth, including step-up authorization when a tool needs a scope the current token doesn't have.
| Endpoint | Role |
|---|---|
https://oncall.xaa.rocks/mcp |
The MCP endpoint, using the Streamable HTTP transport. Requires a Bearer access token. |
https://oncall.xaa.rocks/.well-known/oauth-protected-resource/mcp |
Protected resource metadata, which points clients at the authorization server |
Access tokens must be issued by https://aparecki-dev.okta.com/oauth2/aus26pk2nxibL5MsI1d8 with an audience of https://oncall.xaa.rocks.
All four tools are always listed, regardless of what your token contains. The authorization check happens when a tool is called, so a client can see the full set of capabilities and knows which scope to ask for.
| Tool | What it does | Requires |
|---|---|---|
who_is_on_call |
Reports who is currently on call, and recent handoffs | Nothing |
set_myself_on_call |
Takes over the on-call rotation yourself | The oncall role in the roles claim |
page_on_call |
Sends a page to whoever is on call | The page scope |
declare_incident |
Declares an incident and assigns it a number | The incident scope |
mcp scope. Without it the server returns 403 with WWW-Authenticate: Bearer error="insufficient_scope".401 and a WWW-Authenticate header containing resource_metadata, which is how your client discovers the authorization server.page and incident scopes only when you need them, so you can exercise the step-up flow.Note: the on-call state is shared and lives in Redis, so anyone testing against this server sees the same on-call person.