Skip to content

DotCraft full configuration reference

Configuration fields, defaults, and JSON examples, grouped by subsystem. For first-time setup, read Getting started. For what a feature does and when to reach for it, start from its feature page and come back here for the exact fields.

DotCraft reads global ~/.craft/config.json first, then overlays workspace .craft/config.json. Workspace fields win. String values support $VAR and ${VAR} environment variable placeholders. An unset variable keeps its placeholder unchanged.

Inspect configuration from the CLI

dotcraft config schema prints every section and field this build understands, with its type, default, sensitivity, and reload behavior. dotcraft config show prints the merged configuration of one workspace with ApiKey, Password, and Token values masked as ***.

bash
dotcraft config schema --section Tools.Web
dotcraft config schema --json
dotcraft config show --json

--section accepts a section's display name or its JSON path. --json writes machine-readable output, and config show is indented JSON either way. config show reads the workspace in the current directory; pass --workspace for another one.

Basic model and provider

FieldDescriptionDefault
ProviderIdCurrent personal provider id. Empty means no provider is selectedEmpty
ProviderPreferencesComplete MainAgent preferences keyed by provider id. The selected provider must have an effective entry{}
NetworkTimeoutSecondsGlobal model request timeout in seconds; providers can override it600
ProvidersPersonal model provider dictionary, usually stored in ~/.craft/config.jsonEmpty
SubagentMaxConcurrencyMaximum concurrent subagents3
MaxSessionQueueSizeMaximum queued requests per session; 0 means unlimited3
ConsolidationModelMemory consolidation model. Empty uses the main modelEmpty
DebugModePrints untruncated tool arguments in the consolefalse
EnabledToolsGlobally enabled tool names. Empty enables all tools[]

Personal provider example:

json
{
  "Providers": {
    "anthropic": {
      "DisplayName": "Anthropic",
      "Protocol": "anthropic",
      "ApiKey": "${ANTHROPIC_API_KEY}"
    },
    "openrouter": {
      "DisplayName": "OpenRouter",
      "Protocol": "openai-chat-completions",
      "ApiKey": "${OPENROUTER_API_KEY}",
      "EndPoint": "https://openrouter.ai/api/v1"
    }
  }
}

Workspace model selection example:

json
{
  "ProviderId": "anthropic",
  "ProviderPreferences": {
    "anthropic": {
      "Model": "claude-sonnet-4-5",
      "Reasoning": {
        "Enabled": true,
        "Effort": "High",
        "Output": "Full"
      },
      "Speed": "Fast",
      "ContextWindow": {
        "Mode": "Max"
      }
    }
  }
}

ProviderPreferences merges per provider id, never field by field. When global and workspace config both define the same provider id, the workspace record replaces the global one in full.

Preference fieldValuesDescription
ModelNon-empty model idModel used for new MainAgent threads
Reasoning.Enabledtrue, falseEnables reasoning when the model supports the choice
Reasoning.EffortLow, Medium, High, ExtraHighRequested reasoning effort
Reasoning.OutputNone, Summary, FullRequested reasoning output
SpeedStandard, FastRequested inference speed; unsupported Fast runs as Standard
ContextWindow.ModeDefault, MaxRequested context-window mode; unsupported Max resets to Default

Provider object fields:

FieldDescriptionDefault
DisplayNameUser-facing provider name; falls back to the provider id when emptyEmpty
ProtocolProvider protocol: anthropic, openai-chat-completions, or openai-responses. Empty values default to openai-chat-completions.openai-chat-completions
ApiKeyProvider API key; prefer ${ENV_NAME} environment variable referencesEmpty
AuthMethodAuthentication method: apiKey uses the static ApiKey; chatgptOAuth authenticates with a ChatGPT subscription account (OpenAI protocols only, see below). Unrecognized values fall back to apiKeyapiKey
ChatGptAccountIdChatGPT account id written by the Sign in with ChatGPT flow; do not edit manuallyEmpty
ChatGptPlanTypeChatGPT plan tier written by the Sign in with ChatGPT flow (free, plus, pro, business, enterprise, edu); do not edit manuallyEmpty
EndPointProvider base URL; empty values use the protocol default endpointOpenAI protocols: https://api.openai.com/v1; anthropic: https://api.anthropic.com
NetworkTimeoutSecondsPer-provider request timeout, overriding the global NetworkTimeoutSecondsEmpty
MaxOutputTokensPer-provider default maximum output tokens, applied when a request does not set its ownEmpty
StreamMaxRetriesPer-provider streaming reconnection attempts for dropped or idle provider streams; 0 disables stream retry5
StreamIdleTimeoutMsPer-provider idle timeout for streaming responses, in milliseconds300000
SupportsHostedImageGenerationEnables hosted image generation for this provider. When omitted, ChatGPT OAuth and the official OpenAI Responses API-key endpoint default to true; custom OpenAI-compatible Responses endpoints default to false.Provider default

