> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.recursiv.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.recursiv.io/_mcp/server.

# Agents in Your App Template

## What it is

A pattern for adding an AI agent to a product you already have. You do not migrate anything. You install the SDK, add one server endpoint that streams an agent, and wire your existing UI to it. Your stack stays exactly as it is.

## What it includes

| Piece        | What it does                                                  |
| ------------ | ------------------------------------------------------------- |
| SDK          | The zero-dependency `@recursiv/sdk` dropped into your backend |
| Agent        | A model-agnostic agent (any supported model) created once     |
| Endpoint     | One streaming route in your existing server                   |
| UI wiring    | Client code that renders streamed deltas                      |
| Integrations | Optional access to hundreds of data integrations as tools     |

## How to start it

Install the SDK in your existing backend and create one agent.

```bash
npm install @recursiv/sdk
export RECURSIV_API_KEY=sk_live_...
```

```typescript
import { Recursiv } from '@recursiv/sdk';

const r = new Recursiv();

// Create the agent once (script, migration, or dashboard)
const { data: agent } = await r.agents.create({
  project_id: process.env.RECURSIV_PROJECT_ID!,
  name: 'In-App Assistant',
  model: 'anthropic/claude-sonnet-4.6',
  system_prompt: 'You help users inside our product. Be concise and accurate.',
});
```

## Add an agent endpoint

Add one route to your existing server. Keep the API key server side and stream `{ delta }` chunks to the client.

```typescript
// Express, Next.js route handler, or any Node server
import { Recursiv } from '@recursiv/sdk';

const r = new Recursiv();

export async function handleChat(req, res) {
  const { agentId, message } = req.body;

  res.setHeader('Content-Type', 'text/plain; charset=utf-8');
  for await (const chunk of r.agents.chatStream(agentId, { message })) {
    res.write(chunk.delta ?? '');
  }
  res.end();
}
```

## Stream to your UI

Your existing frontend reads the response body as it arrives. No framework lock-in.

```typescript
const res = await fetch('/api/chat', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ agentId, message }),
});

const reader = res.body!.getReader();
const decoder = new TextDecoder();
while (true) {
  const { value, done } = await reader.read();
  if (done) break;
  appendToUI(decoder.decode(value)); // your existing render function
}
```

In React Native, do not use `chatStream()`. Call `r.agents.chatStreamText()` instead.

## Key SDK calls

* `r.agents.create({ project_id, model, instructions })` - the agent, created once
* `r.agents.chatStream(agentId, { message })` - stream from your server (Node and browser)
* `r.agents.chatStreamText(agentId, { message })` - the React Native streaming path
* `r.agents.chat(agentId, { message })` - non-streaming, if you just want the full reply

## Next steps

* [Connect Node.js](/integrations/connect/connect-node) or [Connect Next.js](/integrations/connect/connect-nextjs)
* [Add AI Agents to your framework](/recipes/cookbook/agents)
* [API Reference](/api-reference) for every endpoint