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 →
Use this file to discover all available pages before exploring further.
Observability
Instrument your agents with OpenTelemetry using the SDK’s hooks system to capture traces for every agent turn and tool use.
AI Router Beta
Route your Claude calls through the AI Router 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())
The Anthropic SDK is the native client for Claude models. Connect it to Orq.ai’s AI Router with a single base_url change and no modifications to your existing agent logic.
import Anthropic from '@anthropic-ai/sdk';const client = new Anthropic({ apiKey: process.env.ORQ_API_KEY, baseURL: 'https://my.orq.ai/v3/anthropic',});const stream = client.messages.stream({ model: 'anthropic/claude-sonnet-4-6', max_tokens: 1024, messages: [ { role: 'user', content: 'Write a haiku about AI routing.' }, ],});stream.on('text', (text) => { process.stdout.write(text);});await stream.finalMessage();
Python
import osimport anthropicclient = anthropic.Anthropic( api_key=os.environ["ORQ_API_KEY"], base_url="https://my.orq.ai/v3/anthropic",)with client.messages.stream( model="anthropic/claude-sonnet-4-6", max_tokens=1024, messages=[{"role": "user", "content": "Write a haiku about AI routing."}],) as stream: for text in stream.text_stream: print(text, end="", flush=True)
Route Claude Code through the AI Router 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.