Core Concepts
Composable orchestration
Section titled “Composable orchestration”NimbleBrain’s core value is composing multiple MCP servers into a single, orchestrated workspace. Rather than connecting to one MCP server at a time, NimbleBrain aggregates tools from every installed app into a unified namespace, layers prompts to give the agent awareness of all available capabilities, and filters tool access per-task through skills.
┌──────────────────────────────────────────────────┐│ ToolRegistry ││ ││ ┌─────────┐ ┌─────────┐ ┌──────────────────┐ ││ │ App 1 │ │ App 2 │ │ App 3 (remote) │ ││ │ (stdio) │ │ (stdio) │ │ (HTTP/SSE) │ ││ │ 3 tools │ │ 5 tools │ │ 2 tools │ ││ └─────────┘ └─────────┘ └──────────────────┘ ││ ││ Unified namespace: 10 app tools + system tools │└──────────────────────────────────────────────────┘ │ │ ▼ ▼ Skill filtering Agent Engine (allowed-tools) (agentic loop)Three mechanisms make this composable:
| Mechanism | What it does |
|---|---|
| Tool aggregation | The ToolRegistry collects tools from every MCP source (local stdio, remote HTTP/SSE) and presents them as a flat namespace. The agent doesn’t know or care which server owns a tool. |
| Skill-scoped filtering | Each skill declares allowed-tools glob patterns. When a skill matches, only tools matching those patterns (plus system tools) are visible to the agent. This scopes the agent’s capabilities per task. |
| 4-layer prompt composition | System prompts are assembled from: (1) identity, (2) core context, (3) installed app metadata with trust scores, and (4) the matched skill’s prompt. Every layer adds awareness without the agent needing to discover it. |
Agent loop
Section titled “Agent loop”Every chat message triggers an agentic loop in the AgentEngine. The loop repeats until the model produces a response with no tool calls, or a limit is reached.
User message │ ▼┌─────────────────┐│ Call Claude │◄─────────────────┐│ (with tools) │ │└────────┬────────┘ │ │ │ ┌────┴────┐ │ │ Tool │ Yes │ │ calls? │──────► Execute tools │ │ │ in parallel ───┘ └────┬────┘ │ No ▼ Return responseEach pass through the loop is one iteration. Defaults:
| Setting | Default | Hard cap |
|---|---|---|
| Max iterations | 10 | 25 |
| Max input tokens | 500,000 | — |
| Max output tokens | 16,384 | — |
| Model | claude-sonnet-4-5-20250929 | — |
The engine stops for one of three reasons:
complete— the model responded without requesting any tool callsmax_iterations— the iteration limit was reachedtoken_budget— cumulative input tokens exceededmaxInputTokens. When this happens, tool calls from the current LLM response are dropped (not executed) to avoid running tools whose results can’t be processed.
All tool calls within a single iteration run in parallel via Promise.all().
Orchestration flow
Section titled “Orchestration flow”Before the engine loop starts, the Runtime orchestrates the composition described above:
- Resolve or create a conversation
- Match the user message to a skill (triggers, then keywords)
- Compose the system prompt — 4-layer: identity + core skills + installed apps + matched skill
- Filter the unified tool namespace based on the matched skill’s
allowed-toolsglobs - Run the
AgentEngineloop against the composed tool set - Persist the conversation (JSONL or in-memory)
Bundles (apps)
Section titled “Bundles (apps)”A bundle is an MCP server package installed into NimbleBrain. Bundles follow the MCPB format — each has a manifest.json declaring how to start the server, what tools it provides, and optional UI metadata.
Three sources
Section titled “Three sources”Configure bundles in nimblebrain.json:
{ "bundles": [ { "name": "@nimblebraininc/ipinfo" }, { "path": "../my-local-server" }, { "url": "https://mcp.example.com/mcp", "serverName": "remote" } ]}| Source | How it works |
|---|---|
name | Downloaded from the mpak registry. The agent can install these at runtime via nb__manage_bundle. |
path | Local filesystem path to a bundle directory. Resolved relative to the config file. |
url | Remote MCP server over Streamable HTTP or SSE transport. |
Lifecycle states
Section titled “Lifecycle states”Each bundle process goes through these states:
starting ──► running ──► crashed ──► dead │ ▲ └──► stopped ─────────┘| State | Meaning |
|---|---|
starting | Process is spawning |
running | Healthy and serving tools |
crashed | Process exited unexpectedly (will attempt recovery) |
dead | Repeated crashes, not restarting |
stopped | Manually stopped via API or CLI |
Default bundle
Section titled “Default bundle”NimbleBrain ships with @nimblebraininc/bash installed by default. This gives the agent basic shell access. Disable it with "noDefaultBundles": true in your config.
Bundle options
Section titled “Bundle options”{ "name": "@nimblebraininc/postgres", "env": { "DATABASE_URL": "postgres://localhost/mydb" }, "protected": true}| Field | Description |
|---|---|
env | Environment variables passed to the bundle process |
protected | Prevents uninstall via the nb__manage_bundle system tool |
trustScore | MTF trust score (0–100) from the mpak registry |
ui | UI metadata: name, icon, and optional primaryView resource URI |
Skills
Section titled “Skills”Skills are Markdown files with YAML frontmatter. They control what the agent knows and what tools it can use for a given message.
Skill file format
Section titled “Skill file format”---name: researchdescription: Deep research on a topicversion: "1.0"type: skillpriority: 5allowed-tools: - "websearch__*" - "nb__discover_tools"metadata: triggers: - "research this" - "deep dive" keywords: - research - investigate - analyze - sources - findings---
You are a research agent. Search the web, gather multiple sources,and synthesize findings into a structured report.Two types
Section titled “Two types”| Type | Priority | Behavior |
|---|---|---|
context | ≤ 10 | Always included in the system prompt, regardless of what the user says |
skill | Any | Matched against each user message. Only the best match is used. |
Two-phase matching
Section titled “Two-phase matching”When a user sends a message, skills of type skill are matched in two phases:
Phase 1 — Triggers. Each skill’s triggers list is checked for a substring match against the message. First hit wins. Triggers are high-confidence explicit patterns.
Phase 2 — Keywords. If no trigger matched, each skill’s keywords are counted against the message. A skill needs at least 2 keyword hits to qualify. The skill with the most hits wins.
User: "research this topic and analyze the sources" │ Phase 1: triggers "research this" ── match! ──► research skill selectedA matched skill:
- Injects its markdown body into the system prompt
- Filters available tools to those matching its
allowed-toolsglobs
Skill directories
Section titled “Skill directories”Skills are loaded from three locations (in order):
- Built-in —
src/skills/builtin/(shipped with the package) - Global —
~/.nimblebrain/skills/ - Config — directories listed in the
skillDirsconfig option
Tools come from two places: MCP bundles and built-in system tools.
System tools
Section titled “System tools”Every NimbleBrain instance has these nb__* tools available:
| Tool | Description |
|---|---|
nb__discover_tools | Search available tools by keyword across all installed bundles |
nb__discover_bundles | Search the mpak registry for bundles to install |
nb__manage_bundle | Install, uninstall, or configure a bundle |
nb__bundle_status | Get version, health, tool count for installed bundles |
nb__delegate | Spawn a child agent for sub-tasks (multi-agent delegation) |
nb__manage_skill | Create, update, or delete skill files at runtime |
Tool surfacing strategy
Section titled “Tool surfacing strategy”NimbleBrain uses tiered tool surfacing to keep the LLM’s tool list manageable:
| Condition | What the LLM sees |
|---|---|
| Total tools ≤ 30 | All tools surfaced directly |
| Total tools > 30, no skill matched | Only nb__* system tools. Others available via nb__discover_tools. |
Skill matched with allowed-tools | Tools matching the globs + system tools. Others via nb__discover_tools. |
The threshold is configurable via maxDirectTools (default: 30).
Multi-agent delegation
Section titled “Multi-agent delegation”The nb__delegate tool spawns a child AgentEngine run with a scoped system prompt and filtered tool set. Named agent profiles are configured in nimblebrain.json:
{ "agents": { "researcher": { "description": "Deep research agent", "systemPrompt": "You are a research agent...", "tools": ["websearch__*"], "maxIterations": 8, "model": "claude-sonnet-4-5-20250929" } }}The child agent’s iteration budget is capped at min(child.maxIterations, parent.remaining - 1). Multiple delegations in the same turn run concurrently.
Conversations
Section titled “Conversations”Conversations persist across messages so the agent remembers context.
Storage backends
Section titled “Storage backends”| Backend | Default for | Location |
|---|---|---|
| JSONL | CLI, HTTP server | ~/.nimblebrain/conversations/ |
| In-memory | Programmatic/SDK use | — |
JSONL format
Section titled “JSONL format”Each conversation is a single .jsonl file:
{"id":"conv_abc123","createdAt":"2025-03-15T10:30:00Z"}{"role":"user","content":"What files are in my home directory?","ts":"..."}{"role":"assistant","content":"Let me check...","ts":"...","toolCalls":[...]}Line 1 is metadata (ID, creation timestamp). Lines 2+ are StoredMessage objects with role, content, timestamp, and optional tool call records.
Resuming conversations
Section titled “Resuming conversations”Use --resume <id> in the CLI to continue an existing conversation:
nb --resume conv_abc123Through the API, pass conversationId in the chat request body to continue an existing conversation.
MCP Apps
Section titled “MCP Apps”NimbleBrain is a full MCP Apps host, implementing the ext-apps specification. MCP Apps are interactive UI applications — built with HTML/JavaScript — that render directly inside the host as sandboxed iframes.
Unlike traditional web apps, MCP Apps:
- Live inside the conversation — no tab-switching, context stays together
- Call tools bidirectionally — apps invoke MCP tools and receive pushed results from the agent
- Inherit the host’s theme — CSS variables are injected automatically
- Run in a security sandbox — no access to the parent page, cookies, or other apps
Any MCP bundle that declares UI resources and placements becomes an MCP App. See MCP Apps for the full concept and MCP App Bridge for the implementation protocol.
Platform as MCP server
Section titled “Platform as MCP server”NimbleBrain exposes a /mcp endpoint that turns the entire platform into a Streamable HTTP MCP server. External MCP clients — Claude Code, Open WebUI, or another NimbleBrain instance — can connect and access all installed tools through a single endpoint.
This means NimbleBrain is both an MCP client (connecting to installed bundles) and an MCP server (exposing composed tools to external hosts). See MCP Endpoint for configuration and usage.