Generate Images in Cursor: MCP Server Setup Guide
Connect Cursor to one remote MCP server and generate images straight into your repo: mcp.json config, env-var secrets, client quirks, real costs from $0.03.
Orijinal en dilinde

An MCP server for Cursor is an external toolbox the editor's agent can call from chat: you add one JSON block to mcp.json, and Cursor gains abilities its base models don't have, image generation included. Cursor's agent edits files and runs terminal commands all day, but none of the models behind it can produce an image file. Wire in a generation server and "make me a 16:9 hero for this landing page" becomes a normal chat instruction that ends with a real file in your repo.
Here's the whole setup, if that's all you came for. Create an API key in your BananaBanana profile, then add this to ~/.cursor/mcp.json (global) or .cursor/mcp.json in the project:
{
"mcpServers": {
"bananabanana": {
"url": "https://bananabanana.pro/api/mcp",
"headers": {
"Authorization": "Bearer ${env:BB_API_KEY}"
}
}
}
}
Export BB_API_KEY=bb_live_YOUR_KEY in your environment and you're done. No local server process, no Google Cloud account, no subscription. Images bill from $0.03 off a prepaid balance, video from $0.10. Both demo images in this guide were generated through this exact config on a live key while I wrote the text; the traces and the $0.55 media bill are below.
Why bolt an image generator onto Cursor?
Because frontend work keeps needing images at exactly the moment your hands are in the code. A hero for the landing page. Product-card placeholders so the grid doesn't ship with grey boxes. An OG image for the blog post you just wired up. None of these are hard, but each one used to mean the same detour: open a generator in a browser tab, type a prompt, download, rename, drag into public/, come back, write the <img> tag. Ten minutes of glue work per asset, and you've lost your place in the component.
With an MCP server the agent runs that whole loop. It writes the prompt (usually better than my lazy first draft), calls generate_image, downloads the result into the right folder, and writes the markup with alt text. You review a diff instead of doing chores.
The other half of the pitch is what you don't install. Local MCP servers for image generation exist and work, but they mean running your own Node or Python process and bringing your own Google API key, with quotas and billing on your Google account. A remote server skips all of it: the endpoint already runs on our side, on the same pipeline as the BananaBanana generator, and your only credential is one bb_live_ key.

How do you add an MCP server to Cursor?
Three steps, about two minutes. Config details below are checked against the official Cursor MCP docs as of July 11, 2026.
First, register and open Profile → MCP API Keys. Create a key. It's shown once, starts with bb_live_, and is stored hashed on our side, so copy it immediately. New accounts start with $0.10 on the balance, enough for three test images on the cheapest model.
Second, pick where the config lives. Cursor reads two locations:
~/.cursor/mcp.json— global, the server follows you into every project;.cursor/mcp.jsonin the repo root — project-scoped, and safe to commit if you keep the key out of it.
That "if" is what the ${env:BB_API_KEY} interpolation in the snippet above solves: Cursor substitutes environment variables into mcp.json values at load time, so the file itself contains no secret. The same syntax also supports ${workspaceFolder} and a few other variables, per the docs.
Third, restart or reload Cursor and open Cursor Settings → MCP. The server should show up with a green indicator and a list of seven tools, list_models through list_generations. Our MCP server page keeps the same snippet plus a compatibility table for every other client we've verified:

