Python Quick Start — API Key Mode

Connect to TengineAI programmatically using the Anthropic Python SDK and a project API key.

Note: TengineAI is accessed through MCP-compatible model SDKs. This guide uses the Anthropic Python SDK as a concrete example. No TengineAI-specific SDK is required.

This guide assumes you have at least one tool registered in your project. If you haven't done that yet, start with Get Started in 5 Minutes.

For per-user attribution, see Python Quick Start — User-Scoped Mode.


Prerequisites

  • Python 3.8+
  • An Anthropic API key
  • A TengineAI project with at least one tool enabled
  • A TengineAI project API key (tengine_...)

Installation

pip install anthropic

Connect and Call a Tool

import json
import os
import anthropic

client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])

response = client.beta.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    messages=[
        {
            "role": "user",
            "content": "Fetch post number 3 and tell me what it's about.",
        }
    ],
    mcp_servers=[
        {
            "type": "url",
            "url": "https://app.tengine.ai/mcp/",
            "name": "tengineai",
            "authorization_token": os.environ["TENGINEAI_API_KEY"],
        }
    ],
    betas=["mcp-client-2025-04-04"],
)

for block in response.content:
    if block.type == "text":
        print(block.text)
    elif block.type == "mcp_tool_use":
        print(
            f"[tool_use] server={block.server_name} tool={block.name} id={block.id} "
            f"input={json.dumps(block.input, default=str)}"
        )
    elif block.type == "mcp_tool_result":
        print(
            f"[tool_result] id={block.tool_use_id} is_error={getattr(block, 'is_error', False)}"
        )
        print(block.content)

This example assumes posts-jsonplaceholder-get_post is registered in your project (from Get Started in 5 Minutes). Substitute any tool name and prompt that matches your setup.


What Actually Happened

  1. Tool discovery — The SDK fetched the list of tools enabled for your project from TengineAI
  2. Tool selection — The model chose the appropriate tool based on the prompt
  3. Request rendered — TengineAI rendered the URL template with the model-provided arguments
  4. Execution — TengineAI called your registered API endpoint with the appropriate auth headers
  5. Result returned — The API response was passed back to the model as tool output
  6. Model responded — Claude synthesized the response into natural language

Your application code never made a direct API call. TengineAI executed the tool against the registered endpoint.


Environment Variables

import json
import os
import anthropic

client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])

response = client.beta.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    messages=[{"role": "user", "content": "What tools are available?"}],
    mcp_servers=[
        {
            "type": "url",
            "url": "https://app.tengine.ai/mcp/",
            "name": "tengineai",
            "authorization_token": os.environ["TENGINEAI_API_KEY"],
        }
    ],
    betas=["mcp-client-2025-04-04"],
)

for block in response.content:
    if block.type == "text":
        print(block.text)
    elif block.type == "mcp_tool_use":
        print(
            f"[tool_use] server={block.server_name} tool={block.name} id={block.id} "
            f"input={json.dumps(block.input, default=str)}"
        )
    elif block.type == "mcp_tool_result":
        print(
            f"[tool_result] id={block.tool_use_id} is_error={getattr(block, 'is_error', False)}"
        )
        print(block.content)
export ANTHROPIC_API_KEY="sk-ant-..."
export TENGINEAI_API_KEY="tengine_..."

Multi-Turn Conversations

Pass the full message history and include mcp_servers on each call:

import os
import anthropic

client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])

mcp_servers = [
    {
        "type": "url",
        "url": "https://app.tengine.ai/mcp/",
        "name": "tengineai",
        "authorization_token": os.environ["TENGINEAI_API_KEY"],
    }
]

messages = []

def get_text_from_response(response) -> str:
    text_blocks = [block.text for block in response.content if block.type == "text"]
    if not text_blocks:
        raise ValueError("Model response did not contain any text blocks.")
    return "\n".join(text_blocks)

def chat(user_message: str) -> str:
    messages.append({"role": "user", "content": user_message})

    response = client.beta.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=1024,
        messages=messages,
        mcp_servers=mcp_servers,
        betas=["mcp-client-2025-04-04"],
    )

    reply = get_text_from_response(response)
    messages.append({"role": "assistant", "content": reply})
    return reply

print(chat("Fetch post number 1."))
print(chat("Now fetch post number 2 and compare it to the first."))

Error Handling

import json
import anthropic

try:
    response = client.beta.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=1024,
        messages=[{"role": "user", "content": "Run the lookup tool"}],
        mcp_servers=[
            {
                "type": "url",
                "url": "https://app.tengine.ai/mcp/",
                "name": "tengineai",
                "authorization_token": os.environ["TENGINEAI_API_KEY"],
            }
        ],
        betas=["mcp-client-2025-04-04"],
    )
    for block in response.content:
        if block.type == "text":
            print(block.text)
        elif block.type == "mcp_tool_use":
            print(
                f"[tool_use] server={block.server_name} tool={block.name} id={block.id} "
                f"input={json.dumps(block.input, default=str)}"
            )
        elif block.type == "mcp_tool_result":
            print(
                f"[tool_result] id={block.tool_use_id} is_error={getattr(block, 'is_error', False)}"
            )
            print(block.content)
except anthropic.AuthenticationError:
    print("Invalid API key — check TENGINEAI_API_KEY")
except anthropic.PermissionDeniedError:
    print("Tool not enabled for this project")
except anthropic.RateLimitError:
    print("Rate limit exceeded — back off and retry")

Next Steps