Mastra

Use CleverRouter as the LLM for `new Agent({ model: cr('...') })`. Memory and tools stay unchanged.

CleverRouter provides a Mastra-compatible model factory. Drop it into new Agent({ model: cr('mistral/...') }) and the rest of Mastra — memory, tools, workflows — works without changes.

At a glance

Installbun add @cleverrouter/sdk@alpha @mastra/core
ImportcreateCleverRouterMastra from @cleverrouter/sdk/mastra
Default model in our examplesmistral/mistral-large-2

Setup

cr.ts
import { createCleverRouterMastra } from '@cleverrouter/sdk/mastra';

export const cr = createCleverRouterMastra({
  apiKey: process.env.CLEVERROUTER_API_KEY!,
  provider: 'scaleway', // optional default
});

A minimal agent

agent.ts
import { Agent } from '@mastra/core/agent';
import { cr } from './cr';

export const supportAgent = new Agent({
  name: 'support',
  model: cr('mistral/mistral-large-2'),
  instructions: 'You are customer support. Reply precisely, always in German.',
});

const reply = await supportAgent.generate(
  'Wie hoch ist mein Tagesbudget?',
);
console.log(reply.text);

With tools

Mastra tools are typed against Zod schemas — they wire into our function-calling support without extra glue:

agent-with-tools.ts
import { Agent } from '@mastra/core/agent';
import { createTool } from '@mastra/core/tools';
import { z } from 'zod';
import { cr } from './cr';

const getBudget = createTool({
  id: 'get-budget',
  description: 'Returns the current daily budget in cents.',
  inputSchema: z.object({ keyId: z.string() }),
  execute: async ({ context }) => {
    const cents = await db.query.apiKeys.findFirst({
      where: eq(apiKeys.id, context.keyId),
    });
    return { remainingCents: cents?.dailyBudgetCents ?? 0 };
  },
});

export const supportAgent = new Agent({
  name: 'support',
  model: cr('mistral/mistral-large-2'),
  instructions: 'Help users diagnose budget issues. Use the tools.',
  tools: { getBudget },
});

With memory

agent-with-memory.ts
import { Agent } from '@mastra/core/agent';
import { Memory } from '@mastra/memory';
import { PostgresStore } from '@mastra/store-pg';
import { cr } from './cr';

const memory = new Memory({
  storage: new PostgresStore({ connectionString: process.env.DATABASE_URL! }),
});

export const supportAgent = new Agent({
  name: 'support',
  model: cr('mistral/mistral-large-2'),
  instructions: 'Helpful, concise, German.',
  memory,
});

Mastra memory writes to your Postgres — CleverRouter never sees the conversation history.

Per-call routing

await supportAgent.generate('Hi.', {
  model: cr('mistral/mistral-large-2', {
    provider: 'tensorix',
    strategy: 'fastest',
  }),
});

What stays the same

  • Workflows (new Workflow(...)).
  • RAG via @mastra/rag — Mastra calls our embeddings endpoint through the same provider helper.
  • Evals (@mastra/evals) — point them at any model in the catalog.
  • Multi-agent orchestration patterns.

Mastra ZDR posture

Mastra logs agent runs to your own storage. CleverRouter's ZDR applies to the inference call only — anything Mastra writes to a store you configured lives in your system, not ours.