> **Building with AI coding agents?** Install the authstack plugin with one command. This equips your agent with accurate Scalekit implementation patterns.
>
> **Recommended**:
> ```bash
> npx @scalekit-inc/cli setup
> ```
>
> Global:
> ```bash
> npm install -g @scalekit-inc/cli
> scalekit setup
> ```
>
> Supports Claude Code, Cursor, GitHub Copilot, Codex + skills for 40+ agents.
> Features: full-stack-auth, agent-auth, mcp-auth, modular-sso, modular-scim.
> [Full setup guide](https://docs.scalekit.com/dev-kit/build-with-ai/)

---

# Publish your MCP connector to Claude & ChatGPT

Give MCP connector directory reviewers a test user and static code so they can authenticate and test your server end to end.
To list your MCP connector in the [Claude connector directory](https://claude.com/docs/connectors/building/submission) or the [ChatGPT app directory](https://developers.openai.com/apps-sdk/deploy/submission#review-and-approval-faqs), a reviewer must sign in to your server and run every tool end to end. Both submission forms have a testing-access step that expects every credential and step needed to reach a fully-populated account.

Scalekit's [Test Users](/authenticate/run-e2e-tests/) feature makes this possible without handing over a real inbox: allowlist a reviewer email and set a **static 6-digit code**, and the reviewer signs in through Scalekit's hosted login using that code. This page shows how to prepare the credential and write the instructions to paste into the submission form.

> caution: Works only with Scalekit-managed auth
>
> Test Users works only when **Scalekit manages your app's login, sessions, and user management** (Full Stack Auth / SaaSKit), because it intercepts Scalekit's own Magic Link/OTP delivery.
>
> It does **not** work when your MCP server runs in [Bring Your Own Auth](/mcp/auth-methods/custom-auth/) mode. In that mode Scalekit federates to your own identity provider and never owns the login screen or the OTP, so there is no static code to hand a reviewer. For Bring Your Own Auth, create a reviewer account directly in your identity provider and share those credentials instead.

## Prerequisites

- An MCP connector already protected with Scalekit MCP Auth using Scalekit-managed auth. See the [MCP Auth quickstart](/authenticate/mcp/quickstart/).
- The **Magic Link & OTP** auth method enabled, with delivery set to `Verification Code` or `Magic Link + Verification Code`. `Magic Link`-only delivery is not supported. See the [Test Users prerequisite](/authenticate/run-e2e-tests/#prerequisites).

## How reviewer sign-in works

The reviewer follows the same OAuth 2.1 flow as any [human interacting with your MCP server](/authenticate/mcp/overview/#the-authorization-flow-in-practice):

1. The MCP client (MCP Inspector or Claude as a custom connector) calls your protected server and receives a `401` pointing to Scalekit.
2. The client redirects the reviewer to Scalekit's hosted login.
3. The reviewer enters the **test email** and the **static code** you configured — no inbox required.
4. The reviewer approves the consent screen, Scalekit issues an access token, and the client runs your tools.

## Prepare the reviewer credential

1. ## Enable Test Users and add a reviewer email

   In **Dashboard > Environment settings > Test users**, toggle **Enable test users** and add a reviewer address. The email must contain `+sktest` in the local part — for example `reviewer+sktest@yourapp.com`. Set the **Static confirmation code** (the default is `424242`).

   For the full field-by-field reference, see [Configure test users](/authenticate/run-e2e-tests/#configure-test-users).

2. ## Create the reviewer inside a fully-populated organization

   Reviewers expect your tools to return real data, so add the reviewer user to an organization that already has representative content. Create the user with `sendInvitationEmail: false` so no email goes out, then confirm the same email is on the Test Users allowlist.

   
     ### Node.js

```ts title="Create the reviewer user"
import { ScalekitClient } from '@scalekit-sdk/node'

const scalekit = new ScalekitClient(
  process.env.SCALEKIT_ENVIRONMENT_URL!,
  process.env.SCALEKIT_CLIENT_ID!,
  process.env.SCALEKIT_CLIENT_SECRET!
)

try {
  // Add the reviewer to a populated org so tools return real data during review.
  const { user } = await scalekit.user.createUserAndMembership(orgId, {
    email: 'reviewer+sktest@yourapp.com',
    sendInvitationEmail: false,
  })
} catch (error) {
  console.error('Failed to create reviewer user:', error)
}
```

     ### Python

```python title="Create the reviewer user"
import os
from scalekit import ScalekitClient
from scalekit.v1.users.users_pb2 import CreateUser

scalekit_client = ScalekitClient(
  env_url=os.environ["SCALEKIT_ENVIRONMENT_URL"],
  client_id=os.environ["SCALEKIT_CLIENT_ID"],
  client_secret=os.environ["SCALEKIT_CLIENT_SECRET"],
)

try:
  # Add the reviewer to a populated org so tools return real data during review.
  user_response = scalekit_client.users.create_user_and_membership(
    org_id,
    CreateUser(email="reviewer+sktest@yourapp.com"),
    send_invitation_email=False,
  )
except Exception as error:
  print(f"Failed to create reviewer user: {error}")
```

     ### Go

```go title="Create the reviewer user"
import usersv1 "github.com/scalekit-inc/scalekit-sdk-go/v2/pkg/grpc/scalekit/v1/users"

scalekitClient := scalekit.NewScalekitClient(
  os.Getenv("SCALEKIT_ENVIRONMENT_URL"),
  os.Getenv("SCALEKIT_CLIENT_ID"),
  os.Getenv("SCALEKIT_CLIENT_SECRET"),
)

// Add the reviewer to a populated org so tools return real data during review.
userResp, err := scalekitClient.User().CreateUserAndMembership(ctx, orgID,
  &usersv1.CreateUser{Email: "reviewer+sktest@yourapp.com"},
  false,
)
if err != nil {
  log.Fatalf("failed to create reviewer user: %v", err)
}
```

     ### Java

```java title="Create the reviewer user"
import com.scalekit.grpc.scalekit.v1.users.*;

ScalekitClient scalekitClient = new ScalekitClient(
  System.getenv("SCALEKIT_ENVIRONMENT_URL"),
  System.getenv("SCALEKIT_CLIENT_ID"),
  System.getenv("SCALEKIT_CLIENT_SECRET")
);

try {
  // Add the reviewer to a populated org so tools return real data during review.
  CreateUserAndMembershipRequest request = CreateUserAndMembershipRequest.newBuilder()
    .setUser(CreateUser.newBuilder().setEmail("reviewer+sktest@yourapp.com").build())
    .setSendInvitationEmail(false)
    .build();

  CreateUserAndMembershipResponse userResp = scalekitClient.users()
    .createUserAndMembership(orgId, request);
} catch (Exception error) {
  System.err.println("Failed to create reviewer user: " + error.getMessage());
}
```

   

## Verify

Connect to your server the same way the reviewer will — via [MCP Inspector](https://github.com/modelcontextprotocol/inspector) or as a custom connector in Claude — and sign in with the reviewer email and static code.

Verification succeeds when:

- Sign-in completes with the static code and no real verification email is sent.
- Every tool runs successfully and returns representative data from the populated organization.

Fix any gaps before you submit to a directory.

## Write the test setup instructions

Paste instructions into the submission form's testing-access field — the **Test setup instructions** box on Claude's **Test & launch** step, or the equivalent testing-instructions field in the ChatGPT app submission. Give the reviewer everything needed to authenticate autonomously:

```text title="Test setup instructions (paste-ready)" frame="terminal" showLineNumbers=false
Connector URL: https://mcp.yourapp.com/mcp

Authentication: OAuth 2.0 (hosted login). When prompted to connect, use the
test account below — no email inbox is required.

  Email: reviewer+sktest@yourapp.com
  Verification code: 424242

Steps:
  1. Add the connector and start the OAuth sign-in.
  2. On the login screen, enter the email above and continue.
  3. At the verification-code prompt, enter 424242 and continue.
  4. Approve the consent screen.
  5. The account belongs to a fully-populated organization, so every tool
     returns representative data.
```

Replace the URL, email, and code with your own values. Keep the code identical to the **Static confirmation code** configured in the dashboard.

## Next steps

Once your connector is approved, remove the reviewer email from the allowlist or rotate the static code — see [Configure test users](/authenticate/run-e2e-tests/#configure-test-users) for how to manage the allowlist.

## Common scenarios

## The reviewer still receives a real verification email

All three conditions must be true for Test Users to apply:

- **Test Users** is enabled in the environment.
- The reviewer email is on the allowlist (case-insensitive match).
- **Magic Link & OTP** is enabled with delivery set to `Verification Code` or `Magic Link + Verification Code`.

## My connector uses Bring Your Own Auth — can I still do this?

No. Test Users only affects Scalekit's own Magic Link/OTP delivery. In [Bring Your Own Auth](/mcp/auth-methods/custom-auth/) mode, Scalekit federates to your identity provider, which owns the login and any verification codes. Create a dedicated reviewer account in your identity provider and share those credentials in the test setup instructions instead.


---

## 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 |
