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.