For AI agents & MCP clients
BananaBanana MCP Server
Generate AI images and videos directly from Claude Desktop, Claude Code and any other MCP client — billed per generation from your BananaBanana balance. No subscription.
One endpoint, every model
A remote Model Context Protocol server exposing the full BananaBanana generation stack as agent tools: Google Nano Banana 2 Lite / 2 / Pro images (from $0.03), Veo 3.1 / Fast / Lite video and Gemini Omni Flash with sound ($0.30–1.00). Your agent sees live prices, confirms costs before expensive runs, and every generation lands in the same history and balance as the website.
- Endpoint:
https://bananabanana.pro/api/mcp(Streamable HTTP) - Auth: sign in with OAuth 2.1 (claude.ai and other connector-style clients) or a Bearer API key from your profile
- Rate limit: 20 tool calls per minute per key; optional per-key daily spend cap
- No MCP client? The same endpoint is plain JSON-RPC over HTTPS — call it from curl, Python or TypeScript without any SDK
- Failed or filtered generations are refunded automatically
- Open docs,
server.jsonand copy-paste client examples in the bananabanana-mcp GitHub repository
Connected in three steps
1. Create an account and top up the balance. 2. In Profile → MCP API Keys create a key (shown once). 3. Add the server to your client:
claude.ai, Claude Desktop, mobile (OAuth — nothing to copy)
Settings → Connectors → Add custom connector, paste https://bananabanana.pro/api/mcp, then press Connect. Claude registers itself, you approve access on a BananaBanana screen, and generations are billed to the account you signed in with.
Settings → Connectors → Add custom connector
URL: https://bananabanana.pro/api/mcp
→ Add → Connect → approve access on bananabanana.proThe same flow works in any client that implements MCP authorization — MCP Inspector, ChatGPT and Grok web connectors, Claude Code. Connected apps are listed in your profile and can be disconnected there at any time.
Claude Code
# with an API key
claude mcp add --transport http bananabanana https://bananabanana.pro/api/mcp \
--header "Authorization: Bearer bb_live_YOUR_KEY"
# or with OAuth — no key, sign in in the browser
claude mcp add --transport http bananabanana https://bananabanana.pro/api/mcp
# then run /mcp inside Claude Code and pick "Authenticate"Claude Desktop
Add to claude_desktop_config.json (Settings → Developer → Edit Config); requires Node.js for the mcp-remote bridge:
{
"mcpServers": {
"bananabanana": {
"command": "npx",
"args": [
"-y", "mcp-remote", "https://bananabanana.pro/api/mcp",
"--header", "Authorization: Bearer bb_live_YOUR_KEY"
]
}
}
}Cursor
Add to ~/.cursor/mcp.json (global) or .cursor/mcp.json in the project; to keep the key out of the file, use ${env:BB_API_KEY} instead of the literal value:
{
"mcpServers": {
"bananabanana": {
"url": "https://bananabanana.pro/api/mcp",
"headers": {
"Authorization": "Bearer bb_live_YOUR_KEY"
}
}
}
}Full Cursor walkthrough, including quirks and a live-key demo: Generate Images in Cursor.
VS Code / GitHub Copilot
Add to .vscode/mcp.json in the workspace (or your user settings.json); VS Code prompts for the key once and stores it encrypted:
{
"servers": {
"bananabanana": {
"type": "http",
"url": "https://bananabanana.pro/api/mcp",
"headers": {
"Authorization": "Bearer ${input:bb-api-key}"
}
}
},
"inputs": [
{
"type": "promptString",
"id": "bb-api-key",
"description": "BananaBanana API key (bb_live_…)",
"password": true
}
]
}Full VS Code / Copilot walkthrough, including quirks and a live-key demo: Generate Images in VS Code: Copilot MCP Setup Guide.
Windsurf
Add to ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"bananabanana": {
"serverUrl": "https://bananabanana.pro/api/mcp",
"headers": {
"Authorization": "Bearer bb_live_YOUR_KEY"
}
}
}
}Windsurf MCP Setup: Generate Images in Cascade
Cline
{
"mcpServers": {
"bananabanana": {
"type": "streamableHttp",
"url": "https://bananabanana.pro/api/mcp",
"headers": {
"Authorization": "Bearer bb_live_YOUR_KEY"
},
"disabled": false,
"autoApprove": ["list_models", "get_account", "get_result"]
}
}
}Cline MCP Server: Generate Images From Your Editor
Any other MCP client (raw JSON-RPC)
POST https://bananabanana.pro/api/mcp
Authorization: Bearer bb_live_YOUR_KEY
Content-Type: application/json
Accept: application/json, text/event-stream
{"jsonrpc":"2.0","id":1,"method":"tools/list"}Every method except ping and the discovery lists (tools/list, prompts/list, resources/list) needs a credential — initialize included: an unauthenticated handshake answers 401 with a WWW-Authenticate challenge. The asymmetry is deliberate, not a bug: that challenge is how a connector client discovers this server uses OAuth. Reading the tool catalogue without a key still works.
Prefer a walkthrough? The tutorial Generate Images in Claude Code covers the Claude setup end to end, with four real use cases and their actual costs.
Client compatibility
MCP is an open protocol: any client that speaks Streamable HTTP and can attach an Authorization header connects. Current state, verified against each vendor's official docs (last checked August 2026):
| Client | Works today? | How |
|---|---|---|
| Claude Code | yes | claude mcp add --transport http … --header |
| Claude Desktop / claude.ai | yes | custom connector: paste the URL and sign in with OAuth (a request-header key also works, beta) |
| Cursor | yes | .cursor/mcp.json: url + headers, secrets via ${env:…} — see the snippet above |
| VS Code / GitHub Copilot | yes | .vscode/mcp.json: type: "http" + url + headers; store the key as a promptString input — VS Code asks once and keeps it encrypted |
| ChatGPT desktop / Codex CLI / IDE | yes | shared ~/.codex/config.toml: url + bearer_token_env_var (put the key in the env var). ChatGPT web connectors sign in with OAuth instead of a pasted key |
| Gemini CLI | yes | url + type: "http" + headers in settings.json (httpUrl also works). Setup guide |
| Windsurf | yes | serverUrl + headers in mcp_config.json (Devin Local agent: url + transport: "http"). Setup guide |
| Cline | yes | type: "streamableHttp" + url + headers in the MCP settings JSON. Setup guide |
| xAI API (Grok) | yes | MCP tool with server_url and an authorization value sent to the server |
| grok.com (web) | partially | custom connectors take a server URL (Connectors → New Connector → Custom); sign-in goes through our OAuth 2.1 flow |
| ZCode (GLM-5.2) | yes | Settings → MCP Servers → type HTTP + Authorization header; GLM-5.2 inside Claude Code inherits the Claude Code config |
| Anything else | yes | raw JSON-RPC over HTTPS — see Call it from code below |
Codex example — add to ~/.codex/config.toml and export BB_API_KEY=bb_live_…:
[mcp_servers.bananabanana]
url = "https://bananabanana.pro/api/mcp"
bearer_token_env_var = "BB_API_KEY"Full Codex walkthrough — CLI, IDE extension and ChatGPT desktop from one config, with quirks and a live-key demo: Codex MCP Setup: Images and Video from One config.toml.
Call it from code
Don't use an MCP client? You don't need one — and you don't need an SDK either. The server is plain JSON-RPC 2.0 over HTTPS: one POST endpoint, a Bearer header, a single JSON response. It is stateless, so there is no session handshake to manage — tools/call works as the very first request from curl, Python, TypeScript or anything else that can send HTTP.
curl
# start an image generation (charges one image, $0.03 on the default Lite model)
curl -s https://bananabanana.pro/api/mcp \
-H "Authorization: Bearer bb_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{
"name":"generate_image",
"arguments":{"prompt":"studio photo of a ceramic mug on linen, soft daylight"}}}'
# → result.structuredContent.job_id = "cmxy…"
# fetch the result (long-polls server-side up to 30 s; free)
curl -s https://bananabanana.pro/api/mcp \
-H "Authorization: Bearer bb_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{
"name":"get_result",
"arguments":{"job_id":"cmxy…","wait_seconds":30}}}'Python
Only requests — no MCP library:
import requests
MCP = "https://bananabanana.pro/api/mcp"
HEADERS = {"Authorization": "Bearer bb_live_YOUR_KEY"}
def call(tool, **args):
r = requests.post(MCP, headers=HEADERS, json={
"jsonrpc": "2.0", "id": 1, "method": "tools/call",
"params": {"name": tool, "arguments": args},
})
r.raise_for_status()
return r.json()["result"]["structuredContent"]
job = call("generate_image", prompt="watercolor painting of a lighthouse at dawn")
result = call("get_result", job_id=job["job_id"], wait_seconds=30)
while result["status"] == "processing":
result = call("get_result", job_id=job["job_id"], wait_seconds=30)
print(result["files"][0]["url"], "cost:", result["cost_charged_usd"])TypeScript / Node.js
Zero dependencies — built-in fetch (Node 18+, Deno, Bun, browsers):
const MCP = "https://bananabanana.pro/api/mcp";
async function call(tool: string, args: Record<string, unknown>) {
const res = await fetch(MCP, {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.BB_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
jsonrpc: "2.0", id: 1, method: "tools/call",
params: { name: tool, arguments: args },
}),
});
const { result } = await res.json();
return result.structuredContent;
}
const job = await call("generate_image", {
prompt: "isometric 3D render of a tiny greenhouse at golden hour",
});
let out = await call("get_result", { job_id: job.job_id, wait_seconds: 30 });
while (out.status === "processing") {
out = await call("get_result", { job_id: job.job_id, wait_seconds: 30 });
}
console.log(out.files[0].url, "cost:", out.cost_charged_usd);Details that matter when you script it:
- Every tool response carries the same JSON twice: machine-readable
result.structuredContentand a text block inresult.content— parse whichever is easier. - Video (and multi-image batches) are a two-step call: the first
generate_videoreturns a quote and charges nothing; repeat it withconfirm_costset to the quoted amount to start. - Pass an
idempotency_keyon generation calls — network retries will never double-charge. tools/listworks without a key, so you can explore the full schemas before creating an account. Tool calls are limited to 20 per minute per key.
Ten task-shaped tools
| Tool | Cost | What it does |
|---|---|---|
| list_models | free | All models with live per-unit prices, resolutions and constraints. |
| get_account | free | Balance, key spend cap and today's usage. |
| top_up | free | Create a secure balance top-up link. OAuth gets deposit-only access; API keys use the profile. |
| generate_image | $0.03–$0.20 | Text-to-image on Nano Banana 2 Lite / 2 / Pro, up to 4K. Returns a job_id. |
| edit_image | price of one image | Refine a finished image with a text instruction (multi-turn editing). |
| generate_video | $0.10–$4.40 | Veo 3.1 family or Omni Flash (always with sound), optionally from a start frame and reference images. Always quotes the exact cost first. |
| edit_video | $0.30–1.00 | Video-to-video editing on Omni Flash: your own clip or a public URL — restyle, replace objects, relight. First 10 s, 720p with sound. |
| generate_speech | $0.01 / 200 chars | Generate one- or two-speaker WAV speech. Charged per started 200 characters. |
| get_result | free | Poll a job: hosted media URLs (24 h links), cost charged, balance left, inline image preview. |
| list_generations | free | Recent generation history — shared with the website. |
Cost transparency, built in
- Prices are served live by
list_models— the same source the website uses. - Every video (and multi-image batch) call first returns a quote and charges nothing; the agent repeats the call with
confirm_costto start. - Every result includes
cost_charged_usdandbalance_remaining_usd. - Upstream failures and content-filter rejections are refunded automatically — same policy as the web app.
- Optional
idempotency_keyguarantees retries never double-charge.
A real conversation
→ generate_video {"prompt": "drone shot over a misty pine forest", "model": "veo-3.1-fast"}
← {"status": "confirmation_required", "quoted_cost_usd": 0.70, ...}
→ generate_video {..., "confirm_cost": 0.70}
← {"job_id": "cmxy…", "status": "processing", "cost_charged_usd": 0.70, "balance_remaining_usd": 12.40}
→ get_result {"job_id": "cmxy…"}
← {"status": "completed", "files": [{"url": "https://…"}], "cost_charged_usd": 0.70}Media URLs & security
- Result URLs are signed and valid for 24 hours; the media itself stays in your account — call
get_resultagain for fresh links, or download from the website. - API keys are stored hashed and shown only once at creation; revoke them any time in your profile.
- OAuth connections use one-hour access tokens with rotating refresh tokens, stored hashed and valid for this server only; disconnecting an app in your profile kills its tokens instantly.
- Per-key usage log (tool, model, cost, prompt preview) is visible in Profile → MCP API Keys.
- MCP generations appear in the same generation history and analytics as web generations.
Ready to plug your agent in?
Create a key, add one config line — your agent generates studio-grade media in minutes.
Get your API key