> **Building with AI coding agents?** Install the authstack plugin with one command. This equips your agent with accurate Scalekit implementation patterns.
>
> **Recommended** (the `-y` flags skip prompts, so the command runs without an interactive terminal):
> ```bash
> npx -y @scalekit-inc/cli setup -y
> ```
>
> Global:
> ```bash
> npm install -g @scalekit-inc/cli
> scalekit setup -y
> ```
>
> Supports Claude Code, Cursor, GitHub Copilot, Codex + skills for other Agent Skills-compatible agents in `~/.agents/skills`.
> Skills: integrate-agentkit, implement-saaskit, add-mcp-oauth, implement-sso, implement-scim.
> [Full setup guide](https://docs.scalekit.com/dev-kit/build-with-ai/)

---

# Mint a session token for a connection

`POST /api/v1/mcp/connections/{key_id}/tokens`

Mints a short-lived token for one user that an MCP client sends to one connection's MCP server, at `<environment URL>/mcp/v3/connections/{key_id}`, without a Virtual MCP server. The token's `sub` claim is the identifier and its `aud` claim is that server URL, so the token works only there. Use it when an agent needs the tools of exactly one connection.

**Path parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `key_id` | string | Yes | The connection name, as shown in AgentKit > Connections. It's also the last path segment of the connection's MCP server URL. |

**Request body**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `identifier` | string | Yes | Your app's ID for the user, the same value you used when the user connected. |
| `access_level` | string (enum) | No | Which tools the token can use: `FULL` (the default) or `READ_ONLY`, in capitals. A `READ_ONLY` token sees and calls only the server's read-only tools. See [Limit an agent to read-only tools](https://docs.scalekit.com/agentkit/mcp/read-only-tokens/). One of: `FULL`, `READ_ONLY`. |
| `expiry` | string | No | How long the token lasts, in seconds with an `s` suffix, such as `1800s`. Between `60s` and `86400s` (24 hours). Defaults to `3600s`. |

**Response (200)**

| Name | Type | Description |
| --- | --- | --- |
| `expires_at` | string | When the token expires: the time it was minted plus `expiry`. |
| `token` | string | The session token, a signed JWT. Its `sub` claim is the identifier and its `aud` claim is the MCP server URL it works at. Send it as `Authorization: Bearer <token>` from the MCP client. |

**Errors**

- `400`: Invalid request - `key_id` or `identifier` is missing or malformed, `expiry` is outside the 60s-24h window, `access_level` isn't `FULL` or `READ_ONLY`, the connection isn't an AgentKit connection, or the user has no active account on the connection. Depending on the environment, Scalekit instead creates a pending account for the user and returns a token, so the user can authorize from the MCP client.
- `404`: Not found - no active connection with this name exists in the environment.

**Request**

```bash
curl -sS -X POST \
  "$SCALEKIT_ENVIRONMENT_URL/api/v1/mcp/connections/gmail/tokens" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "identifier": "user_123",
    "expiry": "1800s"
  }'
```

**Response**

```json
{
  "token": "[SESSION TOKEN]",
  "expires_at": "2026-10-02T15:00:00Z"
}
```

**Python SDK:** `scalekit_client.actions.mcp.create_session_token`

Create a short-lived session token for a user to access an MCP server. Pass exactly one of `mcp_config_id` or `connection_name`; the token works only on the MCP server of that target: `mcp_config_id`: the MCP configuration's server, at the config's `mcp_server_url`. It serves the tools the configuration exposes. `connection_name`: the connection's own MCP server, at `<environment_url>/mcp/v3/connections/<connection_name>`. It serves every tool of that connection, with no MCP configuration. Send the token as a `Bearer` token in the `Authorization` header when calling that URL.

```python
scalekit_client.actions.mcp.create_session_token(
    mcp_config_id: str | None = None,
    identifier: str | None = None,
    expiry: timedelta | None = None,
    access_level: str | None = None,
    connection_name: str | None = None,
) -> CreateMcpSessionTokenResponse
```

Example:

```python
from datetime import timedelta

result = scalekit_client.actions.mcp.create_session_token(
    identifier="user_123",
    expiry=timedelta(seconds=1800),
    connection_name="gmail",
)
```

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `mcp_config_id` | `str \| None` | No | Scalekit ID of the MCP configuration the token grants access to, e.g. `"cfg_01abc123"`. |
| `identifier` | `str \| None` | No | Your app's ID for the user, the same value you used when the user connected. Use a stable internal ID, not an email address. |
| `expiry` | `timedelta \| None` | No | Requested lifetime for the token as a Python `timedelta`. The server accepts 60 seconds to 24 hours and applies 1 hour when omitted. Fractions of a second are dropped. Example values: `timedelta(minutes=30)` — 30-minute token; `timedelta(hours=8)` — 8-hour token (work-day session); `timedelta(days=1)` — 24-hour token |
| `access_level` | `str \| None` | No | Tools the token can use. `"READ_ONLY"` limits it to tools annotated read-only: other tools are left out of the tool list and refused when called. `"FULL"`, or omitting it, exposes every tool of the target. Values are case-sensitive. |
| `connection_name` | `str \| None` | No | The connection name, as shown in **AgentKit** > **Connections**. |

Returns `CreateMcpSessionTokenResponse`: The session `token`, a signed JWT, and `expires_at`, when it expires (UTC).

**Node.js SDK:** `scalekit.actions.mcp.createSessionToken`

Mints a session token for one user, for either a Virtual MCP server or a connection's own MCP server. Set a target; if both are set, `mcpConfigId` is used: `mcpConfigId`: the token works on that configuration's `config.mcpServerUrl` (see `getConfig`). `connectionName`: the token works on the connection's own MCP server at `<environment URL>/mcp/v3/connections/<connection name>`, which exposes all of that connection's tools without an MCP configuration. The name is matched without regard to case, but the URL path is case-sensitive: build it from the connection's name exactly as stored. A token works only on the server it was minted for. The server URL is static; the token is what carries user identity. Mint a fresh one before every agent run and never reuse one across runs. Set the expiry longer than the run is expected to take. For a connection, the user should have an active connected account on it. When they do not, the server either rejects the call, or creates a pending connected account and returns a token whose tool calls report the account as not connected, depending on the environment.

```ts
scalekit.actions.mcp.createSessionToken(
  params: {
    identifier: string;
    expirySeconds?: number;
    accessLevel?: McpSessionTokenAccessLevel;
    mcpConfigId?: string;
    connectionName?: string;
  },
): Promise<CreateMcpSessionTokenResponse>
```

Example:

```ts
const result = await scalekit.actions.mcp.createSessionToken({
  identifier: "user_123",
  expirySeconds: 1800,
  connectionName: "gmail",
});
```

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `identifier` | `string` | Yes | Your app's ID for the user, the same value you used when the user connected. Use a stable internal ID, not an email address. |
| `expirySeconds` | `number` | No | Token lifetime in whole seconds, 60 to 86400. Defaults to 3600. |
| `accessLevel` | `McpSessionTokenAccessLevel` | No | Tools the token can use. Omit for `'FULL'`. |
| `mcpConfigId` | `string` | No | ID of the MCP configuration whose server the token is for. |
| `connectionName` | `string` | No | The connection name, as shown in **AgentKit** > **Connections**. |

Returns `Promise<CreateMcpSessionTokenResponse>`: The session `token` and its `expiresAt` time.

**Used in**

- [Anthropic](https://docs.scalekit.com/agentkit/examples/anthropic/)
- [Build a multi-agent email triage crew with CrewAI](https://docs.scalekit.com/cookbooks/crewai-agentkit-email-triage/)
- [Build a Vapi voice assistant with Scalekit](https://docs.scalekit.com/cookbooks/build-voice-assistant-1000-tools/)
- [Claude Managed Agents](https://docs.scalekit.com/agentkit/examples/claude-managed-agents/)
- [CrewAI](https://docs.scalekit.com/agentkit/examples/crewai/)
- [Google ADK](https://docs.scalekit.com/agentkit/examples/google-adk/)
- [LangChain](https://docs.scalekit.com/agentkit/examples/langchain/)
- [LangGraph](https://docs.scalekit.com/agentkit/examples/langgraph/)
- [Limit an agent to read-only tools](https://docs.scalekit.com/agentkit/mcp/read-only-tokens/)
- [Mastra](https://docs.scalekit.com/agentkit/examples/mastra/)
- [Mint session tokens](https://docs.scalekit.com/agentkit/mcp/session-tokens/)
- [OpenAI Agents SDK](https://docs.scalekit.com/agentkit/examples/openai-agents-sdk/)
- [Use a connection's MCP server](https://docs.scalekit.com/agentkit/mcp/connection-mcp-servers/)


Part of [Virtual MCP servers](https://docs.scalekit.com/agentkit/reference/virtual-mcp-servers/) in the [AgentKit API reference](https://docs.scalekit.com/agentkit/reference/). Authentication: https://docs.scalekit.com/agentkit/reference/authentication.md. Errors and rate limits: https://docs.scalekit.com/agentkit/reference/errors.md. Pagination: https://docs.scalekit.com/agentkit/reference/pagination.md


---

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