Sign in with ChatGPT example:

json
{
  "Providers": {
    "openai": {
      "DisplayName": "OpenAI (ChatGPT)",
      "Protocol": "openai-responses",
      "AuthMethod": "chatgptOAuth"
    }
  }
}

A chatgptOAuth provider authenticates with a ChatGPT subscription instead of an API key. Run dotcraft auth openai login to sign in — it stores the OAuth token bundle as auth.json in the user data directory, writes the provider entry above into the global configuration, makes it the default provider when none is selected, and seeds a default model preference when the provider has none. In this mode ApiKey and EndPoint are ignored and the effective protocol is always openai-responses; the resolution rules live in Configure model providers. dotcraft auth openai logout deletes the tokens and reverts the provider to apiKey.

Workspace memory and skills

FieldDescriptionDefault
Memory.AutoConsolidateEnabledEnables automatic long-term memory consolidationtrue
Memory.ConsolidateEveryNTurnsSuccessful turns per thread between long-term memory consolidation attempts5
Skills.DisabledSkillsSkill names disabled for this workspace. A disabled skill stays on disk but is left out of agent context[]
Skills.SelfLearning.EnabledMaster switch for agent skill self-learning; off hides skill editing from the modeltrue
Skills.SelfLearning.VariantModeSkill variant write mode: enabled routes self-learning updates to workspace-local skill variants, disabled turns variants offenabled
Skills.SelfLearning.MaxSkillContentCharsMax chars for a single SKILL.md written through self-learning100000
Skills.SelfLearning.MaxSupportingFileBytesMax bytes for a single supporting file written through self-learning1048576

Self-learning example:

json
{
  "Skills": {
    "SelfLearning": {
      "Enabled": true,
      "MaxSkillContentChars": 100000,
      "MaxSupportingFileBytes": 1048576
    }
  }
}

SkillManage(action, ...) reference:

ActionRequired parametersPurpose
createname, contentCreate a new workspace skill
patchname, oldString, newStringLocal patch of SKILL.md or supporting file
editname, contentReplace an existing workspace skill's SKILL.md
write_filename, filePath, fileContentWrite a supporting file
remove_filename, filePathDelete a supporting file

create triggers a kind: skill approval, and destructive deletes require approval too. Self-learning writes only to the current workspace's skill directory. System and personal skills are read-only, supporting files may only live under scripts/ or assets/, and absolute paths or .. traversal are rejected.

Compaction

FieldDescriptionDefault
Compaction.AutoCompactEnabledEnables threshold-based auto compactiontrue
Compaction.ReactiveCompactEnabledEnables reactive compaction for prompt_too_long errorstrue
Compaction.ContextWindowModel context window in tokens. When unset, DotCraft infers it from the current effective modelModel catalog value / 256000
Compaction.MaxContextWindowUpper bound used for inferred model catalog context windows; explicit values are preserved256000
Compaction.SummaryReserveTokensTokens reserved for summary output20000
Compaction.SummaryMaxOutputTokensMaximum output tokens for a compaction summary request12000
Compaction.AutoCompactBufferTokensToken buffer below the hard limit that triggers auto compaction13000
Compaction.WarningBufferTokensToken buffer before auto threshold that emits warning20000
Compaction.ErrorBufferTokensToken buffer before auto threshold that emits error10000
Compaction.ManualCompactBufferTokensHeadroom below the effective context window used for the reported context-pressure limit3000
Compaction.KeepRecentMinTokensMinimum recent tail tokens after partial summary10000
Compaction.KeepRecentMinGroupsMinimum recent API groups after partial summary3
Compaction.KeepRecentMaxTokensMaximum recent tail tokens after partial summary40000
Compaction.MicrocompactEnabledEnables micro-compactiontrue
Compaction.MicrocompactKeepRecentRecent tool results kept during micro-compaction8
Compaction.MicrocompactGapMinutesAlso triggers after this many minutes since last assistant message; 0 disables it20
Compaction.MaxConsecutiveFailuresConsecutive failures before circuit breaking compaction3

