AI-assisted draft. I wrote and verified the setup against the current Brandiseer MCP endpoint and developer docs.
Disclosure: I work on Brandiseer. This whole post uses its MCP server, so read it with that in mind.
Ask Cursor for a hero image for a landing page and you'll get something back. Usually it's a decent picture that has nothing to do with your brand. When I tried it for an old bakery site I got a croissant on grey marble with teal accents. The bakery's boxes are orange. Every follow-up prompt drifted a little further, because the agent has no idea what the brand looks like and guesses fresh each time.
What fixed it for me was moving the brand out of the prompt. The agent still decides when it needs an image and what goes in it. The look comes from a server that already knows the brand. That split is a good fit for MCP: the agent gets a few tools, and the rules live behind them.
What the server is
URL: https://brandiseer.com/api/mcp
Transport: streamable-http
Header: Authorization: Bearer bds_...
API keys start with bds_. The same key works for the REST API, but the header is different there (more on that below, it's the most common mistake).
The tools
brandiseer_list_brands
Returns your saved brands with id, name and creation date. Ids look like bds_c_42. The agent needs one before it can generate anything, so this is usually its first call.
brandiseer_check_credits
Returns your credit balance. I have the agent call it before anything batch-shaped.
brandiseer_generate_image
Generates one still image and returns it inline, so it shows up right in the chat. Under the hood it calls POST /api/v2/generate. The exception is mode: "design", which goes through the async endpoint (POST /api/v2/generate/async, then polling GET /api/v2/jobs/:jobId). The MCP server does that polling for you. From the agent's side it's still one tool call, it just takes longer.
Since it wraps v2, you're working with the v2 knobs:
| Option | Values |
|---|---|
| brand id | from brandiseer_list_brands
|
| prompt | what's in the frame (see the prompting section) |
| aspect ratio |
1:1, 16:9, 9:16, 4:3
|
| resolution |
1K, 2K, 4K
|
mode |
fast, design, pro
|
useLogo |
true / false
|
If you open the live manifest at https://brandiseer.com/.well-known/mcp/manifest.json you'll also see brandiseer_create_brand and brandiseer_check_brand_creation_job. Those are newer (API v2.2). You give it a website URL, it starts an async job, and you poll until it hands back a brandId. It costs 20 credits, charged only if the brand actually gets created. Handy if you don't have a brand yet, but I'm leaving them out of this walkthrough.
What you need
- A Brandiseer account with at least one brand saved
- An API key from Settings > API (
https://brandiseer.com/settings/api) - Cursor, or a Claude host that supports remote MCP servers
- A few credits. A fast 1K image is 4.
Wire it into Cursor
Cursor reads MCP config from .cursor/mcp.json in a project, or ~/.cursor/mcp.json for every project. Remote servers take a url and headers:
{
"mcpServers": {
"brandiseer": {
"url": "https://brandiseer.com/api/mcp",
"headers": {
"Authorization": "Bearer bds_YOUR_KEY"
}
}
}
}
I'd rather not have a real key in a file that can end up in git, though. Cursor interpolates ${env:NAME} inside url and headers, so this works too:
{
"mcpServers": {
"brandiseer": {
"url": "https://brandiseer.com/api/mcp",
"headers": {
"Authorization": "Bearer ${env:BRANDISEER_API_KEY}"
}
}
}
}
Put BRANDISEER_API_KEY in your shell profile or system environment and restart Cursor. Don't bother with a .env file here. envFile only works for stdio servers, remote ones ignore it.
Then open Customize in the sidebar and check the server is on and lists its tools. If it shows an error instead, the Output panel has an "MCP Logs" entry with the actual message.
Claude Code and Claude Desktop
This post is Cursor-first, but Claude Code takes the same two values:
claude mcp add --transport http brandiseer https://brandiseer.com/api/mcp \
--header "Authorization: Bearer bds_YOUR_KEY"
Or check it into the project as .mcp.json:
{
"mcpServers": {
"brandiseer": {
"type": "http",
"url": "https://brandiseer.com/api/mcp",
"headers": {
"Authorization": "Bearer bds_YOUR_KEY"
}
}
}
}
Claude Desktop is the odd one. As far as I know its custom connectors go through an OAuth sign-in rather than a header you paste. The server's 401 response does mention OAuth sign-in as an option, but I haven't walked through that flow for this post, so I won't pretend to document it. Any host that lets you set a URL plus a Bearer header uses the values above.
Prompting without fighting the brand
This is where most of the bad images come from. Brandiseer keeps each brand's colors, typography and visual style in its brand memory and applies them on every generation. If your prompt also says "navy palette" or "elegant serif headline", it competes with that, and it can win. Then you get an off-brand image out of a tool whose only job is the opposite.
So the prompt describes what's in the frame and how it's laid out: the subject, the layout and composition, and any text that goes on the image. Nothing about how it should look.
Fights the brand:
Instagram post for a coffee shop, cozy warm tones, minimalist aesthetic,
soft pastel colors, elegant serif font for the headline, latte on a
wooden table by a window
Works with it:
Instagram post for a coffee shop: a latte on a wooden table by a window,
morning light through the glass. Headline across the top: "Open from 7"
Some words sound like style but aren't. "Golden hour" and "studio lighting" describe what's physically in the scene. "Flat illustration", "isometric" and "photorealistic" pick the medium, which the brand doesn't decide. The ones to cut are mood words like "moody" or "cinematic", vague quality words like "premium", and any named color or font. The full rules are at https://brandiseer.com/guide/image. It's written for agents, so you can point yours at it directly.
Also, aspect ratio and resolution are tool arguments. Writing "square, 4K" into the prompt text does nothing.
Agents love to "improve" prompts with "clean modern aesthetic" on the way to the tool call. A project rule stops most of that. In Cursor, .cursor/rules/brandiseer.mdc:
---
description: Rules for Brandiseer image generation
alwaysApply: false
---
When calling brandiseer_generate_image:
- Describe subject, layout, composition and on-image text only.
- Never add colors, fonts, or mood words (moody, cinematic, premium).
The brand already sets those.
- Put aspect ratio and resolution in the tool arguments, not the prompt.
- Use mode "fast" unless I ask for design or pro. Never send proMode.
The same text works in a CLAUDE.md for Claude Code.
Smoke test
Three messages in agent chat, in this order.
1. "List my Brandiseer brands." The agent should call brandiseer_list_brands. Cursor asks before running an MCP tool by default, and the arrow next to the tool name shows the arguments. You get back ids, names and dates. Copy the id you want.
2. "How many Brandiseer credits do I have?" That's brandiseer_check_credits. If both of these work, auth is fine and anything that breaks later is about the generate call itself.
3. A boring, layout-only image.
Use brandiseer_generate_image with brand bds_c_42, aspect ratio 1:1,
resolution 1K, mode fast, no logo.
Prompt: a flat lay of a notebook, a phone and a coffee cup on a desk,
seen from above. Text at the top: "Monday plan"
Swap in your own brand id. Before you approve the call, expand the arguments and read the prompt the agent is actually sending. If it slipped in style words, reject it and say why. The image comes back inline.
For reference, credits per image:
| Mode | 1K | 2K | 4K |
|---|---|---|---|
| Fast | 4 | 6 | 8 |
| Design | 5 | 6 | 8 |
| Pro | 6 | 8 | 10 |
So that smoke test costs 4.
When it breaks
401 when Cursor connects. With no auth header at all the endpoint answers:
Missing Authorization: Bearer <api-key-or-oauth-token> header. Connect via
OAuth sign-in or paste an API key from https://brandiseer.com/settings/api.
The MCP endpoint wants Authorization: Bearer bds_.... X-API-Key is the REST header, and putting that in mcp.json is the usual mix-up. The other two I'd check are a missing Bearer prefix and an env var that only exists in one terminal session, which Cursor can't see.
Images come back off-brand. Read the prompt in the tool arguments. Usually there's a color or mood word in there that you didn't write.
Design mode looks stuck. Design takes roughly 40 to 70 seconds, and the MCP server is polling the async job for you during that time. Let it finish. Cancelling and asking again just submits a new job. For quick checks and iterating on a layout, stay on fast and switch to design once you know what you want.
When to use REST instead
MCP is for when an agent is in the loop. For a batch script, a CI step or a backend job, call the API directly. Use v2, which takes the key as X-API-Key:
curl -X POST https://brandiseer.com/api/v2/generate \
-H "X-API-Key: $BRANDISEER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"brandId": "bds_c_42",
"prompt": "Website hero: a baker pulling a tray of bread out of an oven. Headline on the left: \"Baked before 6\"",
"aspectRatio": "16:9",
"resolution": "1K",
"mode": "fast",
"useLogo": false
}'
That returns { "imageUrl": "...", "creditsUsed": 4 }.
For design mode with your own timeouts, submit to the async endpoint and poll. The docs say every 3 to 5 seconds, until status is done or failed:
import os
import time
import httpx
API = "https://brandiseer.com/api/v2"
headers = {"X-API-Key": os.environ["BRANDISEER_API_KEY"]}
body = {
"brandId": "bds_c_42",
"prompt": 'Event poster: a long dinner table in a courtyard. Text at the top: "Supper club, Friday 8pm"',
"aspectRatio": "4:3",
"resolution": "2K",
"mode": "design",
"useLogo": True,
}
with httpx.Client(headers=headers, timeout=30) as client:
r = client.post(f"{API}/generate/async", json=body)
r.raise_for_status()
job_id = r.json()["data"]["jobId"]
deadline = time.monotonic() + 9 * 60 # jobs expire after 10 minutes
while time.monotonic() < deadline:
time.sleep(4)
job = client.get(f"{API}/jobs/{job_id}").json()["data"]
if job["status"] == "done":
print(job["imageUrl"], job["creditsUsed"])
break
if job["status"] == "failed":
raise RuntimeError(job["error"])
# anything else: still running, keep waiting
else:
raise TimeoutError(f"job {job_id} did not finish")
A few details from the docs that matter here. Credits come off when you submit, and they're refunded automatically if the job fails. You have to poll with the same key you submitted with. Jobs expire after 10 minutes, hence the 9 minute deadline. I wrote up the general pattern (backoff, idempotency, Retry-After) in an earlier post on polling image jobs if you want more than this loop.
Full reference: https://brandiseer.com/developers/docs
Ignore proMode
The v1 API used proMode: true/false and only had fast and pro. v2 replaced it with mode. Some discovery surfaces still say proMode. As of 14 Oct 2026 that includes the description of brandiseer_generate_image in the MCP manifest itself, which says it "costs 4-10 credits depending on resolution and proMode".
Agents read tool descriptions, so Cursor may try to send proMode: true. For MCP and v2, use mode with fast, design or pro. That's why the rule file above says "never send proMode". /api/v1/generate still accepts proMode for old integrations, but don't mix the two. Not every surface is cleaned up yet, so if you see proMode in a doc, an OpenAPI file or a tool description, you're looking at the old API.
Top comments (0)