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 <head> snippetThe 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";
// <link rel="icon" href={`${prefix}favicon.ico`} />
// <link rel="icon" sizes="32x32" href={`${prefix}favicon-32x32.png`} />
// <link rel="manifest" href={manifest} />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
- 1
Check the files are there
Confirm staging-* and dev-* files (and their manifests) are in your static dir.
- 2
Set the env var per deployment
The snippet reads NEXT_PUBLIC_APP_ENV or your equivalent. Set it on every environment.
- 3
Suffix each manifest name
For example "Acme", "Acme (Staging)", "Acme (Dev)".
- 4
Verify each environment
Run /verify against each environment URL to confirm the right icon is live.