Model capability catalog

DotCraft ships a built-in catalog for model context windows and Fast Mode support. Extend or override it with:

  • Global: ~/.craft/models.json
  • Workspace: .craft/models.json
json
{
  "defaultContextWindow": 256000,
  "models": {
    "my-256k-model": {
      "contextWindow": 256000
    },
    "custom-fast-model": {
      "contextWindow": 1048576,
      "fast": {
        "protocols": ["openai-responses"]
      }
    },
    "custom-anthropic-model": {
      "fast": {
        "protocols": ["anthropic"]
      }
    }
  }
}

Workspace entries override global entries, which override the built-in catalog. Fields merge independently for each model pattern. Set fast to null to disable an inherited Fast capability. Model patterns use case-insensitive longest-prefix matching and also match namespaced suffixes such as provider/custom-fast-model.

Reasoning and prompt caching

FieldDescriptionDefault
Reasoning.EnabledRequests provider reasoning supportfalse
Reasoning.EffortReasoning depth: None / Low / Medium / High / ExtraHighMedium
Reasoning.OutputReasoning visibility: None / Summary / FullFull
PromptCaching.EnabledInject prompt cache markers for matching modelstrue
PromptCaching.ModelPatternsCase-insensitive model name fragments. Empty matches no models["claude"]
PromptCaching.PlacementMarker placement strategy. Currently only ConversationTail is supportedConversationTail
PromptCaching.TtlAnthropic cache TTL. Empty uses the default 5 minutes; 1h requests the long cacheEmpty

Deep-thinking adapter catalog files:

  • Global: ~/.craft/model-thinking-adapters.json
  • Workspace: .craft/model-thinking-adapters.json

The built-in catalog exposes full reasoning choices for unlisted Anthropic-protocol models, but does not assume they support Anthropic adaptive request shaping. Add anthropicThinking entries for models or endpoints that explicitly support that shape.

For Anthropic-compatible providers, anthropicMessageContent can declare how DotCraft reasoning history should be represented. The built-in DeepSeek Anthropic adapter maps historical TextReasoningContent to Anthropic-compatible thinking blocks before sending history; it is not a generic unsupported-block filter.

json
{
  "deepThinking": {
    "models": ["deepseek", "mimo", "my-thinking-model-"],
    "endpoints": ["deepseek", "my-thinking-gateway"]
  },
  "anthropicThinking": {
    "adapters": [
      {
        "models": ["my-adaptive-anthropic-model-"],
        "thinking": { "type": "adaptive", "display": "fromReasoningOutput" },
        "outputConfig": { "effort": "fromReasoningEffort" }
      }
    ]
  },
  "anthropicMessageContent": {
    "adapters": [
      {
        "models": ["deepseek"],
        "endpoints": ["deepseek"],
        "reasoningHistory": { "blockType": "thinking" }
      }
    ]
  }
}

Tools security and sandbox

