# Bring your agent

> Put the agent you built with the Claude Agent SDK, the OpenAI Agents SDK, the Vercel AI SDK or LangChain on VoiceLayer's calls and text channels.

Source: https://docs.vlayers.ai/developers/frameworks

Kind: Concept

You already have an agent. VoiceLayer gives it a phone number, SMS, WhatsApp, Telegram, Discord and email, and keeps everything that is hard to run: speech, telephony, delivery, and the guard that checks what goes out. You keep the agent: its prompt, its model, its tools and its framework.

There are three ways to connect it. They are separate on purpose, and you can use any mix of them.

| | Answer calls | Answer texts | Use channels as tools |
|---|---|---|---|
| **What it does** | Your agent is the brain of a VoiceLayer voice agent. The caller talks to VoiceLayer's voice; your agent writes each reply. | Your process answers every incoming message in the conversations your code controls. | Your agent sends, replies and reads messages by calling VoiceLayer's tools. |
| **Channels** | Phone calls | SMS, WhatsApp, Telegram, Discord, email | The same, as tools; the API key decides which |
| **What you write** | `defineAgent({ brain })` with an adapter: `openaiBrain(agent)`, `claudeBrain(options)`, `aiSdkBrain(agent)` or `langchainBrain(graph)` | `serveDirect(agent)` (for Claude, its `options`) | `voicelayerMcpServer()`, `voicelayerMcp()` or `voicelayerTools()`, depending on the framework |
| **Package** | `@voicelayer/sdk` and `@voicelayer/agents` | `@voicelayer/agents` | `@voicelayer/agents` |
| **You keep** | The agent loop, the model and its key, the worker process that runs it | The agent loop, the model and its key, the process that runs it | Everything: the agent decides when to use a tool |
| **VoiceLayer keeps** | Speech to text, text to speech, turn-taking, telephony, the transcript, and a guard on what your agent says and does | The channels, delivery, the event stream, and the same checks on every reply as on any send, the output guard included | The channels, the API key's scopes, and the same checks as any API call |

## What works with which framework

The adapter for each framework ships in `@voicelayer/agents`. This is what exists today:

| Framework | Calls | Texts | Tools |
|---|---|---|---|
| [Claude Agent SDK](https://docs.vlayers.ai/developers/frameworks/claude) | `claudeBrain(options)` | `serveDirect(options)` | `voicelayerMcp()` |
| [OpenAI Agents SDK](https://docs.vlayers.ai/developers/frameworks/openai) | `openaiBrain(agent)` | `serveDirect(agent)` | `voicelayerMcpServer()` |
| [Vercel AI SDK](https://docs.vlayers.ai/developers/frameworks/ai-sdk) | `aiSdkBrain(agent)` | `serveDirect(agent)` | `voicelayerTools()` |
| [LangChain and LangGraph](https://docs.vlayers.ai/developers/frameworks/langchain) | `langchainBrain(graph)` | `serveDirect(graph)` | `voicelayerTools()` |

Every brain adapter works the same way for the caller. They differ in how your agent gets VoiceLayer's call controls (transfer, hang up, keypad digits): the OpenAI adapter adds them to your agent for you, and the other three give them to a function you write. Each framework page says which.

The Vercel AI SDK adapter is in `@voicelayer/agents` only. The lower-level `@voicelayer/sdk` has adapters for the OpenAI Agents SDK, the Claude Agent SDK and LangGraph, but none for the AI SDK. The Python package, `voicelayer-agents`, covers texts and tools for Claude, OpenAI Agents and LangGraph. It has no call adapter: see [Python frameworks](https://docs.vlayers.ai/developers/frameworks/python).

## Answering calls and texts with the same agent

You can share one agent between both modes today. Write the agent once in a module, then import it from two small files: one is your voice agent (`defineAgent({ brain })`), the other calls `serveDirect`. Each framework page ends with this pattern.

> **Warning:** Not yet: a single process, started once, that answers calls and texts from one object. A call reaches your brain, but a text does not: VoiceLayer's text channels cannot send a turn to a brain yet. That needs the text engine to run without a call room, which is not released. Until then you run two processes, one for calls and one for texts. They share the agent's code and prompt, not a running agent: each process keeps its own state.

## Pick your framework

- [Claude Agent SDK](https://docs.vlayers.ai/developers/frameworks/claude): claudeBrain, serveDirect and voicelayerMcp from @voicelayer/agents/claude
- [OpenAI Agents SDK](https://docs.vlayers.ai/developers/frameworks/openai): openaiBrain, serveDirect and voicelayerMcpServer from @voicelayer/agents/openai
- [Vercel AI SDK](https://docs.vlayers.ai/developers/frameworks/ai-sdk): aiSdkBrain, serveDirect and voicelayerTools from @voicelayer/agents/ai-sdk
- [LangChain and LangGraph](https://docs.vlayers.ai/developers/frameworks/langchain): langchainBrain, serveDirect and voicelayerTools from @voicelayer/agents/langchain
- [Python frameworks](https://docs.vlayers.ai/developers/frameworks/python): Texts and tools for Claude, OpenAI Agents and LangGraph in Python

## Not using a framework

- A function is enough for a voice brain: see [Brains in code](https://docs.vlayers.ai/developers/sdks/brains).
- A plain handler is enough for texts: see [Direct mode](https://docs.vlayers.ai/developers/sdks/direct).
- A model behind an HTTP endpoint, with no SDK code: see [Brain connectors](https://docs.vlayers.ai/build/brain-connectors).

## Next steps

- [Voice agents in code](https://docs.vlayers.ai/developers/sdks/voice-agents): how a voice agent is defined, run and deployed.
- [Conversations and handoff](https://docs.vlayers.ai/developers/handoff): which conversations direct mode answers.
- [The MCP tools](https://docs.vlayers.ai/developers/mcp): what each channel tool does.
