---
title: Meta provider (run sessions on Meta's Muse Spark API)
---

# Meta Provider (Muse Spark)

## What it is

Omniscio supports spawning Claude-Code-style sessions backed by **Meta**'s Anthropic-compatible API — Meta's **Muse Spark** Model API (hosted at `api.meta.ai`) — as an additional provider, alongside `claude` (the default), `codex`, `gemini`, `antigravity`, `deepseek`, `kimi`, `glm`, and `minimax`. It is the **fifth** member of the `anthropic-compat` family.

## Where to find it

**Settings → Accounts** — but the whole Meta section stays hidden until you flip **Show alternative AI providers**. Once revealed, Meta appears as a provider in the normal session-creation pickers.

## How it behaves

### What the user sees

A Meta session looks identical in the sidebar and main pane to a Claude session — same status dots, same streaming bubbles, same Ctrl+Enter to send, same Plan / Auto-Accept / Bypass Permissions modes, same tool-call approval UI. The provider is invisible in normal chat. The only user-visible difference is the Meta icon (its infinity-loop mark in Meta blue, no text label) in the session header.

Tool-call behavior is **identical to Claude** because the same `claude` CLI binary is doing the talking — only the model and the upstream endpoint differ. There is **no yolo / auto-approve mode** like Gemini or Anti-Gravity; the standard Claude approval flow applies.

### How to enable

> **Master toggle required first.** Meta is an alternative provider — by default Omniscio ships as a Claude-only product, and the entire Meta setup section below is hidden in Settings → Accounts. Flip **Settings → Accounts → Show alternative AI providers** to ON (off by default) and the Meta panel appears alongside Gemini, Codex, Anti-Gravity, DeepSeek, Kimi, GLM, and MiniMax. With the master off, the per-project "Default provider" radio collapses to a single Claude row and the session header's provider switcher (ChangeProviderButton) hides Meta — Meta effectively does not exist in the UI even if every gate below is configured. Your saved API key and "Allow Meta sessions" toggle are preserved across master-toggle flips.

You need the toggle below plus a way to pay for Meta — your own Meta API key, Omniscio credits, or both, with Meta's supply list (**Settings → Accounts → Who pays & who serves**) deciding which pays first (note: no binary check — same `claude` binary as Claude). The opt-in **toggle leads and gates the key field** — the API key input appears only once Meta is turned on, so a key can't be entered into a disabled provider (when off, a hint keeps the `meta-api-key` Settings-search anchor landable and a saved key is preserved):

1. **Settings → Accounts → Allow Meta sessions in any project** — opt-in toggle, off by default; same security stance as the Codex/Gemini/DeepSeek/Kimi/GLM/MiniMax spawn guards. Turning it on reveals the key field below.
2. **Settings → Accounts → Meta → API key** — paste a Meta Model API key from the [Meta developer portal](https://dev.meta.ai) (US-only public preview at time of writing; $20 in free credits per new account). Encrypted at rest via Electron `safeStorage`. **Optional when Meta's supply list has an Omniscio credits row** (a new user's list has one) — with no key saved, the session runs on your prepaid credits through the gateway. When both are present, the order of Meta's list decides which pays first. See [model-vendors.md](model-vendors.md).

Once both are green, you can launch a Meta session in three ways:

- **Per-launch override** — on a fresh (zero-message) session, the **ChangeProviderButton** in the new session's main panel (the launch-config pickers on a fresh session) lets you pick a one-off provider before sending the first message. Non-ready providers appear `aria-disabled` with a short hint — "Add key" or "Set up" — and deep-link to the right Settings panel.
- **Per-project default** — Edit Project dialog (three-dot menu → Edit) has a "Default provider" section listing every enabled provider. Pick Meta and the project's sidebar "+ New Session" button spawns Meta automatically.
- **Programmatically** — anything that creates a session with `provider: 'meta'` (recipes, agent-driven sessions, the CLI control HTTP API). Same readiness gates apply on the backend.

### Choosing the model

A fresh Meta session lets you pick the model in the launch-config pickers (next to the provider chooser). The list is registry-driven (`MODELS_BY_PROVIDER.meta` in [provider-models.ts](../../src/shared/providers/provider-models.ts)) and offers four ids, newest first:

| Id | What it is |
| --- | --- |
| `muse-spark-1.3` | **The default.** Meta's current flagship (2026-09-02) — its biggest jump yet on coding and agentic work, 1M context. |
| `muse-spark-1.2` | The previous generation, kept pickable for pinning an older checkpoint. |
| `muse-spark-1.1` | The original July-2026 flagship. |
| `muse-spark-1.3-contributor` | The same 1.3 model at a steep discount, in exchange for letting Meta train on your prompts. Runs only on your own Meta API key. Listed last and never the default — see the warning below. |

The three standard-tier ids are 1M-context and bill at the SAME published rate — $1.25/M input, $4.25/M output, $0.15/M cache read. Meta's "almost too cheap to meter" framing for 1.3 is about capability per token, not a price cut: the standard-tier sticker has not moved since 1.1.

**Use default** spawns **`muse-spark-1.3`** rather than omitting the model flag — Meta _requires_ a real Muse id (the shared `claude` binary's built-in default is a Claude id that Meta's endpoint would reject), so the registry pins one via `getProviderDefaultModel`. The pin tracks the CURRENT flagship, so it moved 1.1 → 1.3 when 1.3 shipped. Meta has no separate "reasoning effort" knob in Omniscio. A Meta session never inherits your Claude default model (those are Claude ids its endpoint would reject).

> **The cut-price `-contributor` tier is offered — read the trade before you pick it.** Meta sells `muse-spark-1.3-contributor` at $0.10/M input, $0.20/M output, $0.002/M cached input — roughly **12× cheaper on input** than the standard tier — but its own listing states that prompts and outputs on that tier **may be used to improve Meta's products**, and Meta lists it as text-only where the standard tier is multimodal (inside Omniscio the Meta provider is registered without image support either way — `images: false` in its registry capabilities). It is also rate-limited to **100 RPM** against the standard tier's 3,000. It is never the default: "Use default" stays on the standard tier, so choosing it is always deliberate. Use it for work you are happy to hand over; keep the standard tier for private code and business data.
>
> **It runs only on your own Meta API key — never on Omniscio credits.** Omniscio credits go through Omniscio's gateway, which only uses tiers that do not train on your prompts, so it has no route for the contributor tier (and OpenRouter, which serves that lane, refuses the tier under the company account's data policy too). Meta's supply list therefore passes over its Omniscio credits row for this model, and the session runs on your own Meta key when that row can serve. With no own Meta key that can serve it, the session is refused before it starts, with a message naming the model and the two fixes: save your own Meta key (and keep its row in Meta's list in Settings → Accounts → Who pays & who serves) — or pick another model, such as Muse Spark 1.3 (the same model at the standard price). Before this check existed, such a session failed silently with an empty turn.
>
> The tier is excluded only from **OpenRouter's** model picker, where its models arrive as one unlabelled entry among hundreds with nowhere to state that trade (`OPENROUTER_DROP_SUBSTRINGS` in `model-discovery-filters`). The Meta picker is a short curated list, so it can say so on the entry itself.

### Per-project default

Each project remembers a default provider in the `projectDefaultProviders` setting (a `Record<projectId, ProviderId>`). Empty by default — every project falls back to Claude. Change it from the project's three-dot menu → Edit → Default provider radios; the change persists immediately.

When you set a project's default to Meta but Meta isn't ready (toggle off or key missing), an amber **"!" badge** appears on that project's sidebar row. Hover the badge for a tooltip explaining the gap; click it to deep-link straight to the right Settings panel. The badge checks readiness when the row first appears and whenever the project's default provider changes — it does not re-check on its own after you fix the gap in Settings, so it clears the next time the row is rebuilt (for example after an app restart). Claude defaults never show the badge — Claude is always considered ready.

### Error states and fixes

Two gap codes — fewer than Gemini/Codex because there is no separate binary to check:

| Gap           | What it means                            | Click-to-fix lands you at…                      |
| ------------- | ---------------------------------------- | ----------------------------------------------- |
| `toggle-off`  | "Allow Meta sessions" is OFF in Settings | Settings → Accounts → Allow Meta sessions toggle |
| `key-missing` | No row of Meta's supply list can serve (no Meta key, and no other row ready) | Settings → Accounts → Meta API key field, or Who pays & who serves |

**Test your key.** The Meta API-key field has a **"Test key"** button that checks your key against Meta's model list (`https://api.meta.ai/v1/models`) and returns one plain-language verdict: the key works, Meta rejected it, or Meta could not be reached (offering "Save anyway"). It proves the key is accepted — so a mistyped or revoked key surfaces _before_ you spawn a session — but it does not check your credit balance or a particular model; those surface on the first turn, named by the handling below.

**Retired / unavailable model.** If a session's selected model is no longer accepted by Meta — either Omniscio has removed it from the picker or the vendor killed a still-listed id server-side — Omniscio surfaces a clear _"this Meta model is no longer available — open the model picker and choose another"_ and parks the session as `needs_you` / `recovery_failed`, instead of silently retrying the rejected request into the generic placeholder-stuck give-up loop. This shares the same anthropic-compat guards the DeepSeek/Kimi/GLM/MiniMax siblings use. See [provider-spawn-model-availability-contract.md](../../.claude/memory/contracts/provider-spawn-model-availability-contract.md).

**The real reason, not a blanket "model unavailable."** A Meta rejection arrives the same way regardless of cause — a synthetic placeholder with zero output — so when the rejection is _not_ about the model (the account ran out of credit, the conversation outgrew the context window, the key became invalid, or you hit a rate limit), Omniscio reads Meta's actual error off that placeholder and surfaces the _specific_ cause + fix: **out of balance** → top up the account, then resend; **conversation too long** → start a fresh session; **bad/expired key** → check the Meta key in Settings; **rate-limited** → wait a moment, then resend. This shares the exact `classifyAnthropicCompatPlaceholderError` path the DeepSeek/Kimi/GLM/MiniMax siblings use.

### Cost tracking

Spend is recorded on the session itself: the `claude` CLI reports each turn's usage in its `stream-json` output, Omniscio re-prices it (below) and adds it to the session's running cost (`sessions.cost_usd`). The Stats → Spend views group that spend by the session's provider (`meta`), so Meta spend shows separately from Claude/Codex/Gemini. Meta session turns are not written to `api_cost_log`.

**Cost is re-priced, not taken verbatim.** The `claude` binary computes its `total_cost_usd` from its OWN (Claude) price table, which has no Muse Spark row — so it would bill Muse Spark at Claude rates. Meta is therefore `costReporting: 'estimated'`, and Omniscio recomputes each turn's cost from the token counts × Meta's real per-M rate ($1.25 / 1M input, $4.25 / 1M output; [model-pricing.ts](../../src/shared/model-pricing.ts) `MODEL_PRICING`) via `repriceAnthropicCompatTurnCost` — the same token-pricing path its anthropic-compat siblings use. See [central-ai-spend-contract.md](../../.claude/memory/contracts/central-ai-spend-contract.md).

Telemetry: every successful Meta spawn fires the `spawn_non_claude_session` feature event, recording `{ provider: 'meta', engine: 'anthropic-compat' }` — no session ID, project ID, or prompt content.

## For agents

### How it works under the hood

**Spawn-env redirect, no alternate manager.** Meta publishes an Anthropic-compatible API — same request/response shape as Anthropic's Messages API, just at a different base URL. Meta's own developer docs document Claude Code as a supported client. So Omniscio reuses the existing `claude` CLI binary (the same one Claude sessions use) and redirects every HTTP call at spawn time by setting two environment variables on the child process:

- `ANTHROPIC_BASE_URL=https://api.meta.ai` — sends every HTTP request to Meta's compat endpoint instead of `api.anthropic.com`. **Meta is the one anthropic-compat vendor whose base URL is the BARE HOST** (no `/anthropic` path): the `claude` CLI appends `/v1/messages`, so `https://api.meta.ai` becomes `https://api.meta.ai/v1/messages`. (The OpenAI-format base is `https://api.meta.ai/v1`; the Anthropic/Claude-Code base is the bare host — mixing them up is the most likely integration mistake.)
- `ANTHROPIC_AUTH_TOKEN=<your Meta API key>` — supersedes the Claude OAuth/API-key for this child only. When the Omniscio credits row of Meta's supply list serves, the same variable carries the short-lived **gateway** token and `ANTHROPIC_BASE_URL` points at the gateway rather than `api.meta.ai`.

The child process never knows it isn't talking to Anthropic. Streaming, tool calls, `--resume` for multi-turn, `--output-format stream-json` parsing all "just work" because they're handled by the standard `claude` binary against an upstream that speaks the same protocol.

No alternate session manager exists for Meta — readiness gates, the `spawn_non_claude_session` feature event fires, then it falls through to the same `createSessionWithPrompt()` path Claude sessions use. The `provider: 'meta'` value is stored on the session row in the database; [spawn-cluster-manager.ts](../../src/main/process/spawn-cluster-manager.ts) reads that column and injects the right spawn-env on every CLI invocation (initial spawn, resume, aside-runner). Meta is **not user-key-only**: it rides the same company-credits gateway lane as its Kimi / MiniMax / Qwen siblings. When the Omniscio credits row of Meta's supply list is the row that serves, the child is pointed at Omniscio's gateway instead of `api.meta.ai` (lane `/v1/meta`, funded by the pooled OpenRouter key; the gateway pins each id to `meta/<id>` and routes `meta/muse-spark-1.3`, `-1.2` and `-1.1` to the same ids on OpenRouter — the contributor tier has no route, see above) and authenticates with the gateway token rather than a Meta key. Whichever of your `metaApiKey` row and the credits row comes first in Meta's list pays first, and **either** credential makes the provider spawn-ready. See `FUNDABLE_PROVIDERS` in [fundable-providers.ts](../../src/shared/providers/fundable-providers.ts).