FieldDescriptionDefault
Security.BlacklistedPathsPaths the agent must not access; subpaths are also checked[]
Tools.File.RequireApprovalOutsideWorkspaceApprove file and shell ops outside workspace; false blocks themtrue
Tools.File.MaxFileSizeMax readable file size in bytes10485760
Tools.File.RipgrepPathOptional rg path; empty tries DOTCRAFT_RG_PATH, PATH, then fallback""
Tools.File.SearchTimeoutSecondsMax GrepFiles content-search time before timeout30
Tools.Shell.TimeoutShell timeout in seconds300
Tools.Shell.MaxOutputLengthMax shell output length in characters10000
Tools.Shell.Background.EnabledEnable background terminal sessionstrue
Tools.Shell.Background.DefaultYieldTimeMsDefault wait before a running command returns a background-session snapshot1000
Tools.Shell.Background.MaxYieldTimeMsMaximum wait accepted for a background-session read or write30000
Tools.Shell.Background.MaxSessionsPerThreadMaximum concurrent background terminals per thread8
Tools.Shell.Background.MaxSessionsPerWorkspaceMaximum concurrent background terminals in one workspace32
Tools.Shell.Background.IdleTimeoutSecondsReserved; not currently enforced by the background terminal service1800
Tools.Shell.Background.OutputMaxBytesReserved; not currently enforced by the background terminal service67108864
Tools.Shell.Background.OutputRetentionDaysRetention window for completed or lost terminal metadata and output; running terminals are excluded7
Tools.Shell.Background.StallWatchdogSecondsReserved; not currently enforced by the background terminal service45
Tools.Shell.Background.DefaultReadMaxOutputCharsDefault maximum characters returned in a terminal snapshot10000
Tools.Web.MaxCharsMax chars for web fetch50000
Tools.Web.TimeoutWeb request timeout in seconds300
Tools.Web.SearchMaxResultsDefault search result count5
Tools.Web.SearchProviderBing / ExaExa
Tools.ResultLimits.MaxToolResultCharsDefault tool result length in characters before the result spills to disk; 0 removes the limit for tools that use the global default50000
Tools.ResultLimits.SpillPreviewLinesHead and tail lines kept in the preview when a result spills to disk40
Tools.Lsp.EnabledEnables built-in LSP toolsfalse
Tools.Lsp.MaxFileSizeMax LSP file size10485760
Tools.ImageGeneration.EnabledAllows supported OpenAI Responses providers to generate images in conversationtrue
Tools.ImageGeneration.ModelReserved for image-client integrations; conversation image generation uses the active Responses modelgpt-image-2
Tools.ImageGeneration.MaxReferenceImagesReserved for image-client integrations that accept reference images5
Tools.Sandbox.EnabledEnable sandboxfalse
Tools.Sandbox.DomainOpenSandbox service addresslocalhost:5880
Tools.Sandbox.ApiKeyOpenSandbox API keyEmpty
Tools.Sandbox.UseHttpsUse HTTPSfalse
Tools.Sandbox.ImageContainer Docker imageubuntu:latest
Tools.Sandbox.TimeoutSecondsSandbox timeout in seconds600
Tools.Sandbox.CpuContainer CPU limit1
Tools.Sandbox.MemoryContainer memory limit512Mi
Tools.Sandbox.NetworkPolicydeny / allow / customallow
Tools.Sandbox.AllowedEgressDomainsCustom allowed egress domains[]
Tools.Sandbox.IdleTimeoutSecondsIdle timeout in seconds300
Tools.Sandbox.SyncWorkspaceSync workspace into containertrue
Tools.Sandbox.SyncExcludeWorkspace-relative paths excluded from that sync, matched as path prefixes. The defaults keep sensitive .craft/ runtime data out of the container, so extend the list instead of replacing it[".craft/config.json", ".craft/sessions", ".craft/memory", ".craft/dashboard", ".craft/security", ".craft/logs"]

Generated images are saved under the Agent data directory at generated_images/<threadId>/<callId>.png. When connected to a remote computer, files are saved to the remote workspace’s .craft/generated_images/<threadId>/<callId>.png instead. If saving fails, the conversation still displays the generated image and reports the storage failure.

With a supported OpenAI Responses provider, ask DotCraft to generate an image in a normal conversation. DotCraft requests PNG output and shows the image inline in clients that render rich content.

Two switches gate the hosted image_generation tool, and both must be true: the global Tools.ImageGeneration.Enabled, and the provider's own SupportsHostedImageGeneration. Omitting the provider field leaves ChatGPT OAuth and the official OpenAI Responses API-key endpoint enabled, and custom OpenAI-compatible Responses endpoints disabled. Enable a custom endpoint only once you know it supports the hosted tool.

Personal local hardening example:

json
{
  "Security": {
    "BlacklistedPaths": [
      "~/.ssh",
      "~/.gnupg",
      "~/.aws"
    ]
  },
  "Tools": {
    "File": {
      "RequireApprovalOutsideWorkspace": true
    },
    "Shell": {
      "Timeout": 300
    }
  }
}

Tool allow-list example:

json
{
  "EnabledTools": ["ReadFile", "GrepFiles", "WebSearch"]
}

OpenSandbox example:

json
{
  "Tools": {
    "Sandbox": {
      "Enabled": true,
      "Domain": "localhost:5880",
      "Image": "ubuntu:latest",
      "NetworkPolicy": "allow",
      "SyncWorkspace": true
    }
  }
}

Automations goals and hooks

