---
title: "AI providers, MailKaro Docs"
description: "Run the editor's AI actions (generate a design, rewrite copy, subject lines, alt text, images) through an adapter you point at your own AI provider."
---

# AI providers

AI & MCP

# AI providers

The editor's AI actions, generate a design, rewrite copy, suggest subject lines, write alt text, and **generate images**, run through a `MailkaroAiAdapter` you pass as `config.ai.adapter`. MailKaro ships **first-party adapters** for OpenAI, Anthropic (Claude), and Google Gemini, so you don't have to write one.

⚠ These adapters use your provider API key, create them on your **server** (or a proxy) and hand the editor the resulting adapter. Never ship a raw API key to the browser.

## Use a built-in provider

ts ai.ts

```
import { createOpenAiAdapter, createAnthropicAdapter, createGeminiAdapter } from "react-email-craft";

const adapter = createOpenAiAdapter({ apiKey: process.env.OPENAI_API_KEY!, model: "gpt-4o-mini" });
// or createAnthropicAdapter({ apiKey, model: "claude-sonnet-5" })
// or createGeminiAdapter({ apiKey, model: "gemini-1.5-flash" })

<EmailEditor config={{ ai: { adapter } }} />;
```

|Prop |Type |Default |Description |
|`apiKey` |string |- |Your provider API key (server-side). |
|`model` |string? |- |Model id, each provider has a sensible default. |
|`baseUrl` |string? |- |Override the API base (proxy / gateway / self-host). |
|`fetch` |typeof fetch? |- |Injectable HTTP client (testing / custom transport). |
|`imageModel` |string? |- |Image model for `generateImage` (OpenAI / Gemini). |

## What each does

- **generateSubjectLines / rewriteText / generateAltText**, all providers.
- **generateDesignFromPrompt**, parses the model's JSON into a validated design (falls back to a summary).
- **generateImage**, OpenAI & Gemini; wires the image block's *Generate with AI* box.
- **editDesign**, powers the conversational assistant (below).

## Conversational assistant

When the adapter implements `editDesign` (all first-party providers do), the toolbar shows a **chat panel**: describe a change in plain language, “add a footer with an unsubscribe link”, “make the button green”, and the assistant edits the design in place. Under the hood the model returns a list of declarative **design ops** that MailKaro applies with `applyDesignOps`; each edit is a saved, undoable snapshot. The panel appears only when `editDesign` is present and the editor isn't read-only.

ts assistant.ts

```
// Any adapter can implement it; the first-party providers already do.
const result = await adapter.editDesign({ message: "add a footer with an unsubscribe link", design });
// → { design?: Design, summary: string, operations?: DesignOp[] }

// Reuse the same apply engine anywhere:
import { applyDesignOps } from "email-craft-sdk";
const { design: next, applied, errors } = applyDesignOps(design, [
 { op: "set_body", values: { subject_line: "Spring Sale" } }, { op: "add_block", type: "button", values: { label: "Shop now", href: "https://…" } }
]);
```

✦ Prefer your own model or a different vendor? Implement `MailkaroAiAdapter` yourself, the built-ins are just a convenience. AI features are gated by the [AI entitlements](https://mailkaro.com/docs/plans) (pro+). The same op vocabulary is available to any AI over MCP via the [edit_design](https://mailkaro.com/docs/mcp) tool.

Source: https://docs.mailkaro.com/ai-providers
