blu.module.json: the module manifest
One file at the module's root describes the module to Blu. The team's CI registers it with each Blu environment's Admin, and a Blu admin then enables the module for clients. Code is checked against it: blu check statically, and the MCP endpoint again at startup.
{
"manifestVersion": 1,
"id": "pacing",
"displayName": "Campaign Pacing",
"owner": "Pacing team",
"version": "1.0.0",
"contractVersion": "1.3.0",
"remote": { "name": "pacing", "exposed": "./Page" },
"navDefaults": { "label": "Campaign Pacing", "path": "/pacing", "order": 5, "icon": "◔" },
"routes": [
{ "name": "campaigns", "path": "/campaigns", "title": "Campaigns" },
{ "name": "campaign", "path": "/campaigns/:campaignId", "title": "Campaign" }
],
"environments": {
"dev": {
"remoteEntry": "https://pacing.dev.example.com/mf-manifest.json",
"apiBase": "https://pacing-api.dev.example.com",
"mcpUrl": "https://pacing-api.dev.example.com/mcp",
"standaloneRedirectUris": ["https://pacing.dev.example.com/"]
},
"prod": { "…": "same keys for each stage" }
},
"serviceScopes": [],
"mcp": {
"tools": [
{ "name": "list_campaigns", "title": "Campaigns with pacing", "readOnly": true, "requires": { "blu": ["pacing:read"] } }
]
}
}
Fields
| Field | Rules |
|---|---|
manifestVersion |
1 |
id |
starts with a letter, then lowercase letters, digits, dashes; 2–41 characters. Blu issues this module's tokens for blu-module:<id>, and the API's moduleId must equal it. |
displayName, owner |
required text |
version |
semver, the module's own version |
contractVersion |
the Blu contract version it targets; major must be 1. Use "1.3.0". |
remote |
{ "name": <Module Federation name>, "exposed": <exposed key, e.g. "./Page" or "./App"> }. Must match the build config. |
navDefaults |
path (required, starts with /; where the module lives in Blu), label, optional order, icon, moduleInfo (true/false) |
routes |
optional; places others may link to (the Concierge's answers, for example). name: lowercase letters, digits, dashes. path: module-relative, made of literal segments and :params; not / on its own. title required. |
environments |
at least one of local, dev, staging, prod. Each has apiBase and mcpUrl (absolute URLs), remoteEntry (the URL of mf-manifest.json), and optional standaloneRedirectUris. |
standaloneRedirectUris |
exact addresses where "Sign in with Blu" may return to the module's standalone app: https, no localhost outside local, no wildcards |
serviceScopes |
an array; [] unless other backends call this API through Blu |
mcp.tools |
[], or one entry per Concierge tool: name (lowercase, digits, underscores), title, readOnly, requires (entry point → permissions, matching the tool's policy in code) |
Ask the user for the real environment URLs. Don't invent hostnames; leave clearly marked placeholders if they aren't known yet.
blu check validates the manifest with the same rules Blu Admin applies.