Because Meta **runs the `claude` binary**, it is eligible for the same crash/restart/suspended/re-arm recovery as native Claude (`claude --resume` re-applies the Meta env overlay from the session row) — distinct from Anthropic _account_ machinery (rate-limit recovery, load-balancing), which it stays out of since it authenticates with a Meta key or a company-credits gateway token, not an Anthropic login.

Compared to:

- **DeepSeek / Kimi / GLM / MiniMax** — same shape exactly (Anthropic-compat, no binary, spawn-env redirect). The only differences are the vendor base URL and the credential field. Meta is the fifth member of this `anthropic-compat` family and shares every code path with them — the one wrinkle is the bare-host base URL above.
- **Codex / Anti-Gravity** — separate CLI binaries with their own protocols; need dedicated `*-session-manager.ts` files. Meta does not.
- **Gemini** — a long-lived `gemini --acp` ACP child per session (its own JSON-RPC protocol). Meta keeps the long-lived `claude` child process; resume via `claude --resume <uuid>`.
- **OpenClaw** — remote WebSocket gateway. Meta is plain HTTP to a vendor-hosted compat endpoint.

### Files

- [src/shared/providers/registry.ts](../../src/shared/providers/registry.ts) — the `meta` descriptor (`anthropic-compat` runtimeKind, capabilities, label, pickerOrder)
- [src/main/services/providers/main-registry.ts](../../src/main/services/providers/main-registry.ts) — the Meta readiness wiring (toggle + API-key gates, no binary gate)
- [src/main/services/anthropic-compat-provider.ts](../../src/main/services/anthropic-compat-provider.ts) — the bare-host `https://api.meta.ai` base URL + credential accessors (`ANTHROPIC_COMPAT_PROVIDERS` membership)
- [src/main/services/meta-credential-store.ts](../../src/main/services/meta-credential-store.ts) — the encrypted `metaApiKey` store
- [src/main/db/migrations/20260709123500-allow-meta-provider.ts](../../src/main/db/migrations/20260709123500-allow-meta-provider.ts) — extends the `sessions.provider` allow-list to include `meta`
- [src/main/process/spawn-cluster-manager.ts](../../src/main/process/spawn-cluster-manager.ts) — injects `ANTHROPIC_BASE_URL` + `ANTHROPIC_AUTH_TOKEN` per session row's `provider` column
- [src/main/process/spawn-build.ts](../../src/main/process/spawn-build.ts) — `creditsLaneModelRefusal`, the pre-launch verdict that refuses an `ownKeyOnly` model (the contributor tier) on the Omniscio-credits lane
- [src/shared/types/provider-readiness.ts](../../src/shared/types/provider-readiness.ts) — `ProviderId` union
- [src/shared/types/settings/accounts-providers-settings.ts](../../src/shared/types/settings/accounts-providers-settings.ts) — `allowMetaSessionSpawn` setting
- [src/shared/types/settings/ai-features-settings.ts](../../src/shared/types/settings/ai-features-settings.ts) — `metaApiKey` setting
- [src/renderer/src/features/settings/sections/accounts/AnthropicCompatProvider.tsx](../../src/renderer/src/features/settings/sections/accounts/AnthropicCompatProvider.tsx) — the Meta block of the shared anthropic-compat settings (API key field + Test key button), shown under "Show alternative AI providers"
- [src/renderer/src/components/ui/MetaIcon.tsx](../../src/renderer/src/components/ui/MetaIcon.tsx) — the Meta infinity-mark icon

## Related

### Related

- [minimax-provider.md](minimax-provider.md) — same shape (Anthropic-compat, no binary, spawn-env redirect), different vendor + key
- [glm-provider.md](glm-provider.md) — another `anthropic-compat` sibling
- [kimi-provider.md](kimi-provider.md) — another `anthropic-compat` sibling
- [deepseek-provider.md](deepseek-provider.md) — the other `anthropic-compat` sibling
- [switching-providers.md](switching-providers.md) — the unified session-provider guide
- [model-vendors.md](model-vendors.md) — who pays for a Meta session (the supply list)
- [provider-registry-contract.md](../../.claude/memory/contracts/provider-registry-contract.md) — the DeepSeek + Kimi + GLM + MiniMax + Meta (`anthropic-compat`) invariants

