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

---

# Set up and connect a Virtual MCP server

Create a Virtual MCP Server, verify user connections, mint session tokens, and connect your agent using bearer auth.
## Prerequisites

Before creating a Virtual MCP Server, configure the connections you want to expose. Each `connection_name` you reference must already exist in **AgentKit > Connections**.

See [Configure a connection](/agentkit/connections/) if you haven't done this yet.

## Create a Virtual MCP server

Create the server once per agent role — not once per user. The response includes a static `mcp_server_url` you reuse for every user and every session.

```python

from scalekit import ScalekitClient
from scalekit.actions.models.mcp_config import McpConfigConnectionToolMapping

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

vmcp_response = scalekit_client.actions.mcp.create_config(
    name="email-calendar-agent",
    connection_tool_mappings=[
        McpConfigConnectionToolMapping(
            connection_name="gmail",
            tools=["gmail_fetch_mails"],
        ),
        McpConfigConnectionToolMapping(
            connection_name="googlecalendar",
            tools=[
                "googlecalendar_list_events",
                "googlecalendar_create_event",
            ],
        ),
    ],
)

config_id = vmcp_response.config.id
mcp_server_url = vmcp_response.config.mcp_server_url
```

Save `config_id` and `mcp_server_url`. You pass these to every agent session.

**Selecting tools**: Each `McpConfigConnectionToolMapping` controls which tools from a connection appear on the server. Omit `tools` to expose all tools for that connection. To find available tool names, browse **AgentKit > Catalog** or open the connection from **AgentKit > Connections**.

## Connect an agent

Run these steps before each agent session.

1. ## Check that connections are active

   Verify all connections are still active for this user before minting a token. OAuth credentials can expire or be revoked at any time.

   ```python
   accounts_response = scalekit_client.actions.mcp.list_mcp_connected_accounts(
       config_id=config_id,
       identifier="user_123",      # your app's unique identifier for this user
       include_auth_link=True,     # include re-auth URLs for any inactive connections
   )

   for account in accounts_response.connected_accounts:
       if account.connected_account_status != "ACTIVE":
           print(f"{account.connection_name} needs auth: {account.authentication_link}")
   ```

   `identifier` is any string that uniquely identifies a user in your system — an email, user ID, or UUID. Use the same value consistently across all calls.

   If any connection is not `"ACTIVE"`, surface the `authentication_link` to the user before proceeding. See [Authorize user connections](/agentkit/tools/authorize/).

2. ## Mint a session token

   Mint a fresh token before every agent run. Never reuse a token from a previous session.

   ```python
   from datetime import timedelta

   token_response = scalekit_client.actions.mcp.create_session_token(
       mcp_config_id=config_id,
       identifier="user_123",
       expiry=timedelta(hours=1),
   )

   token = token_response.token
   ```

   Set `expiry` longer than the expected agent run duration. For a task that typically takes 20 minutes, a 30-minute expiry is sufficient.

3. ## Pass the token to your agent

   Pass `mcp_server_url` and the session token to your agent framework using bearer auth.

   ```python
   mcp_server = {
       "url": mcp_server_url,
       "headers": {"Authorization": f"Bearer {token}"},
   }
   ```

   How you register the MCP server depends on your framework. For a complete end-to-end example using Claude Managed Agents — including vault-based auth injection and response streaming — see [Claude Managed Agents](/agentkit/examples/claude-managed-agents/).

## Manage servers

**List servers**

```python
configs = scalekit_client.actions.mcp.list_configs()
for config in configs.configs:
    print(config.id, config.name, config.mcp_server_url)

# Filter by name
configs = scalekit_client.actions.mcp.list_configs(filter_name="email-calendar-agent")
```

**Update a server**

You can update `description` or `connection_tool_mappings` on an existing server. Only do this when no agent sessions are actively running — updating mid-session can cause tools to become unavailable. For significant changes, create a new server and swap the `mcp_server_url` in your agent definition so existing sessions complete cleanly.

```python
scalekit_client.actions.mcp.update_config(
    config_id=config_id,
    connection_tool_mappings=[
        McpConfigConnectionToolMapping(
            connection_name="gmail",
            tools=["gmail_fetch_mails", "gmail_send_mail"],
        ),
        McpConfigConnectionToolMapping(
            connection_name="googlecalendar",
            tools=["googlecalendar_create_event", "googlecalendar_list_events"],
        ),
    ],
)
```

**Delete a server**

```python
scalekit_client.actions.mcp.delete_config(config_id=config_id)
```

Deleting a server immediately invalidates the `mcp_server_url`. Any agent connected to that URL loses tool access. Confirm no active sessions are running before deleting.


---

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