Metadata-Version: 2.4
Name: apatero-studio-mcp
Version: 0.2.0
Summary: Apatero Studio inside Claude: an MCP server + CLI to generate images, video, talking avatars, and persistent AI characters
Project-URL: Homepage, https://apatero.ai
Project-URL: Repository, https://github.com/Apatero-Org/Monorepo
Project-URL: Documentation, https://github.com/Apatero-Org/Monorepo/tree/main/projects/apatero-studio/mcp#readme
Project-URL: Issues, https://github.com/Apatero-Org/Monorepo/issues
Author-email: Apatero <contact@apatero.com>
License: MIT
License-File: LICENSE
Keywords: ai,apatero,claude,cli,image-generation,mcp,model-context-protocol,video-generation
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Multimedia :: Graphics
Classifier: Topic :: Multimedia :: Video
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27
Requires-Dist: mcp>=1.2.0
Requires-Dist: pillow>=10
Requires-Dist: starlette>=0.37
Requires-Dist: uvicorn>=0.30
Description-Content-Type: text/markdown

# Apatero Studio MCP (MCP server + CLI)

Drive [Apatero Studio](https://apatero.ai) from inside Claude. Ask Claude to generate an image, render a video, animate a talking avatar, or build a persistent AI character, and the result comes straight back, with generated images rendered **inline in the conversation** (plus a full-resolution link every time). It ships as an MCP server (stdio and remote HTTP transports) plus an `apatero` CLI. Every call authenticates with your own Apatero account and hits the real generation API; nothing is mocked, and generating spends credits on the account that owns the key.

## Tool Catalog

The server exposes 20 tools. Read-only tools cost no credits; the rest submit real generations.

### Account and Info

| Tool | What It Does |
|---|---|
| `apatero_list_models` | List the generation models available to you (slug, name, modality, credit cost). Optional `modality` filter (e.g. `image`, `video`, `audio`). |
| `apatero_credit_balance` | Show how many Apatero Studio credits the account has left. |
| `apatero_recent_generations` | List your most recent generations (id, status, result). `limit` defaults to 10. |
| `apatero_generation_status` | Check any generation by `generation_id`; a completed image renders inline plus its result URL. |
| `apatero_show_image` | Display an image inline in the conversation on demand: pass a `generation_id`, a `soul_id`, or a direct `image_url`. |

### Generate

| Tool | What It Does |
|---|---|
| `apatero_generate_image` | Generate or edit an image and return the result URL(s). `prompt` required; optional `model`, `num_images` (1-8), `aspect_ratio`, `negative_prompt`, `image_url` (single reference), `images` (list of references), `wait` (default true). With a reference image and no model, defaults to `nano-banana-2-edit`. |
| `apatero_generate_video` | Submit a video render and return the generation id right away (renders take 1-5 min; fetch with `apatero_generation_status`). `prompt` required; optional `image_url` (starting frame, switches to image-to-video `seedance-2-i2v`; text-only uses `seedance-2-t2v`), `duration` (4-15s, default 5), `aspect_ratio`, `model`, `wait` (pass `true` to block until done on long-timeout clients). |
| `apatero_talking_avatar` | Animate a still portrait into a talking avatar (Kling Avatar v2 Pro). `image_url` required; provide exactly one of `script` (spoken via backend TTS) or `audio_url` (lip-sync to existing audio). Submits and returns the generation id right away (renders take 2-8 min); `wait=true` to block. |
| `apatero_remix` | Remix a COMPLETED generation into a seed-offset variation. Takes `generation_id`, re-runs the same prompt with a different seed, returns the new URL. |

### Characters (Souls)

| Tool | What It Does |
|---|---|
| `apatero_list_souls` | List your saved Souls (reusable characters). Returns id, name, reference count, reference image URLs. Read-only. |
| `apatero_create_soul` | Create a Soul from 1-6 reference image URLs of the SAME character. `name` and `reference_image_urls` required; optional `description`. Uploads the images to your gallery first (requires an active subscription); costs no generation credits. |
| `apatero_generate_with_soul` | Generate a NEW scene of a saved Soul, keeping the character's identity. `soul_id` and `prompt` required; optional `num_images` (1-8), `aspect_ratio`, `model` (default edit model `nano-banana-2-edit`). Anchored to the Soul's primary reference. |

### Brands

| Tool | What It Does |
|---|---|
| `apatero_list_brands` | List your saved Marketing Studio brands (name, tagline, palette). Read-only. |
| `apatero_generate_with_brand` | Generate an on-brand marketing image from a brand kit plus a brief. `brand_id` and `brief` required; optional `num_images` (1-8), `aspect_ratio`, `model`. Builds a prompt from the brand's voice/palette/tagline, anchored to the brand's primary asset. |

### Batch (Insta Dump)

| Tool | What It Does |
|---|---|
| `apatero_instadump` | Turn one reference photo into N Instagram-ready persona images. `reference_image_url` and `niche` required (`niche` is one of fitness, travel, fashion, food, books, tech, wellness, beauty, gaming, parenting, finance, lifestyle); optional `output_count` (3-15, default 5), `target_format` (`story_9_16`, `feed_1_1`, `feed_4_5`, or `mix`; default `feed_1_1`). Uploads the reference (requires an active subscription); polls up to ~10 min. |
| `apatero_instadump_status` | Check an Insta Dump batch by `job_id`: aggregate status plus every variant URL. |

### Influencer Composites

| Tool | What It Does |
|---|---|
| `apatero_create_influencer` | Create a brand-new AI influencer: generate a portrait set, then save it as a reusable Soul. `name` and `persona` required; optional `num_portraits` (1-6, default 4), `aspect_ratio` (default `3:4`). Fails gracefully mid-chain (you still get portrait URLs if the Soul step fails). |
| `apatero_influencer_clip` | Make a short video of a saved Soul in a scene (optionally talking). `soul_id` and `scene` required; optional `script` (makes a talking avatar), `duration` (4-15s, default 5, plain-video path), `mode` (`video`, `talking`, or empty=auto). Generates a scene still, then animates it. Can take up to ~12 min. |

### Stories

| Tool | What It Does |
|---|---|
| `apatero_create_story` | Start a new Story (a multi-panel illustrated story) in DRAFT and return its id. `premise` (10-2000 chars) and `style` (`storybook`, `comic`, `cinematic`, `watercolor`, `anime`) required; optional `panel_budget` (4-12, or omit for auto), `title`. Requires a Studio-tier subscription. Does NOT drive the beats/cast/generate steps (those run in the Apatero Studio UI). |
| `apatero_story_status` | Check a Story by `story_id`: state, panels (with image URLs), characters, locations. |

The `apatero` CLI covers the core generation subset: `models`, `balance`, `generate`, `status`, `recent`, `login`, `logout`.

## What You Can Do

Generated images come back **inline in the conversation** (rendered right in the chat), and every result still includes a full-resolution link. On hosts that support MCP Apps (claude.ai, Claude Desktop), image results additionally render in an inline panel directly in the chat flow via the bundled `ui://apatero/image-panel` app (SEP-1865; disable with `MCP_APPS_UI=0`); other hosts fall back to the standard inline image blocks. Just ask in plain language, or pick one of the ready-made prompts from the prompt picker in claude.ai:

| Prompt | What It Does |
|---|---|
| **Create an AI Influencer** | Make a brand-new AI character (a set of consistent portraits saved as a reusable Soul) you can reuse in any scene. |
| **Make an Influencer Clip** | Turn one of your characters into a short video, talking or silent. |
| **Generate an Image** | Create a picture from a description. |
| **Generate a Video** | Create a short video from a description or a starting image. |
| **Talking Avatar** | Make a still portrait speak your words out loud. |
| **Instagram Batch** | Turn one photo into a batch of Instagram-ready posts. |
| **Soul Photoshoot** | Put one of your saved characters in a brand-new scene. |

Behind the scenes each prompt chains the right tools in the right order (for consistent-character work it creates a Soul first, then reuses it). On connect, the server also sends Claude a short capability map so it knows when to reach for Souls, InstaDump, talking avatars, brands, and stories.

## Authentication

You need an Apatero account with credits. Pick one of two auth paths.

### Option A: API key (headless / CI / remote)

1. Open the Apatero app and go to the Developer / API keys section (under Billing).
2. Create a key. It starts with `ap_live_`.
3. Set it in your environment: `export APATERO_API_KEY=ap_live_...`

If set, an API key takes precedence over the cached login. (The key can also be minted directly with `POST /api/billing/developer/keys/`.)

### Option B: OAuth browser login (interactive)

```bash
apatero login
```

Your browser opens, you sign in to Apatero and click **Authorize**, and a token is cached at `~/.apatero/credentials.json` and auto-refreshed. No key to paste. The stdio MCP server picks up the same cached login. Sign out with `apatero logout`.

## Install

Install from source (until published to PyPI):

```bash
cd projects/apatero-studio/mcp && pip install -e .
```

Once published, `pipx install apatero-studio-mcp` or `uv tool install apatero-studio-mcp` also work. Installing registers three console scripts: `apatero` (CLI), `apatero-studio-mcp` (stdio MCP server), and `apatero-studio-mcp-http` (remote HTTP server).

## Connect From Claude Code (stdio, local)

Run the server as a local subprocess. Pass your API key via `--env`:

```bash
claude mcp add apatero --env APATERO_API_KEY=ap_live_... -- apatero-studio-mcp
```

Or, if you have already run `apatero login`, drop the `--env` (the server reads your cached login):

```bash
claude mcp add apatero -- apatero-studio-mcp
```

Equivalent `.mcp.json` (project-scoped config) form:

```json
{
  "mcpServers": {
    "apatero": {
      "command": "apatero-studio-mcp",
      "env": { "APATERO_API_KEY": "ap_live_..." }
    }
  }
}
```

## Connect From Claude Code (remote HTTP)

Point Claude Code at the hosted server. It passes your credential in one `Authorization` header (the header accepts both `ap_live_` API keys and OAuth JWTs):

```bash
claude mcp add --transport http apatero https://mcp.apatero.ai/mcp \
  --header "Authorization: Bearer ap_live_..."
```

Requires the remote service to be deployed at `mcp.apatero.ai` (see `DISTRIBUTION.md`).

## Connect From claude.ai (custom connector)

1. In claude.ai, open **Settings** then **Connectors** then **Add custom connector**.
2. Paste `https://mcp.apatero.ai/mcp`.
3. Complete the OAuth sign-in when prompted (the connector discovers the authorization server via RFC 9728 protected-resource metadata and signs you in against Apatero).

Requires the remote service to be deployed at `mcp.apatero.ai`.

## Connect From Claude Desktop (stdio config JSON)

Add to `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "apatero-studio": {
      "command": "apatero-studio-mcp",
      "env": { "APATERO_API_KEY": "ap_live_..." }
    }
  }
}
```

(Drop the `env` block if you have run `apatero login` and want to use the cached OAuth token instead.)

## Worked Example: The Influencer Loop

A realistic end-to-end flow you can drive entirely in chat. The identity stays consistent because every step after the first is anchored to the same Soul.

**1. Create the character (`apatero_create_influencer`).** This generates a portrait set and saves it as a reusable Soul.

> "Create an AI influencer named Mara with Apatero. Persona: mid-20s, warm brown eyes, freckles, effortless streetwear, confident and friendly. Make 4 portraits in 3:4."

Claude returns the portrait URLs and the new Soul id.

**2. Generate scenes (`apatero_generate_with_soul`).** Reuse the Soul to put Mara anywhere; the face stays consistent.

> "Using Mara's soul, generate her sipping coffee at a Lisbon rooftop cafe at golden hour, 9:16, 3 images."

**3. Produce a clip (`apatero_influencer_clip`).** Turn a scene into a short video, optionally talking.

> "Make a talking clip of Mara in a cozy bookshop saying 'This one's my favorite read this month.' 5 seconds."

**4. Batch social posts (`apatero_instadump`).** Fan one reference photo out into a set of niche-ready posts.

> "Take that first Mara portrait and do an Insta Dump: fashion niche, 8 outputs, mixed formats."

Then poll it with `apatero_instadump_status` if it is still running, and check `apatero_credit_balance` between steps to watch spend.

## Requirements and Limits

Stated honestly so you know what to expect:

- **Active subscription required for upload-dependent tools.** `apatero_create_soul`, `apatero_instadump`, and `apatero_create_influencer` upload images to your gallery first, which needs an active subscription on the account.
- **Story Mode requires a Studio-tier subscription.** `apatero_create_story` only creates the DRAFT and returns its id; it does not drive the beats/cast/panel-generation steps (those run in the Apatero Studio UI, because the beats step is a paid AI call that writes the scene list and characters generate async reference images).
- **Edit models honor the primary reference image only.** `apatero_generate_with_soul` and `apatero_generate_with_brand` anchor to the Soul's or brand's primary (cover) asset. The full reference list is sent on the wire, but today's backend applies just the primary; the extras are future-proofing for when the backend widens its allow-list.
- **Video and avatar generations take minutes.** `apatero_generate_video` and `apatero_talking_avatar` poll for up to ~10 minutes; `apatero_influencer_clip` up to ~12. If a job is still processing when that window elapses, the tool returns a "still processing" note with the generation id and the job keeps running server-side. Check it later with `apatero_generation_status`.
- **Credits scale with output.** Cost scales with `num_images` (image tools), `duration` (video), and `output_count` (Insta Dump). Model access follows your subscription tier; locked models are marked as such.
- **`apatero_remix` requires a completed generation** and spends credits like a fresh generation.

## Environment

| Var | Default | Notes |
|---|---|---|
| `APATERO_API_KEY` | (optional) | `ap_live_...` key; alternative to `apatero login`, takes precedence if set |
| `APATERO_API_BASE` | `https://api.apatero.ai` | Point at a dev/staging API if needed |

## Troubleshooting

- **401 Unauthorized.** Your credential is missing or invalid. Set `APATERO_API_KEY` to an `ap_live_...` key, or run `apatero login` to sign in. On the remote transport, make sure the `Authorization: Bearer ...` header is present (the server returns 401 with an RFC 9728 challenge when it is absent).
- **402 Insufficient credits.** The account is out of credits for that generation (the error names how many are required when the API reports it). Top up at `https://app.apatero.ai/billing`.
- **"Still processing" result.** Video, avatar, Insta Dump, and influencer-clip jobs can outlast the polling window. You get the generation/job id back; poll it with `apatero_generation_status` (or `apatero_instadump_status` for batches) once it finishes server-side.

## Terminal Usage

```bash
apatero login                 # sign in once (or set APATERO_API_KEY for headless)
apatero models --modality image
apatero balance
apatero generate "a red fox in deep snow, golden hour" --aspect 16:9
apatero generate "an app icon, minimal" --model nano-banana-2 --no-wait
apatero status <generation_id>
apatero recent --limit 5
apatero logout
```

Maintainer publish + deploy steps live in [`DISTRIBUTION.md`](./DISTRIBUTION.md).