FieldDescriptionDefault
Automations.EnabledEnables the Automations orchestratortrue
Automations.PollingIntervalPolling interval00:00:10
Automations.MaxConcurrentTasksMaximum concurrent local tasks3
Automations.TurnTimeoutSingle-turn timeout00:30:00
Automations.WorktreeRetentionEnabledEnables retention cleanup for idle automation task worktreestrue
Automations.WorktreeRetentionIdlePeriodIdle period before a clean automation task worktree is eligible for cleanup21.00:00:00
Goals.EnabledEnables goal storage, AppServer methods, goal context injection, usage accounting, and model goal toolstrue
Goals.AutoContinueEnabledAllows active goals to continue when a Thread is idletrue
Hooks.EnabledEnables Hookstrue
Hooks.StatePer-hook user state keyed by stable hook key. Stores Enabled and TrustedHash for Desktop toggle/trust actions{}

Automations.WorktreeRetentionIdlePeriod must be at least 14.00:00:00. The retention sweep only removes managed automation task worktrees that are idle, clean, and have no commits ahead of their base.

Automation AppServer methods:

MethodDescription
automation/listList definitions
automation/readRead a definition
automation/createCreate an automation
automation/updateSave with expectedVersion
automation/runQueue one run
automation/deleteDelete a definition
automation/runs/listRead run history
automation/presets/listList conversational presets

Goal AppServer methods:

MethodDescription
thread/goal/setSet, replace, pause, or resume a Thread goal
thread/goal/getRead current Thread goal state
thread/goal/clearClear current Thread goal

Hook commands live in hooks.json, not in config.json. DotCraft loads global hooks from ~/.craft/hooks.json, workspace hooks from .craft/hooks.json, and plugin hooks from enabled plugin hook files. For a user-facing overview and the Desktop workflow, start with Lifecycle Hooks.

Hook quick start (.craft/hooks.json):

json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Exec",
        "hooks": [
          {
            "type": "command",
            "command": "node .craft/hooks/log-tool-call.js",
            "timeout": 10
          }
        ]
      }
    ]
  }
}

Hook matcher group fields:

FieldDescription
matcherRegex for matching tool names. Empty matches all tool-related events
hooksOrdered list of hook handlers for the event and matcher

Hook handler fields:

FieldDescription
typeSupports "command"
commandShell command to run
timeoutHook timeout in seconds
ifOptional condition such as Bash(git commit:*)
shellOptional shell override
statusMessageOptional UI status label
asyncRun without blocking the current action
asyncRewakeAllows hook feedback to enqueue a follow-up turn
rewakeMessagePrefix for follow-up feedback
rewakeSummaryShort follow-up summary

Lifecycle events:

EventPurpose
SessionStartRuns when a new session starts
UserPromptSubmitRuns when a user prompt is submitted, before prompt assembly
PrePromptDotCraft-native compatibility event before the assembled prompt is sent
PreToolUseChecks or blocks before tool calls
PermissionRequestRuns before a permission request is shown
PostToolUseLogs, formats, or notifies after successful tool calls
PostToolUseFailureRuns after a tool call fails
PreCompact / PostCompactRun around context compaction
SubagentStart / SubagentStopRun around subagent lifecycle
StopRuns after the assistant response and can enqueue follow-up feedback
StopFailureRuns after Stop hook handling fails

Tool-related Hook stdin usually includes:

json
{
  "hook_event_name": "PreToolUse",
  "cwd": "/workspace/example",
  "sessionId": "thread-id",
  "session_id": "thread-id",
  "toolName": "Bash",
  "tool_name": "Bash",
  "toolArgs": {
    "command": "dotnet test"
  },
  "tool_input": {
    "command": "dotnet test"
  }
}

Turn-related Hook stdin usually includes:

json
{
  "hook_event_name": "Stop",
  "cwd": "/workspace/example",
  "sessionId": "thread-id",
  "session_id": "thread-id",
  "last_assistant_message": "Agent completed the turn",
  "stop_hook_active": false
}

DotCraft emits both camelCase and snake_case field names. JSON stdout can return hookSpecificOutput.additionalContext to inject model-visible context, or decision: "block" plus reason to block supported events or request a rewake follow-up from an asyncRewake hook. The complete engineering contract lives in specs/features/lifecycle-hooks.md.

Exit code semantics:

Exit codeMeaning
0Success, continue
2Block supported events, or request follow-up feedback for rewake hooks
Other non-zeroHook failed; DotCraft records the failure and continues according to the event's runtime policy

