> **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 other Agent Skills-compatible agents.
> 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/).

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, or the connections and tools it serves. | `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. | REST only | REST only |


## 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 entries. |
| `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. |

**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 entries. |
| `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 (_). |

**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"
        ]
      }
    ]
  }'
```

**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"
  }
}
```

**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,
) -> 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"],
        ),
    ],
)
```

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

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'];
  },
): 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"],
    },
  ],
});
```

| 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 mappings. |

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 entries. |
| `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 (_). |

**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"
  }
}
```

**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 entries. |
| `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 (_). |
| `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"
    }
  ],
  "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 entries. |
| `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. |

**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 entries. |
| `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 (_). |

**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"
  }
}
```

**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,
) -> 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. |

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'];
  },
): 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. |

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.

**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. |
| `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. The token is scoped to a specific MCP configuration and end-user. Pass it as a `Bearer` token in the `Authorization` header when making requests to the MCP server URL associated with the config.

```python
scalekit_client.actions.mcp.create_session_token(
    mcp_config_id: str,
    identifier: str,
    expiry: Optional[timedelta] = 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` | Yes | Scalekit ID of the MCP configuration the token should grant access to, 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. |
| `expiry` | `Optional[timedelta]` | No | Requested lifetime for the token as a Python `timedelta`. When omitted, the server-side default TTL is applied (typically 1 hour). Example values: `timedelta(minutes=30)` — 30-minute token; `timedelta(hours=8)` — 8-hour token (work-day session); `timedelta(days=1)` — 24-hour token |

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 against one configuration. The server URL is static; this 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.

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

Example:

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

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `mcpConfigId` | `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. |
| `expirySeconds` | `number` | No | Token lifetime in whole seconds. |

Returns `Promise<CreateMcpSessionTokenResponse>`.

**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/)
- [Mastra](https://docs.scalekit.com/agentkit/examples/mastra/)
- [Mint session tokens](https://docs.scalekit.com/agentkit/mcp/session-tokens/)

## 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. |
| `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, or the connection isn't an AgentKit connection. When the user has no active account on the connection yet, Scalekit creates a pending one and still 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:** 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.post(
    f"{env_url}/api/v1/mcp/connections/gmail/tokens",
    headers={"Authorization": f"Bearer {token}"},
    json={"identifier": "user_123", "expiry": "1800s"},
)
response.raise_for_status()
result = response.json()
```

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

```ts
const envUrl = process.env.SCALEKIT_ENVIRONMENT_URL!;
const tokenResponse = await fetch(`${envUrl}/oauth/token`, {
  method: "POST",
  body: new URLSearchParams({
    grant_type: "client_credentials",
    client_id: process.env.SCALEKIT_CLIENT_ID!,
    client_secret: process.env.SCALEKIT_CLIENT_SECRET!,
  }),
});
const token = (await tokenResponse.json()).access_token;

const response = await fetch(`${envUrl}/api/v1/mcp/connections/gmail/tokens`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${token}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ identifier: "user_123", expiry: "1800s" }),
});
if (!response.ok) throw new Error(`${response.status}: ${await response.text()}`);
const result = await response.json();
```


---

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