Skip to main content
moda-claude-agent-sdk is a separate PyPI package that instruments the Claude Agent SDK (claude-agent-sdk) for Python. The Claude Agent SDK runs Claude Code as a subprocess rather than calling the Anthropic API from your process, so the Anthropic instrumentation in moda-ai never sees those calls — this package wraps ClaudeSDKClient directly instead. It is Python only; there is no Node.js equivalent.

Prerequisites

  • Python 3.10 or later
  • The moda-ai and claude-agent-sdk packages
  • A Moda API key, created at Settings → Ingestion keys (see Authentication)

Set up

1

Install all three packages

moda-claude-agent-sdk is not bundled with moda-ai — it must be installed explicitly.
2

Initialize Moda and run the agent

Call moda.init() before constructing ClaudeSDKClient. No other wiring is needed: moda.init() activates the instrumentation automatically when both packages are installed.
agent.py
3

Verify in the dashboard

Open Conversations in the dashboard. Within minutes you should see a conversation with ID session_8f2a containing your prompt as a user message and the agent’s replies as assistant messages, with token counts attached.

How it works

The package wraps two methods on ClaudeSDKClient:
  • query() — captures the prompt.
  • receive_response() — wraps the returned async generator; messages pass through unchanged while token usage, completions, tool-call counts, and agent metadata accumulate.
Each query() / receive_response() cycle produces one span (claude_agent.chat) carrying the prompt, the assistant completions from that run, token usage, and agent metadata. Prompt content is captured up to 4,000 characters and each assistant completion up to 8,000 characters.
Token usage comes from the ResultMessage at the end of the stream. If your code breaks out of receive_response() early, the run is still recorded but token counts are missing. Always consume the generator to completion. With ClaudeAgentOptions(include_partial_messages=True), usage is also accumulated from streaming events as a secondary source.

Conversation grouping

Each agent run is a separate trace, so without an explicit conversation ID every run lands in its own conversation. Set moda.conversation_id (or use the with moda.set_conversation_id(...) context manager) before running the agent so that multi-turn sessions group together:
multi_turn.py
The agent’s own session ID is recorded as the claude_agent.session_id attribute, but it is not used for conversation grouping — only moda.conversation_id is.

What gets captured

Streaming partial messages (include_partial_messages=True) and tool use are captured; assistant text streamed in deltas is assembled per turn.

Troubleshooting

Next steps

  • Moda SDK for Python — init options, environment variables, and context APIs.
  • Anthropic — auto-instrumentation for direct Anthropic API calls.
  • Conversations — how agent runs appear in the dashboard.
  • Data model — how conversations, messages, and signals relate.