Skip to content

Manifest Reference

NimbleBrain reads Synapse metadata from the _meta["ai.nimblebrain/synapse"] key in your MCPB manifest.json. This is where you declare your app’s name, icon, primary view, sidebar placements, and settings section.

manifest.json
{
"manifest_version": "0.4",
"name": "@myorg/my-app",
"version": "1.0.0",
"description": "My NimbleBrain app",
"author": {
"name": "My Org",
"email": "dev@myorg.com",
"url": "https://myorg.com"
},
"server": {
"type": "python",
"mcp_config": {
"command": "python",
"args": ["-m", "my_app.server"]
}
},
"_meta": {
"ai.nimblebrain/synapse": {
"name": "My App",
"icon": "database",
"primaryView": {
"resourceUri": "ui://dashboard"
},
"placements": [
{
"slot": "sidebar",
"resourceUri": "ui://nav",
"priority": 50,
"label": "My App",
"icon": "database",
"route": "my-app",
"size": "compact"
}
],
"settings": {
"id": "my-app",
"label": "My App",
"icon": "settings",
"resourceUri": "ui://settings"
}
}
}
}

These fields are defined by the MCPB specification. NimbleBrain supports both v0.3 and v0.4 formats.

FieldTypeRequiredDescription
manifest_versionstringNoMCPB spec version ("0.3" or "0.4").
namestringYesScoped package name (e.g., @myorg/my-app).
versionstringYesSemver version string.
descriptionstringNoHuman-readable description.
authorobjectNoAuthor info: name, email, url.
server.typestringYesRuntime type: "python", "node", "binary", or "uv".
server.entry_pointstringNoEntry point file path.
server.mcp_configMcpConfigYesSpawn configuration (see below).
_metaobjectNoExtension metadata. NimbleBrain reads _meta["ai.nimblebrain/synapse"].
FieldTypeRequiredDescription
commandstringYesExecutable to run ("python", "node", etc.).
argsstring[]NoCommand-line arguments. Use ${__dirname} for the bundle directory.
envRecord<string, string>NoEnvironment variables passed to the process.

Synapse metadata: _meta["ai.nimblebrain/synapse"]

Section titled “Synapse metadata: _meta["ai.nimblebrain/synapse"]”
FieldTypeRequiredDescription
namestringYesDisplay name shown in the sidebar and app list.
iconstringYesLucide icon name in kebab-case (e.g., "database", "message-square", "hand").
primaryViewobjectNoThe main view loaded when a user navigates to your app.
primaryView.resourceUristringYes (if primaryView set)ui:// URI for the main view (e.g., "ui://dashboard").
placementsPlacementDeclaration[]NoExplicit shell layout placement declarations. See Placements.
FieldTypeRequiredDescription
settings.idstringYesUnique section ID across all bundles.
settings.labelstringYesTab label in the settings UI.
settings.iconstringYesLucide icon name for the settings tab.
settings.resourceUristringYesui:// URI that renders the settings section HTML.

Each entry in the placements array:

FieldTypeRequiredDefaultDescription
slotstringYesShell slot to fill: "sidebar", "sidebar.conversations", "sidebar.bottom", "main", "toolbar.right".
resourceUristringYesui:// URI served by this MCP server.
prioritynumberNo100Sort order within the slot. Lower values appear first.
labelstringNoHuman-readable label for sidebar items and tabs.
iconstringNoLucide icon name (kebab-case). Falls back to CircleDot if unset or unrecognized.
routestringNoRoute path for "main" slot placements. Registers as /app/<route>.
size"compact" | "full" | "auto"NoSize hint for the slot renderer.

If your manifest has placements, those are used directly. If it only has primaryView (no placements array), NimbleBrain converts it to a single "main" slot placement automatically:

// Legacy conversion (from PlacementRegistry.registerLegacy)
{
slot: "main",
resourceUri: uiMeta.primaryView.resourceUri,
label: uiMeta.name,
icon: uiMeta.icon,
route: bundleName // e.g., "@myorg/my-app"
}

The route for legacy bundles uses the scoped bundle name as the path. For @myorg/my-app, the URL becomes /app/@myorg/my-app.

Icons use Lucide names. The resolver accepts both kebab-case and PascalCase:

  • "message-square" resolves to the MessageSquare component
  • "database" resolves to Database
  • "hand" resolves to Hand

If the icon name is not recognized, CircleDot is used as the default fallback.

The smallest manifest that registers a UI view:

manifest.json
{
"name": "@myorg/hello",
"version": "0.1.0",
"server": {
"type": "node",
"mcp_config": {
"command": "node",
"args": ["${__dirname}/dist/index.js"]
}
},
"_meta": {
"ai.nimblebrain/synapse": {
"name": "Hello",
"icon": "hand",
"primaryView": {
"resourceUri": "ui://index"
}
}
}
}

No _meta needed for tools-only bundles:

manifest.json
{
"name": "@myorg/calculator",
"version": "1.0.0",
"server": {
"type": "python",
"mcp_config": {
"command": "python",
"args": ["-m", "calculator.server"]
}
}
}