When the agent runs inside your application instead of an IDE, declare DataDam as a function-calling tool. The pattern is identical across providers: define the tool, let the model emit a call, forward the arguments to the proxy, return the response.
Anthropic Messages API (tool_use)
Define DataDam as a tool. The model emits a tool_use block; your application code POSTs to /:source/query and returns the row count plus rows in the tool_result.
import os
from anthropic import Anthropic
client = Anthropic()
PROXY = "https://proxy.acme.example"
KEY = os.environ["DATADAM_API_KEY"]
datadam_tool = {
"name": "query_warehouse",
"description": "Run a governed SQL query against the production warehouse.",
"input_schema": {
"type": "object",
"properties": {
"sql": {"type": "string", "description": "Read-only SQL"},
},
"required": ["sql"],
},
}
response = client.messages.create(
model="claude-opus-4-7",
max_tokens=2048,
tools=[datadam_tool],
messages=[{"role": "user", "content": "Top customers by revenue this quarter."}],
)
# When response.content carries a tool_use block, forward it to DataDam:
import httpx
if response.stop_reason == "tool_use":
tu = next(b for b in response.content if b.type == "tool_use")
result = httpx.post(
f"{PROXY}/warehouse/query",
json={"sql": tu.input["sql"]},
headers={"Authorization": f"Bearer {KEY}"},
timeout=30.0,
).json()
# Send result back to Claude as a tool_result message and resume.
OpenAI Chat Completions (function calling)
OpenAI's function-calling shape. Same idea as Anthropic tool_use: declare the tool, intercept the function call, forward to the proxy.
import os
from openai import OpenAI
import httpx
client = OpenAI()
PROXY = "https://proxy.acme.example"
KEY = os.environ["DATADAM_API_KEY"]
datadam_tool = {
"type": "function",
"function": {
"name": "query_warehouse",
"description": "Run a governed SQL query against the production warehouse.",
"parameters": {
"type": "object",
"properties": {
"sql": {"type": "string"},
},
"required": ["sql"],
},
},
}
response = client.chat.completions.create(
model="gpt-5",
tools=[datadam_tool],
messages=[{"role": "user", "content": "Top customers by revenue this quarter."}],
)
call = response.choices[0].message.tool_calls[0]
import json
args = json.loads(call.function.arguments)
result = httpx.post(
f"{PROXY}/warehouse/query",
json={"sql": args["sql"]},
headers={"Authorization": f"Bearer {KEY}"},
timeout=30.0,
).json()
OpenAI Responses API
The Responses API supercedes Chat Completions for new builds. Same wire protocol on our side; the SDK shape differs.
import os
from openai import OpenAI
client = OpenAI()
PROXY = "https://proxy.acme.example"
KEY = os.environ["DATADAM_API_KEY"]
response = client.responses.create(
model="gpt-5",
tools=[
{
"type": "function",
"name": "query_warehouse",
"description": "Governed SQL against production warehouse.",
"parameters": {
"type": "object",
"properties": {"sql": {"type": "string"}},
"required": ["sql"],
},
}
],
input="Top customers by revenue this quarter.",
)
LangChain Tool
A LangChain Tool wrapper around the proxy. Drop it into any agent constructor.
import os
import httpx
from langchain.tools import tool
PROXY = "https://proxy.acme.example"
KEY = os.environ["DATADAM_API_KEY"]
@tool
def query_warehouse(sql: str) -> dict:
"""Run a governed SQL query against the production warehouse."""
return httpx.post(
f"{PROXY}/warehouse/query",
json={"sql": sql},
headers={"Authorization": f"Bearer {KEY}"},
timeout=30.0,
).json()
Vercel AI SDK
TypeScript wrapper for the Vercel AI SDK's tool primitive. Works with streamText / generateText alongside any LLM provider the SDK supports.
import { tool } from "ai";
import { z } from "zod";
const PROXY = "https://proxy.acme.example";
const KEY = process.env.DATADAM_API_KEY!;
export const queryWarehouse = tool({
description: "Run a governed SQL query against the production warehouse.",
parameters: z.object({
sql: z.string().describe("Read-only SQL statement"),
}),
execute: async ({ sql }) => {
const r = await fetch(`${PROXY}/warehouse/query`, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${KEY}`,
},
body: JSON.stringify({ sql }),
});
if (!r.ok) throw new Error(`DataDam denied: ${r.status}`);
return r.json();
},
});