prompt-to-asset
Generates Android adaptive icons (including monochrome) and exports asset bundles for Android apps.
Integrates with Cloudflare Workers AI to generate assets using Flux-1-Schnell and SDXL models, with a free daily quota.
Produces Flutter launcher icons and asset bundles for Flutter projects.
Supports Google Gemini models (e.g., Nano Banana Pro) for image generation via API or Google AI Studio paste UI.
Generates iOS AppIconSet, including all required sizes and visionOS parallax icons.
Integrates with OpenAI image generation models (e.g., gpt-image-1.5) for creating assets.
Generates Progressive Web App icons (192x192, 512x512, maskable) and favicon bundles.
Generates sprite sheet atlases compatible with Unity, along with 9-slice data and border-image CSS.
30-second start
Pick one. Run it. You're done. The recommended path is first.
Runtime: Node β₯ 20.11 (24 recommended). macOS, Linux, Windows (WSL2 for --fix native deps).
π΅ AI assistant Β· recommended
Click an install button above. Then paste one of these into chat:
β’ Make a transparent logo for Forge, a dev-tools brand. Flat vector, warm orange.
β’ Make a favicon for my app, dark-mode aware.
β’ Fan this master.png out to iOS + Android + PWA.
β’ Ingest this screenshot as a mark, vectorize, export everything.Works in Cursor, Claude Code, VS Code, Windsurf, Codex, Gemini CLI. Zero terminal typing.
π’ Zero key, zero install
One curl, one npx. Offline fan-out to every platform.
curl -o logo.png \
"https://image.pollinations.ai/prompt/\
minimal+flat+vector+logo\
?model=flux&width=1024&nologo=true"
npx prompt-to-asset export logo.png \
--platforms ios,android,pwa,faviconOutputs: iOS AppIconSet, Android adaptive, PWA, favicon bundle, visionOS scaffold.
π£ CLI Β· with an API key
For CI and no rate limits.
npm i -g prompt-to-asset
p2a doctor # check env
p2a doctor --fix # auto-install deps
p2a pick # interactiveSupports OpenAI, Ideogram, Recraft, BFL/Flux, Gemini, Stability, Leonardo, fal.ai.
Free paths at a glance
You don't need a paid API key. Ranked best-first:
Route | Gets you | Signup |
| Logos, favicons, icon packs β instant | None |
Pollinations (HTTP GET) | Flux-quality raster, RGB | None |
Cloudflare Workers AI | Flux-1-Schnell + SDXL, 10k neurons/day | Free token + account ID |
HF Inference | SDXL, SD3, Flux dev/schnell | Free read token |
Stable Horde | SDXL, Flux on community GPUs | Anonymous queue |
Google AI Studio (paste-only UI) | Nano Banana / Nano Banana Pro | Google account |
Details + quotas: Free paths beyond Pollinations. Run p2a doctor or ask your assistant for asset_doctor() to see what's live right now.
Stuck? ClickInstall in Cursor or Install in VS Code above, restart the editor, and say: "make a favicon for my app, dark-mode aware."
Highlights
Three execution modes β
inline_svg(host LLM authors SVG),external_prompt_only(paste into any web UI),api(server calls the routed provider). Pick what fits. All three finish on $0.60+ models, one router β gpt-image-1.5, Ideogram 3 Turbo, Recraft V4, Flux.2, Nano Banana Pro, Imagen 4, SDXL/SD3, plus free-tier Pollinations / HF / Horde / Cloudflare. Each rule cites a research source.
Refuses to do the wrong thing β the
Nevercolumn. No wordmarks past 3 words through a diffusion sampler. No transparent PNG through Imagen. Nonegative_prompton Flux.Offline platform fan-out β one 1024Β² master β iOS AppIconSet, Android adaptive + monochrome, PWA 192/512/512-maskable, favicon bundle, visionOS parallax, Flutter launcher. Zero network.
Validates before shipping β tier-0 checks on every output: dims, alpha presence, checkerboard FFT, safe-zone bbox, ΞE2000 palette drift, WCAG contrast, OCR Levenshtein on wordmarks.
Sprite sheets + 9-slice β pack PNG frames into TexturePacker-compatible atlases (Phaser, PixiJS, Godot, Unity); emit 9-slice numbers + CSS
border-image+ Android.9.png.
Table of contents
Usage β what to say to your assistant
The three modes β inline_svg Β· external_prompt_only Β· api
The router β which model for which job, and what never
Models covered β 60+
MCP tools β 24 tools
Usage
You just talk to your assistant. Example from a new chat:
Make me a transparent logo for a developer-tools company called Forge. Flat vector, two-tone warm orange on neutral.
Behind the scenes:
asset_doctor()β check what modes and providers are live.asset_init_brand({ app_name: "Forge", palette: ["#EA580C", "#F5F5F4"] })if nobrand.jsonexists.asset_enhance_prompt({ brief })returns anAssetSpec: classification, rewritten prompt,modes_available[], optionalsvg_brief, optionalpaste_targets, and arouting_tracepointing at the research file that backed the decision (plusnever_modelsβ why Imagen or DALLΒ·E got rejected).Assistant offers you
inline_svg/external_prompt_only/api.If
inline_svg: it writes<svg>inline and callsasset_save_inline_svgβ writesmaster.svg,favicon.ico, apple-touch, AppIconSet, PWA bundle to disk.If
external_prompt_only: assistant shows the refined prompt and the best paste target (free first). You generate, save, then say "ingest this file" βasset_ingest_external.If
api: assistant calls the routed provider. Server mattes, vectorizes, exports, validates.Follow-up: "also fan this out for iOS and Android" β
asset_export_bundlewith the saved master.
Zero CLI typing. The CLI is still first-class for CI, shell scripts, and non-MCP environments β both surfaces hit the same core.
Why this exists
Two facts shape everything here.
Producing production-grade software assets is a routing and post-processing problem, not a prompt-engineering problem.
Imagen 3/4 and Gemini Flash Image can't produce real RGBA PNGs β their VAE is RGB-only, so asking for a transparent background renders the grey-and-white checkerboard as pixels. SDXL can't spell past ~8 characters. Only Recraft emits native SVG. Flux errors on negative_prompt. None of that is visible in the model UI. All of it silently breaks one-shot "prompt β asset" tools.
You may not have an image-model API key. The plugin works anyway.
Every one of the three modes can finish on $0.
The three modes
flowchart LR
A["one-line brief"] --> B["asset_enhance_prompt"]
B --> C{"mode"}
C -->|inline_svg| D["Host LLM emits SVG inline<br/>β asset_save_inline_svg"]
C -->|external_prompt_only| E["Paste into web UI<br/>β asset_ingest_external"]
C -->|api| F["Server calls routed provider"]
D --> G["matte Β· vectorize Β· validate"]
E --> G
F --> G
G --> H["AssetBundle<br/>ios Β· android Β· pwa Β· favicon Β· visionos Β· flutter"]Mode | Key? | What happens | Best for |
| No | Server returns an SVG-authoring brief (viewBox, palette, path budget β€ 40). Host LLM emits | Logos, favicons, icon packs, stickers, simple app-icon masters |
| No | Server returns the dialect-correct prompt plus a ranked list of paste targets, free paths first: Pollinations, HF Inference, Stable Horde, Google AI Studio, Ideogram, Recraft, Midjourney, fal.ai, BFL, ChatGPT, Firefly, Krea. Generate elsewhere, save locally, call | Anything β best for illustrations, heroes, text-heavy logos |
| Optional | Server calls the provider directly. Works zero-key via Pollinations / Horde / HF, or with paid keys. Route β generate β matte β vectorize β export β validate β content-addressed bundle. | Automation, CI, no rate-limit tolerance |
The host LLM picks the mode, or you do. The server surfaces modes_available so the assistant offers them to you. Free paths first β always.
The router
Router decisions live in data/routing-table.json. Capability matrix in data/model-registry.json. Every rule cites its research source.
Need | Primary | Fallback | Never |
Transparent PNG mark |
| Ideogram 3 Turbo ( | Imagen, Gemini Flash Image, SD 1.5 |
Logo with 1β3 word text | Ideogram 3 Turbo β | Composite SVG type over mark | Imagen, SD 1.5, |
Logo with >3 word text | Never a diffusion sampler. Mark + SVG typography composite. | β | β |
Native SVG | Recraft V4 (V3 for brand-style pipelines) |
| Everyone else |
Photoreal hero | Flux Pro / Flux.2 β | SDXL + brand LoRA | DALLΒ·E 3, Imagen 4 (deprecated) |
Iterate an existing mark |
| Pollinations Kontext (free) | β |
Zero-key everything | Pollinations (Flux) β | Stable Horde β HF Inference β paste-only | β |
The Never column matters. It's why prompt-to-asset refuses to render wordmarks past 3 words in any diffusion sampler, and why asking for a transparent PNG never goes to Imagen.
Free paths beyond Pollinations
Option | How | Best at | Catch |
Cloudflare Workers AI | Free API token + account ID | Flux-1-Schnell, SDXL, DreamShaper | 10k neurons/day cap (~900 Flux-Schnell or 5k SDXL-Lightning) |
HF Inference | Free read token | SDXL, SD3, Flux dev + schnell | Rate-limited, cold-start latency |
Pollinations.ai |
| Flux-quality raster, instantly | ~1 req / 15s anonymous, RGB only |
Stable Horde | Anonymous kudos queue | SDXL, Flux community GPUs | Minutes of queue on the free lane |
Google AI Studio (UI) | Free interactive web UI at aistudio.google.com | Nano Banana / Nano Banana Pro | No free API β paste-only; download PNG, call |
Local ComfyUI | Community | Full fidelity, no caps | You bring the GPU |
| Host LLM emits | Logos, favicons, simple icons | β€40 paths; simple geometry |
| Paste into any web UI | Whatever that UI gives you | Manual save, then |
Verified against ai.google.dev/gemini-api/docs/pricing:
No Gemini or Imagen image model has a public API free tier.
gemini-3.1-flash-image-preview(Nano Banana 2),gemini-3-pro-image-preview(Nano Banana Pro),gemini-2.5-flash-image(original Nano Banana), and allimagen-4.0-*variants showFree Tier: Not availableon Google's own pricing page. An unbilledGEMINI_API_KEYreturns HTTP 429 withlimit: 0on every image endpoint.Free for text, multimodal understanding, and embeddings. The Gemini text-out models still have
Free of chargeinput + output on the free tier.Free interactive image generation is only via the AI Studio web UI at aistudio.google.com. Community-observed limit 500β1,000 images/day, dynamic. Use
external_prompt_only+asset_ingest_external.Free image generation via the Gemini consumer app at gemini.google.com: Basic 20/day, AI Plus 50/day, AI Pro 100/day, Ultra 1,000/day.
Paid API pricing (per image, standard): Nano Banana (
gemini-2.5-flash-image) $0.039; Nano Banana 2 Flash (gemini-3.1-flash-image-preview) $0.045/0.5K, $0.067/1K, $0.101/2K, $0.151/4K; Nano Banana Pro (gemini-3-pro-image-preview) $0.134/1K-2K, $0.24/4K (+ $0.0011 per input image); Imagen 4 Fast $0.02, Standard $0.04, Ultra $0.06. Batch API is 50% off.
Run
p2a doctor(or ask your assistant forasset_doctor()) to see what's live in your environment right now.
Install
Every command works via npx β no install required.
# Zero install
npx prompt-to-asset doctor # what's live in this shell right now
npx prompt-to-asset doctor --fix # auto-install native deps (brew / cargo / scoop; never sudo)
npx prompt-to-asset pick # interactive route picker
npx prompt-to-asset init --register # scaffold brand.json + register in .cursor / .vscode / .windsurf
# Or global for daily use
npm i -g prompt-to-asset
p2a doctor
# Or per-project for CI
npm i -D prompt-to-assetRegister with your AI assistant
Claude Code
claude mcp add prompt-to-asset -- p2aSmithery (universal)
npx -y @smithery/cli install prompt-to-asset --client claudeCursor Β· VS Code Β· Windsurf Β· Codex Β· Gemini CLI
Use the install buttons at the top of this README, or see docs/install.md for the exact stanza per IDE.
Claude Desktop
Download the .mcpb bundle β double-click β restart.
Once registered, your assistant has the full 24 asset_* tool surface.
Models covered
Paid direct APIs: gpt-image-1, gpt-image-1.5, dall-e-3 (deprecated 2026-05-12), imagen-3, imagen-4, gemini-3-flash-image (Nano Banana), gemini-3-pro-image, sd-1.5, sdxl, sd3-large, playground-v3, flux-schnell, flux-dev, flux-pro, flux-2, flux-kontext-pro, ideogram-3, ideogram-3-turbo, recraft-v3, leonardo-phoenix, leonardo-diffusion-xl, fal-flux-pro, fal-flux-2, fal-sdxl.
Free-tier / zero-key: pollinations-flux, pollinations-turbo, pollinations-kontext, pollinations-sd, horde-sdxl, horde-flux, hf-sdxl, hf-sd3, hf-flux-schnell, hf-flux-dev.
Paste-only surfaces: midjourney-v6, midjourney-v7, firefly-3, krea-image-1. Calling asset_generate_* with mode: "api" against a paste-only primary soft-falls-back to the first API-reachable model in the chain and surfaces a warning. If the whole chain is paste-only, you get an ExternalPromptPlan rather than an error.
Tool | Purpose |
| Inventory of modes + providers. Buckets paid / free-tier / paste-only; surfaces zero-key routes first. Read-only. |
| Classify, route, rewrite. Returns modes + |
|
|
| Same three modes. |
|
|
| 1200Γ630 via Satori + |
|
|
| iOS |
| Marketing hero art (16:9 / 21:9 / 3:2 / 2:1). |
| Round-trip for |
| Round-trip for |
| BiRefNet / BRIA RMBG-2.0 / LayerDiffuse / difference matte / UΒ²-Net. |
|
|
| DAT2 / Real-ESRGAN / SUPIR / img2img / Lanczos; asset-type-aware. |
| Tier-0 (dims, alpha, checkerboard FFT, safe-zone bbox, ΞE2000 palette, WCAG contrast, OCR Levenshtein). Tier-2 VLM-as-judge via |
| Parse |
| Structured env inventory: native deps, free-tier routes ranked best-first, paid keys, paste-only surfaces, pipeline URLs, mode flags, "what to try next." Read-only. |
| Browse the 60+ model registry with filters: |
| Full capability dump for one model id (or aka alias). Strengths, weaknesses, paste targets, routing rules, env status. Read-only. |
| Fan a 1024Β² master PNG into iOS AppIconSet + Android adaptive + PWA maskable + visionOS parallax + Flutter launcher + favicon. Offline. |
| Pack PNG/WEBP/JPG frames into a sprite sheet + TexturePacker-compatible JSON atlas (Phaser / PixiJS / Godot / Unity). Offline. |
| Emit a 9-slice config + CSS |
| Scaffold |
| Wrap a user-owned LoRA training endpoint ( |
Tools are annotated readOnlyHint / idempotentHint so Cursor auto-approves without prompting.
Used by the LLM over Bash when MCP isn't registered yet, and by CI. Every read-only command accepts --json.
p2a # default β MCP stdio server
p2a mcp # same, explicit
p2a export <master.png> # offline platform fan-out
p2a export <master.png> --json
p2a init # interactive brand.json + IDE registration hints
p2a init --register # + auto-write .cursor/mcp.json / .vscode/mcp.json / .windsurf/mcp.json
p2a pick # interactive model picker
p2a doctor # environment inventory
p2a doctor --json # structured output
p2a doctor --data # check data/model-registry.json β data/routing-table.json consistency
p2a doctor --fix # auto-install missing native deps (brew / cargo / scoop; never sudo)
p2a models list # --free | --paid | --paste-only | --rgba | --svg
p2a models inspect <id> # full capability dump
p2a sprite-sheet <dir> # pack frames β PNG + atlas
p2a nine-slice <image> # 9-slice JSON + CSS + engine numbers + .9.png
p2a --help{
"name": "Halcyon",
"palette": ["#2563eb", "#ffffff"],
"fonts": { "display": { "family": "Inter", "weights": [700, 800] } },
"style_refs": ["https://β¦/sample1.png", "./refs/style2.png"],
"do_not": ["drop shadows", "heavy gradients"],
"lora": "halcyon-flux-v2",
"sref_code": "--sref 1234567890",
"style_id": "rc_halcyon_01"
}p2a init writes this for you, detecting the framework and suggesting an assets directory. Once present, every generator reads from it automatically.
Platform | What you get |
iOS (Xcode) |
|
Android | Adaptive foreground + background, Android 13 monochrome, all mipmap densities, optional |
PWA / web |
|
Flutter | Pre-populated |
visionOS | Three-layer parallax scaffold with a README. Layer split stays a human decision. |
Next.js / Astro / Vite / Remix / Nuxt / Expo / React Native / Electron | Framework detection via |
Games |
|
brief (text)
β asset_capabilities β modes available + free/paid/paste-only bucketing
β asset_enhance_prompt β AssetSpec {
β routing_trace: { rule_id, reason, research_sources, never_models, fallback_chain },
β modes_available,
β svg_brief?, (inline_svg)
β paste_targets?, (external_prompt_only)
β rewritten_prompt, β¦
β }
β
ββ mode: inline_svg β host LLM emits <svg>; asset_save_inline_svg writes bundle
ββ mode: external_prompt_only β user pastes into web UI; asset_ingest_external runs matte β vectorize β validate
ββ mode: api β provider(model, prompt, params) β matte β vectorize β upscale β export β validateContent-addressed storage: assets/<hash[0:2]>/<hash>/<variant>.<ext>. The MCP server is synchronous and stateless. prompt_hash and params_hash in every AssetBundle are designed to drop straight into a BullMQ / SQS / Cloudflare Queues jobId for a hosted pipeline. Reference design: docs/research/18-asset-pipeline-tools/18e-production-pipeline-architecture.md.
Design thesis
You own the API keys. The LLM owns everything else.
The only thing that happens in a terminal is installing the package and putting keys in .env. Secrets shouldn't pass through chat. Every other verb β doctor checks, model inspection, platform fan-out, brand scaffolding, sprite sheets, 9-slice configs β is an MCP tool the assistant calls when you ask in natural language.
Comparison
Tool | Prompt enhancement | Multi-model routing | Zero-key | Dev-asset bundle | Offline platform fan-out |
Promptati / PromptHero | cinematic only | β | β | β | β |
Looka / Brandmark / Designs.ai | β | β | β | partial | β |
ChatGPT / Midjourney / Ideogram (direct) | β | β | β | β | β |
appicon.co | β | β | β | partial | iOS only |
flutter_launcher_icons | β | β | β | partial | iOS + Android |
| β | β (60+ models) | β (Pollinations / HF / Horde / SVG) | β | β (iOS + Android + PWA + visionOS + favicon + Flutter) |
Security
This tool handles API keys for up to 15 providers. Non-negotiables:
Keys live in env vars only. Never written to disk, never logged, never echoed in MCP responses. Provider error bodies go through
redact()(packages/mcp-server/src/security/redact.ts) before reaching the host LLM.Path access is allow-listed.
image_path/output_dir/existing_mark_svgresolve through symlinks and reject anything escaping project cwd + configured output dir + cache dir + OS tempdir. Widen withP2A_ALLOWED_PATHS=/path1:/path2.SVG is XSS-sanitized before any write.
<script>,<foreignObject>,on*=handlers,javascript:URIs, external<image href>/<use href>, CSS@importover the network β all rejected. The check runs unconditionally; SVGO is not required.Cost guardrail. Set
P2A_MAX_SPEND_USD_PER_RUN=5.00to cap any single tool call. Pre-flight estimate refuses to call if over. Free-tier routes are always $0.Data integrity at boot.
assertDataIntegrityAtBoot()runs on start. If a routing rule points at a model id not in the registry, the server refuses to boot with a clear error. Check in CI withp2a doctor --data.No telemetry. No remote calls unless the routed provider explicitly requires one.
Full policy: SECURITY.md.
Research-backed decisions
Every routing rule, dialect switch, safe-zone size, and text ceiling that's implemented is backed by a file under docs/research/. asset_enhance_prompt returns a routing_trace.research_sources array on every call. The angle β code pointer map, plus an honest ledger of what's wired and what's deferred, lives in docs/RESEARCH_MAP.md.
Development
git clone https://github.com/MohamedAbdallah-14/prompt-to-asset.git
cd prompt-to-asset
npm install
npm run build
npm run typecheck
npm run lint
npm test # vitest watch
npm run test:run # vitest run (CI)
npm run smoke # list tools via MCP stdio + correctness assertions
npm run sync # regenerate IDE mirrors from SSOTs
npm run verify # byte-verify mirrors match SSOTsSSOTs live in skills/*/SKILL.md, rules/*.md, .claude-plugin/, and data/*.json. Don't edit .cursor/, .claude/, .windsurf/ directly β they're regenerated by scripts/sync-mirrors.sh and CI byte-verifies them.
Contribution flow: CONTRIBUTING.md
User on-ramp: GETTING_STARTED.md
Common snags: TROUBLESHOOTING.md
Release notes: CHANGELOG.md
Community
Issues + feature requests: GitHub Issues
Security disclosures: SECURITY.md
Code of Conduct: CODE_OF_CONDUCT.md
Star history:
If this repo saved you from hand-crafting another AppIconSet, a star helps it reach other developers fighting the same fight.
License
MIT Β© prompt-to-asset contributors.
Maintenance
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/MohamedAbdallah-14/prompt-to-asset'
If you have feedback or need assistance with the MCP directory API, please join our Discord server