Matcher examples:

matcherMatches
WriteFile|EditFileFile writes and edits
ExecShell commands
.*All tools

Desktop manages per-user hook state in ~/.craft/config.json:

json
{
  "Hooks": {
    "State": {
      "/workspace/.craft/hooks.json:pre_tool_use:0:0": {
        "Enabled": false,
        "TrustedHash": "sha256:..."
      }
    }
  }
}

Enabled: false disables one hook without editing the source file. TrustedHash records the last trusted normalized hook definition. Hooks from config and plugins must be trusted before they run, and modified hooks must be trusted again. Plugin hooks are usually trusted as one plugin bundle in Desktop, while the saved state remains per hook.

Plugin hook files use the same hooks.json structure. In plugin hook commands, DotCraft expands ${DOTCRAFT_PLUGIN_ROOT} and ${DOTCRAFT_PLUGIN_DATA} and injects the same names as environment variables.

Operational logging

DotCraft writes workspace host diagnostics to <workspace>/.craft/logs and Hub diagnostics to ~/.craft/logs.

FieldDescriptionDefault
Logging.EnabledWrites operational diagnostics to rolling filestrue
Logging.ConsoleAlso writes diagnostics to the console. Protocol hosts use stderr so stdout remains protocol-onlyfalse
Logging.MinLevelMinimum level: Trace, Debug, Information, Warning, Error, or CriticalInformation
Logging.DirectoryLog directory relative to the host's .craft directorylogs
Logging.RetentionDaysDeletes older rolled files at startup; 0 disables cleanup7
json
{
  "Logging": {
    "Enabled": true,
    "Console": false,
    "MinLevel": "Information",
    "Directory": "logs",
    "RetentionDays": 7
  }
}

Operational logs contain timestamps, severity, process ID, category, messages, exceptions, and active diagnostic scopes. Raw ACP traffic and opt-in session stream debug records use separate files because they can contain sensitive or high-volume payloads.

Entry points and services

FieldDescriptionDefault
Acp.EnabledEnables ACP modefalse
DashBoard.EnabledEnables Dashboardtrue
DashBoard.HostDashboard listen address127.0.0.1
DashBoard.PortDashboard listen port8080
AppServer.ModeAppServer transport mode: Disabled, Stdio, WebSocket, or StdioAndWebSocketDisabled
AppServer.WebSocket.HostWebSocket listen host127.0.0.1
AppServer.WebSocket.PortWebSocket listen port9100
AppServer.WebSocket.TokenToken required by remote WebSocket clientsEmpty
ExternalChannelsExternal channel registration map{}

Dashboard example:

json
{
  "DashBoard": {
    "Enabled": true,
    "Host": "127.0.0.1",
    "Port": 8080
  }
}

External channel registration examples:

Desktop-managed built-in TypeScript channel:

json
{
  "ExternalChannels": {
    "qq": {
      "enabled": true,
      "transport": "managedWebsocket",
      "builtinModule": "channel-qq"
    }
  }
}

Standalone adapter:

json
{
  "AppServer": {
    "Mode": "WebSocket",
    "WebSocket": {
      "Host": "127.0.0.1",
      "Port": 9100,
      "Token": ""
    }
  },
  "ExternalChannels": {
    "wecom": {
      "enabled": true,
      "transport": "websocket"
    }
  }
}

Platform connections, allowlists, and approval timeouts live in adapter-specific files such as .craft/qq.json and .craft/wecom.json. See Channel configuration reference for TypeScript channel examples.

Plugins MCP and LSP

FieldDescriptionDefault
Plugins.EnabledPluginsPlugin ids explicitly enabled for this workspace[]
Plugins.DisabledPluginsPlugin ids explicitly disabled for this workspace. A disabled entry wins over an enabled entry and over the plugin's default state[]
Plugins.PluginRootsExtra plugin root directories maintained outside .craft/plugins/[]
Plugins.PluginRegistriesPlugin marketplace sources available for catalog discovery[]
Plugins.DisableDefaultPluginRegistryIgnore the host-provided default official plugin registryfalse
McpServersMCP server configuration map{}
Tools.DeferredLoading.StrategyDeferred tool loading strategy: Off, Auto, Simulated, or NativeAuto
Tools.DeferredLoading.AlwaysLoadedToolsMCP tool names always loaded upfront[]
Tools.DeferredLoading.DeferThresholdMinimum MCP tool count before MCP tools are deferred10
Tools.DeferredLoading.MaxSearchResultsMaximum deferred tool search results per query5
LspServersLSP server configuration map{}
Tools.Lsp.EnabledEnables built-in LSP toolsfalse

