Traces
Cursor SDK Traces
Trace Cursor agent runs, streamed messages, wait results, and tool calls.
Inference platform instruments the Cursor SDK in TypeScript. Initialize tracing before
calling Agent.create() so the Agent static methods and the returned
SDKAgent / Run objects are patched before any run is observed.
Use this guide for Node applications that run programmatic Cursor agents with
@cursor/sdk. Cursor publishes a TypeScript SDK only, so there is no Python
equivalent for this integration.
Cursor's SDK streams runs over HTTP/2 via @connectrpc/connect-node. Run
Inference Tracing-enabled Cursor apps under Node (>= 22). Bun's HTTP/2 client currently
emits NGHTTP2_FRAME_SIZE_ERROR mid-stream against api.cursor.com.
What Is Captured
- One AGENT span named
Cursor Agent Runper observed run, started lazily whenrun.stream(),run.wait(),run.conversation(), orrun.cancel()is first called cursor.agent_id,cursor.run_id,cursor.run_status,cursor.duration_ms, request IDs, and model metadata (llm.model_name,llm.invocation_parameters)input.valuefromagent.send()andoutput.valuefrom streamed assistant text,run.wait()results, orrun.conversation()turns- TOOL child spans for streamed
tool_callevents, includingtool.name,tool_call.id, JSON arguments, and tool results - Aggregate counts:
agent.tool_call_count,agent.llm_call_count - Error status and exception details when run streaming, waiting, or cancellation fails
Install
bun add @inference/tracing @cursor/sdkTypeScript Cursor Agent Run
Initialize tracing before creating Cursor agents. Auto-instrumentation detects
@cursor/sdk when it is installed in the project, so the smoothest path is just
setup().
import { Agent } from "@cursor/sdk";
import { setup } from "@inference/tracing";
const tracing = await setup({
serviceName: "cursor-agent-runner",
});
const agent = await Agent.create({
apiKey: process.env.CURSOR_API_KEY!,
model: { id: "composer-2" },
local: { cwd: process.cwd() },
});
try {
const run = await agent.send("Summarize what this repository does");
for await (const event of run.stream()) {
console.log(event.type);
}
const result = await run.wait();
console.log(`run ${run.id} ${result.status}`);
} finally {
await agent[Symbol.asyncDispose]();
await tracing.shutdown();
}For manual initialization, pass the SDK namespace into the granular entry point:
import * as CursorSdk from "@cursor/sdk";
import { setup } from "@inference/tracing";
import { instrumentCursorSdk } from "@inference/tracing/cursor-sdk";
const tracing = await setup({ autoInstrument: false });
instrumentCursorSdk(CursorSdk, tracing);Lazy Span Lifecycle
The AGENT span starts when the application first observes a run through
run.stream(), run.wait(), run.conversation(), or run.cancel(), not when
agent.send() returns. This avoids leaking open spans for fire-and-handoff
workflows where one process kicks off a Cursor run and another process observes
it later. Each unique observed run produces one AGENT span; observing the same
run twice in the same process does not double-emit.
Stable Agent Identity
Cursor's SDK exposes its own run and agent identifiers, which Inference platform preserves
as cursor.run_id and cursor.agent_id. For the canonical Agents dashboard
grouping key, wrap the Cursor run you operate with agentSpan() and pass your
stable product ID as agentId.
import { agentSpan } from "@inference/tracing";
await agentSpan(
{
agentId: "cursor-repo-maintainer",
agentName: "Cursor Repo Maintainer",
spanName: "cursor-repo-maintainer.run",
sessionId: "conversation-repo-tour",
role: "code-maintenance",
system: "cursor",
},
async (span) => {
const input = "Summarize what this repository does";
span.setInput(input);
const run = await agent.send(input);
const result = await run.wait();
span.setOutput(result);
},
);Verify in the Inference platform
Filter traces by your service.name (for example cursor-agent-runner). A
successful run should show one Cursor Agent Run AGENT span with cursor.run_id
and the model name, plus nested TOOL spans for each tool call the agent
produced.
For short-lived scripts, always call tracing.shutdown() before process exit so
batched spans are flushed to the Inference platform.