---
title: Bring your own agent
description: Your code, your process, your keys — in the same comparison as Claude Code.
---

Your agent stays where it is. You do not deploy it here, you do not expose a
port, and you do not rewrite it for us. You export it with the SDK and run one
command; the CLI dials Redline, registers what you exported, claims runs
launched at it, executes your function locally, and streams the record back
while it works.

Because the connection is outbound, it works from a laptop behind NAT — and your
code and your API keys never leave your machine. What arrives here is the record
of what the agent did.

## Connect it

**TypeScript**

1. **Install and scaffold**

    In your agent's repository:

    ```bash
    npm i -D @redlineai/sdk
    npx redline init
    ```

    `init` writes two files: `redline.config.ts` (the connection) and
    `redline/my-agent.ts` (your agent's doorway).

2. **Replace the TODO with one call to your agent**

    ```ts title="redline/my-agent.ts"
    import { defineAgent } from "@redlineai/sdk";
    import { yourAgent } from "../src/agent";   // your existing code, unchanged

    export const myAgent = defineAgent({
      id: "my-agent",
      name: "My Agent",
      run: (task) => yourAgent(task.prompt),   // the one line that is yours
    });
    ```

    `task.prompt` is the experiment's instructions. Return your final answer as
    a string. That is the whole integration — do not restructure your agent
    around us.

3. **Create a runner key**

    On the **Agents** page, open *Connect your agent* and press **create key**.
    It is shown once.

    ```bash
    export REDLINE_API_KEY=rl_…
    ```

    The key proves the process in your repository belongs to this project. Do
    not commit it.

4. **Connect**

    ```bash
    npx redline dev
    ```

    Success is the line `connected — <id> registered and online`, and your agent
    appearing on the Agents page with a green dot. Leave it running: runs
    execute in this process when an experiment is launched at your agent.

**Python**

1. **Install and scaffold**

    In your agent's repository, inside its virtualenv if it has one:

    ```bash
    pip install redlineai-sdk
    redline init
    ```

    `init` writes `agents.py` — your agent's doorway. It must be named
    `agents.py`, not `redline.py`, which would shadow the SDK package.

2. **Replace the TODO with one call to your agent**

    ```python title="agents.py"
    from redline import agent
    from my_app.agent import your_agent   # your existing code, unchanged

    @agent(id="my-agent", name="My Agent")
    def run(task, ctx):
        return your_agent(task.prompt)    # the one line that is yours
    ```

    If your entry point is async, run it: `asyncio.run(your_agent(task.prompt))`.
    If it streams, collect the streamed text and return the whole of it.

3. **Create a runner key**

    On the **Agents** page, open *Connect your agent* and press **create key**.

    ```bash
    export REDLINE_API_KEY=rl_…
    ```

4. **Connect**

    ```bash
    redline dev
    ```

    Leave it running.

> **Let a coding agent do it**
>
> The *Connect your agent* panel has a **Copy instructions for a coding agent**
> button. It copies the whole job — the commands, the wrapper contract, the edge
> cases, and how to verify it worked — with your runner key already substituted
> in. Paste it into Claude Code or Codex inside that repository and it will do
> all four steps.

## What lands in the transcript

Most of it, without you writing anything.

If your agent uses a framework that speaks OpenTelemetry — the Vercel AI SDK,
LangChain, Pydantic AI (with `pip install redlineai-sdk[otel]`) — the CLI installs
a span processor in your process, and your model calls and tool calls appear in
the run's transcript by themselves.

`ctx` exists for what the spans do not say, and every method on it is optional:

```ts
run: async (task, ctx) => {
  ctx.thinking("Reading the brief");
  ctx.tool("search", { q: "flaky spec" });
  ctx.toolResult("search", results);
  ctx.artifact("plan.md", plan);
  ctx.usage(tokens, costCents);
  if (ctx.cancelled) return "stopped";
  return answer;
}
```

See the [SDK reference](/agents/sdk-reference) for the full surface.

## Attached tools arrive by themselves

When an experiment attaches an **MCP server**, its tools appear in your agent's
own tool list — no line of yours. The SDK wraps the few places that both declare
tools to a model and execute the calls that come back:

| Framework | Wrapped |
|---|---|
| Vercel AI SDK | `generateText`, `streamText`, `Agent` |
| LangGraph | `createReactAgent` |
| LangChain | `createToolCallingAgent`, `createReactAgent` |
| Pydantic AI (Python) | `Agent(...)` |
| LangChain (Python) | `create_tool_calling_agent` |

If your agent builds its own loop, or the wrapper cannot reach it, ask for the
tools explicitly:

```ts
import { redlineTools } from "@redlineai/sdk";

const attached = await redlineTools(task);
const { text } = await generateText({
  model, prompt: task.prompt,
  tools: { ...myTools, ...attached.tools },
});
await attached.close();
```

**Skills** need none of this — they arrive inside `task.prompt` as text.

## What Redline will not do to your machine

> **Warning**
>
> Attaching a **CLI**, an **SDK package** or a **plugin** means installing
> software. On a catalog agent that happens inside a disposable container. On
> *your* agent it would happen on your computer, so Redline never does it for
> you.
>
> Instead the run gets a container of its own and your agent reaches it with the
> `machine_run` tool — see [Machines](/build/machines). If you genuinely want
> the CLIs installed locally, call `installClis(task)` yourself.

## Online, offline, and getting back

Your agent's dot on the Agents page reflects one thing: whether its `redline
dev` process is currently connected. Nothing is configured here — the agent
exists because that process said so.

When it goes offline, the row shows the exact command to bring it back, with the
directory it last ran in already in it:

```bash
cd ~/code/my-agent && npx redline dev
```

Press *Copy start command* and paste it into a terminal. Redline cannot start it
for you — nothing here can reach into your machine, which is the same property
that keeps your code and keys out of ours.

> **Note**
>
> An experiment cannot be launched at an offline agent. The launch is refused
> with `… is offline — run redline dev in its project first`, rather than
> queueing runs nothing will ever claim. The same applies to a schedule that
> fires: it records the reason and waits for its next slot.

## When something is not working

```bash
npx redline doctor
```

It checks the whole chain without spending a run: that the key and URL resolve,
that your file actually exports an agent, which env files were found, and
whether attached tools are reaching the framework you use.