Official DotCraft Desktop and Docker hosts supply the official plugin marketplace as the default registry through DOTCRAFT_DEFAULT_PLUGIN_REGISTRY_URL. Marketplace sources added through Desktop are stored in the global configuration; a workspace PluginRegistries value follows the normal workspace-over-global precedence. Docker Stack deployments persist the global configuration and marketplace cache under state/dotcraft.

Each McpServers and LspServers entry accepts only the fields defined by its current schema. Unknown properties cause configuration parsing to fail.

Plugins.PluginRegistries entry fields:

FieldDescriptionDefault
NameMarketplace identity. Required for manual entries and must match the marketplace document; maintained automatically when added through Desktop or AppServerEmpty
SourceTypeSource kind: git, local, or archiveInferred when omitted
UrlGit URL, local directory, archive URL, or archive fileEmpty
RefGit branch, tag, or commit to check outSource default
SparsePathsRepository-relative paths included in a Git checkout[]
MarketplacePathMarketplace document path inside the source root.craft/plugins/marketplace.json
LastUpdatedUTC timestamp of the last successful add or refreshEmpty
LastRevisionResolved Git revision from the last successful fetchEmpty

When SourceType is omitted, an existing directory or archive file is read locally; other values are treated as archive URLs. Ref and SparsePaths apply only to Git sources.

See Plugin Market for source syntax, the marketplace document, and lifecycle behavior.

Plugin settings files

Plugin-defined settings do not live under Plugins in the main config.json. A plugin declares "settings": "./settings.schema.json" in .craft-plugin/plugin.json, and the host reads two dedicated files:

ScopePath
Personal<UserDataPath>/plugin-config.json; the official app uses ~/.craft/plugin-config.json
Workspace<DataPath>/plugin-config.json; the default is <workspace>/.craft/plugin-config.json

The root object is keyed directly by canonical plugin id:

json
{
  "acme.review-core": {
    "checklistLimit": 5,
    "tone": "concise"
  }
}

Effective settings resolve as schema defaults, then personal values, then workspace values. Objects merge recursively; arrays and scalar values replace the lower layer. A namespace is rejected as a whole when it contains an undeclared field or an invalid value. Removing a workspace value reveals the personal value or schema default below it.

These files are for small JSON configuration, not blobs, databases, or caches. Plugin data remains separate at <UserDataPath>/plugins/<id>/data when UserDataPath is configured, or <DataPath>/plugin-data/<id> otherwise. Disabling, removing, or reinstalling a plugin does not delete either its configuration namespace or data directory.

Local plugin development override example:

json
{
  "Plugins": {
    "PluginRoots": ["/path/to/local/plugins"]
  }
}

MCP example:

json
{
  "McpServers": {
    "everything": {
      "command": "npx",
      "arguments": ["-y", "@modelcontextprotocol/server-everything"]
    }
  },
  "Tools": {
    "DeferredLoading": {
      "Strategy": "Auto",
      "DeferThreshold": 10
    }
  }
}

With Tools.DeferredLoading.Strategy = Auto, all modes use the canonical SearchTools operation. OpenAI Responses maps it to the provider's client-executed tool_search wire type, Anthropic returns native tool references, and chat-completions injects the discovered schemas on the next model request.

Subagent and external CLI profiles

For the concept and everyday use, read Subagents.

FieldDescriptionDefault
SubAgent.MaxDepthMaximum spawn depth for session-backed subagents. The first child is depth 11
SubAgent.MaxConcurrentSubAgentsMaximum resident session-backed subagents inside one root thread's subtree. Exceeding it auto-closes the oldest idle subagent, and the spawn fails instead when every resident subagent is still running16
SubAgent.ProviderPreferencesComplete native subagent preferences keyed by the parent thread provider. A missing entry inherits that thread's complete MainAgent preference{}
SubAgent.MinWaitTimeoutMsMinimum accepted WaitAgent.timeoutMs value in milliseconds15000
SubAgent.DefaultWaitTimeoutMsWaitAgent.timeoutMs used when the tool call omits a timeout60000
SubAgent.MaxWaitTimeoutMsMaximum accepted WaitAgent.timeoutMs value in milliseconds3600000
SubAgent.EnableExternalCliSessionResumeAllows external CLI profiles that support resume to reuse saved external sessionsfalse
SubAgent.DisabledProfilesSubagent profile names hidden and disabled for this workspace[]
SubAgent.RolesWorkspace-defined subagent roles. Entries with built-in names override built-in roles[]

