> **Building with AI coding agents?** If you're using an AI coding agent, install the official Scalekit plugin. It gives your agent full awareness of the Scalekit API — reducing hallucinations and enabling faster, more accurate code generation.
>
> - **Claude Code**: `/plugin marketplace add scalekit-inc/claude-code-authstack` then `/plugin install <auth-type>@scalekit-auth-stack`
> - **GitHub Copilot CLI**: `copilot plugin marketplace add scalekit-inc/github-copilot-authstack` then `copilot plugin install <auth-type>@scalekit-auth-stack`
> - **Codex**: run the bash installer, restart, then open Plugin Directory and enable `<auth-type>`
> - **Skills CLI** (Windsurf, Cline, 40+ agents): `npx skills add scalekit-inc/skills --list` then `--skill <skill-name>`
>
> `<auth-type>` / `<skill-name>`: `agent-auth`, `full-stack-auth`, `mcp-auth`, `modular-sso`, `modular-scim` — [Full setup guide](https://docs.scalekit.com/dev-kit/build-with-ai/)

---

# Bring Your Own Auth

Scalekit also offers the option to integrate your existing authentication infrastructure with Scalekit's OAuth layer for MCP servers. **Use this when you have an existing auth system and want to add MCP OAuth without migrating users.**

When your B2B application already has an established authentication system, you can connect it to your MCP server through Scalekit. This ensures that:
- Users see the same familiar login screen whether accessing your application or your MCP server
- No user migration required - your existing user accounts work immediately with MCP
- You maintain control over your authentication logic while gaining MCP OAuth 2.1 compliance

This "bring your own auth" approach standardizes the authorization layer without requiring you to rebuild your existing authentication infrastructure from scratch.
**Update your login endpoint for MCP token exchange
:** The following changes will need to be made in your B2B apps's Login API Endpoint. The connection ID, User POST URL and Redirect URI allows your app to know that scalekit is attempting to perform the Token Exchange for MCP Auth, so the user should get redirected to the correct consent screen post MCP Login instead of your B2B app.

## Step-by-Step Workflow

When an MCP client initiates an authentication flow, Scalekit redirects to your login endpoint. You then provide user details to Scalekit via a secure backend call, and finally redirect back to Scalekit to complete the process.

```d2 pad=36
title: "Scalekit MCP Bring you own Auth flow" {
  near: top-center
  shape: text
  style.font-size: 18
}

shape: sequence_diagram

MCP Client -> Scalekit Auth Server: Initiate /oauth/authorize (DCR, CIMD)
Scalekit Auth Server ->  Your B2B App: Redirect to /login?login_request_id&state
Your B2B App -> Scalekit Auth Server: POST user details (Machine-to-Machine)
Scalekit Auth Server ->  Your B2B App: 200 Success Response (Upon Successful Login)
Your B2B App -> Scalekit Auth Server: Redirect to /partner:callback?state
Scalekit Auth Server -> MCP Client: Continue Consent, token exchange and permissions delegation.
```

### 1. Initiate Authentication

- The MCP client starts the authentication flow by calling `/oauth/authorize` on Scalekit.
- Scalekit redirects the user to your login endpoint, passing two parameters:
  - `login_request_id`: Unique identifier for the login request.
  - `state`: Value to maintain state between requests.

```txt wrap showLineNumbers=false title="Example Redirect URL"
https://app.example.com/login?login_request_id=lri_86659065219908156&state=HntJ_ENB6y161i9_P1yzuZVv2SSTfD3aZH-Tej0_Y33_Fk8Z3g
```

### 2. Handle Authentication in Your Application

Once the user lands on your login page:

#### a. Authenticate the User

Take the user through your regular authentication logic (e.g., username/password, SSO, etc.).

#### b. Send User Details to Scalekit

Send the authenticated user’s profile details from your backend to Scalekit to complete the login handshake.

```bash
pip install scalekit-sdk-python
```

```python title="send_user_details.py"
from scalekit import ScalekitClient
import os

scalekit = ScalekitClient(
    os.environ.get('SCALEKIT_ENVIRONMENT_URL'),
    os.environ.get('SCALEKIT_CLIENT_ID'),
    os.environ.get('SCALEKIT_CLIENT_SECRET')
)

# Update login user details
scalekit.auth.update_login_user_details(
    connection_id="{{connection_id}}",
    login_request_id="{{login_request_id}}",
    user={
        "sub": "1234567890",
        "email": "alice@example.com"
    },
)
```

```bash
npm install @scalekit-sdk/node
```

```javascript title="sendUserDetails.js"
import { Scalekit } from '@scalekit-sdk/node';

// Initialize client
const scalekit = new Scalekit(
  process.env.SCALEKIT_ENVIRONMENT_URL,
  process.env.SCALEKIT_CLIENT_ID,
  process.env.SCALEKIT_CLIENT_SECRET
);

// Update login user details
await scalekit.auth.updateLoginUserDetails(
  '{{connection_id}}',              // connectionId
  '{{login_request_id}}',           // loginRequestId
  {
    sub: '1234567890',
    email: 'alice@example.com'
  }
);
```

```bash
go get -u github.com/scalekit-inc/scalekit-sdk-go
```

```go title="send_user_details.go"
import (
	"context"
	"fmt"
	"github.com/scalekit-inc/scalekit-sdk-go/v2"
	"os"
)

// Get the connectionId from ScaleKit dashboard -> MCP Server -> Your Server -> User Info Post Url
// eg. https://example.scalekit.dev/api/v1/connections/conn_70982106544698372/auth-requests/{{login_request_id}}/user
// Your connectionId is conn_70982106544698372 in this example
func updateLoggedInUserDetails() error {
	skClient := scalekit.NewScalekitClient(
		os.Getenv("SCALEKIT_ENVIRONMENT_URL"),
		os.Getenv("SCALEKIT_CLIENT_ID"),
		os.Getenv("SCALEKIT_CLIENT_SECRET"),
	)
	err := skClient.Auth().UpdateLoginUserDetails(context.Background(), &scalekit.UpdateLoginUserDetailsRequest{
		ConnectionId:   "{{connection_id}}",
		LoginRequestId: "{{login_request_id}}", // this value is dynamic per login
		User: &scalekit.LoggedInUserDetails{
			Sub:   "1234567890",
			Email: "alice@example.com",
		},
	})
	if err != nil {
		return err
	}
	// Only if there is no error, perform the redirect to scalekit using the redirect url on your Scalekit Dashboard -> MCP Servers
	return nil
}
```

Acquire an `access_token` before you could send user details by hitting the `/oauth/token` endpoint. You can get `env_url`, `sk_client_id` and `sk_client_secret` from _Scalekit Dashboard > Settings_

```bash title="Terminal" frame="terminal"
curl --location '{{env_url}}/oauth/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'client_id={{sk_client_id}}' \
--data-urlencode 'client_secret={{sk_client_secret}}'
```

Scalekit responds with a JSON payload similar to:

```json
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIn0...",
  "token_type": "Bearer",
  "expires_in": 3600
}
```

Use the `access_token` in the `Authorization` header when making a machine-to-machine POST request to Scalekit with the user's details.

```bash
curl --location '{{env_url}}/api/v1/connections/{{connection_id}}/auth-requests/{{login_request_id}}/user' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer {{access_token}}' \
  --data-raw '{
    "sub": "1234567890",
    "email": "alice@example.com"
  }'
```

:::note
- Replace placeholders like `{{env_url}}`, `{{connection_id}}`, `{{login_request_id}}`, and `{{access_token}}` with actual values.
- Only `sub` and `email` are required fields; all other properties are optional.

You can get the `{{connection_id}}` from the User Info Post URL from Scalekit MCP server dashboard.
If the user info post url is `https://yourapp.scalekit.com/api/v1/connections/conn_1234567890/auth-requests/{{login_request_id}}/user`, your connection_id is `conn_1234567890`.

:::

---

### 3. Redirect Back to Scalekit

- Once you receive a successful response from Scalekit, redirect the user back to Scalekit using the provided `state` value to the below endpoint.

**Example Redirect URL:**

```txt wrap showLineNumbers=false frame="none"
{{envurl}}/sso/v1/connections/{{connection_id}}/partner:callback?state={{state_value}}
```

`state_value` should match the `state` parameter you received in Step 1.

---

### 4. Completion

- After processing the callback from your auth system, Scalekit will handle the remaining steps (showing the consent screen to the user, token exchange, etc.) automatically.

:::tip

- Ensure your backend securely stores and transmits all sensitive data.
- The `login_request_id` and `state` parameters are essential for correlating requests and maintaining security.

:::

**Download our sample MCP Server:** We have put together a simple MCP server that you can check out and run it locally to test the end to end functionality of a working MCP server complete with authentication and authorization. You can download and execute a sample MCP server implementation from <a href="https://github.com/scalekit-inc/mcp-auth-demos" target="_blank" rel="noopener">GitHub</a>.

**Try out the BYOA MCP server**: Scalekit provides a demo MCP server that shows how to implement your own auth integration. Clone the <a href="https://github.com/scalekit-inc/byoa-demo-mcp" target="_blank" rel="noopener">BYOA MCP server</a> to test end-to-end authentication in your environment.

---

## More Scalekit documentation

| Resource | What it contains | When to use it |
|----------|-----------------|----------------|
| [/llms.txt](/llms.txt) | Structured index with routing hints per product area | Start here — find which documentation set covers your topic before loading full content |
| [/llms-full.txt](/llms-full.txt) | Complete documentation for all Scalekit products in one file | Use when you need exhaustive context across multiple products or when the topic spans several areas |
| [sitemap-0.xml](https://docs.scalekit.com/sitemap-0.xml) | Full URL list of every documentation page | Use to discover specific page URLs you can fetch for targeted, page-level answers |