If the server doesn't appear, jump to the quirks section. The cause is almost always the environment variable, not the config.
Use case: a landing hero and product shots without leaving the chat
The scenario this article was built around: you're a frontend developer assembling a landing page for an outdoor gear brand, and the design calls for a full-width dawn-camping hero. In Cursor's chat you ask for it, the agent composes a photography-style prompt and calls the tool. This is the actual trace from my session, real job id and all:
→ generate_image {"prompt": "A photorealistic wide hero shot for an outdoor
gear brand landing page: a lone orange tent glowing softly on the shore of
a still alpine lake at dawn, mist over the water, sharp granite peaks
catching the first pink light, generous empty sky for headline text, low
angle, 35mm lens, no text", "model": "nano-banana-pro", "aspect_ratio": "16:9"}
← {"job_id": "cmrgox3xj000s…", "status": "processing",
"cost_charged_usd": 0.11, "balance_remaining_usd": 1554.40}
→ get_result {"job_id": "cmrgox3xj000s…"}
← {"status": "completed", "files": [{"url": "https://bananabanana.pro/api/files/…"}]}
Eighteen seconds from call to finished file. Here's that exact output, first take, no rerolls:

The agent then pulls the file from the signed URL into public/ and writes the component. Links stay valid for 24 hours; a fresh get_result call reissues them after that.
Product placeholders are the same move with a squarer brief. For the card grid I asked for a water bottle shot the way you'd brief a photographer: subject, surface, light, lens. One call, $0.11, twenty seconds:

Both demos ran on Nano Banana Pro because they ship on this page. For throwaway grid fillers I'd honestly use nano-banana-2-lite at $0.03 and upgrade only the images that survive the design review; our Lite guide covers where the cheap model is good enough. And if you need the same mascot across a series of images, prompting technique matters more than the client, so see the character consistency field guide.
Video works from the same chat too. generate_video never charges on the first call: it returns a quote, and the agent must repeat the call with confirm_cost accepting the exact amount. A silent 720p Veo 3.1 Lite clip starts at $0.10; Omni Flash with sound is a flat $1.00.
Cursor quirks worth knowing before you ship
Every client has its own sharp edges. These are the ones I'd actually warn a teammate about, collected while testing the setup above.

1. ${env:…} only works if Cursor can see the variable. An export in your .zshrc is visible when you launch Cursor from a terminal, but a GUI app started from the Dock or a desktop launcher doesn't read your shell profile, so the same config silently fails there. In my experience this is the number one "server won't connect" cause on macOS. Fixes: set the variable at the OS level (launchctl setenv on macOS, or system environment variables on Windows), or launch Cursor from a terminal once to verify the config is otherwise fine.
2. The project config is a team feature, one key per person. Commit .cursor/mcp.json with the ${env:BB_API_KEY} placeholder and every teammate gets the server the moment they clone, each on their own key. That split matters more than it looks: keys are free, and each one gets its own usage log (tool, model, cost, prompt preview) and an optional daily USD cap in Profile → MCP API Keys. When someone leaves, you revoke one key, and nobody else notices. Cursor's business plans can also push MCP servers from the team dashboard, but the committed file works on any plan.
3. Cursor asks before every tool call, and you should probably leave that on. By default each MCP call waits for your approval, with the arguments visible under a small arrow next to the tool name. In auto-run modes, allowlisted tools execute immediately. Clicking approve twenty times during a batch gets tedious, I know, but for tools that spend real money per call I'd keep approval on and let only the free ones (list_models, get_result) auto-run. Video has a second seatbelt on our side regardless: nothing above a quote is charged without confirm_cost.
4. You see the render inside the chat. Per the Cursor docs, images returned by MCP tools are attached to the conversation, and vision-capable models analyze them. Our get_result includes a small webp preview alongside the URL, so the agent (and you) can judge a render without opening a browser. It also means the agent can self-correct: ask it to check the image and reroll if, say, the tent ended up in the middle of the headline area.
5. One-click install links exist, but don't put keys in them. Cursor supports cursor:// deeplinks that install an MCP server from a base64-encoded config, per the install-links docs. Handy for open servers; wrong for authenticated ones, because the encoded config would carry your literal key, and anyone who gets the link gets your balance. That's why the button on our site is a copy-paste snippet with an env placeholder instead of an Add-to-Cursor deeplink. Paste, export the variable, done.
One honest limitation from the product side while we're being frank: the MCP generate_image tool doesn't accept input images yet, so reference-based generation and image-to-video still need the web generator. Text-to-image, multi-turn edit_image refinement and text-to-video all work over MCP today.
What did this article's demo media cost?
Standard per-generation prices, same numbers list_models reports to the agent, no staff discount:
| Asset | Model | Price |
|---|---|---|
| Landing hero demo, via MCP from a live key | Nano Banana Pro, 1K | $0.11 |
| Product placeholder demo, via MCP | Nano Banana Pro, 1K | $0.11 |
| Cover + 2 editorial illustrations | Nano Banana Pro, 1K | $0.33 |
| Docs-page screenshot | browser, not a generation | $0.00 |
| Total | $0.55 |
Every generation landed on the first attempt this time, which won't always happen; budget a reroll or two on product shots and zoom in before shipping, since object geometry is still where photorealistic models slip most often.
If you already run this server in Claude, the Cursor config above is the only new part: same key, same balance, same history. If you're starting from zero, the Claude Code walkthrough covers four more use cases that apply to Cursor almost verbatim. Ready to try? Create a key and ask Cursor for your first hero image.
FAQ
Does Cursor support remote MCP servers with an Authorization header?
Yes, natively. Since Cursor added Streamable HTTP transport, a remote server is just a url plus an optional headers object in mcp.json, no local bridge process required, and ${env:VAR} interpolation keeps the secret out of the file. That's the config this guide uses, verified against the official Cursor MCP docs on July 11, 2026. Cursor also supports OAuth for remote servers; our endpoint currently authenticates with Bearer keys, with OAuth 2.1 planned as a second option.
Do I need a Google API key to generate images in Cursor?
No. Locally-run image MCP servers call the Gemini API directly, so they need your own Google key with your own quotas and billing. With the remote server the generation runs on BananaBanana's managed pool of Vertex AI keys, and your only credential is the bb_live_ key from your profile. You trade direct access to Google's raw API for per-generation prices with no minimum spend, one prepaid balance, and a key you can revoke in one click.
Should the MCP config be global or per-project?
Both work; the difference is scope and sharing. ~/.cursor/mcp.json follows you into every repo, which suits a personal setup. .cursor/mcp.json in the project root travels with the repo, so the whole team gets the server after a clone; keep the key as an ${env:…} reference and the file is safe to commit. My default is project-level for anything a team touches, because a committed config plus per-developer keys gives you usage logs and revocation per person.
Can Cursor generate video through the same server?
Yes, with a cost-confirmation step. The generate_video tool always returns a quote first, and the agent must repeat the call with confirm_cost matching the exact amount before anything is charged. Prices run from $0.10 for a 4-second silent 720p Veo 3.1 Lite clip up to $4.40 for a top-end Veo 3.1 render with audio, and Omni Flash with sound is a flat $1.00. Clips take one to ten minutes, so the agent polls get_result while it keeps working on your code.
Why doesn't my server show up in Cursor after editing mcp.json?
Three usual suspects, in order of likelihood. The environment variable isn't visible to the Cursor process: GUI-launched apps don't read your shell profile, so set the variable at the OS level or start Cursor from a terminal. The config didn't reload: fully restart Cursor or use the refresh control in the MCP settings. Or the JSON is subtly invalid, a trailing comma being the classic. If the server shows up but tool calls fail with 401, the key itself is wrong or was revoked; test it with a raw request from the snippet on the MCP server page.