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

---

# Anthropic

Build an agent using Anthropic's Claude that reads a user's Gmail inbox. Scalekit returns tool schemas with `input_schema`, the exact format Anthropic's tool use API expects.

## Install

```sh
pip install scalekit-sdk-python anthropic
```
  ```sh
npm install @scalekit-sdk/node @anthropic-ai/sdk
```
  ## Initialize

```python
import os
import scalekit.client
import anthropic
from google.protobuf.json_format import MessageToDict

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
client = anthropic.Anthropic()
```
  ```typescript
import { ScalekitClient } from '@scalekit-sdk/node';
import { ConnectorStatus } from '@scalekit-sdk/node/lib/pkg/grpc/scalekit/v1/connected_accounts/connected_accounts_pb';
import Anthropic from '@anthropic-ai/sdk';

const scalekit = new ScalekitClient(
  process.env.SCALEKIT_ENV_URL!,
  process.env.SCALEKIT_CLIENT_ID!,
  process.env.SCALEKIT_CLIENT_SECRET!,
);
const anthropic = new Anthropic();
```
  ## Connect the user to Gmail

```python
response = actions.get_or_create_connected_account(
    connection_name="gmail",
    identifier="user_123",
)
if response.connected_account.status != "ACTIVE":
    link = actions.get_authorization_link(connection_name="gmail", identifier="user_123")
    print("Authorize Gmail:", link.link)
    input("Press Enter after authorizing...")
```
  ```typescript
const { connectedAccount } = await scalekit.actions.getOrCreateConnectedAccount({
  connectionName: 'gmail',
  identifier: 'user_123',
});
if (connectedAccount?.status !== ConnectorStatus.ACTIVE) {
  const { link } = await scalekit.actions.getAuthorizationLink({ connectionName: 'gmail', identifier: 'user_123' });
  console.log('Authorize Gmail:', link);
}
```
  See [Authorize a user](/agentkit/tools/authorize/) for production auth handling.

## Run the agent

Fetch tools scoped to this user, then run the full Claude tool-use loop:

```python
# Fetch tools scoped to this user
scoped_response, _ = actions.tools.list_scoped_tools(
    identifier="user_123",
    filter={"connection_names": ["gmail"]},
)
llm_tools = [
    {
        "name": MessageToDict(t.tool).get("definition", {}).get("name"),
        "description": MessageToDict(t.tool).get("definition", {}).get("description", ""),
        "input_schema": MessageToDict(t.tool).get("definition", {}).get("input_schema", {}),
    }
    for t in scoped_response.tools
]

# Run the agent loop
messages = [{"role": "user", "content": "Fetch my last 5 unread emails and summarize them"}]

while True:
    response = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=1024,
        tools=llm_tools,
        messages=messages,
    )
    if response.stop_reason == "end_turn":
        print(response.content[0].text)
        break

    tool_results = []
    for block in response.content:
        if block.type == "tool_use":
            result = actions.execute_tool(
                tool_name=block.name,
                identifier="user_123",
                tool_input=block.input,
            )
            tool_results.append({
                "type": "tool_result",
                "tool_use_id": block.id,
                "content": str(result.data),
            })

    messages.append({"role": "assistant", "content": response.content})
    messages.append({"role": "user", "content": tool_results})
```
  ```typescript
// Fetch tools scoped to this user
const { tools } = await scalekit.tools.listScopedTools('user_123', {
  filter: { connectionNames: ['gmail'] },
});
const llmTools = tools.map(t => ({
  name: t.tool.definition.name,
  description: t.tool.definition.description,
  input_schema: t.tool.definition.input_schema,
}));

// Run the agent loop
const messages: Anthropic.MessageParam[] = [
  { role: 'user', content: 'Fetch my last 5 unread emails and summarize them' },
];

while (true) {
  const response = await anthropic.messages.create({
    model: 'claude-sonnet-4-6',
    max_tokens: 1024,
    tools: llmTools,
    messages,
  });

  if (response.stop_reason === 'end_turn') {
    const text = response.content.find(b => b.type === 'text');
    if (text?.type === 'text') console.log(text.text);
    break;
  }

  const toolResults: Anthropic.ToolResultBlockParam[] = [];
  for (const block of response.content) {
    if (block.type === 'tool_use') {
      const result = await scalekit.actions.executeTool({
        toolName: block.name,
        identifier: 'user_123',
        toolInput: block.input as Record<string, unknown>,
      });
      toolResults.push({ type: 'tool_result', tool_use_id: block.id, content: JSON.stringify(result.data) });
    }
  }
  messages.push({ role: 'assistant', content: response.content });
  messages.push({ role: 'user', content: toolResults });
}
```
  ## Use MCP instead

Claude Desktop and other Anthropic-compatible MCP hosts connect directly to Scalekit MCP URLs. Add the URL to your MCP host config:

```json
{
  "mcpServers": {
    "scalekit": {
      "transport": "streamable-http",
      "url": "your-scalekit-mcp-url"
    }
  }
}
```

For programmatic use, connect via any MCP client library and pass tools to `anthropic.messages.create`. See [Connect an MCP client](/agentkit/mcp/connect-mcp-client/) for setup details and [Generate user MCP URLs](/agentkit/mcp/generate-user-urls/) to get the URL.

---

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