Skip to content
Scalekit Docs
Talk to an Engineer Dashboard

Claude Managed Agents

Run Claude Managed Agents with Scalekit-authenticated tools using Virtual MCP Servers and Anthropic vaults.

Run a background agent that reads Gmail and creates Google Calendar events — without managing any agent loop. Anthropic handles tool discovery, execution, retries, and session state. You provide the task.

Scalekit connects the agent to user-authorized tools via a Virtual MCP Server. Before each run, you mint a short-lived session token and store it in an Anthropic vault. The agent accesses the MCP server using the vault credential.

  • A Scalekit account with Gmail and Google Calendar connections configured. See Configure a connection.
  • An Anthropic API key with access to the Managed Agents beta.
  • An Anthropic environment ID set as ANTHROPIC_ENVIRONMENT_ID.

The flow has three phases:

  1. Build (one-time) — Create a Virtual MCP Server and a Claude Managed Agent. Save mcp_id and agent_id.
  2. Authorize user for external connections (once per user) — Authorize the user’s Gmail and Google Calendar accounts.
  3. Run a session (per agent run) — Check connections, mint a session token, store it in an Anthropic vault, and start a session.
Terminal window
pip install anthropic scalekit-sdk-python python-dotenv

Run this once to create your Virtual MCP Server and Claude Managed Agent. Save the returned mcp_id and agent_id — you reuse them for every user and every session.

builder.py
import os
import anthropic
from scalekit import ScalekitClient
from scalekit.actions.models.mcp_config import McpConfigConnectionToolMapping
from dotenv import load_dotenv
load_dotenv()
anthropic_client = anthropic.Anthropic()
scalekit_client = ScalekitClient(
env_url=os.environ["SCALEKIT_ENV_URL"],
client_id=os.environ["SCALEKIT_CLIENT_ID"],
client_secret=os.environ["SCALEKIT_CLIENT_SECRET"],
)
GMAIL_TOOLS = ["gmail_fetch_mails"]
GCAL_TOOLS = [
"googlecalendar_list_calendars",
"googlecalendar_list_events",
"googlecalendar_get_event_by_id",
"googlecalendar_create_event",
"googlecalendar_update_event",
]
vmcp_response = scalekit_client.actions.mcp.create_config(
name="email-calendar-demo",
connection_tool_mappings=[
McpConfigConnectionToolMapping(
connection_name="gmail",
tools=GMAIL_TOOLS,
),
McpConfigConnectionToolMapping(
connection_name="googlecalendar",
tools=GCAL_TOOLS,
),
],
)
mcp_id = vmcp_response.config.id
mcp_server_url = vmcp_response.config.mcp_server_url
agent = anthropic_client.beta.agents.create(
name="Email Meeting Manager",
model="claude-haiku-4-5-20251001",
system=(
"You are an email and calendar assistant. When invoked, you will:\n"
"1. Fetch the single most recent unread email from Gmail.\n"
"2. Summarize it in 2-3 sentences.\n"
"3. Create a Google Calendar event titled 'Action Required: <email subject>' "
"with your summary as the description."
),
mcp_servers=[
{
"type": "url",
"name": "email-calendar-mcp",
"url": mcp_server_url,
}
],
tools=[
{"type": "agent_toolset_20260401", "default_config": {"enabled": True}},
{
"type": "mcp_toolset",
"mcp_server_name": "email-calendar-mcp",
"default_config": {
"enabled": True,
"permission_policy": {"type": "always_allow"},
},
},
],
)
print("Virtual MCP ID:", mcp_id)
print("Agent ID: ", agent.id)

The agent definition references the mcp_server_url but carries no auth credentials. Authentication is injected at runtime via the Anthropic vault.

Each user authorizes their Gmail and Google Calendar accounts once. All future agent sessions for that user reuse those connections.

executor_setup.py
import os
from scalekit import ScalekitClient
from dotenv import load_dotenv
load_dotenv()
scalekit_client = ScalekitClient(
env_url=os.environ["SCALEKIT_ENV_URL"],
client_id=os.environ["SCALEKIT_CLIENT_ID"],
client_secret=os.environ["SCALEKIT_CLIENT_SECRET"],
)
# Retrieve mcp_id by listing Virtual MCP Servers filtered by name to use below
accounts_response = scalekit_client.actions.mcp.list_mcp_connected_accounts(
config_id=mcp_id,
identifier=identifier, # your app's unique user ID
)
for account in accounts_response.connected_accounts:
if account.connected_account_status != "ACTIVE":
auth_response = scalekit_client.actions.get_authorization_link(
identifier=identifier,
connection_name=account.connection_name,
)
print(f"{account.connection_name} needs auth: {auth_response.link}")
else:
print(f"✓ {account.connection_name}{account.connected_account_status}")

Surface the auth link in your app UI or send it via email. Users only need to do this once.

Run the following for each agent execution.

  1. Before minting a token, confirm all connections are still "ACTIVE". OAuth tokens for connected accounts can expire or be revoked.

    executor.py
    accounts_response = scalekit_client.actions.mcp.list_mcp_connected_accounts(
    config_id=mcp_id,
    identifier=identifier,
    )
    inactive = [
    a.connection_name
    for a in accounts_response.connected_accounts
    if a.connected_account_status != "ACTIVE"
    ]
    if inactive:
    print("Inactive connections:", inactive)
    # Prompt the user to re-authorize before proceeding
  2. Mint a short-lived session token and store it in an Anthropic vault. Claude Managed Agents access the MCP server using the vault credential — not a direct bearer header.

    executor.py
    from datetime import timedelta
    configs_response = scalekit_client.actions.mcp.list_configs(filter_id=mcp_id)
    mcp_server_url = configs_response.configs[0].mcp_server_url
    token_response = scalekit_client.actions.mcp.create_session_token(
    mcp_config_id=mcp_id,
    identifier=identifier,
    expiry=timedelta(hours=1),
    )
    token = token_response.token
    # Create vault and credential on first run; update the token on subsequent runs
    if vault_id and credential_id:
    anthropic_client.beta.vaults.credentials.update(
    credential_id,
    vault_id=vault_id,
    auth={"type": "static_bearer", "token": token},
    )
    else:
    vault = anthropic_client.beta.vaults.create(display_name="email-calendar-vault")
    vault_id = vault.id
    credential = anthropic_client.beta.vaults.credentials.create(
    vault_id,
    display_name="email-calendar-credential",
    auth={
    "type": "static_bearer",
    "mcp_server_url": mcp_server_url,
    "token": token,
    },
    )
    credential_id = credential.id
  3. Pass vault_ids to the session so the agent can authenticate against the MCP server.

    executor.py
    session = anthropic_client.beta.sessions.create(
    agent=agent_id,
    environment_id=os.environ["ANTHROPIC_ENVIRONMENT_ID"],
    vault_ids=[vault_id],
    )
    with anthropic_client.beta.sessions.events.stream(session_id=session.id) as stream:
    anthropic_client.beta.sessions.events.send(
    session_id=session.id,
    events=[{"type": "user.message", "content": [{"type": "text", "text": prompt}]}],
    )
    for event in stream:
    if event.type == "agent.message":
    for block in event.content:
    if block.type == "text":
    print(block.text, end="", flush=True)
    elif event.type == "agent.mcp_tool_use":
    print(f"\n{event.name}", flush=True)
    elif event.type in ("session.status_idle", "session.status_terminated"):
    break