> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mcp-use.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Scalekit Provider

> Configure Scalekit MCP Auth for an MCP server.

Use `oauthScalekitProvider` when Scalekit is the authorization server. MCP clients register directly with Scalekit. mcp-use verifies Scalekit access tokens against the resource id. The resource server does not hold a client secret.

## Configure Scalekit

In the [Scalekit Dashboard](https://app.scalekit.com), create an MCP server resource and copy:

1. The **Environment URL**.
2. The **resource id** (`res_…`). This is the JWT audience.
3. The public MCP URL. It must match the URL mcp-use advertises, with no trailing slash.

Authorization-server metadata advertises the resource-scoped issuer (`{environmentUrl}/resources/{resourceId}`). Scalekit serves the live document. mcp-use also needs a static copy so protected-resource metadata can name that issuer. The verifier accepts both the environment-root issuer and the resource-scoped issuer so tokens issued during Scalekit's issuer migration still verify. A token minted for a different `res_…` in the same environment is rejected.

Optional `audience` is an extra value that must also appear in `aud`. It does not replace the resource-id check.

## Configure the server

```bash theme={null}
MCP_USE_OAUTH_SCALEKIT_ENVIRONMENT_URL=https://your-env.scalekit.dev
MCP_USE_OAUTH_SCALEKIT_RESOURCE_ID=res_your_resource
MCP_URL=https://mcp.example.com/mcp
```

```typescript theme={null}
import { MCPServer } from "mcp-use";
import { oauthScalekitProvider } from "mcp-use/oauth/scalekit";

const server = new MCPServer({
  name: "scalekit-server",
  version: "1.0.0",
  oauth: oauthScalekitProvider(),
});

export default server;
```

## Use the caller

Scalekit maps `sub` to `ctx.auth.user.id`. `subjectType` is `"machine"` only when `sub` equals `client_id` or `azp`. User tokens also carry a host `client_id`, so presence of that claim is not a machine signal. Optional `org_id` and `sid` become `organizationId` and `sessionId`. Token permissions are top-level `ctx.auth.permissions`. Custom claims and every other JWT field are on `ctx.auth.payload`. Read them there. Do not put them on `ctx.auth.user`.

```typescript theme={null}
server.tool(
  {
    name: "whoami",
    description: "Return the authenticated Scalekit caller.",
  },
  async (_args, ctx) => {
    if (ctx.auth.user.subjectType === "machine") {
      return {
        isError: true,
        content: [{ type: "text", text: "User session required" }],
      };
    }

    return {
      content: [
        {
          type: "text",
          text: JSON.stringify({
            id: ctx.auth.user.id,
            organizationId: ctx.auth.user.organizationId,
            scopes: ctx.auth.scopes,
            permissions: ctx.auth.permissions,
          }),
        },
      ],
    };
  },
);
```

<CardGroup cols={2}>
  <Card title="Scalekit documentation" icon="book-open" href="https://docs.scalekit.com">
    Review Scalekit MCP authorization and resource ids.
  </Card>

  <Card title="User Context" icon="user" href="/v2/typescript/server/authentication/user-context">
    Use Scalekit caller, organization, and permissions.
  </Card>
</CardGroup>
