The Model Context Protocol is going global, and the manifest schema needed to catch up.
I just merged PR #132 adding localization and theming support to MCPB (Model Context Protocol Bundles) manifest v0.3. This post breaks down the design decisions and why they matter for anyone building MCP infrastructure.
The Problem: Manifest Bloat vs. User Experience
When you’re building desktop MCP servers that need to work across languages and UI themes, you face a fundamental tension:
Inline everything → Clean implementation, massive manifests
External resources → Lean manifests, more complexity
For a single language? Inline works fine. For 20+ languages? The manifest becomes unwieldy, especially in desktop contexts where you’re loading this data repeatedly. Windows alone ships in hundreds of languages and locales—this pattern needs to scale.
And that’s before considering theme-aware icons. Do you inline base64-encoded images for every size and theme variant? Of course not.
The Design: Per-Locale Resource Discovery
The solution establishes a resource discovery pattern:
{
"manifest_version": "0.3",
"display_name": "Sample MCP Server",
"description": "Provides advanced features",
"localization": {
"resources": "resources/${locale}.json",
"default_locale": "en-US"
}
}
Key Design Choices
BCP 47 Compliance
Locale identifiers must follow BCP 47 (e.g., en-US, fr-FR, zh-Hans). This isn’t just pedantic spec compliance—it’s essential for cross-platform consistency. Every major platform uses BCP 47, so we do too.
Default Locale in Main Manifest
The default locale content lives directly in the manifest. This means:
- Zero-resource fallback: if locale files fail to load, you still have usable text
- Simpler implementation for monolingual servers
- Clear contract: the manifest is always valid on its own
Graceful Fallback
When a locale file is missing a field, fall back to a language-appropriate locale (e.g., from es-UY to es-MX), and if that fails, the default locale value. This is critical for partial translations and incremental localization work.
Client-Side Resolution
Clients resolve the resource path relative to the server’s installation directory. This keeps the manifest portable and doesn’t require absolute paths or URL schemes.
Localizable Fields
Not everything needs localization. Here’s what we’re supporting:
display_name- User-facing name in UIdescription- Short descriptionlong_description- Extended description for details viewskeywords- When rendered as user-visible labelsauthor.name- If displayed in UI
Explicitly not localizable: structured data like name (package identifier), URLs, version numbers, etc.
Sample Locale File
A French locale file (fr-FR.json) looks like:
{
"display_name": "Serveur MCP Exemple",
"description": "Fournit des fonctionnalités avancées",
"long_description": "Description détaillée pour les utilisateurs",
"keywords": ["protocole", "contexte", "serveur"]
}
Clean, simple, focused on user-visible text.
Theming: Beyond Light and Dark
Theme-aware icons follow the same principle: avoid bloat while supporting real requirements.
"icons": [
{
"src": "assets/icons/icon-16-light.png",
"sizes": "16x16",
"theme": "light"
},
{
"src": "assets/icons/icon-16-dark.png",
"sizes": "16x16",
"theme": "dark"
}
]
This aligns with the MCP Registry server.json pattern, creating consistency across the ecosystem.
Why theme matters:
Desktop applications increasingly support system-wide theme preferences. A black icon on a dark background is unusable. Supporting theme variants is table stakes for good UX.
Why not localize icons?
Icons are visual and typically language-agnostic. Regional variations exist (left-to-right vs. right-to-left UI, cultural symbols), but those are edge cases better handled through platform-specific _meta conventions if needed.
The Trade-offs We Made
External Resources > Inline
Why: Manifest size matters in desktop contexts. Clients can lazy-load locale files and cache them separately from the manifest.
Cost: Slightly more implementation complexity. Clients need resource resolution logic.
Verdict: Worth it. The alternative (inline everything) doesn’t scale beyond a handful of languages.
BCP 47 Strict
Why: Cross-platform consistency. macOS, Windows, Linux, and web all use BCP 47.
Cost: More complex than simple language codes (en vs. en-US).
Verdict: Pay the complexity tax once at the spec level, avoid platform-specific quirks everywhere else.
Default Locale in Manifest
Why: Robustness. The manifest is always valid, even if resource loading fails.
Cost: Slight duplication (default locale exists in manifest and potentially in a locale file).
Verdict: Robustness wins. Agents and clients need guaranteed text, even in degraded scenarios.
Why This Matters for the MCP Ecosystem
This isn’t just about one manifest format. It’s about establishing patterns that work across the MCP ecosystem.
Desktop bundles (MCPB) and registry servers are converging on shared patterns. When both use the same icon schema, the same extensibility mechanisms (_meta), and now similar localization approaches, the ecosystem gets stronger.
Developers learn once, apply everywhere. If you know how localization works in MCPB, you can apply similar patterns to registry servers or custom MCP implementations.
Tools can work across implementations. Build a localization tool for one format, adapt it trivially for the other.
This is how open ecosystems scale: through alignment on fundamentals while allowing platform-specific extensions.
Implementation Details
If you’re building MCP clients or servers:
For Servers:
- Place locale files in a
resources/directory - Use BCP 47 locale identifiers (
en-US.json,fr-FR.json) - Include all localizable fields in each locale file
- Default locale content goes directly in the manifest
For Clients:
- Detect user’s locale (system preference or user selection)
- Resolve the locale file path relative to server’s install directory
- Load and parse the JSON
- Fall back to manifest defaults for missing fields
- Cache locale data to avoid repeated I/O
Fallback chain:
- Try user’s specific locale (
es-UY) - Try language-appropriate fallback locale (
es-MX) - Fall back to default locale from manifest
- Use field value from manifest if all else fails
The Broader Pattern
This work continues a theme: bringing desktop MCP implementations and web-based implementations closer together.
Previous work:
- Platform metadata with
_meta - Icon schema alignment with registry
This work:
- Localization framework
- Theme-aware assets
The goal isn’t unification—desktop and web have different constraints. The goal is alignment where it makes sense, reducing ecosystem fragmentation while preserving platform-appropriate flexibility.
Get Involved
The MCPB spec is evolving through community contributions. If you’re building MCP infrastructure:
- Review the updated schema
- Open issues for problems or enhancements
- Contribute PRs for improvements
The Model Context Protocol ecosystem is still young. Patterns we establish now will echo through years of tooling. Get involved early.
This work emerged from conversations between the Anthropic team, and Windows about real needs in desktop MCP implementations. Special thanks to the reviewers who helped shape this design.
Links: