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:
| Mode | When to use |
|---|---|
| API Key | Automation, scripts, single-identity workflows |
| User-Scoped | Multi-tenant apps where each user has their own session |
tengine_...)See Get Started in 5 Minutes to register your first tool.
Open a terminal in Cursor and install the Anthropic SDK:
pip install anthropic
For user-scoped mode, also install:
pip install PyJWT cryptography requests
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.
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.
# 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"
.env Setuppip install python-dotenv
from dotenv import load_dotenv
load_dotenv()
Add .env to your .gitignore — never commit API keys.