> **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**: `/plugin marketplace add scalekit-inc/claude-code-authstack` then `/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/)

---

# Configure an MCP server

Suppose you ship an agent that reads a user's email and creates calendar events from chat. You want an **MCP client** (for example LangChain or Claude Desktop) to call those tools **without** storing users' OAuth tokens in the MCP client or in browser code, and **without** writing a custom tool-calling loop in your app. Scalekit keeps tokens server-side. An **MCP config** is the single template that lists which [connections](/agentkit/connections/) (for example Gmail and Google Calendar) and which tools appear on the MCP server. This page shows how to create that config. [Generate user MCP URLs](/agentkit/mcp/generate-user-urls/) and [Connect an MCP client](/agentkit/mcp/connect-mcp-client/) cover the steps that follow.

| Use MCP when | Use the SDK when |
|---|---|
| You want any MCP-compatible framework to connect | You need fine-grained control over tool execution |
| You're exposing tools to external agents or Claude Desktop | You're building a custom agent loop |
| You want to expose different tool sets to different agent roles | You need to mix Scalekit tools with custom logic |

The SDK approach gives your code direct control: you call `execute_tool`, manage the response, and drive the agent loop. The MCP approach inverts this: you generate a pre-authenticated URL per user and hand it to any MCP-compatible agent or framework. The agent discovers available tools itself and executes them through the MCP protocol. Your application code doesn't manage the loop.

## How it works

Two objects are central to this model:

| Object | What it is | Created |
|---|---|---|
| **MCP config** | A reusable template that defines which connections and tools are exposed | Once, by your app |
| **MCP instance** | A per-user instantiation of a config, with its own URL | Once per user |

You create a config once. For each user, Scalekit generates a unique, pre-authenticated URL from that config. The agent connects to the URL. Scalekit routes tool calls using the user's authorized credentials.

### One-time setup

Declare the MCP config once with `create_config`: which connections and tools appear on the server.

```d2 pad=48
direction: right

title: "How Scalekit MCP tool access works: one-time setup" {
  near: top-center
  shape: text
  style.font-size: 22
}

one_time: {
  label: "ONE-TIME SETUP"
  style.fill: "#E3F2FD"
  style.font-size: 16

  your_app: "Your App" {
    shape: oval
    style.fill: "#FFE0B2"
    style.font-size: 16
  }
  mcp_config: "MCP Config\ngmail_fetch_mails\ngooglecalendar_create_event" {
    shape: rectangle
    style.font-size: 16
  }
  your_app -> mcp_config: create_config()
}

next_flow: "Next: Per-user →" {
  shape: text
  style.font-size: 14
  link: "#per-user"
}

one_time.mcp_config -> next_flow: ensure_instance()
```

### Per-user

Call `ensure_instance` for each user. They authorize OAuth for each connection (`auth link`) until every connection is active. You receive a pre-authenticated MCP URL for that user.

```d2 pad=48
direction: right

title: "How Scalekit MCP tool access works: per-user" {
  near: top-center
  shape: text
  style.font-size: 22
}

prev_flow: "← One-time setup" {
  shape: text
  style.font-size: 14
  link: "#one-time-setup"
}

per_user: {
  label: "PER-USER"
  style.fill: "#E8F5E9"
  style.font-size: 16

  instance: "Per-user instance\nmcp.scalekit.com\n/u/john-doe/..." {
    shape: rectangle
    style.font-size: 16
  }
  user_auth: "User authorizes" {
    shape: oval
    style.fill: "#FFE0B2"
    style.font-size: 16
  }
  instance -> user_auth: auth link
}

next_flow: "Next: Runtime →" {
  shape: text
  style.font-size: 14
  link: "#runtime"
}

prev_flow -> per_user.instance
per_user.user_auth -> next_flow: MCP URL
```

### Runtime

Point your MCP client at that URL (the diagram labels it **AI Agent (MCP URL)**). Tool calls flow to the providers Scalekit proxies using that user's tokens.

```d2 pad=48
direction: right

title: "How Scalekit MCP tool access works: runtime" {
  near: top-center
  shape: text
  style.font-size: 22
}

prev_flow: "← Per-user" {
  shape: text
  style.font-size: 14
  link: "#per-user"
}

restart_flow: "↺ One-time setup" {
  shape: text
  style.font-size: 14
  link: "#one-time-setup"
}

runtime: {
  label: "RUNTIME"
  style.fill: "#F3E5F5"
  style.font-size: 16

  agent: "AI Agent\n(MCP URL)" {
    shape: rectangle
    style.font-size: 16
  }
  gmail: Gmail {
    shape: rectangle
    style.fill: "#B2EBF2"
    style.font-size: 16
  }
  gcal: "Google Calendar" {
    shape: rectangle
    style.fill: "#B2EBF2"
    style.font-size: 16
  }
  agent -> gmail: tool calls
  agent -> gcal: tool calls
}

prev_flow -> runtime.agent
runtime.agent -> restart_flow
```

## Prerequisites

Before creating a config, configure the connections you want to expose. Each `connection_name` in the config must already exist in **Agent Auth > Connections**.

See [Configure a connection](/agentkit/connections/) if you haven't set these up yet.

## Create an MCP config

An MCP config declares which connections and tools your server exposes. Create it once (not once per user).

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

scalekit_client = scalekit.client.ScalekitClient(
    client_id=os.getenv("SCALEKIT_CLIENT_ID"),
    client_secret=os.getenv("SCALEKIT_CLIENT_SECRET"),
    env_url=os.getenv("SCALEKIT_ENV_URL"),
)
actions = scalekit_client.actions

cfg_response = actions.mcp.create_config(
    name="email-calendar-assistant",
    description="Reads email and creates calendar reminders",
    connection_tool_mappings=[
        McpConfigConnectionToolMapping(
            connection_name="MY_GMAIL",
            tools=["gmail_fetch_mails"],
        ),
        McpConfigConnectionToolMapping(
            connection_name="MY_CALENDAR",
            tools=["googlecalendar_create_event"],
        ),
    ],
)
config_name = cfg_response.config.name
print("Config created:", config_name)
```
**One config, many use cases:** Create multiple configs for different agent roles: a customer support config that exposes ticketing tools, a sales config that exposes CRM tools. Each config produces a different URL with a different tool set.

## Whitelist specific tools

The `tools` array in each `McpConfigConnectionToolMapping` controls exactly which tools are exposed on the server. To find the available tool names for a connector, call `list_tools` or check the connector's page in **Agent Auth > Connectors**.

```python
# Expose all tools for a connector; omit tools to expose everything
McpConfigConnectionToolMapping(connection_name="MY_GMAIL")

# Expose only specific tools
McpConfigConnectionToolMapping(
    connection_name="MY_GMAIL",
    tools=["gmail_fetch_mails", "gmail_send_mail"],
)
```

Full working code for all MCP steps is on [GitHub](https://github.com/scalekit-inc/python-connect-demos/tree/main/mcp).

---

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