Skip to main content
Requires: @anthropic-ai/claude-agent-sdk v0.2.0+ as a peer dependency. Works with the query() function for one-shot and multi-turn interactions.

What Gets Tracked Automatically

Sessions

Created on init, completed on result — with agent name, user ID, and metadata.

Tool Calls

Every tool execution (Bash, Read, Write, etc.) with input, output, and tool use ID.

Tokens & Cost

Prompt tokens, completion tokens, total tokens, and estimated cost in USD.

Conversation Threading

Group related sessions with convoId — multi-turn conversations appear linked.

Errors

Failed tool calls, errored sessions, and generator exceptions — all recorded.

Duration

Wall-clock time from start to result, plus API-side duration when available.

Installation

npm install @sentrial/sdk @anthropic-ai/claude-agent-sdk

Quick Start

Wrap the query() function once, then use it exactly like normal.
import { query } from '@anthropic-ai/claude-agent-sdk';
import { SentrialClient, wrapClaudeAgent } from '@sentrial/sdk';

// 1. Create a Sentrial client
const sentrial = new SentrialClient({
  apiKey: process.env.SENTRIAL_API_KEY,
});

// 2. Wrap query()
const trackedQuery = wrapClaudeAgent(query, {
  client: sentrial,
  defaultAgent: 'my-agent',
  userId: 'user-123',
});

// 3. Use normally — everything is tracked
for await (const message of trackedQuery({
  prompt: 'Fix the failing tests in src/auth.ts',
  options: {
    maxTurns: 10,
    permissionMode: 'bypassPermissions',
  },
})) {
  if (message.type === 'assistant') {
    // Handle assistant messages
  }
}
// Session auto-completed with tokens, cost, duration, and all tool calls

Configuration Options

const trackedQuery = wrapClaudeAgent(query, {
  client: sentrial,           // required — SentrialClient instance
  defaultAgent: 'my-agent',   // optional — agent name for grouping (default: 'claude-agent')
  userId: 'user-123',         // optional — ties sessions to your end users (default: 'anonymous')
  convoId: 'convo-abc',       // optional — group sessions into a conversation thread
  extraMetadata: {             // optional — merged into every session's metadata
    environment: 'production',
    version: '1.2.0',
  },
});
Fail-Safe by Default — If Sentrial is unreachable, all messages pass through unchanged. Your agent never breaks due to tracking failures.

Conversation Threading

Use convoId to group related sessions into a conversation. Each call to trackedQuery() creates a new session, but they appear linked in the dashboard.
const convoId = `user-${userId}-${Date.now()}`;

const trackedQuery = wrapClaudeAgent(query, {
  client: sentrial,
  defaultAgent: 'code-assistant',
  userId,
  convoId,
});

// Session 1: Explore the codebase
for await (const msg of trackedQuery({
  prompt: 'List all API routes and their handlers',
})) { /* ... */ }

// Session 2: Follow-up (same convoId, linked in dashboard)
for await (const msg of trackedQuery({
  prompt: 'Add rate limiting to the /api/users endpoint',
})) { /* ... */ }

How Tool Tracking Works

The wrapper uses PostToolUse and PostToolUseFailure hooks to capture every tool execution. Hooks fire asynchronously and never block the agent. A session-ready gate ensures hooks wait for session creation before tracking.
// No extra code needed — tool calls are tracked automatically
for await (const message of trackedQuery({
  prompt: 'Read package.json and tell me the project name',
  options: {
    allowedTools: ['Bash', 'Read', 'Glob'],
  },
})) {
  // Each tool call (Read, Bash, etc.) is recorded as an event
  // with input args, output, and execution metadata
}
In the dashboard, each tool call appears as an event under the session timeline.

Error Handling

If the agent errors or the generator throws, the session is automatically marked as failed with the error message.
try {
  for await (const message of trackedQuery({
    prompt: 'Deploy to production',
  })) {
    // ...
  }
} catch (error) {
  // Session already marked as failed in Sentrial
  // with failure_reason = error.message
  console.error(error);
}

Full Production Example

import { query } from '@anthropic-ai/claude-agent-sdk';
import { SentrialClient, wrapClaudeAgent } from '@sentrial/sdk';

const sentrial = new SentrialClient({
  apiKey: process.env.SENTRIAL_API_KEY!,
});

async function runAgent(userPrompt: string, userId: string) {
  const convoId = `session-${userId}-${Date.now()}`;

  const trackedQuery = wrapClaudeAgent(query, {
    client: sentrial,
    defaultAgent: 'code-review-agent',
    userId,
    convoId,
    extraMetadata: {
      environment: process.env.NODE_ENV,
    },
  });

  let result = '';

  for await (const message of trackedQuery({
    prompt: userPrompt,
    options: {
      model: 'claude-sonnet-4-20250514',
      maxTurns: 15,
      permissionMode: 'bypassPermissions',
      allowedTools: ['Bash', 'Read', 'Write', 'Glob', 'Grep'],
    },
  })) {
    if (message.type === 'result') {
      result = message.result ?? '';
    }
  }

  return result;
}

What You See in the Dashboard

Session Overview

Agent name, user ID, conversation thread, status, duration, cost.

Input / Output

The prompt and Claude’s final response.

Tool Call Timeline

Every Bash, Read, Write, Glob call — with input, output, and tool use ID.

Token & Cost Breakdown

Prompt tokens, completion tokens, total, estimated USD cost.

Next Steps