Anthropic
Build an Anthropic agent with Scalekit-authenticated tools. Scalekit returns tool schemas in Anthropic's native format; no conversion needed.
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
Section titled “Install”pip install scalekit-sdk-python anthropicnpm install @scalekit-sdk/node @anthropic-ai/sdkInitialize
Section titled “Initialize”import osimport scalekit.clientimport anthropicfrom 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.actionsclient = anthropic.Anthropic()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
Section titled “Connect the user to Gmail”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...")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 for production auth handling.
Run the agent
Section titled “Run the agent”Fetch tools scoped to this user, then run the full Claude tool-use loop:
# Fetch tools scoped to this userscoped_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 loopmessages = [{"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})// Fetch tools scoped to this userconst { 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 loopconst 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
Section titled “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:
{ "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 for setup details and Generate user MCP URLs to get the URL.