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

# Mastra

> Use Opper as a first-class provider in Mastra, the TypeScript agent framework

[Mastra](https://mastra.ai) is a TypeScript framework for building agents, workflows, and RAG applications. Opper is a **first-class provider in Mastra's model router** — there is no base URL to configure and no compatibility shim to set up. Prefix a model with `opper/` and Mastra handles the rest.

## Setup

Set your key in the environment:

```bash theme={null}
# .env
OPPER_API_KEY=your-opper-api-key
```

Then name any Opper model on an agent:

```ts theme={null}
import { Agent } from "@mastra/core/agent";

const agent = new Agent({
  id: "my-agent",
  name: "My Agent",
  instructions: "You are a helpful assistant",
  model: "opper/anthropic/claude-sonnet-5"
});

const response = await agent.generate("Hello!");

const stream = await agent.stream("Tell me a story");
for await (const chunk of stream) {
  console.log(chunk);
}
```

Mastra picks up `OPPER_API_KEY` automatically — no client construction, no `baseURL`.

## Choosing a model

Model IDs are the catalog ID with an `opper/` prefix: `opper/anthropic/claude-sonnet-5`, `opper/openai/gpt-5.5`, `opper/xai/grok-4.6`. Mastra's router ships a snapshot of the catalog with context windows and per-token pricing, sourced from [models.dev](https://models.dev).

Because that list is a snapshot, a model added to Opper very recently may not appear in Mastra's router yet. Name it explicitly with the object form below, or check the [Opper catalog](/capabilities/models) for what's live.

## Routing per request

Mastra accepts a function for `model`, so you can pick per request — cheap model for routine work, frontier model for the hard path:

```ts theme={null}
const agent = new Agent({
  id: "dynamic-agent",
  name: "Dynamic Agent",
  model: ({ requestContext }) =>
    requestContext.task === "complex"
      ? "opper/anthropic/claude-opus-5"
      : "opper/openai/gpt-5.6-luna"
});
```

To move that decision off your code entirely, deploy a [routing graph](/control-plane/route) and name it once instead.

## Custom headers

The object form takes explicit configuration, which is also how you attach [usage tags](/build/gateway/usage-attribution):

```ts theme={null}
const agent = new Agent({
  id: "custom-agent",
  name: "custom-agent",
  model: {
    url: "https://api.opper.ai/v3/compat",
    id: "opper/anthropic/claude-sonnet-5",
    apiKey: process.env.OPPER_API_KEY,
    headers: {
      "X-Opper-Tags": "app:support-bot,env:prod"
    }
  }
});
```

<Note>
  Mastra routes through Opper's OpenAI-compatible `/chat/completions` surface. Opper features that live outside that surface — [structured output](/build/gateway/structured-output) beyond `response_format`, [realtime](/build/realtime/quickstart), and the [audio](/build/multimodal/audio) and [image](/build/multimodal/images) endpoints — need a direct call rather than the Mastra agent.
</Note>

## Related

<CardGroup cols={2}>
  <Card title="Routing graphs" icon="signs-post" href="/control-plane/route">
    Move model choice out of application code.
  </Card>

  <Card title="Vercel AI SDK" icon="bolt" href="/integrations/frameworks/vercel-ai-sdk">
    The other TypeScript toolkit with an Opper provider.
  </Card>
</CardGroup>
