Using TengineAI from Cursor

Cursor doesn't have a native TengineAI connector. Instead, you call TengineAI directly from your code using the Anthropic Python SDK — Cursor becomes the editor where you write and run that code.

TengineAI exposes whatever tools you've registered in your project. The model calls them transparently, and TengineAI handles execution against your APIs.

Two authentication modes are available:

ModeWhen to use
API KeyAutomation, scripts, single-identity workflows
User-ScopedMulti-tenant apps where each user has their own session

Prerequisites

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

See Get Started in 5 Minutes to register your first tool.


Installation

Open a terminal in Cursor and install the Anthropic SDK:

pip install anthropic

For user-scoped mode, also install:

pip install PyJWT cryptography requests

Mode 1: API Key

All requests authenticate as the project. This is the fastest way to get started.

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 do you have access to?"}],
    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)

See Python Quick Start — API Key Mode for the full guide including multi-turn conversations and error handling.


Mode 2: User-Scoped Sessions

Each user gets their own MCP session. Your backend mints a short-lived session token per user, which carries member identity into every tool call.

import os
import time
import jwt
import requests
import anthropic

with open(os.environ["TENGINEAI_PRIVATE_KEY_PATH"]) as f:
    PRIVATE_KEY = f.read()

def get_session_token(user_id: str) -> str:
    now = int(time.time())
    assertion = jwt.encode(
        {
            "sub": user_id,
            "aud": f"tengine:project:{os.environ['TENGINEAI_PROJECT_ID']}",
            "iat": now,
            "exp": now + 60,
        },
        PRIVATE_KEY,
        algorithm="ES256",
        headers={"kid": os.environ["TENGINEAI_ASSERTION_KID"]},
    )

    response = requests.post(
        "https://app.tengine.ai/api/v1/mcp/session-token",
        headers={"Authorization": f"Bearer {os.environ['TENGINEAI_API_KEY']}"},
        json={"member_assertion": assertion},
        timeout=10,
    )
    response.raise_for_status()
    return response.json()["token"]


def chat_as_user(user_id: str, message: str) -> str:
    token = get_session_token(user_id)

    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": message}],
        mcp_servers=[
            {
                "type": "url",
                "url": "https://app.tengine.ai/mcp/",
                "name": "tengineai",
                "authorization_token": token,
            }
        ],
        betas=["mcp-client-2025-04-04"],
    )
    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)


print(chat_as_user("user_alice_123", "Run the contact lookup for ID c_001"))

See Python Quick Start — User-Scoped Mode for the full guide including token caching and multi-turn conversations.


Environment Variables

# Required for both modes
export ANTHROPIC_API_KEY="sk-ant-..."
export TENGINEAI_API_KEY="tengine_..."

# Required for user-scoped mode only
export TENGINEAI_PROJECT_ID="42"
export TENGINEAI_ASSERTION_KID="my-backend-v1"
export TENGINEAI_PRIVATE_KEY_PATH="/path/to/private_key.pem"

Cursor .env Setup

pip install python-dotenv
from dotenv import load_dotenv
load_dotenv()

Add .env to your .gitignore — never commit API keys.


Next Steps