> **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/)

---

# Virtual MCP servers

A Virtual MCP server exposes the tools you choose to an MCP client, for one user at a time. In the API a server is an MCP configuration, under `/api/v1/mcp/configs`. See [Create a Virtual MCP server](https://docs.scalekit.com/agentkit/mcp/configure-mcp-server/) and [Mint session tokens](https://docs.scalekit.com/agentkit/mcp/session-tokens/).

A server exposes its tools in one of two ways, set with `tool_exposure`. `DIRECT`, the default, lists every tool you map to the server, for up to 25 connections. `META` gives the agent five tools to search for, inspect and run the mapped tools, and to connect the user's accounts, with no connection limit. See [How an agent uses a META server](https://docs.scalekit.com/agentkit/mcp/configure-mcp-server/#how-an-agent-uses-a-meta-server).

One page per endpoint, each with its own markdown copy:

| Endpoint | Request | What it does | Python SDK | Node.js SDK |
| --- | --- | --- | --- | --- |
| [Create a Virtual MCP server](https://docs.scalekit.com/agentkit/reference/virtual-mcp-servers/create-a-virtual-mcp-server.md) | `POST /api/v1/mcp/configs` | Create a server that serves the connections and tools you choose. | `actions.mcp.create_config` | `actions.mcp.createConfig` |
| [Get a Virtual MCP server](https://docs.scalekit.com/agentkit/reference/virtual-mcp-servers/get-a-virtual-mcp-server.md) | `GET /api/v1/mcp/configs/{config_id}` | Get a server's connections, tools and MCP server URL. | REST only | `actions.mcp.getConfig` |
| [List Virtual MCP servers](https://docs.scalekit.com/agentkit/reference/virtual-mcp-servers/list-virtual-mcp-servers.md) | `GET /api/v1/mcp/configs` | List the servers in your environment, with a search on their name. | `actions.mcp.list_configs` | `actions.mcp.listConfigs` |
| [Update a Virtual MCP server](https://docs.scalekit.com/agentkit/reference/virtual-mcp-servers/update-a-virtual-mcp-server.md) | `PUT /api/v1/mcp/configs/{config_id}` | Change a server's description, the connections and tools it serves, or how it exposes tools. | `actions.mcp.update_config` | `actions.mcp.updateConfig` |
| [Delete a Virtual MCP server](https://docs.scalekit.com/agentkit/reference/virtual-mcp-servers/delete-a-virtual-mcp-server.md) | `DELETE /api/v1/mcp/configs/{config_id}` | Delete a server and the connections and tools it serves. | `actions.mcp.delete_config` | `actions.mcp.deleteConfig` |
| [Check a user's connected accounts for a server](https://docs.scalekit.com/agentkit/reference/virtual-mcp-servers/check-connected-accounts-for-a-server.md) | `POST /api/v1/mcp/configs/{config_id}/connected_accounts` | Check a user's accounts for a server, with links for any that aren't active. | `actions.mcp.list_mcp_connected_accounts` | `actions.mcp.listConnectedAccounts` |
| [Mint a session token](https://docs.scalekit.com/agentkit/reference/virtual-mcp-servers/mint-a-session-token.md) | `POST /api/v1/mcp/configs/{mcp_config_id}/tokens` | Mint a short-lived token that lets a user's MCP client call the server. | `actions.mcp.create_session_token` | `actions.mcp.createSessionToken` |
| [Mint a session token for a connection](https://docs.scalekit.com/agentkit/reference/virtual-mcp-servers/mint-a-connection-session-token.md) | `POST /api/v1/mcp/connections/{key_id}/tokens` | Mint a short-lived token that lets a user's MCP client call one connection's tools. | `actions.mcp.create_session_token` | `actions.mcp.createSessionToken` |


## Create a Virtual MCP server

`POST /api/v1/mcp/configs`

Creates a new MCP configuration with a set of connections and tools.

**Request body**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | string | Yes | Unique name for the MCP configuration. Must be 1–100 characters. Allowed characters: lowercase letters (a–z), digits (0–9), hyphens (-), and underscores (_). |
| `connection_tool_mappings` | array of object | No | List of connection-to-tool mappings for this MCP config. Maximum 25 connections in `DIRECT` mode. |
| `connection_tool_mappings.connection_name` | string | Yes | Developer-assigned connection name. |
| `connection_tool_mappings.tools` | array of string | No | List of tool names linked to this connection (empty = all tools). |
| `description` | string | No | Description of the MCP configuration. |
| `tool_exposure` | string (enum) | No | How the server exposes tools to agents. `DIRECT` lists every tool you map to it, for up to 25 connections. `META` gives agents five tools to search for, inspect and run the mapped tools, with no limit on connections. `DIRECT` is the default when you create a server without it. One of: `DIRECT`, `META`. |

**Response (200)**

| Name | Type | Description |
| --- | --- | --- |
| `config` | object | The created MCP configuration. |
| `config.connection_tool_mappings` | array of object | List of connection-to-tool mappings for this MCP config. Maximum 25 connections in `DIRECT` mode. |
| `config.connection_tool_mappings.connected_account_id` | string | Connected account backing this connection in the MCP instance context. |
| `config.connection_tool_mappings.connected_account_status` | string | Authentication status for the connected account. |
| `config.connection_tool_mappings.connection_id` | string | Unique ID of the connection. |
| `config.connection_tool_mappings.connection_name` | string | Developer-assigned connection name. |
| `config.connection_tool_mappings.provider` | string | Provider name for this connection. |
| `config.connection_tool_mappings.tools` | array of string | List of tool names linked to this connection (empty = all tools). |
| `config.description` | string | Description of the MCP configuration. |
| `config.id` | string | Unique ID of the MCP config. |
| `config.mcp_server_url` | string | The URL MCP clients connect to for this server. Every user and session shares it; the session token identifies the user. |
| `config.name` | string | Unique name for the MCP configuration. Must be 1–100 characters. Allowed characters: lowercase letters (a–z), digits (0–9), hyphens (-), and underscores (_). |
| `config.tool_exposure` | string (enum) | How the server exposes tools to agents. `DIRECT` lists every tool you map to it, for up to 25 connections. `META` gives agents five tools to search for, inspect and run the mapped tools, with no limit on connections. `DIRECT` is the default when you create a server without it. One of: `DIRECT`, `META`. |

**Errors**

- `400`: Invalid request - missing required fields or invalid connection/tool mappings
- `401`: Authentication required - missing or invalid access token

**Request**

```bash
curl -sS -X POST \
  "$SCALEKIT_ENVIRONMENT_URL/api/v1/mcp/configs" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "repo-assistant",
    "description": "Reads the user'\''s GitHub repositories and issues",
    "connection_tool_mappings": [
      {
        "connection_name": "github-connect",
        "tools": [
          "github_user_repos_list",
          "github_issues_list"
        ]
      }
    ],
    "tool_exposure": "DIRECT"
  }'
```

**Response**

```json
{
  "config": {
    "id": "cfg_85630864460904897",
    "name": "repo-assistant",
    "description": "Reads the user's GitHub repositories and issues",
    "connection_tool_mappings": [
      {
        "connection_id": "conn_70219645518267719",
        "connection_name": "github-connect",
        "provider": "GITHUB",
        "tools": [
          "github_user_repos_list",
          "github_issues_list"
        ]
      }
    ],
    "mcp_server_url": "https://your-env.scalekit.dev/mcp/v3/servers/3d9f6a2e-7b41-4c8e-a5d2-0f1e8b6c4a93",
    "tool_exposure": "DIRECT"
  }
}
```

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

Create a new MCP configuration from the supplied metadata and tool mappings.

```python
scalekit_client.actions.mcp.create_config(
    name: str,
    description: Optional[str] = None,
    connection_tool_mappings: Optional[List[McpConfigConnectionToolMapping]] = None,
    tool_exposure: Optional[str] = None,
) -> CreateMcpConfigResponse
```

Example:

```python
from scalekit.actions.types import McpConfigConnectionToolMapping

result = scalekit_client.actions.mcp.create_config(
    name="repo-assistant",
    description="Reads the user's GitHub repositories and issues",
    connection_tool_mappings=[
        McpConfigConnectionToolMapping(
            connection_name="github-connect",
            tools=["github_user_repos_list", "github_issues_list"],
        ),
    ],
    tool_exposure="DIRECT",
)
```

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | `str` | Yes | Human readable name for the configuration. |
| `description` | `Optional[str]` | No | Summary that surfaces in dashboards and APIs. |
| `connection_tool_mappings` | `Optional[List[McpConfigConnectionToolMapping]]` | No | Explicit mapping between connectors and tools. |
| `tool_exposure` | `Optional[str]` | No | How the server exposes tools to agents. `DIRECT` lists every tool you map to the server, for up to 25 connections. `META` gives agents five tools, `search_available_tools`, `list_available_tools`, `get_tool_details`, `execute_tool` and `connect_account`, to find and run the mapped tools, with no connection limit. Defaults to `DIRECT`. |

Returns `CreateMcpConfigResponse`: The created configuration payload.

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

Creates a Virtual MCP server configuration. Create this once per agent role. The response carries a static `config.mcpServerUrl` that every user and every session reuses.

```ts
scalekit.actions.mcp.createConfig(
  params: {
    name: string;
    description?: string;
    connectionToolMappings?: MessageInitShape<typeof McpConfigSchema>['connectionToolMappings'];
    toolExposure?: McpToolExposure;
  },
): Promise<CreateMcpConfigResponse>
```

Example:

```ts
const result = await scalekit.actions.mcp.createConfig({
  name: "repo-assistant",
  description: "Reads the user's GitHub repositories and issues",
  connectionToolMappings: [
    {
      connectionName: "github-connect",
      tools: ["github_user_repos_list", "github_issues_list"],
    },
  ],
  toolExposure: "DIRECT",
});
```

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `name` | `string` | Yes | Unique name. 1-100 characters, lowercase letters, digits, hyphens and underscores. |
| `description` | `string` | No | Human-readable summary of what this server exposes. |
| `connectionToolMappings` | `MessageInitShape<typeof McpConfigSchema>['connectionToolMappings']` | No | Which connections, and which tools from each, to expose. Omit `tools` on a mapping to expose every tool for that connection. Maximum 25 connections when `toolExposure` is `'DIRECT'`. |
| `toolExposure` | `McpToolExposure` | No | How the server exposes tools to agents. `DIRECT` lists every tool you map to the server, for up to 25 connections. `META` gives agents five tools, `search_available_tools`, `list_available_tools`, `get_tool_details`, `execute_tool` and `connect_account`, to find and run the mapped tools, with no connection limit. Defaults to `DIRECT`. |

Returns `Promise<CreateMcpConfigResponse>`.

**Used in**

- [Claude Managed Agents](https://docs.scalekit.com/agentkit/examples/claude-managed-agents/)
- [Create a Virtual MCP server](https://docs.scalekit.com/agentkit/mcp/configure-mcp-server/)
- [Mastra](https://docs.scalekit.com/agentkit/examples/mastra/)

## Get a Virtual MCP server

`GET /api/v1/mcp/configs/{config_id}`

Returns a single MCP configuration for the current environment by ID.

**Path parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `config_id` | string | Yes | ID of the MCP configuration to fetch. |

**Response (200)**

| Name | Type | Description |
| --- | --- | --- |
| `config` | object | The requested MCP configuration. |
| `config.connection_tool_mappings` | array of object | List of connection-to-tool mappings for this MCP config. Maximum 25 connections in `DIRECT` mode. |
| `config.connection_tool_mappings.connected_account_id` | string | Connected account backing this connection in the MCP instance context. |
| `config.connection_tool_mappings.connected_account_status` | string | Authentication status for the connected account. |
| `config.connection_tool_mappings.connection_id` | string | Unique ID of the connection. |
| `config.connection_tool_mappings.connection_name` | string | Developer-assigned connection name. |
| `config.connection_tool_mappings.provider` | string | Provider name for this connection. |
| `config.connection_tool_mappings.tools` | array of string | List of tool names linked to this connection (empty = all tools). |
| `config.description` | string | Description of the MCP configuration. |
| `config.id` | string | Unique ID of the MCP config. |
| `config.mcp_server_url` | string | The URL MCP clients connect to for this server. Every user and session shares it; the session token identifies the user. |
| `config.name` | string | Unique name for the MCP configuration. Must be 1–100 characters. Allowed characters: lowercase letters (a–z), digits (0–9), hyphens (-), and underscores (_). |
| `config.tool_exposure` | string (enum) | How the server exposes tools to agents. `DIRECT` lists every tool you map to it, for up to 25 connections. `META` gives agents five tools to search for, inspect and run the mapped tools, with no limit on connections. `DIRECT` is the default when you create a server without it. One of: `DIRECT`, `META`. |

**Errors**

- `400`: Invalid request
- `401`: Authentication required
- `404`: Not Found - MCP configuration does not exist

**Request**

```bash
curl -sS -X GET \
  "$SCALEKIT_ENVIRONMENT_URL/api/v1/mcp/configs/cfg_85630864460904897" \
  -H "Authorization: Bearer $TOKEN"
```

**Response**

```json
{
  "config": {
    "id": "cfg_85630864460904897",
    "name": "repo-assistant",
    "description": "Reads the user's GitHub repositories and issues",
    "connection_tool_mappings": [
      {
        "connection_id": "conn_70219645518267719",
        "connection_name": "github-connect",
        "provider": "GITHUB",
        "tools": [
          "github_user_repos_list",
          "github_issues_list"
        ]
      }
    ],
    "mcp_server_url": "https://your-env.scalekit.dev/mcp/v3/servers/3d9f6a2e-7b41-4c8e-a5d2-0f1e8b6c4a93",
    "tool_exposure": "DIRECT"
  }
}
```

**Python:** Call this endpoint over REST, as the example shows.

```python
import os

import requests

env_url = os.environ["SCALEKIT_ENVIRONMENT_URL"]
token = requests.post(
    f"{env_url}/oauth/token",
    data={
        "grant_type": "client_credentials",
        "client_id": os.environ["SCALEKIT_CLIENT_ID"],
        "client_secret": os.environ["SCALEKIT_CLIENT_SECRET"],
    },
).json()["access_token"]

response = requests.get(
    f"{env_url}/api/v1/mcp/configs/cfg_85630864460904897",
    headers={"Authorization": f"Bearer {token}"},
)
response.raise_for_status()
result = response.json()
```

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

Fetches a single MCP configuration by ID.

```ts
scalekit.actions.mcp.getConfig(
  configId: string,
): Promise<GetMcpConfigResponse>
```

Example:

```ts
const result = await scalekit.actions.mcp.getConfig("cfg_85630864460904897");
```

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `configId` | `string` | Yes | ID of the configuration to fetch (`cfg_...`). |

Returns `Promise<GetMcpConfigResponse>`.

## List Virtual MCP servers

`GET /api/v1/mcp/configs`

Lists the Virtual MCP servers in your environment. Filter by ID, exact name, provider or MCP server URL, or pass `search` to match part of the name.

**Query parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `filter.id` | string | No | Filter by MCP configuration id. |
| `filter.mcp_server_url` | string | No | Filter configs by MCP server URL. The UUID is extracted from the last path segment of the URL and used to find the matching configuration. |
| `filter.name` | string | No | Case-insensitive exact match on configuration name. Allowed characters: letters (a–z, A–Z), digits (0–9), hyphens (-), and underscores (_). Maximum 100 characters. |
| `filter.provider` | string | No | Return only servers with a connection for this app, such as `GMAIL`. |
| `page_size` | integer | No | Number of configs to return per page (max 30). |
| `page_token` | string | No | Pagination token to fetch the next or previous page. |
| `search` | string | No | Return servers whose name contains this text, case-insensitive. At least 3 characters. |

**Response (200)**

| Name | Type | Description |
| --- | --- | --- |
| `configs` | array of object | List of MCP configurations. |
| `configs.connection_tool_mappings` | array of object | List of connection-to-tool mappings for this MCP config. Maximum 25 connections in `DIRECT` mode. |
| `configs.connection_tool_mappings.connected_account_id` | string | Connected account backing this connection in the MCP instance context. |
| `configs.connection_tool_mappings.connected_account_status` | string | Authentication status for the connected account. |
| `configs.connection_tool_mappings.connection_id` | string | Unique ID of the connection. |
| `configs.connection_tool_mappings.connection_name` | string | Developer-assigned connection name. |
| `configs.connection_tool_mappings.provider` | string | Provider name for this connection. |
| `configs.connection_tool_mappings.tools` | array of string | List of tool names linked to this connection (empty = all tools). |
| `configs.description` | string | Description of the MCP configuration. |
| `configs.id` | string | Unique ID of the MCP config. |
| `configs.mcp_server_url` | string | The URL MCP clients connect to for this server. Every user and session shares it; the session token identifies the user. |
| `configs.name` | string | Unique name for the MCP configuration. Must be 1–100 characters. Allowed characters: lowercase letters (a–z), digits (0–9), hyphens (-), and underscores (_). |
| `configs.tool_exposure` | string (enum) | How the server exposes tools to agents. `DIRECT` lists every tool you map to it, for up to 25 connections. `META` gives agents five tools to search for, inspect and run the mapped tools, with no limit on connections. `DIRECT` is the default when you create a server without it. One of: `DIRECT`, `META`. |
| `next_page_token` | string | Pagination token to fetch the next page. |
| `prev_page_token` | string | Pagination token to fetch the previous page. |
| `total_size` | integer | Total number of configs matching the filter. |

**Errors**

- `400`: Invalid request - bad filter or pagination parameters
- `401`: Authentication required

**Request**

```bash
curl -sS -G -X GET \
  "$SCALEKIT_ENVIRONMENT_URL/api/v1/mcp/configs" \
  -H "Authorization: Bearer $TOKEN" \
  --data-urlencode "search=repo-assistant"
```

**Response**

```json
{
  "configs": [
    {
      "id": "cfg_85630864460904897",
      "name": "repo-assistant",
      "description": "Reads the user's GitHub repositories and issues",
      "connection_tool_mappings": [
        {
          "connection_id": "conn_70219645518267719",
          "connection_name": "github-connect",
          "provider": "GITHUB",
          "tools": [
            "github_user_repos_list",
            "github_issues_list"
          ]
        }
      ],
      "mcp_server_url": "https://your-env.scalekit.dev/mcp/v3/servers/3d9f6a2e-7b41-4c8e-a5d2-0f1e8b6c4a93",
      "tool_exposure": "DIRECT"
    }
  ],
  "next_page_token": "",
  "prev_page_token": "",
  "total_size": 1
}
```

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

List MCP configurations with optional pagination and filtering.

```python
scalekit_client.actions.mcp.list_configs(
    page_size: Optional[int] = None,
    page_token: Optional[str] = None,
    filter_id: Optional[str] = None,
    filter_provider: Optional[str] = None,
    filter_name: Optional[str] = None,
    filter_mcp_server_url: Optional[str] = None,
    search: Optional[str] = None,
) -> ListMcpConfigsResponse
```

Example:

```python
result = scalekit_client.actions.mcp.list_configs(
    search="repo-assistant",
)
```

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `page_size` | `Optional[int]` | No | Maximum number of configs to include in the current page. Defaults to the server-side default (typically 20). |
| `page_token` | `Optional[str]` | No | Cursor token returned by a previous `list_configs` call. Pass this to fetch the next page of results. |
| `filter_id` | `Optional[str]` | No | Return only the server with this ID, such as `"cfg_85630864460904897"`. |
| `filter_provider` | `Optional[str]` | No | Return only servers with a connection for this app, such as `"GMAIL"`. |
| `filter_name` | `Optional[str]` | No | Return only the server with this name, case-insensitive exact match, such as `"repo-assistant"`. |
| `filter_mcp_server_url` | `Optional[str]` | No | Return only the server with this MCP server URL, such as `"https://your-env.scalekit.dev/mcp/v3/servers/3d9f6a2e-7b41-4c8e-a5d2-0f1e8b6c4a93"`. |
| `search` | `Optional[str]` | No | Return servers whose name contains this text, case-insensitive. At least 3 characters. |

Returns `ListMcpConfigsResponse`: The page of servers in `configs`, with `next_page_token` and `total_size`.

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

Lists MCP configurations for the current environment.

```ts
scalekit.actions.mcp.listConfigs(
  options?: {
    search?: string;
    pageSize?: number;
    pageToken?: string;
  },
): Promise<ListMcpConfigsResponse>
```

Example:

```ts
const result = await scalekit.actions.mcp.listConfigs({
  search: "repo-assistant",
});
```

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `search` | `string` | No | Return servers whose name contains this text, case-insensitive. At least 3 characters. |
| `pageSize` | `number` | No | Maximum number of configurations to return per page (max 30; a larger value fails with `[invalid_argument] Validation error`). |
| `pageToken` | `string` | No | Token from a previous `listConfigs` response. |

Returns `Promise<ListMcpConfigsResponse>`.

**Used in**

- [Build a multi-agent email triage crew with CrewAI](https://docs.scalekit.com/cookbooks/crewai-agentkit-email-triage/)
- [Claude Managed Agents](https://docs.scalekit.com/agentkit/examples/claude-managed-agents/)
- [Create a Virtual MCP server](https://docs.scalekit.com/agentkit/mcp/configure-mcp-server/)
- [CrewAI](https://docs.scalekit.com/agentkit/examples/crewai/)
- [Mastra](https://docs.scalekit.com/agentkit/examples/mastra/)

## Update a Virtual MCP server

`PUT /api/v1/mcp/configs/{config_id}`

Updates the description and connection-to-tool mappings for an existing MCP configuration. The configuration name cannot be changed after creation.

**Path parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `config_id` | string | Yes | ID of the MCP configuration to update. |

**Request body**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `connection_tool_mappings` | array of object | No | Updated list of connection-to-tool mappings for this MCP config. Maximum 25 connections in `DIRECT` mode. |
| `connection_tool_mappings.connection_name` | string | Yes | Developer-assigned connection name. |
| `connection_tool_mappings.tools` | array of string | No | List of tool names linked to this connection (empty = all tools). |
| `description` | string | No | Updated description for the MCP configuration. |
| `tool_exposure` | string (enum) | No | Change how the server exposes tools to agents: `DIRECT` or `META`. Leave it out to keep the current mode. Switching to `DIRECT` fails when the server has more than 25 connections. After a switch, MCP clients must list the tools again; session tokens keep working. One of: `DIRECT`, `META`. |

**Response (200)**

| Name | Type | Description |
| --- | --- | --- |
| `config` | object | The updated MCP configuration. |
| `config.connection_tool_mappings` | array of object | List of connection-to-tool mappings for this MCP config. Maximum 25 connections in `DIRECT` mode. |
| `config.connection_tool_mappings.connected_account_id` | string | Connected account backing this connection in the MCP instance context. |
| `config.connection_tool_mappings.connected_account_status` | string | Authentication status for the connected account. |
| `config.connection_tool_mappings.connection_id` | string | Unique ID of the connection. |
| `config.connection_tool_mappings.connection_name` | string | Developer-assigned connection name. |
| `config.connection_tool_mappings.provider` | string | Provider name for this connection. |
| `config.connection_tool_mappings.tools` | array of string | List of tool names linked to this connection (empty = all tools). |
| `config.description` | string | Description of the MCP configuration. |
| `config.id` | string | Unique ID of the MCP config. |
| `config.mcp_server_url` | string | The URL MCP clients connect to for this server. Every user and session shares it; the session token identifies the user. |
| `config.name` | string | Unique name for the MCP configuration. Must be 1–100 characters. Allowed characters: lowercase letters (a–z), digits (0–9), hyphens (-), and underscores (_). |
| `config.tool_exposure` | string (enum) | How the server exposes tools to agents. `DIRECT` lists every tool you map to it, for up to 25 connections. `META` gives agents five tools to search for, inspect and run the mapped tools, with no limit on connections. `DIRECT` is the default when you create a server without it. One of: `DIRECT`, `META`. |

**Errors**

- `400`: Invalid request - malformed payload or invalid mappings
- `401`: Authentication required
- `404`: Not Found - MCP configuration does not exist

**Request**

```bash
curl -sS -X PUT \
  "$SCALEKIT_ENVIRONMENT_URL/api/v1/mcp/configs/cfg_85630864460904897" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "description": "Reads the user'\''s GitHub repositories, issues and pull requests",
    "connection_tool_mappings": [
      {
        "connection_name": "github-connect",
        "tools": [
          "github_user_repos_list",
          "github_issues_list",
          "github_pull_requests_list"
        ]
      }
    ]
  }'
```

**Response**

```json
{
  "config": {
    "id": "cfg_85630864460904897",
    "name": "repo-assistant",
    "description": "Reads the user's GitHub repositories, issues and pull requests",
    "connection_tool_mappings": [
      {
        "connection_id": "conn_70219645518267719",
        "connection_name": "github-connect",
        "provider": "GITHUB",
        "tools": [
          "github_user_repos_list",
          "github_issues_list",
          "github_pull_requests_list"
        ]
      }
    ],
    "mcp_server_url": "https://your-env.scalekit.dev/mcp/v3/servers/3d9f6a2e-7b41-4c8e-a5d2-0f1e8b6c4a93",
    "tool_exposure": "DIRECT"
  }
}
```

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

Update mutable fields on an existing MCP configuration.

```python
scalekit_client.actions.mcp.update_config(
    config_id: str,
    description: Optional[str] = None,
    connection_tool_mappings: Optional[List[McpConfigConnectionToolMapping]] = None,
    tool_exposure: Optional[str] = None,
) -> UpdateMcpConfigResponse
```

Example:

```python
from scalekit.actions.types import McpConfigConnectionToolMapping

result = scalekit_client.actions.mcp.update_config(
    config_id="cfg_85630864460904897",
    description="Reads the user's GitHub repositories, issues and pull requests",
    connection_tool_mappings=[
        McpConfigConnectionToolMapping(
            connection_name="github-connect",
            tools=[
                "github_user_repos_list",
                "github_issues_list",
                "github_pull_requests_list",
            ],
        ),
    ],
)
```

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `config_id` | `str` | Yes | Identifier of the configuration to update. |
| `description` | `Optional[str]` | No | New description to persist, if provided. |
| `connection_tool_mappings` | `Optional[List[McpConfigConnectionToolMapping]]` | No | Replacement connector-to-tool mappings. |
| `tool_exposure` | `Optional[str]` | No | Change how the server exposes tools: `DIRECT` or `META`. Leave it out to keep the current mode. Switching to `DIRECT` fails when the server has more than 25 connections or two connections map tools with the same name. After a switch, MCP clients must list the tools again; session tokens keep working. |

Returns `UpdateMcpConfigResponse`: The updated configuration payload.

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

Updates the description and connection-to-tool mappings of a configuration. The name cannot be changed after creation. Avoid updating while agent sessions are running — tools can become unavailable mid-session. For a significant change, create a new configuration and swap the URL instead.

```ts
scalekit.actions.mcp.updateConfig(
  params: {
    configId: string;
    description?: string;
    connectionToolMappings?: MessageInitShape<typeof UpdateMcpConfigRequestSchema>['connectionToolMappings'];
    toolExposure?: McpToolExposure;
  },
): Promise<UpdateMcpConfigResponse>
```

Example:

```ts
const result = await scalekit.actions.mcp.updateConfig({
  configId: "cfg_85630864460904897",
  description: "Reads the user's GitHub repositories, issues and pull requests",
  connectionToolMappings: [
    {
      connectionName: "github-connect",
      tools: [
        "github_user_repos_list",
        "github_issues_list",
        "github_pull_requests_list",
      ],
    },
  ],
});
```

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `configId` | `string` | Yes | ID of the configuration to update. |
| `description` | `string` | No | New description. |
| `connectionToolMappings` | `MessageInitShape<typeof UpdateMcpConfigRequestSchema>['connectionToolMappings']` | No | Replacement connection-to-tool mappings. |
| `toolExposure` | `McpToolExposure` | No | Change how the server exposes tools: `DIRECT` or `META`. Leave it out to keep the current mode. Switching to `DIRECT` fails when the server has more than 25 connections or two connections map tools with the same name. After a switch, MCP clients must list the tools again; session tokens keep working. |

Returns `Promise<UpdateMcpConfigResponse>`.

**Used in**

- [Create a Virtual MCP server](https://docs.scalekit.com/agentkit/mcp/configure-mcp-server/)

## Delete a Virtual MCP server

`DELETE /api/v1/mcp/configs/{config_id}`

Deletes a Virtual MCP server and its connection and tool mappings. MCP clients can no longer connect to its URL. Users keep their connected accounts.

**Path parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `config_id` | string | Yes | ID of the MCP configuration to delete. |

**Errors**

- `400`: Invalid request
- `401`: Authentication required
- `404`: Not Found - MCP configuration does not exist

**Request**

```bash
curl -sS -X DELETE \
  "$SCALEKIT_ENVIRONMENT_URL/api/v1/mcp/configs/cfg_85630864460904897" \
  -H "Authorization: Bearer $TOKEN"
```

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

Deletes a Virtual MCP server.

```python
scalekit_client.actions.mcp.delete_config(
    config_id: str,
) -> DeleteMcpConfigResponse
```

Example:

```python
result = scalekit_client.actions.mcp.delete_config(
    config_id="cfg_85630864460904897",
)
```

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `config_id` | `str` | Yes | Identifier of the configuration to remove. |

Returns `DeleteMcpConfigResponse`: An empty response.

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

Deletes an MCP configuration.

```ts
scalekit.actions.mcp.deleteConfig(
  configId: string,
): Promise<DeleteMcpConfigResponse>
```

Example:

```ts
const result = await scalekit.actions.mcp.deleteConfig("cfg_85630864460904897");
```

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `configId` | `string` | Yes | ID of the configuration to delete. |

Returns `Promise<DeleteMcpConfigResponse>`.

**Used in**

- [Create a Virtual MCP server](https://docs.scalekit.com/agentkit/mcp/configure-mcp-server/)

## Check a user's connected accounts for a server

`POST /api/v1/mcp/configs/{config_id}/connected_accounts`

Returns the user's connected account on each connection the server uses, with its status. Call it before you mint a session token, and send the user the authorization link for any account that isn't `ACTIVE`. With `include_auth_link` set to `true`, the call creates any account the user doesn't have yet and returns a fresh [authorization link](https://docs.scalekit.com/agentkit/reference/authorization/get-an-authorization-link/) for every connection, in `authentication_link`. Without it, nothing is created, and a connection where the user has no account comes back with an empty `connected_account_id`.

**Path parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `config_id` | string | Yes | ID of the MCP configuration. |

**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. Use a stable internal ID, not an email address. |
| `include_auth_link` | boolean | No | Set to `true` to get a fresh authorization link for every connection, creating any connected account the user doesn't have yet. |

**Response (200)**

| Name | Type | Description |
| --- | --- | --- |
| `connected_accounts` | array of object | Connected account state for each connection in the configuration. |
| `connected_accounts.authentication_link` | string | The authorization link for this connection. Empty unless the request set `include_auth_link`. |
| `connected_accounts.connected_account_id` | string | The user's connected account on this connection. Empty when the user has none. |
| `connected_accounts.connected_account_status` | string | The account's status, such as `ACTIVE` or `PENDING_AUTH`. Empty when the user has no account. |
| `connected_accounts.connection_id` | string | ID of the connection. |
| `connected_accounts.connection_name` | string | Name of the connection. |
| `connected_accounts.provider` | string | The app, such as `GITHUB`. |

**Errors**

- `400`: Bad request - config_id or identifier is missing or invalid
- `404`: Not found - no MCP configuration exists with the given config_id

**Request**

```bash
curl -sS -X POST \
  "$SCALEKIT_ENVIRONMENT_URL/api/v1/mcp/configs/cfg_85630864460904897/connected_accounts" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "identifier": "user_123",
    "include_auth_link": true
  }'
```

**Response**

```json
{
  "connected_accounts": [
    {
      "connection_id": "conn_70219645518267719",
      "connection_name": "github-connect",
      "provider": "GITHUB",
      "connected_account_id": "ca_24834495392091352",
      "connected_account_status": "PENDING_AUTH",
      "authentication_link": "https://your-env.scalekit.dev/magicLink/7f0c2b9e-4d1a-4c3e-9b8f-2a6d5e1c3f40_o"
    }
  ]
}
```

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

Lists the user's connected account on each connection a Virtual MCP server uses. Returns each account's status and, with `include_auth_link=True`, an authorization link the user opens to connect or reconnect. Call it before you mint a session token.

```python
scalekit_client.actions.mcp.list_mcp_connected_accounts(
    config_id: str,
    identifier: str,
    include_auth_link: Optional[bool] = None,
) -> ListMcpConnectedAccountsResponse
```

Example:

```python
result = scalekit_client.actions.mcp.list_mcp_connected_accounts(
    config_id="cfg_85630864460904897",
    identifier="user_123",
    include_auth_link=True,
)
```

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `config_id` | `str` | Yes | Scalekit ID of the MCP configuration to inspect, e.g. `"cfg_01abc123"`. |
| `identifier` | `str` | 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. |
| `include_auth_link` | `Optional[bool]` | No | Set to `true` to get a fresh authorization link for every connection, creating any connected account the user doesn't have yet. |

Returns `ListMcpConnectedAccountsResponse`: One entry per connection in `connected_accounts`, with `connection_name`, `provider`, `connected_account_id`, `connected_account_status`, such as `ACTIVE` or `PENDING_AUTH`, and `authentication_link`, the authorization link when you set `include_auth_link`.

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

Lists the connected accounts backing a configuration for one user. Call this before minting a session token: OAuth credentials can expire or be revoked at any time, and an agent that starts without an active connection fails on every tool call. Surface `authenticationLink` for any account whose `connectedAccountStatus` is not `"ACTIVE"`.

```ts
scalekit.actions.mcp.listConnectedAccounts(
  params: {
    configId: string;
    identifier: string;
    includeAuthLink?: boolean;
  },
): Promise<ListMcpConnectedAccountsResponse>
```

Example:

```ts
const result = await scalekit.actions.mcp.listConnectedAccounts({
  configId: "cfg_85630864460904897",
  identifier: "user_123",
  includeAuthLink: true,
});
```

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `configId` | `string` | Yes | ID of the configuration. |
| `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. |
| `includeAuthLink` | `boolean` | No | Set to `true` to get a fresh authorization link for every connection, creating any connected account the user doesn't have yet. |

Returns `Promise<ListMcpConnectedAccountsResponse>`.

**Used in**

- [Claude Managed Agents](https://docs.scalekit.com/agentkit/examples/claude-managed-agents/)
- [Mint session tokens](https://docs.scalekit.com/agentkit/mcp/session-tokens/)

## Mint a session token

`POST /api/v1/mcp/configs/{mcp_config_id}/tokens`

Mints a short-lived JWT that represents a user identifier across the connected accounts associated with an MCP configuration. The supplied identifier becomes the token's `sub` claim; the token's `aud` claim is the MCP server URL bound to the configuration. Claims also carry the MCP configuration ID (`mcp_cfg`) and the list of resolved connected-account IDs (`ca_ids`). Use this operation to issue a single credential an MCP server can present on the user's behalf when calling provider tools. The mint fails if any connection mapped to the configuration has no active connected account for the identifier. For a `META` server, the user needn't have connected accounts yet.

**Path parameters**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `mcp_config_id` | string | Yes | Unique ID of the MCP configuration whose connections back the token. The configuration must exist in the caller's environment. |

**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 - mcp_config_id or identifier is missing or malformed, expiry is outside the 60s-24h window, the MCP configuration has no connections, or a connection has no active connected account for the supplied identifier
- `404`: Not Found - no MCP configuration exists with the supplied ID in the caller's environment

**Request**

```bash
curl -sS -X POST \
  "$SCALEKIT_ENVIRONMENT_URL/api/v1/mcp/configs/cfg_85630864460904897/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(
    mcp_config_id="cfg_85630864460904897",
    identifier="user_123",
    expiry=timedelta(seconds=1800),
)
```

| 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,
  mcpConfigId: "cfg_85630864460904897",
});
```

| 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/)

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


---

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