no-api-media
Provides image and video generation using Google AI Pro/Ultra accounts, including Nano Banana and Veo 3.1 through Google Flow and Gemini, with sign-in and status checks.
Provides image generation through ChatGPT (GPT Image) using a ChatGPT Plus/Pro account, either via the Codex CLI or chatgpt.com sign-in, with account status and credit checks.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@no-api-media create a 16:9 hero image for our landing page, match the site's style"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
no-api-media-mcp is an open source MCP server (Apache-2.0, Node 22+) that lets Claude Code, Cursor, Codex and other MCP clients make images and videos for your projects with the AI subscriptions you already pay for. No API keys. No second bill. Uses your own ChatGPT, Google AI Pro, Higgsfield and Grok accounts.
Intro video • Features • Quick start • Connect accounts • Installation • Tools • CLI commands • Troubleshooting
Watch the 72 second intro
https://github.com/user-attachments/assets/c96b3ad1-4795-4c54-91e7-95d3cd4627d3
A short narrated tour, 1080p: the problem it solves, the server making a real image from a prompt, and how to install it. The video itself was made with our own intro video tool and its synthetic NexaForge narrator. Download the MP4 (9.4 MB).
Related MCP server: img-vid-mcp
Features
Images and videos from your own plans: GPT Image (ChatGPT via Codex), Nano Banana and Veo 3.1 (Google Flow), Gemini, Higgsfield (Seedance, Kling and more), Grok
No API keys at all: you sign in once, by hand, in a private Chrome window. API-key variables are stripped before any tool runs
Understands your project: reads what it does, its colours, fonts, 3D or animation libraries and existing images, then matches the style (luxury, premium, playful, corporate, modest)
Premium by default: writes a real creative brief for every asset, with named looks like
neon-glass(the style of the graphics on this page)Built-in media studio (new in 0.2): background removal, video editing for Reels and Shorts, and every social size from one image, all running locally
Saves straight into your project: full quality, no Download folder, no Save dialog, never outside the project
Shrinks for the web without visible loss: WebP and H.264, checked with an SSIM quality score
Credit-safe: shows the cost first, hard
max_creditscap, one job at a timeAdd any site with a small JSON file, no code
What's new in 1.x
Made the way the server now recommends: the background came from design_brief and image_generate (Codex on a ChatGPT plan), every word and logo was set on top in HTML instead of being drawn by the model, then composition_check and media_optimize checked and shrank it. None of the graphics on this page show another company's logo.
Tool | What it does |
| Sets your real headline and a registered brand's logo over generated art: measured placement, at least 4.5:1 contrast, the brand's fonts, no glow |
| The exact file a platform wants (linkedin-feed, instagram-story, x-post, github-social and more): size, smallest JPEG that still looks identical, under the size limit |
| The brands you publish under, with who publishes (a person or a company) and their real logo files, so the right mark is never guessed |
| Remembers what you said was wrong and applies it to every later brief, per brand if you like |
| Finds empty bands at the edges and crops them while keeping your target shape |
| Closes the browser when the work is finished, never while another session still uses it |
The media studio (since 0.2)
Tool | What it does |
| Cuts out the subject into a transparent PNG with BiRefNet models via rembg. Fully local, nothing uploaded. Quality: |
| Trim, reframe to 9:16 / 1:1 / 16:9 / 4:5, speed, fade, mute, replace audio, poster frame, GIF, text overlay, logo, burned-in subtitles, join clips |
| One image into Open Graph, LinkedIn, X, Instagram square/portrait/story, YouTube thumbnail, Pinterest, GitHub social preview, favicon and app icons. Cover, blurred-fill or solid padding |
| Duration, size, frame rate and codecs of any file |
Try:
Remove the background from public/products/lamp.jpg.
Turn this 16:9 clip into a 9:16 Reel with our logo top-right and these subtitles.
Make every social size from public/og.png.Quick start
git clone https://github.com/farhan6667/no-api-media-mcp
cd no-api-media-mcp
npm ci
node dist/src/index.js setupnpm ci installs the exact dependency versions in package-lock.json and builds the server.
setup checks your machine, opens a Chrome window where you sign in to ChatGPT and Google, and prints the line to add to your AI client. Then just ask your agent for what you need.
No prompt writing needed
You don't write image prompts. When your AI client connects, this server hands it a full workflow, and the agent follows it on its own:
Reads your project: what it does (from the README or site), colours, fonts, 3D or animation libraries, existing images
Writes a real creative brief: what the project is, where the image goes, who sees it, what it must achieve, and a premium quality bar. This is the part that makes results look high-end instead of generic
Generates with the right tool: GPT Image (ChatGPT) for designs with text, Google Flow for photo and 3D scenes
Checks every result against a design checklist (spelling, brand fit, no third-party logos, crop) and retries with a corrected brief
Shrinks and places the winner in your project, with real alt text
Try one of these
Copy any of these into Claude Code, Cursor or Codex, inside your project:
Look at this project and tell me where images or video would make the site better, then make them and put them in.Make a premium 16:9 hero image for the landing page that matches our brand.Create a 1200x630 social preview image for this repo, with the project name spelled exactly.Make a premium infographic that explains what this project does, for the top of the README.Make an 8 second calm background video for the hero, quote the credits first.That's the whole interface. Say "premium", "luxury", "minimal" or "playful" if you want a specific level, otherwise it aims for premium.
Made with this MCP
Both of these came out of the prompts above, through Google Flow on an AI Pro plan, 0 credits, no API key:
At a glance
It designs for who's actually looking
Tell design_brief who sees the asset (context.audience, plain English: "CISOs", "developers", "the open source community", "security analysts", "the general public") and it recognises a few real audiences and changes the art direction for them: tone, a default style tier and a palette when you haven't set your own, plus one honest critique question asked from that reader's seat.
You said | It assumes | Tier | A question it adds |
CISOs, executives, buyers | time-pressed, skeptical of a hard sell | corporate | Would they get the one thing that matters in three seconds? |
developers, engineers | can tell marketing gloss from substance | minimal | Would they believe it, or tune it out? |
the open source community, GitHub | scanning a repo list, not a product page | premium | Does it read as open source, not a corporate ad? |
security analysts, pentesters, SOC teams | seen a hundred vendor decks already | premium | Would a working analyst trust it? |
the general public, gamers, consumers | scrolling for fun | playful | Is it fun without turning childish? |
Don't invent an audience it doesn't recognise, say so plainly and it's simply left unset.
It sets the text and logo itself, then delivers the final file
Generated art is only half a post. Register the brands you publish under once:
brand_profiles(action="set", id="sfa", name="SFA", publisher="person", logo_dark="/path/sfa-logo.webp")Then compose sets the headline and that brand's real logo over the art. It measures the picture to find the calmest corner, keeps the text out of the busy part, picks the text colour and a soft scrim for at least 4.5:1 contrast, and never adds a glow. deliver turns the result into the file a platform wants:
compose(input_path="art.png", headline="Shadow AI", brand_id="sfa", platform="linkedin-feed")
deliver(input_path="art-composed-linkedin-feed.png", platform="linkedin-feed")That gives an exact 1080x1350 JPEG, as small as it can be without a visible change, metadata stripped, under LinkedIn's limit, and checked for an empty band.
It measures its own work, and remembers your corrections
design_audit doesn't only take the model's word for it: given the file, it measures it, and an empty band at an edge or a washed-out thumbnail caps the score so a weak result can't ship. composition_check does the same on demand and gives a crop that keeps your target shape.
When you say a result was wrong (the crop, the colours, the wrong logo), the assistant records it with design_feedback, and every later brief applies it. A correction can be tied to one brand, so "use my personal mark" never leaks onto company posts.
It handles several sessions at once
Each Claude (or Cursor, or Codex) session runs its own copy of this server, but there's only one signed-in browser profile. By default a second session simply opens its own tab in the same browser, so both jobs run side by side.
This works through a loopback-only Chrome devtools port that's open while the browser is open. On your own computer that's fine. On a shared machine, turn it off:
node dist/src/index.js config set share_browser falseWith sharing off, the second session waits in line instead and says so in its progress messages: its place in the queue, how long it has waited, and an estimate once there's enough history (taken from how long recent jobs on your machine really took). It carries on by itself when the browser frees up.
The brief also asks before it guesses now: if it doesn't know where an image will be used or what post it goes with, design_brief returns needs_from_user with those questions, so your assistant asks you once instead of producing the wrong size or the wrong message.
It knows 3D and WebGL sites need different assets
Two more asset types for design_brief: texture (a seamless, tileable surface for a background or a Three.js material) and environment-map (a seamless 2:1 equirectangular panorama for reflections and lighting in a Three.js or WebGL scene). Each gets its own critique checklist instead of the usual photo-realism one, since neither is meant to be looked at directly.
loop_check(input_path=".ai-media/flow/hero-loop.mp4")Compares a looping video's first and last frame the same way media_optimize checks quality loss, and tells you if the loop will actually look seamless before it ships.
palette_extract(input_path="public/images/hero.jpg", count=6)Pulls the real dominant colours out of a generated (or any) image and returns a ready :root CSS block, so the site's design system can match what actually got made instead of a guess.
The server also recognises the kind of project it's in on its own now: a GitHub repo, a single social post, a 3D/WebGL site, or an animated landing page, and reaches for the matching asset types without being told each time.
It remembers what actually shipped
design_audit can carry the style (tier and look) a draft used. Once enough drafts of one asset type have shipped under the same tier, design_brief defaults to it on its own next time, instead of always starting from premium. Ask for a specific tier or look and that always wins; this only fills in the gap when you didn't ask.
It compares drafts side by side
contact_sheet(input_paths=["dir1/a.png", "dir1/b.png", "dir1/c.png"], output_path=".ai-media/compare/hero.jpg")Lays up to 12 images on one grid instead of one at a time. No text is baked into the image; the result lists which grid position holds which file.
It knows what actually keeps platforms from cutting your reach
Meta has said plainly that a plain "AI info" label does not by itself reduce a post's reach. What does get penalised is content that reads as a real photo of an event, person or statement that never happened. design_brief's critique list now asks that question directly for every realistic asset type, and social_sizes covers Facebook, YouTube and X/Twitter cover sizes alongside LinkedIn, Instagram and Pinterest.
It keeps a face or a look consistent
Pass reference_images to image_generate (Codex provider only) and the generated picture is built from your own photos. Use it for a person's portrait, a product, or a style you have already approved. The description says what to keep (for example "the same face, glasses and beard") and what to change (clothes, pose, setting, light).
image_generate(provider="codex", reference_images=["refs/me.png", "approved/portrait-v1.png"], prompt="Keep my face exactly. New navy blazer, glass wall at blue hour, calm expression...")Up to four images, and each one has to be a real image file inside the project. Only use a photo of someone who has agreed to it, which usually means your own. For a fixed expression or a repeated fix, name the exact fault in the prompt ("brow crease, flat mouth") and pass the previous result as a reference. It is the one place a client can ask for a specific person, so the server never fetches a reference from the web.
It falls back when a provider breaks
Browser-driven providers depend on the site's own pages, and a redesign can break a selector overnight. Pass fallback_providers to image_generate and it tries the next one automatically instead of failing the whole run:
image_generate(provider="flow", fallback_providers=["codex", "gemini"], ...)The result always lists every attempt and why each one failed, so nothing is silently swallowed. A second local journal (separate from the design one) tracks these outcomes, and when a provider fails the same way three times in a row, the next error says so plainly instead of staying a mystery.
It checks for a new version
Once a day, the server checks this project's GitHub releases. If a newer one is out, it tells you at startup
and in status/setup: what changed, and the exact command to update. It never patches itself while running,
and it never installs anything unless you turn that on:
Setting | Default | What it does |
| checks on | stop checking entirely |
| off | npm installs only: once a newer version is found, install exactly that version with npm for you; it takes effect the next time the server starts, never mid-run. A git checkout is never changed; the notice tells you to |
| 24 | how often to check |
The check is a plain, unauthenticated read of this repo's own GitHub releases, with a size cap and a short
timeout, and a failed check never breaks a real tool call. Only a plain version number (like 1.4.1) is
ever handed to npm.
The package is not published on npm yet, so the setup command and the client config always point at your
own copy by its full path, never at npx no-api-media-mcp.
It learns from its own mistakes
Every time the model scores an image with design_audit (and tells it the asset type), the server writes the scores to a small local journal in your no-api-media folder. It is never uploaded and never lives inside a project. The next design_brief for that kind of asset reads it back: any criterion that has fallen short at least twice (for example "not template" or "brand presence") is turned into advice and put into every prompt up front. A mistake that happened twice stops happening a third time.
On top of that, design_brief carries a short list of built-in lessons from real use, such as these:
Never ask the model to draw a real logo or to spell words. Leave a calm area, then place the real logo file and the text afterwards.
If the image will be cropped much wider than 16:9, keep every important element in the middle band. Set
context.targetAspect(for example3.2:1for a profile banner) and the brief adds this guidance for you.A single big centred object reads as stock. Ask for an abstract backdrop with open space and let the real brand mark be the focal point.
A black-background logo dropped on busy art washes out. Put it on a dark glass plate or a feathered mask.
The full list, with the reasons and the provider notes, is in docs/lessons.md.
It keeps your project tidy
Generated drafts land in <project>/.ai-media. Left alone, that folder fills up with rejected attempts. The server now tracks what happened to each draft:
Status | How it gets there | When it is removed |
draft | just generated | after 30 days |
shortlisted |
| after 60 days |
rejected |
| after 3 days |
used |
| after 14 days, and only if that final file still exists |
Pass the draft's file to design_audit and media_optimize does the rest on its own. The final image goes to your project's own images folder, so nothing important stays in .ai-media.
Cleanup runs once per session, and you can run it yourself with media_cleanup (a dry run by default, so it first shows what would go and how much space it frees). It is strict on purpose: it only looks inside .ai-media, never touches your final files, skips symbolic links, and ignores anything that is not a media file. If .ai-media itself is a link or junction (a cloned repo could ship one), it refuses to read, write or delete anything there. Turn the automatic part off with node dist/src/index.js config set auto_cleanup false or NOAPI_AUTO_CLEANUP=0.
Connect your accounts
You sign in yourself, once. The server never asks for or sees a password.
Account | You need | How to connect | Ready when |
Google AI Pro / Ultra (Flow, Gemini) | A Google account with the plan | Sign in at the Google tab in the setup window |
|
ChatGPT (images) | ChatGPT Plus or Pro |
|
|
Higgsfield | A Higgsfield plan |
|
|
Grok or any JSON site | That site's plan | Ask your agent to run |
|
Close the whole setup window when you're done. The server can't use the private profile while it is open.
Installation
Requirements: Node 22+, Google Chrome, and ffmpeg for shrinking and editing. Optional: rembg for background removal (uv tool install "rembg[cpu,cli]" or pip install "rembg[cpu,cli]"; the model downloads once on first use).
# all projects
claude mcp add --scope user no-api-media -- node /full/path/to/no-api-media-mcp/dist/src/index.js
# this project only
claude mcp add no-api-media -- node /full/path/to/no-api-media-mcp/dist/src/index.jsAdd to your MCP config:
{
"mcpServers": {
"no-api-media": {
"command": "node",
"args": ["/full/path/to/no-api-media-mcp/dist/src/index.js"]
}
}
}Config file locations:
App | File |
Claude Desktop (Windows) |
|
Claude Desktop (macOS) |
|
Cursor |
|
Windsurf |
|
Restart the app after editing.
.vscode/mcp.json:
{
"servers": {
"no-api-media": { "command": "node", "args": ["/full/path/to/no-api-media-mcp/dist/src/index.js"] }
}
}codex mcp add no-api-media -- node /full/path/to/no-api-media-mcp/dist/src/index.jsTools
Tool | What it does |
| Opens the private Chrome window so you sign in |
| Which accounts are ready, plan tier, low-credit warnings |
| Every provider and JSON site, and what each can make |
| Reads the project: style tier, 3D/animated, colours, fonts, reference images |
| Writes a real creative brief (project, purpose, placement, premium quality bar) with concept directions and a critique checklist. Asset types: logo, app icon, hero, illustration, product shot, social post, banner, infographic, poster, background video, product video |
| The art-director check after you look at an image (pass |
| Makes images with |
| Exact credit cost for a Flow or Higgsfield job, generates nothing |
| Veo 3.1 / Omni in Flow, Seedance / Kling in Higgsfield, or Grok, with a credit cap |
| Image to WebP, video to H.264, smaller with no visible change. Strips embedded metadata by default and reports it (see the behaviour notice); |
| Transparent cutout, local BiRefNet models via rembg |
| Trim, reframe, speed, fade, mute, audio, poster frame, GIF, text, logo, subtitles, join |
| Every social and icon size from one image |
| Duration, size, fps, codecs |
id | Makes | Signs in with | Notes |
| images | Codex CLI, ChatGPT login | Most reliable ChatGPT route |
| images | chatgpt.com in the private profile | Cloudflare may ask for a human check; use |
| images, videos | Google, in the private profile | Nano Banana 2 images were 0 credits on AI Pro when tested; videos cost credits |
| images | Google, in the private profile | |
| images, videos | official CLI (OAuth) | Exact cost shown before every job |
| images, videos | grok.com in the private profile | Limits depend on your plan |
Where files go
No
output_path:<project>/.ai-media/<provider>/<date>-<prompt>.<ext>, ignored by git, with amanifest.jsonlof every promptWith
output_path(e.g.public/images/hero.png): must be inside the project and a media file, checked before anything is generated
CLI commands
Command | What it does |
| Check everything, open the sign-in window, print client config |
| Sign in to one service again ( |
| Show which accounts are ready, without opening a window |
| Print the version |
| Show |
| Keep embedded metadata in optimized files ( |
| Other keys: |
| List these commands |
| Check the Codex CLI is signed in with ChatGPT |
| List Higgsfield workspaces to pick one |
| Run the test suite (unit and security tests) |
Without a command, dist/src/index.js runs as the MCP server. That's what your AI client starts.
Troubleshooting
You see | Do this |
| The sign-in window (or another copy of the server) is still open. Close that Chrome window and try again |
| Run |
| ChatGPT's Cloudflare noticed automation. The server never solves these. Use |
| Run |
| Your plan's Codex quota is spent. Use |
|
|
| Sign in with the account that has your AI plan, or set |
| Google changed the Flow page. Update to the latest version or open an issue |
| Video credits are low. Images on Nano Banana 2 usually still work |
| Install Chrome or set |
|
|
|
|
|
|
| Your network inspects TLS. The server passes your system certificates to rembg automatically; if it still fails, run once on another network, the model is cached afterwards |
| Use a path inside the project, like |
|
|
| A symbolic link or junction in that path leads to a missing place. Pick another path or remove the link |
Nothing happens on a Linux server | Chrome needs a display. Run under Xvfb |
Configuration
All optional.
Variable | Default | Meaning |
|
| Private profile and state. Delete it to sign out of everything |
| the folder the client starts the server in | Folders the server may write to |
| first signed-in account | Which Google account to use |
|
| Seconds between two generations on one provider |
| unset |
|
| auto-detected | Binary locations |
Add another site without code
Put a file in ~/.no-api-media/providers/<id>.json. Start from examples/providers/template.json. Media is only downloaded from the hosts you list in mediaHosts, and specs are never read from a project folder.
Safety and terms
Your password never touches this code and the server can't write outside your project. It listens on no network port of its own; the one port is Chrome's loopback-only devtools port while
share_browseris on (the default), which you can turn off. The full threat model is in SECURITY.md.Web providers drive the consumer sites the way you would by hand. OpenAI's, Google's and xAI's terms restrict automated use of those sites, so using them is your call and your account's risk. The server works at human pace, stops at captchas and sign-in pages, and doesn't hide that it is automation. Official CLIs (Codex, Higgsfield) are the safer routes.
Behaviour notice: metadata is stripped from optimized files
Since 0.3.0, media_optimize removes embedded metadata from the files it writes: EXIF, XMP, text chunks and C2PA content credentials (the signed manifest that ChatGPT, Codex, Google Flow, Gemini and Veo embed, and that platforms such as LinkedIn turn into a "Content credentials" badge). This is what most web image optimizers and CDNs do, and in fact 0.2 already dropped it as a silent side effect of re-encoding. 0.3 makes it explicit: every result lists what was removed, and you can turn it off.
Your originals are never touched. Generated files in
.ai-media/keep their manifests; only the optimized copy is stripped.Turn it off in any of three ways:
keep_metadata: trueon a call, the environment variableNO_API_MEDIA_KEEP_METADATA=1, ornode dist/src/index.js config set strip_ai_metadata false.What it does not do. This removes embedded metadata only. It does not remove invisible watermarks such as Google SynthID, which live in the pixels, so platforms and detectors may still identify the AI origin. It is not a way to pass AI images off as real photographs. You are responsible for the rules of the platforms you post to and for any disclosure requirements that apply to you.
A signed C2PA manifest cannot survive re-encoding anyway (it is bound to the original bytes), so with
keep_metadata: truethe result is honest about what the encoder lost rather than copying an invalid manifest.
Frequently asked questions
How do I generate images and videos in Claude Code without an API key?
Install this MCP server, then sign in once to ChatGPT, Google (Flow and Gemini), Higgsfield or Grok in the browser window it opens. After that you can ask Claude Code, Cursor or Codex for an image or a video and it uses the plan you already pay for.
Does it see my password?
No. You type your password yourself in a normal browser window. The server never asks for it, types it or stores it. With share_browser off it drives the browser over a pipe only; with it on (the default) Chrome also opens a loopback-only devtools port so several sessions can share the window, which any program on your computer could use while it's open. Turn it off on a shared machine.
Can it bill my API account by accident?
It is built to prevent that. API key variables are removed from every child process, and Codex only runs when its login status shows a ChatGPT login.
Which clients and providers does it work with?
Any MCP client, including Claude Code, Cursor, Codex and Windsurf. Providers are ChatGPT through Codex, Google Flow (Veo and Nano Banana), Gemini, Higgsfield and Grok, plus any other site you describe in a JSON file.
Which assistant model should I use?
The images themselves come from your provider's image model (GPT Image through Codex or ChatGPT, Nano Banana through Flow or Gemini), so picking a different assistant model doesn't change the picture directly. It does change the result: your assistant writes the brief, looks at every draft and scores it honestly, and sets the final text and logo. Use a current top-tier model with good image understanding and tool use; small, fast models tend to skip steps or pass weak drafts. For designs with words, codex renders text best; for photo and 3D scenes, Flow.
What do I need to install to use it?
An MCP client to talk to it, plus whatever sign-in the providers you want need.
Claude Code: in the terminal, the desktop app, or the Claude Code extension for VS Code. See claude.com/claude-code. Cursor and Windsurf work too.
Codex as your assistant (optional): the Codex IDE extension for VS Code, Cursor and Windsurf (docs), or the Codex CLI.
For the
codeximage provider you need the Codex CLI itself, installed withnpm i -g @openai/codexand signed in withcodex loginusing your ChatGPT plan (not an API key). The server calls the CLI, so the editor extension alone isn't enough for this provider.For Flow, Gemini and ChatGPT on the web, Google Chrome, and a one-time sign-in in the window
accounts_loginopens.
Does it leave browser windows open?
No. Each job's tab closes when the job ends, and the window itself closes when your assistant calls browser_done at the end of the work. If that never happens, a safety net closes it after 20 idle minutes (node dist/src/index.js config set browser_idle_minutes 10 changes that). While the work is still going, between rounds of edits, it deliberately stays open so the next step doesn't have to start the browser again.
Does it remove AI watermarks?
No. media_optimize strips embedded metadata (EXIF, XMP and C2PA content credentials) from the files it writes, by default and with a report, and you can switch that off. It never touches invisible watermarks such as SynthID.
Can it do more than generate?
Yes. It removes backgrounds locally, edits video with ffmpeg, exports every social media size and shrinks files for the web. The design_brief and design_audit tools help the model art direct and judge its own results.
Are the providers fine with this?
The browser-driven providers work like you would by hand, and their terms restrict automated use of the consumer sites, so using them is your call. Official command line routes such as Codex and Higgsfield are the safer ones. See Safety and terms.
Does it put text and logos on the image for me?
Yes. compose renders your headline and a registered brand's real logo over the generated art, measuring where the calm area is and checking contrast. The image model itself never draws your logo or your words.
How does it get the right size and format for LinkedIn or X?
deliver takes a platform name (linkedin-feed, x-post, instagram-story, github-social and others) and produces that exact size as an optimized JPEG under the platform's file limit. For a LinkedIn feed post it's 1080x1350; 1200x627 is only for link previews.
I run several Claude sessions. Why did one say the browser is busy?
With share_browser on (the default) sessions work side by side as separate tabs, so you'll mostly see this when sharing is off or the other browser couldn't be joined. The waiting session queues, reports its place and an estimate, and continues on its own.
Can it make assets for a three.js or WebGL site?
Yes: design_brief has an environment-map asset type (a seamless 2:1 panorama for reflections and lighting) and a texture asset type (a seamless tileable surface), on top of the usual hero and background-video. Both get checked for seams instead of photo-realism.
Does Facebook or another platform penalise AI-made images?
Not for being AI-made and disclosed as such; Meta has said that label alone doesn't cut reach. What does get penalised hard is content that reads as a real photo of an event or statement that never happened. design_brief now asks that question for every realistic asset type, and the honest fix is the same as always: make it obviously a graphic or a considered shot, not a faked real moment.
What happens if a provider's page changes and a call breaks?
Pass fallback_providers to image_generate (for example ["codex", "gemini"]) and it tries the next one in order. The result reports every attempt and its failure reason. A local, redacted journal also tracks this over time, so a real pattern (the same provider failing the same way repeatedly) gets called out instead of looking like one bad run.
Can it keep my face the same across pictures?
Yes, with Codex. Pass reference_images with one or more photos of yourself, and say in the prompt what must stay (face, glasses, beard) and what may change. It is meant for your own photos or people who agreed, and results still need a look from you before they go public.
Does it know who the image is for?
If you tell design_brief who sees it (context.audience), it recognises a short list of real audiences (CISOs, developers, the open source community, security analysts, the general public) and adjusts tone, default tier, palette and the critique question accordingly. It won't guess an audience you didn't name.
Will it update itself without telling me?
No. It checks once a day and tells you when a newer version exists, with the exact command to run. For an npm install it only installs the update for you if you explicitly set NOAPI_AUTO_UPDATE=1, and even then only for the next run, never while the server is live. A git checkout is never updated automatically.
Where do the palette and font suggestions in design_brief come from?
From a reviewed UI design skill's colour and typography database, picked by the same topic detection the brief already does. They are only used when you don't supply your own brand colours, and you can always override them.
Does it learn from my past results?
Yes, locally. design_audit writes each score sheet to a small journal on your machine, and design_brief turns the criteria that keep falling short into advice at the top of the next prompt for that asset type. It also carries built-in lessons from real use. Nothing is uploaded.
Will it fill my disk with old drafts?
No. Rejected drafts are removed after 3 days, drafts that already became a final file after 14 days, and untouched ones after 30. It only ever looks inside .ai-media, never touches your final files, and you can switch it off or run it by hand with media_cleanup.
Is it free?
The server is free and open source under Apache-2.0. It uses the AI plans you already have, so it adds no API bill.
Contributing
Fixes for broken selectors and new site specs are the most useful help. See CONTRIBUTING.md.
Contact and support
Tried it? Tell me how it went, good or bad, with the feedback form. It takes two minutes.
Bugs, questions, ideas: open a GitHub issue or start a discussion.
Security problems: use a private security advisory, see SECURITY.md.
Work with NexaForge (cyber security, vibe coding, web development and IT infrastructure): nexaforge.services@gmail.com or nexaforge.eu.cc/contact.
If this saved you an API bill, a star on the repo is the easiest way to say thanks.
Sponsor the work. If your company can help with hosting, tools or funding, the sponsor page explains how. GitHub Sponsors is not available in Pakistan, so it works by email.
License
Apache-2.0. See NOTICE for the attribution and trademark note.
Built by Syed Farhan Ahmed (SFA) at NexaForge Cyber security · Vibe coding · Web development and IT infrastructure
Website · LinkedIn · Portfolio · Email
Available Tools
25 toolsaccounts_loginSign in to your AI accountsA
Opens a normal Chrome window on the private no-api-media profile so the USER can sign in by hand. The server never sees or stores a password. Tell the user to sign in, then close that window.
Inputs: services.
accounts_statusCheck which accounts are readyB
Checks Codex and Higgsfield CLI sign-in, ChatGPT web sign-in, the Google account and plan tier on Flow, and every JSON-defined site.
Inputs: no named parameters.
background_removeRemove the background from an imageA
Cuts out the subject and saves a transparent PNG, fully on this computer with rembg and BiRefNet models (no upload, no API). quality: fast (BiRefNet lite, default), best (BiRefNet general, slower, ~1 GB model on first use), portrait (people), anime. The first run downloads the model once. Needs rembg: uv tool install "rembg[cpu,cli]".
Inputs: input_path (required), quality, overwrite, output_path.
brand_profilesRegister the brands you publish underB
Keeps a profile per brand so the right logo is never guessed: who publishes (a person posting as themselves, or a company), the real logo files for dark and light backgrounds, and optionally palette and fonts. design_brief takes brand_id and fills these in; compose places that brand's logo. action list, set or remove. Stored on this machine only.
Inputs: id, name, action, colors, +7 more.
browser_doneClose the browser when the work is finishedA
Call this only at the very end: the final asset is in the project (optimized or delivered, wired in where it belongs), you've checked it, and the user has nothing left to change. It closes this session's browser instead of leaving the window open until the idle safety net. Tabs other sessions have open in a shared browser are never closed; the browser then closes on its own once they finish. Don't call it between rounds of edits: reopening costs a few seconds, but closing mid-work makes the next step start over.
Inputs: no named parameters.
composeSet the real headline and logo over generated artA
Renders a headline (and an optional sub line) and a registered brand's real logo over a generated image, the careful way every time: the calmest corner is measured and gets the text, the logo takes the calmest bottom corner left, text colour and a soft scrim are chosen for at least 4.5:1 contrast, the brand's display font (or the brief's) is used, one colour, no glow, no eyebrow label. A logo on its own dark tile gets a feathered edge so it doesn't look boxed. Saves a PNG; run deliver on it for the platform. Opens a tab in the server's browser to render.
Inputs: headline (required), input_path (required), subline, brand_id, +7 more.
composition_checkFind empty bands at the edgesA
Measures an image for the empty band generated art often leaves at an edge (a plain sky or flat strip meant for text that never came) and returns how much of the frame it takes, plus a crop that removes it. Pass output_path to save the cropped version. Run it on a draft before compositing and on the final file before shipping.
Inputs: input_path (required), overwrite, output_path, planned_edges, +1 more.
contact_sheetLay out drafts side by side for comparisonA
Puts up to 12 draft images (for example several directions from image_generate, or a few iterations of the same one) on a single grid, so they can be judged against each other instead of one at a time. No text is drawn onto the image; the result instead lists which grid position holds which file, in reading order (left to right, top to bottom).
Inputs: input_paths (required), output_path (required), columns, overwrite.
deliverMake the final file for a platformA
One step from a finished image to the file a platform wants: exact size (cropped to fill), JPEG at the lowest quality that still looks identical (SSIM), metadata stripped, under the platform's file-size limit, then checked for an empty band. Platforms: linkedin-feed (1080x1350, LinkedIn feed post, portrait 4:5 (takes the most room in a phone feed)); linkedin-square (1080x1080, LinkedIn feed post, square); linkedin-link (1200x627, LinkedIn link preview card, not a feed post); instagram-feed (1080x1350, Instagram feed post, portrait 4:5); instagram-story (1080x1920, Story or reel cover, 9:16; keep text out of the top 14% and bottom 20%); x-post (1600x900, X post image, 16:9); facebook-feed (1080x1350, Facebook feed post, portrait 4:5); youtube-thumbnail (1280x720, YouTube thumbnail, 2 MB limit); github-social (1280x640, GitHub repository social preview, 1 MB limit); og (1200x630, Open Graph link preview).
Inputs: platform (required), input_path (required), overwrite, output_path.
design_auditEye-catch audit of a finished imageA
After you have LOOKED at a generated image, score it 0 to 5 on each criterion (focal-point, thumbnail, hierarchy, palette, topic-cues, brand-presence, text-accuracy, not-template) and pass the scores here. Returns ship or revise, the weakest points and the exact fix for each. Call with no scores to get the criteria. Be harsh: a generic, flat or template-looking result scores 2 or 3. Pass asset_type so the server learns what usually goes wrong and warns you up front next time. Pass file (the draft inside .ai-media) so a revise marks it rejected, which lets it be cleaned up later, and a ship marks it shortlisted. Pass style.tier and style.look (whatever you actually passed to design_brief) so the server can remember, once enough drafts have shipped, which tier and look tend to work for this asset type and suggest it by default next time.
Inputs: file, style, scores, asset_type, +1 more.
design_briefArt direction before generatingA
Call this BEFORE image_generate or video_generate. Returns designer-grade guidance for the asset type: what good looks like, concept directions with ready prompts written like a real creative brief, a critique checklist to judge every result, and the iteration process. Fill context from project_profile and the conversation: what the project is, where the asset goes and why. That story is what makes results premium instead of generic. Quality defaults to premium. For designs with words (infographic, poster, social post) put every word in context.exactText.
Inputs: subject (required), asset_type (required), brand, style, +2 more.
design_feedbackRemember a correction the user gaveA
When the user says something about a result was wrong (a colour, a crop, an empty band, how the text looks, the wrong logo), call this right away with what was wrong and what they want instead. It's kept in a local journal on this machine, and every later design_brief applies it: image corrections go into the prompt as what to do, corrections about text and logos come back as compositing_rules. Set brand when the correction is about one brand ("use the SFA mark on his personal posts"), so it never leaks into another brand's work. action list shows what's stored, action forget removes one entry by its time. Pass file to mark that draft rejected.
Inputs: file, time, brand, action, +4 more.
image_generateGenerate an image with your own accountA
Generates one image (Flow and Higgsfield can return several) and saves the full-quality file inside the project. Providers: codex (ChatGPT plan via Codex CLI, most reliable), chatgpt (chatgpt.com), flow (Google Flow, Nano Banana 2, usually 0 credits), gemini (gemini.google.com), higgsfield (official CLI, costs credits: quote first), plus any JSON-defined site (call providers_list). Without output_path the file goes to /.ai-media//. Look at the result yourself before using it. Pass fallback_providers to try others in order if the first one fails.
Inputs: prompt (required), provider (required), count, model, +7 more.
loop_checkCheck a looping video for a visible seamA
For a background-video or product-video meant to loop: compares its first and last frame with the same structural-similarity check media_optimize uses for quality loss, and reports whether it will look seamless on repeat. A low similarity means a visible jump or jerk when it loops; regenerate with a direction that explicitly brings the motion back to where it started.
Inputs: input_path (required).
media_cleanupClean up old draftsA
Removes old drafts from /.ai-media to stop it growing: rejected drafts after a few days, drafts already used for a final file after a couple of weeks, and untouched drafts after a month. Only files inside .ai-media are ever considered, final assets in the project are never touched, and a used draft goes only if its final file still exists. dry_run is true by default: it lists what would be removed and how much space it frees. Pass dry_run: false to delete. The server also does this on its own once per session unless auto_cleanup is off.
Inputs: dry_run, used_days, draft_days, rejected_days.
media_optimizeShrink an image or video for the web without visible lossA
Images to WebP by default, or JPEG/PNG with format (or a .jpg/.png output_path), for places like LinkedIn post uploads that don't take WebP. Videos to H.264 with faststart. Raises quality until SSIM (similarity to the original) reaches the target, so the size drops but the picture does not visibly change. The original is kept untouched. Behaviour notice: by default the output has embedded metadata stripped (EXIF, XMP, C2PA content credentials, text chunks), like most web image optimizers; the result lists what was removed. Pass keep_metadata: true to keep what re-encoding can carry. Invisible watermarks such as SynthID are never touched.
Inputs: input_path (required), format, max_width, overwrite, +3 more.
media_probeWhat's in a media fileC
Duration, size, frame rate and codecs of an image or video inside the project.
Inputs: input_path (required).
palette_extractPull a website colour palette from an imageA
Reads the dominant colours out of a real image (a generated hero, banner or any photo) and returns them as hex codes with their share of the image, plus a ready :root CSS custom-properties block. This is a colour histogram, not a brand decision: it names the colours --palette-1, --palette-2 and so on by how much of the image they cover, most dominant first. Decide yourself which one is the primary, the accent or the background before wiring it into a stylesheet.
Inputs: input_path (required), count.
project_profileWork out the project's visual personalityA
Read-only scan of the project: 3D or animation libraries, luxury/premium/playful/corporate/modest wording, brand colours, fonts, dark or light theme, and the existing images to use as references. Call it first, open the reference images yourself, then pass the result to design_brief. If the user states the level they want (e.g. 'premium', 'glowing', 'minimal'), that wins.
Inputs: no named parameters.
providers_listList the AI sites this server can driveB
Built-in providers plus JSON specs from ~/.no-api-media/providers. Shows what each can make.
Inputs: no named parameters.
usage_reportLocal usage summaryA
Totals up this project's own .ai-media/manifest.jsonl: how many images and videos were generated, by which provider, in what format, and on which days. Nothing is uploaded; this only reads what the server already wrote to disk while saving each result.
Inputs: since_days.
video_editEdit a video (or put text/logo on an image)A
One operation per call, all local with ffmpeg: trim (start, end), reframe (aspect 9:16/1:1/16:9/4:5/4:3, fit cover|contain), speed (factor), fade (fade_in, fade_out seconds), mute, replace_audio (audio_path), extract_frame (at seconds, e.g. a poster image), gif (start, duration, width, fps), text (text, position top|center|bottom, size, color, box) on a video or image, logo (logo_path, position, width_percent) on a video or image, subtitles (srt_path, burned in), concat (others: more clips joined after this one). Chain calls for several edits.
Inputs: operation (required), input_path (required), at, box, +21 more.
video_generateGenerate a video with your own accountA
provider=flow (default): Veo or Omni in Google Flow. provider=higgsfield: Seedance, Kling, Veo and more via the official CLI. Both spend credits: call video_quote first, tell the user the cost, and pass max_credits. If the real cost is higher, nothing is generated. JSON-defined sites (e.g. grok) show no price up front, so they need confirm_spend: true, which you may only set after the user agreed in chat.
Inputs: prompt (required), model, aspect, quality, +6 more.
video_quoteHow many credits a generation will costB
provider=flow: opens the Flow project, sets model and aspect, reads the cost Flow shows. provider=higgsfield: asks the Higgsfield CLI for the exact cost of model + prompt (images or videos). Generates nothing.
Inputs: count, model, aspect, prompt, +1 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 25 tools
Most tools have clearly distinct roles across the media pipeline: generation, design guidance, QA, compositing, post-processing, delivery, and cleanup. Some overlap exists between social_sizes, deliver, and media_optimize for resizing/compression, and between composition_check and design_audit for quality checks, but the descriptions make the intended stage and purpose reasonably clear.
All names use snake_case, which is good, but the structural pattern is mixed: some are noun_verb (image_generate, video_quote), some noun_noun (project_profile, design_brief), some verb_noun (background_remove, palette_extract), and some bare verbs (deliver, compose). The set remains readable, but an agent cannot rely on a predictable verb_noun convention.
At 25 tools this is borderline heavy for a single server, though the domain is broad and includes generation, design guidance, compositing, post-processing, delivery, account management, and cleanup. Most tools earn their place, but the count is high enough that the surface feels dense rather than tightly scoped.
The tool surface covers a full media asset lifecycle: provider/account setup, project profiling, design briefing and auditing, image/video generation with cost quotes, probing, background removal, palette extraction, compositing, resizing, optimization, delivery, video editing, cleanup, and usage reporting. There are no obvious dead ends for the stated no-api-media purpose.
Maintenance
Related MCP Connectors
Generate AI images, videos and music from your AI client.
Generate images from Claude, ChatGPT, Cursor and Codex with 12 top AI image models. Up to 4 images per call, SVG vectorization, background removal, upscaling and image-to-video. Remote MCP with OAuth, no API keys.
Image and video AI tools and your own pipelines, run from any AI assistant.
Generate images from Claude, ChatGPT, Cursor and Codex with 12 top AI image models and 10 tools: up to 4 images per call, SVG vectorization, editing and more. Remote MCP with OAuth, no API keys. Pay per image, no subscription.
Related MCP Servers
AlicenseNot gradedqualityCmaintenanceGenerates images, video, music, and voice from plain-language prompts, shipping them production-ready as optimised WebP with SEO alt text, directly in your terminal or AI agent.55 npm1MIT- AlicenseNot gradedqualityCmaintenanceEnables AI agents to search the web for images and videos, download them into website projects with automatic optimization, and receive paste-ready HTML snippets, all self-hosted and without API keys.1MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI coding agents to create client-editable photo and video galleries, upload and organize media in bulk, generate embed code for popular site builders, and manage client feedback — so non-technical clients can update their own content without a CMS.80 npm1MIT
- AlicenseAqualityBmaintenanceEnables Claude Code, Cursor, Codex and other MCP clients to generate and edit images and videos directly in a project using AI subscriptions the user already pays for, without API keys or extra billing. Also provides local media tools such as background removal, video editing for social formats, and automatic resizing and optimization of results.25Apache 2.0
social_sizesMake every social and web size from one imageA
From one image, makes the sizes people need: Open Graph, LinkedIn, X (post and profile header), Instagram square/portrait/story, YouTube thumbnail and channel banner, Facebook cover and event cover, Pinterest, TikTok profile, GitHub social preview, favicon and app icons. fit: cover (fill and crop, photos), contain (whole image on a blurred copy of itself, logos and posters), pad (whole image on a solid colour). Facebook and YouTube cover/banner sizes get cropped differently on different devices: keep the subject and any text centred in the middle third so it survives every crop. Files go to the output folder named after each preset.
Inputs: input_path (required), fit, presets, overwrite, +2 more.