> ## Documentation Index
> Fetch the complete documentation index at: https://braintrust.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Cloudflare Agents

> Trace Cloudflare Agents tool calls in Braintrust to debug agent behavior, inspect tool inputs and outputs, and monitor errors

If you are a coding agent, prefer the Braintrust [`bt` CLI](/docs/reference/cli/quickstart) for repeatable, scriptable work: running evals, instrumenting code, querying logs, syncing data, managing functions, and configuring coding agents. Use the MCP server for reasoning over Braintrust data in conversation, and for capabilities the CLI doesn't cover, such as monitor views, alerts, and authoring evaluators, preprocessors, and facets.

[Cloudflare Agents](https://developers.cloudflare.com/agents/) are Durable Object–backed workers built with the `agents` npm package. Braintrust traces every `runAgentTool` call, capturing the agent class name, tool inputs, tool outputs, and errors.

<Note>
  For Cloudflare Workers deployments, use [manual instrumentation](#manual-instrumentation-typescript) with `wrapCloudflareAgent()`. The `--import` auto-instrumentation hook only runs under Node, not in the Cloudflare Workers runtime (`workerd`). See the [Cloudflare setup guide](/docs/sdks/typescript/install-and-instrument#cloudflare) for enabling `nodejs_compat` and flushing traces with `ctx.waitUntil()`.
</Note>

<View title="TypeScript" icon="https://img.logo.dev/typescriptlang.org?token=pk_BdcHD9e5SCW3j1rnJkNyMQ">
  <h2 id="setup-typescript">
    Setup
  </h2>

  Install Braintrust alongside the `agents` package, then set your API keys. Requires `agents` v0.17.0 or later.

  <Steps>
    <Step title="Install packages">
      <CodeGroup>
        ```bash pnpm theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
        pnpm add braintrust agents
        ```

        ```bash npm theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
        npm install braintrust agents
        ```
      </CodeGroup>
    </Step>

    <Step title="Set environment variables">
      ```bash title=".env" theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
      BRAINTRUST_API_KEY=<your-braintrust-api-key>

      # For organizations on the EU data plane, use https://api-eu.braintrust.dev
      # For self-hosted deployments, use your data plane URL
      # BRAINTRUST_API_URL=<your-braintrust-api-url>
      ```
    </Step>
  </Steps>

  <h2 id="manual-instrumentation-typescript">
    Manual instrumentation
  </h2>

  Manual instrumentation is the recommended approach for Cloudflare Workers. Call `wrapCloudflareAgent()` on the base `Agent` class at module scope so all subclasses inherit Braintrust tracing without any changes to your class definitions. Initialize the logger inside `fetch` with your `env` bindings, then pass `logger.flush()` to `ctx.waitUntil()` so buffered traces ship after the response returns.

  ```typescript title="cloudflare-agent-manual.ts" theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  import { initLogger, wrapCloudflareAgent } from "braintrust";
  import { Agent, routeAgentRequest } from "agents";

  interface Env {
    BRAINTRUST_API_KEY: string;
  }

  // Wrap the base class so all subclasses are instrumented
  wrapCloudflareAgent(Agent);

  export class MyAgent extends Agent {
    async onRequest(request: Request) {
      return new Response("Hello from agent");
    }
  }

  export default {
    async fetch(request: Request, env: Env, ctx: ExecutionContext) {
      const logger = initLogger({
        projectName: "cloudflare-agents-example", // Replace with your project name
        apiKey: env.BRAINTRUST_API_KEY,
      });

      try {
        return (
          (await routeAgentRequest(request, env)) ||
          new Response("Not found", { status: 404 })
        );
      } finally {
        ctx.waitUntil(logger.flush());
      }
    },
  };
  ```

  `wrapCloudflareAgent()` returns the same class it receives after patching its prototype. Calling it on the base `Agent` class instruments all subclasses without modifying your class definitions.

  Deploying to Cloudflare Workers requires the `nodejs_compat` compatibility flag and storing `BRAINTRUST_API_KEY` as a Wrangler secret. See the [Cloudflare setup guide](/docs/sdks/typescript/install-and-instrument#cloudflare) for the full deployment configuration.

  <h2 id="auto-instrumentation-typescript">
    Auto-instrumentation
  </h2>

  Auto-instrumentation patches the SDK at runtime without modifying your application code, but the `--import` hook only runs under Node (local development or tests), not in the Cloudflare Workers runtime. For a deployed Worker, use manual instrumentation above.

  <Steps>
    <Step title="Initialize Braintrust and define your agent">
      <CodeGroup>
        ```javascript title="cloudflare-agent-auto.js" theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
        import { initLogger } from "braintrust";
        import { Agent, routeAgentRequest } from "agents";

        initLogger({
          projectName: "cloudflare-agents-example", // Replace with your project name
          apiKey: process.env.BRAINTRUST_API_KEY,
        });

        export class MyAgent extends Agent {
          async onRequest(request) {
            return new Response("Hello from agent");
          }
        }

        export default {
          async fetch(request, env) {
            return (
              (await routeAgentRequest(request, env)) ||
              new Response("Not found", { status: 404 })
            );
          },
        };
        ```
      </CodeGroup>
    </Step>

    <Step title="Run with the import hook">
      ```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
      node --import braintrust/hook.mjs cloudflare-agent-auto.js
      ```

      <Warning>
        The `--import` hook only patches the SDK when your code runs under Node, such as local development or tests. It does not run in the Cloudflare Workers runtime (`workerd`), so a Worker deployed with Wrangler stays uninstrumented. To trace a deployed Worker, use [manual instrumentation](#manual-instrumentation-typescript) with `wrapCloudflareAgent()`.
      </Warning>

      The auto-instrumentation example uses plain JavaScript so `node --import` can run the file directly. The Braintrust APIs work the same in TypeScript projects — compile your TypeScript to JavaScript, then run the compiled file with the import hook.

      <Note>
        If you're using a bundler, see [Trace LLM calls](/docs/instrument/trace-llm-calls#auto-instrumentation) for plugin and loader setup.
      </Note>
    </Step>
  </Steps>

  <h2 id="what-traced-typescript">
    What Braintrust traces
  </h2>

  Braintrust captures:

  * Tool spans for each `runAgentTool` call, named after the agent class (for example, `MyAgent`).
  * Tool input passed to the agent tool call.
  * Tool output returned by the agent, or an error if the call fails.

  <h2 id="resources-typescript">
    Resources
  </h2>

  * [Cloudflare Agents documentation](https://developers.cloudflare.com/agents/)
  * [`agents` on npm](https://www.npmjs.com/package/agents)
  * [Trace LLM calls](/docs/instrument/trace-llm-calls)
</View>
