Orq MCP is live: Use natural language to interrogate traces, spot regressions, and experiment your way to optimal AI configurations. Available in Claude Desktop, Claude Code, Cursor, and more. Start now →
Instrument the Claude Agent SDK with OpenTelemetry and route its model calls through the orq.ai AI Gateway. Capture agent traces, tool use, and cost tracking.
Observability
Instrument your agents with OpenTelemetry using the SDK’s hooks system to capture traces for every agent turn and tool use.
AI Gateway Beta
Route your Claude calls through the AI Gateway with a single base URL change. Zero vendor lock-in: always run on the best model at the lowest cost for your use case.
The Claude Agent SDK (claude-agent-sdk) drives the Claude CLI as a programmable agent supporting multi-turn conversations, tool use, and MCP servers. Use the SDK’s built-in hooks system to attach OpenTelemetry instrumentation at key execution points. Every tool invocation becomes a span, and the full agent workflow is captured as a trace in orq.ai without modifying your agent logic.
Spread the imported SDK module into a mutable namespace, then call ClaudeAgentSDKInstrumentation.manuallyInstrument(...) before sdk.start(). The instrumentation patches every query() call, tool use, and subagent into spans automatically.
TypeScript
import { NodeSDK } from '@opentelemetry/sdk-node';import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';import { ClaudeAgentSDKInstrumentation } from '@arizeai/openinference-instrumentation-claude-agent-sdk';import * as ClaudeAgentSDKModule from '@anthropic-ai/claude-agent-sdk';const ClaudeAgentSDK = { ...ClaudeAgentSDKModule };const instrumentation = new ClaudeAgentSDKInstrumentation();instrumentation.manuallyInstrument(ClaudeAgentSDK);const sdk = new NodeSDK({ traceExporter: new OTLPTraceExporter({ url: 'https://api.orq.ai/v2/otel/v1/traces', headers: { Authorization: `Bearer ${process.env.ORQ_API_KEY}`, }, }), instrumentations: [instrumentation],});sdk.start();const prompt = 'What is the capital of France?';console.log(`User: ${prompt}\n`);for await (const message of ClaudeAgentSDK.query({ prompt })) { if ('result' in message && typeof message.result === 'string') { console.log(`Assistant: ${message.result}`); }}await sdk.shutdown();console.log('\nTraces exported to orq.ai. View them at https://my.orq.ai');
Call ClaudeAgentSDKInstrumentor().instrument() before any agent call. The instrumentor wraps every tool invocation, LLM turn, and subagent in spans automatically. Drive the agent via ClaudeSDKClient (instead of the standalone query() generator) and wrap the call in a root agent-workflow span to stamp the prompt and the final cost.
Python
import asyncioimport osfrom claude_agent_sdk import ( ClaudeAgentOptions, ClaudeSDKClient, AssistantMessage, TextBlock, ResultMessage,)from openinference.instrumentation.claude_agent_sdk import ClaudeAgentSDKInstrumentorfrom opentelemetry.sdk.trace import TracerProviderfrom opentelemetry.sdk.trace.export import BatchSpanProcessorfrom opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporterfrom opentelemetry import tracetracer_provider = TracerProvider()tracer_provider.add_span_processor( BatchSpanProcessor( OTLPSpanExporter( endpoint="https://api.orq.ai/v2/otel/v1/traces", headers={"Authorization": f"Bearer {os.environ['ORQ_API_KEY']}"}, ) ))trace.set_tracer_provider(tracer_provider)ClaudeAgentSDKInstrumentor().instrument(tracer_provider=tracer_provider)tracer = trace.get_tracer(__name__)async def main(): options = ClaudeAgentOptions( model="sonnet", system_prompt="You are a helpful coding assistant.", max_turns=3, allowed_tools=["Read", "Bash"], ) prompt = "What Python version is installed on this system?" print(f"User: {prompt}\n") with tracer.start_as_current_span("agent-workflow") as span: span.set_attribute("agent.prompt", prompt) async with ClaudeSDKClient(options=options) as client: await client.query(prompt) async for message in client.receive_response(): if isinstance(message, AssistantMessage): for block in message.content: if isinstance(block, TextBlock): print(f"Assistant: {block.text}") elif isinstance(message, ResultMessage): span.set_attribute("agent.total_cost_usd", message.total_cost_usd or 0) span.set_attribute("agent.num_turns", message.num_turns) print(f"\nCost: ${message.total_cost_usd or 0:.6f} | Turns: {message.num_turns}") tracer_provider.force_flush() print("\nTraces exported to orq.ai. View them at https://my.orq.ai")asyncio.run(main())
Route the Claude Agent SDK’s model calls through Orq.ai’s AI Gateway without changing any agent logic. The SDK drives the Claude CLI, which reads ANTHROPIC_BASE_URL and ANTHROPIC_AUTH_TOKEN from the environment, so pointing those variables at the gateway routes every turn through Orq.ai.
For the raw Claude Messages API without the agent runtime, see the Anthropic SDK integration.
Set the following environment variables before running the agent:
export ANTHROPIC_BASE_URL="https://api.orq.ai/v3/anthropic"export ANTHROPIC_AUTH_TOKEN="$ORQ_API_KEY"export ANTHROPIC_API_KEY="" # set empty so the SDK does not call the Anthropic API directlyexport ANTHROPIC_MODEL="anthropic/claude-sonnet-4-6" # the anthropic/ prefix is required
With the environment variables set, every agent run routes through the AI Gateway with no change to the calling code:
TypeScript
Python
TypeScript
import { query } from '@anthropic-ai/claude-agent-sdk';const prompt = 'What is the capital of France?';for await (const message of query({ prompt })) { if ('result' in message && typeof message.result === 'string') { console.log(message.result); }}
Python
import asynciofrom claude_agent_sdk import ( ClaudeSDKClient, AssistantMessage, TextBlock,)async def main(): async with ClaudeSDKClient() as client: await client.query("What is the capital of France?") async for message in client.receive_response(): if isinstance(message, AssistantMessage): for block in message.content: if isinstance(block, TextBlock): print(block.text)asyncio.run(main())
Route Claude Code through the AI Gateway using environment variables. Integrate Claude Code with our MCP to access 20+ tools and actions on the platform.
Claude Desktop
Connect your Orq.ai workspace to Claude Desktop using the MCP integration.