Skip to content

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. Team workspace ids are opaque (ws_<16-hex>) and name-independent.

{
"id": "ws_a1b2c3d4e5f60718",
"name": "Product",
"about": "Product team workspace — roadmap, metrics, and customer research.",
"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"
}
FieldTypeRequiredDescription
idstringYesWorkspace ID. Opaque ws_<16-hex> for team workspaces, ws_user_<userId> for personal, _dev in dev mode. Name-independent — never parse it.
namestringYesHuman-readable workspace name shown in the UI. Freely editable; changing it does not change the id or on-disk path.
aboutstring | nullNoShort human-readable description, set in the workspace settings UI. Surfaced on the org “About” view and the workspace directory. Defaults to null.
membersarrayYesUsers with access. Each entry is { userId, role } where role is "admin" or "member".
bundlesarrayYesMCP bundles installed in this workspace. See Bundle Configuration.
connectorsAllowListstring[]NoPer-workspace catalog allow-list. When set, only catalog entries whose id is in this array appear on the workspace’s Connectors page. When unset, the full loaded catalog is visible. Filters the catalog UI only — already-installed bundles keep running regardless.
oauthOperatorAppsobjectNoPer-workspace OAuth app config for auth: static catalog entries. Keyed by catalog id (reverse-DNS ServerDetail.name, e.g. "io.asana/mcp"); each value carries the public client_id plus an audit trail. The matching client_secret lives in the workspace credential store, not here. See Connectors Catalog → Where the secrets live.
skillDirsstring[]NoDirectories scanned for skill markdown files, in addition to the built-in skills.
agentsobjectNoNamed agent profiles available to nb__delegate. See Agent Profiles.
modelsobjectNoPer-workspace model slot overrides. Partial — missing slots inherit from nimblebrain.json.
identitystringNoMarkdown prompt appended as a context skill for this workspace.
isPersonalbooleanNotrue for a user’s auto-provisioned personal workspace. Frozen post-create; never parse the id to infer it.
ownerUserIdstringWhen isPersonalOwner of a personal workspace. Required when isPersonal: true, forbidden otherwise.
createdAtstring (ISO 8601)YesTimestamp, maintained by the runtime.
updatedAtstring (ISO 8601)YesTimestamp, maintained by the runtime.

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.

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 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." }