> ## Documentation Index
> Fetch the complete documentation index at: https://arizeai-433a7140.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Scalekit Tracing

> Trace Scalekit AgentKit tool calls in Phoenix.

[Scalekit](https://docs.scalekit.com/agentkit/connectors/) runs tools for an agent. Add the setup below to an existing app to send those tool calls to Phoenix.

## Install

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
npm install @scalekit-sdk/node @arizeai/phoenix-otel
```

## Configure Environment

First, start Phoenix:

<Card>
  <Tabs>
    <Tab title="Local">
      ```bash theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
      uvx arize-phoenix serve
      ```

      No [uv](https://docs.astral.sh/uv/)? `pip install arize-phoenix && phoenix serve` does the same thing. See [Terminal setup](/docs/phoenix/environments#terminal) for customization.
    </Tab>

    <Tab title="Container">
      ```bash theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
      docker run -p 6006:6006 -p 4317:4317 arizephoenix/phoenix:latest
      ```

      Images are published to [Docker Hub](https://hub.docker.com/r/arizephoenix/phoenix). See [Docker](/docs/phoenix/self-hosting/deployment-options/docker) for volumes, PostgreSQL, and other options.
    </Tab>

    <Tab title="Self-Host">
      Run Phoenix on your own infrastructure, backed by PostgreSQL so traces persist beyond a single process. This is the option to reach for once Phoenix is shared across a team or environment.

      The [self-hosting guide](/docs/phoenix/self-hosting) covers [Kubernetes](/docs/phoenix/self-hosting/deployment-options/kubernetes), [Helm](/docs/phoenix/self-hosting/deployment-options/kubernetes-helm), [Railway](/docs/phoenix/self-hosting/deployment-options/railway), [AWS CloudFormation](/docs/phoenix/self-hosting/deployment-options/aws-with-cloudformation), [Google Cloud Run](/docs/phoenix/self-hosting/deployment-options/google-cloud-run), [Azure](/docs/phoenix/self-hosting/deployment-options/azure), and [Render](/docs/phoenix/self-hosting/deployment-options/render), plus authentication and configuration.
    </Tab>
  </Tabs>

  Phoenix serves its UI and OTLP HTTP on port **6006**, and OTLP gRPC on port **4317**. For a local instance that's [http://localhost:6006](http://localhost:6006). Leave it running while you work.
</Card>

Then create a `.env` file that points your app at it:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
PHOENIX_COLLECTOR_ENDPOINT=http://localhost:6006
PHOENIX_API_KEY=your-api-key # Optional, only if auth is enabled
PHOENIX_PROJECT_NAME=scalekit-agentkit
```

`PHOENIX_COLLECTOR_ENDPOINT` is the Phoenix server URL. `register()` appends `/v1/traces` when that path is missing.

Add the Scalekit credentials from Dashboard → Developers → API credentials to the same `.env` file:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
SCALEKIT_ENVIRONMENT_URL=https://your-env.scalekit.com
SCALEKIT_CLIENT_ID=your-client-id
SCALEKIT_CLIENT_SECRET=your-client-secret
```

## Setup

Call `register()` before the tool runs. It reads `PHOENIX_COLLECTOR_ENDPOINT` and `PHOENIX_API_KEY`. The run command loads `.env` with `--env-file` before the script starts. The project name is `PHOENIX_PROJECT_NAME`, or `scalekit-agentkit` when that variable is unset.

```typescript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
// instrumentation.ts
import { register } from "@arizeai/phoenix-otel";
import { ScalekitClient } from "@scalekit-sdk/node";

export const provider = register({
  projectName: process.env.PHOENIX_PROJECT_NAME ?? "scalekit-agentkit",
});

export const scalekit = new ScalekitClient(
  process.env.SCALEKIT_ENVIRONMENT_URL!,
  process.env.SCALEKIT_CLIENT_ID!,
  process.env.SCALEKIT_CLIENT_SECRET!,
);
```

Wrap `client.actions.executeTool` with `traceTool` from `@arizeai/phoenix-otel`. The span name is the tool name. The span records the call arguments and the result.

```typescript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
// traced-tools.ts
import { traceTool } from "@arizeai/phoenix-otel";
import type { ScalekitClient } from "@scalekit-sdk/node";

type ExecuteToolParams = Parameters<
  ScalekitClient["actions"]["executeTool"]
>[0];

export function createTracedToolExecutor(
  actions: Pick<ScalekitClient["actions"], "executeTool">
) {
  return (params: ExecuteToolParams) =>
    traceTool((toolParams: ExecuteToolParams) => actions.executeTool(toolParams), {
      name: params.toolName,
    })(params);
}
```

Then call a tool through it. `identifier` is the connected account the tool runs as.

```typescript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
// example.ts
import { provider, scalekit } from "./instrumentation.js";
import { createTracedToolExecutor } from "./traced-tools.js";

const executeTool = createTracedToolExecutor(scalekit.actions);

const result = await executeTool({
  toolName: "github_issue_get",
  connector: "github-connect",
  identifier: "test-user",
  toolInput: { owner: "octocat", repo: "Hello-World", issue_number: 1 },
});
console.log(result.data);

await provider.shutdown(); // flush batched spans before the script exits
```

<Note>
  A thrown error is recorded as status ERROR. A call that returns normally is status OK, including when the failure sits inside `result.data`. `traceTool` ends the span before the next line runs, so a later `setStatus` does not change it. The [demo](https://github.com/scalekit-developers/arize-agentkit-tracing-demo/blob/main/lib/traced-tools.ts) marks those resolved failures ERROR on a span it owns.
</Note>

## Running Your Application

The three files above are the example. From the directory that contains them:

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
npx tsx --env-file=.env example.ts
```

## Observe

Phoenix lists the turn under `PHOENIX_PROJECT_NAME`. In this example the tool span is the root span. A thrown error shows status ERROR. In the demo, the tool span and the model span are siblings under the agent span `run_agent`.

## Resources

<Card horizontal icon="github" href="https://github.com/scalekit-developers/arize-agentkit-tracing-demo" title="Scalekit tracing demo" description="Next.js app with its own Scalekit tracer." />

The demo is a separate app. Run it with `npm run dev`. Its tracer is in [`lib/arize.ts`](https://github.com/scalekit-developers/arize-agentkit-tracing-demo/blob/main/lib/arize.ts), and it calls `client.tools.executeTool`. Resolved error payloads are marked ERROR in [`lib/traced-tools.ts`](https://github.com/scalekit-developers/arize-agentkit-tracing-demo/blob/main/lib/traced-tools.ts).

Scalekit connectors: [https://docs.scalekit.com/agentkit/connectors/](https://docs.scalekit.com/agentkit/connectors/).
