Per-Environment App Icons, Generated by Your Agent

When local, staging, and production all show the same tab icon, it is only a matter of time before someone runs the wrong script in the wrong tab. The Favicon Tools MCP fixes that at the source: it returns dev, staging, and production icons by default.

What each stage gets

Stage | Icon
Production | Clean brand icon, no overlay
Staging | Same glyph with a corner "S" badge
Development | Same glyph with a corner "D" badge

One call returns the whole set

Point your agent at the MCP server and call generate_iconset. With the defaults, a single source produces the full per-stage kit plus matching manifests.

// .mcp.json — add the server
{
"mcpServers": {
"favicontools": {
"type": "http",
"url": "https://favicontools.com/api/mcp"
}
}
}

// then the agent calls:
generate_iconset({ source: "noto:fox" })
// → clean production icon
// → staging-* variants (corner "S")
// → dev-* variants (corner "D")
// → manifest.json + staging-manifest.json + dev-manifest.json
// → a stage-aware snippet

Want a single production-only icon?: Pass variantType: "none". The default leans toward full coverage so the per-stage safety net is opt-out, not opt-in.

The install snippet is already conditional

You don't wire the switching logic yourself — the returned snippet renders the right icon and manifest off your environment variable. Drop it into your root layout:

// app/layout.tsx (Next.js)
const isStaging = process.env.NEXT_PUBLIC_APP_ENV === "staging";
const isDev = process.env.NODE_ENV === "development";

// pick the filename prefix + manifest per stage
const prefix = isDev ? "/dev-" : isStaging ? "/staging-" : "/";
const manifest = isDev
? "/dev-manifest.json"
: isStaging
? "/staging-manifest.json"
: "/manifest.json";

//
//
//

The same pattern ships for React, Vue, Svelte, and Astro — it keys off a filename prefix (/, /staging-, /dev-) so production stays clean and the other stages get their badge automatically.

A deploy safety net

The tab bar becomes a glanceable indicator of which environment you're looking at. A badged icon is the pause that stops a destructive command landing on production.

Because the variants and the conditional snippet come back in the same response, you get multi-environment hygiene for free — no second generation pass, no hand-edited link tags.

Before you ship

Check the files are there — Confirm staging-* and dev-* files (and their manifests) are in your static dir.

Set the env var per deployment — The snippet reads NEXT_PUBLIC_APP_ENV or your equivalent — set it on every environment.

Suffix each manifest name — For example "Acme", "Acme (Staging)", "Acme (Dev)".

Verify each environment — Run /verify against each environment URL to confirm the right icon is live.

Never deploy to the wrong tab again: Generate a per-stage icon set now, or read the deeper playbook on environment-specific favicons.