Role example:

json
{
  "SubAgent": {
    "MaxDepth": 2,
    "Roles": [
      {
        "Name": "docs-explorer",
        "Description": "Read-only documentation and code explorer.",
        "ToolAllowList": ["ReadFile", "GrepFiles", "FindFiles", "WebSearch", "WebFetch", "SkillView", "Exec"],
        "ShellAccess": "ReadOnly",
        "AgentControlToolAccess": "Disabled",
        "Instructions": "Inspect files, web sources, and non-mutating shell output such as `git diff`. Do not edit files, manage skills, or spawn agents."
      }
    ]
  }
}

Fields inside each SubAgent.Roles entry:

FieldDescription
NameRole name, also the value used by SpawnAgent.agentRole
DescriptionShort role description exposed to the main Agent
ToolAllowListExact tool allow-list; empty means no additional restriction on eligible tools
ToolDenyListExact tool deny-list removed after the tool set is assembled
ShellAccessHow far a reachable shell tool may go: None / ReadOnly / Full. Applied in addition to the allow/deny lists, not instead of them. Defaults to Full
AgentControlToolAccessAgentTools policy: Disabled / Full / AllowList
AllowedAgentControlToolsAgentTools names allowed when AgentControlToolAccess is AllowList
InstructionsRole instructions delivered as the subagent thread's role context message
ModeOptional mode override
ModelOptional model override
OverrideBasePromptReplaces the base prompt with Instructions; by default instructions are appended

Custom external CLI profiles live under SubAgentProfiles. Workspace config overrides same-named global profiles.

json
{
  "SubAgent": {
    "EnableExternalCliSessionResume": true
  },
  "SubAgentProfiles": {
    "my-cli": {
      "runtime": "cli-oneshot",
      "bin": "my-cli",
      "workingDirectoryMode": "workspace",
      "inputMode": "arg",
      "outputFormat": "text",
      "supportsResume": true,
      "resumeArgTemplate": "--resume {sessionId}",
      "resumeSessionIdJsonPath": "session_id"
    }
  }
}

Fields inside each SubAgentProfiles entry:

FieldDescription
runtimeRuntime type; external short-process CLIs use cli-oneshot
binCLI executable name or absolute path
argsFixed argument list
workingDirectoryModeworkspace / specified
inputModestdin / arg / arg-template / env
inputArgTemplateTemplate for arg-template mode
inputEnvKeyEnv-var name receiving task text in env mode
envFixed env vars injected into the subprocess
envPassthroughNames of env vars to copy from parent
outputFormattext or json
outputJsonPathJSON path to extract the final result in json mode
readOutputFilePrefer reading the output file as the final result
outputFileArgTemplateOutput-file argument template, supports {path}
supportsResumeAllow DotCraft to store and reuse the external session id
resumeArgTemplateResume argument template, supports {sessionId}
resumeSessionIdJsonPathJSON path to extract session id from stdout
resumeSessionIdRegexRegex fallback when stdout is not a single JSON object
timeoutPer-run timeout in seconds
maxOutputBytesMaximum captured output bytes
trustLeveltrusted / prompt / restricted
permissionModeMappingMap DotCraft approval modes to CLI arguments

Vendor headless notes:

ProfileBehavior
cursor-cliDotCraft injects -p --output-format json and appends --resume {sessionId} when resuming
codex-cliDotCraft injects exec plus output-file arguments; resume becomes exec resume {sessionId}

Custom commands

Custom commands are Markdown files rather than a config.json field. DotCraft loads them from the global ~/.craft/commands/ directory and the workspace .craft/commands/ directory, and a workspace file wins a name collision. Each file becomes a /name command usable from the CLI, Desktop, and other entry points.

A command file may open with YAML frontmatter, which is stripped before the body is sent. Inside the body, $ARGUMENTS expands to the full argument string and $1 through $9 expand to positional arguments.