workspace.json
Each workspace has its own config file at <workDir>/workspaces/<wsId>/workspace.json. This is where bundles, skill directories, named agent profiles, and optional model or identity overrides live — not in nimblebrain.json.
In dev mode (no instance.json, no auth configured) the runtime uses a single workspace with ID _dev, so you’ll find its config at <workDir>/workspaces/_dev/workspace.json. Under auth, workspaces are created and managed via the nb__manage_workspaces tool or the HTTP API; their files are maintained by the runtime.
Example
Section titled “Example”{ "id": "ws_product", "name": "Product", "members": [ { "userId": "usr_default", "role": "admin" }, { "userId": "usr_alex01", "role": "member" } ], "bundles": [ { "name": "@nimblebraininc/ipinfo" }, { "name": "@nimblebraininc/granola", "env": { "API_KEY": "grn_..." }, "trustScore": 85 }, { "path": "../mcp-servers/hello" } ], "skillDirs": ["./skills", "/opt/nimblebrain/skills"], "agents": { "researcher": { "description": "Deep research agent with search tools", "systemPrompt": "You are a research agent. Use search tools to find information.", "tools": ["granola__*", "nb__*"], "maxIterations": 8, "model": "fast" } }, "models": { "default": "anthropic:claude-opus-4-6" }, "identity": "You are the Acme Product Copilot. Be concise. Prefer data-backed answers.", "createdAt": "2026-03-05T10:00:00.000Z", "updatedAt": "2026-04-15T09:15:00.000Z"}Fields
Section titled “Fields”| Field | Type | Required | Description |
|---|---|---|---|
id | string | Yes | Workspace ID. Usually ws_<slug>; _dev in dev mode. |
name | string | Yes | Human-readable workspace name shown in the UI. |
members | array | Yes | Users with access. Each entry is { userId, role } where role is "admin" or "member". |
bundles | array | Yes | MCP bundles installed in this workspace. See Bundle Configuration. |
skillDirs | string[] | No | Directories scanned for skill markdown files, in addition to the built-in skills. |
agents | object | No | Named agent profiles available to nb__delegate. See Agent Profiles. |
models | object | No | Per-workspace model slot overrides. Partial — missing slots inherit from nimblebrain.json. |
identity | string | No | Markdown prompt appended as a context skill for this workspace. |
createdAt | string (ISO 8601) | Yes | Timestamp, maintained by the runtime. |
updatedAt | string (ISO 8601) | Yes | Timestamp, maintained by the runtime. |
Workspace isolation
Section titled “Workspace isolation”Bundles, tool registries, and conversation data are scoped to a workspace. Every tool handler resolves its workspace via runtime.requireWorkspaceId() before touching data.
Two workspaces that install the same bundle spawn independent subprocesses. Each gets its own data directory at <workDir>/workspaces/<wsId>/data/<bundle>/, so entity data never crosses the workspace boundary. Sidebar placements, briefing facets, and the app list are filtered per workspace.
Model slot overrides
Section titled “Model slot overrides”Any workspace can override individual model slots. Slots you don’t specify fall through to the instance-level models in nimblebrain.json:
{ "models": { "default": "anthropic:claude-opus-4-6" }}Here the workspace uses Opus for default but still uses the instance defaults for fast and reasoning.
Identity override
Section titled “Identity override”identity is a markdown block appended to the agent’s system prompt as a context skill. Use it to give a workspace a distinct persona or domain focus:
{ "identity": "You are the Acme Product Copilot. When asked about metrics, always cite the underlying query." }Related
Section titled “Related”nimblebrain.json— instance-level config- Bundle Configuration — bundle entry fields
- Agent Profiles — the
agentsobject structure - Features — feature flags (set instance-wide, not per-workspace)