Apps API
The Apps API manages the lifecycle of installed bundles (apps). You can list, install, uninstall, start, stop, and fetch UI resources for any app.
GET /v1/apps
Section titled “GET /v1/apps”List all installed apps with their status, tool count, trust score, and UI metadata.
Response:
{ "apps": [ { "name": "weather", "bundleName": "@nimblebraininc/weather", "version": "0.3.1", "status": "running", "type": "plain", "toolCount": 3, "trustScore": 85, "ui": null }, { "name": "tasks", "bundleName": "@nimblebraininc/tasks", "version": "1.0.0", "status": "running", "type": "upjack", "toolCount": 5, "trustScore": 92, "ui": { "name": "Tasks", "icon": "check-square", "primaryView": { "resourceUri": "ui://tasks/board" } } } ]}App fields:
| Field | Type | Description |
|---|---|---|
name | string | Short server name used in API paths |
bundleName | string | Scoped manifest name (e.g., @nimblebraininc/weather) |
version | string | Version from the bundle manifest |
status | string | Lifecycle state: starting, running, crashed, dead, stopped |
type | string | "upjack" for Upjack apps, "plain" for standard MCP servers |
toolCount | number | Number of tools exposed by this app |
trustScore | number | MTF trust score (0-100) |
ui | object | null | UI metadata, or null if the app has no UI |
Example:
curl http://localhost:27247/v1/apps \ -H "Authorization: Bearer your-secret-key"{ "apps": [ { "name": "bash", "bundleName": "@nimblebraininc/bash", "version": "0.2.0", "status": "running", "type": "plain", "toolCount": 1, "trustScore": 95, "ui": null } ]}POST /v1/apps/install
Section titled “POST /v1/apps/install”Install a bundle from the mpak registry (by name), from a local directory (by path), or from a remote URL.
Request body:
Provide exactly one of name, path, or url:
| Field | Type | Required | Description |
|---|---|---|---|
name | string | One of three | Bundle name from mpak (e.g., @nimblebraininc/weather) |
path | string | One of three | Local filesystem path to a bundle directory |
url | string | One of three | URL of a remote MCP server |
serverName | string | No | Custom server name (used with url installs) |
transport | object | No | Transport config for remote servers (see below) |
env | object | No | Environment variables to pass to the bundle process |
The transport object (for url installs):
| Field | Type | Description |
|---|---|---|
type | string | "streamable-http" or "sse" |
auth | object | Auth config: {type: "bearer", token}, {type: "header", name, value}, or {type: "none"} |
headers | object | Extra HTTP headers |
Response:
{ "name": "weather", "bundleName": "@nimblebraininc/weather", "version": "0.3.1", "status": "running", "type": "plain", "toolCount": 3, "trustScore": 85, "ui": null}Error responses:
| Status | error | Condition |
|---|---|---|
| 400 | bad_request | None or more than one of name, path, url provided |
| 400 | credentials_required | Bundle requires API keys in the env field |
| 409 | already_installed | A bundle with this name is already installed |
| 500 | install_failed | Installation failed (details in message) |
Examples:
curl -X POST http://localhost:27247/v1/apps/install \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-secret-key" \ -d '{"name": "@nimblebraininc/weather"}'curl -X POST http://localhost:27247/v1/apps/install \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-secret-key" \ -d '{"path": "../mcp-servers/weather"}'curl -X POST http://localhost:27247/v1/apps/install \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-secret-key" \ -d '{ "url": "https://mcp.example.com/weather", "serverName": "remote-weather", "transport": { "type": "streamable-http", "auth": { "type": "bearer", "token": "mcp-token-abc123" } } }'curl -X POST http://localhost:27247/v1/apps/install \ -H "Content-Type: application/json" \ -H "Authorization: Bearer your-secret-key" \ -d '{ "name": "@nimblebraininc/postgres", "env": { "DATABASE_URL": "postgres://localhost:5432/mydb" } }'Install response:
{ "name": "weather", "bundleName": "@nimblebraininc/weather", "version": "0.3.1", "status": "running", "type": "plain", "toolCount": 3, "trustScore": 85, "ui": null}DELETE /v1/apps/:name
Section titled “DELETE /v1/apps/:name”Uninstall an app. This stops the MCP server process and removes the app from the configuration. App data is preserved on disk at ~/.nimblebrain/apps/<name>/.
Path parameters:
| Parameter | Description |
|---|---|
:name | The app’s short server name |
Response:
{ "name": "weather", "uninstalled": true, "dataPreserved": true, "dataPath": "~/.nimblebrain/apps/weather/"}Error responses:
| Status | error | Condition |
|---|---|---|
| 403 | protected | Bundle is protected from uninstall |
| 404 | not_found | App not found |
| 500 | uninstall_failed | Uninstall failed |
Example:
curl -X DELETE http://localhost:27247/v1/apps/weather \ -H "Authorization: Bearer your-secret-key"{ "name": "weather", "uninstalled": true, "dataPreserved": true, "dataPath": "~/.nimblebrain/apps/weather/"}POST /v1/apps/:name/start
Section titled “POST /v1/apps/:name/start”Start a stopped app. If the app is already running, this is a no-op that returns the current status.
Path parameters:
| Parameter | Description |
|---|---|
:name | The app’s short server name |
Response:
{ "name": "weather", "status": "running"}Error responses:
| Status | error | Condition |
|---|---|---|
| 404 | not_found | App not found |
| 500 | start_failed | Start failed |
Example:
curl -X POST http://localhost:27247/v1/apps/weather/start \ -H "Authorization: Bearer your-secret-key"{ "name": "weather", "status": "running"}POST /v1/apps/:name/stop
Section titled “POST /v1/apps/:name/stop”Stop a running app. The MCP server process is terminated but the app remains in the configuration.
Path parameters:
| Parameter | Description |
|---|---|
:name | The app’s short server name |
Response:
{ "name": "weather", "status": "stopped"}Error responses:
| Status | error | Condition |
|---|---|---|
| 404 | not_found | App not found |
| 500 | stop_failed | Stop failed |
Example:
curl -X POST http://localhost:27247/v1/apps/weather/stop \ -H "Authorization: Bearer your-secret-key"{ "name": "weather", "status": "stopped"}GET /v1/apps/:name/resources/:path
Section titled “GET /v1/apps/:name/resources/:path”Fetch a UI resource (HTML) served by an app’s MCP server. Apps that declare a primaryView in their manifest expose UI content through this endpoint.
Path parameters:
| Parameter | Description |
|---|---|
:name | The app’s short server name |
:path | Resource path. Use primary to resolve the app’s primary view. |
The special path primary resolves to the app’s primaryView.resourceUri from its manifest metadata. You do not need to know the specific resource URI.
Response:
Returns text/html content on success.
Error responses:
| Status | error | Condition |
|---|---|---|
| 404 | not_found | App not found |
| 404 | resource_not_found | The requested resource does not exist |
Example:
curl http://localhost:27247/v1/apps/tasks/resources/primary \ -H "Authorization: Bearer your-secret-key"<!DOCTYPE html><html> <head><title>Tasks Board</title></head> <body> <div id="app">...</div> </body></html>