Saltar al contenido principal
Versión: 0.23.0

Session options

function buildSessionOptions<TConfig extends BaseSessionConfig>(
config: TConfig,
runDir: string,
spec: AgentSpec<TConfig>,
options?: { autoCompactEnabled?: boolean; run?: RunFolder },
): Promise<{
options: Options; // for the SDK's query()
transcriptLogger: TranscriptLogger;
transcriptPath: string; // <runDir>/transcript.jsonl
modeControl: ModeControl;
language: Language; // the resolved language
}>;
  • config: your session config.
  • runDir: this run's folder. The transcript, the response file and the kit's MCP servers use it. With a runs folder, pass the folder the chat gives your opener (run.dir).
  • spec: your AgentSpec.
  • options.autoCompactEnabled: the SDK's automatic context compaction; true by default.
  • options.run: keeps the SDK's transcript in the run folder and resumes its session if it has one. See Runs and resuming.

What goes into Options​

System prompt​

spec.buildSystemPrompt(config), then the extensions' list and each active one's own section (the awareness's "Who you are", the sources', the knowledge base's), then the reply language line unless spec.replyInLanguage === false.

Tools​

tools (what exists) and allowedTools (what's pre-approved) are the same list, built from the configuration:

ConditionTools added
alwaysWebFetch, WebSearch, TodoWrite
config.extraWritableDirsRead, Write, Edit, Glob, Grep
config.extraReadableDirs, or an extension that asks for them (sources)Read, Glob, Grep
file tools or at least one pluginSkill
spec.buildSubagents() returns somethingAgent; Bash too when a subagent lists it in its tools or has no tools

TodoWrite is the SDK's task list for long jobs (the session's env is process.env plus CLAUDE_CODE_ENABLE_TASKS=0, without which the CLI replaces it with its own Task tools): the chats show the list instead of the calls (see Ink chat). Nothing else of the CLI's built-in tools is available. Bash is there only because the SDK won't spawn a subagent whose own tools aren't in the session's; a hook denies it to the main agent.

MCP servers and permissions​

mcpServers holds spec.buildMcpServers(config, runDir) plus the kit's own, when they apply:

ServerToolWhen
approvalsrequest_human_approval, ask_human, present_planmode is not autonomous
manualLoginrequest_manual_loginmode is not autonomous and spec.manualInterventionTexts is set
sourceFileslist_sources, extract_text, save_to_sources, download_to_sources, and request_file, retire_source outside autonomous modethe sources extension (with its folder)
timecurrent_time, date_mathalways (in config.timeZone, or the system's)
knowledgethe knowledge_* tools (knowledge_retire outside autonomous mode)the knowledge extension (with its folder)

canUseTool is allowAnyMcpTool: every mcp__* call is approved, anything else is denied (the built-in tools above are already pre-approved, so they never reach it). disallowedTools is spec.disallowedTools ?? [] and wins over everything.

Hooks​

PreToolUse, in this order:

  1. the transcript logger;
  2. the file scope gate, with file tools;
  3. the step gate, outside autonomous mode, active only while the mode is interactive;
  4. the plan gate, likewise outside autonomous mode, active only while the mode is plan (see modes);
  5. with subagents, the three subagent gates: type, Bash, foreground.

PostToolUse: the transcript logger.

The result also has apis, what each active extension hands the host, by its name: the sources' addSource at apis.sources.addSource, the knowledge base's store at apis.knowledge.knowledgeStore (see Knowledge store).

Skills, plugins and the working directory​

When the session has file tools or at least one plugin:

  • cwd is config.projectDir;
  • additionalDirectories are the searchable folders: the extensions' read-only ones (the sources folder), then extraWritableDirs, then extraReadableDirs;
  • plugins are spec.pluginRoots(config), plus the knowledge plugin when the knowledge base is on, each loaded as a local plugin with its MCP discovery skipped;
  • skills is spec.skills ?? "all"; "plugins" becomes the skills of the plugins loaded (plugin:folder), and a list gets the enabled extensions' skills added.

Otherwise the SDK's defaults apply (the process's working directory, no plugins).

Settings​

OptionValueWhy
settingSourcesspec.settingSources ?? ["project"]the runner's own Claude Code settings never reach the agent unless asked for
settings.autoCompactEnabledoptions.autoCompactEnabled ?? truelong chats keep working
settings.autoMemoryEnabledfalsethe runner's Claude Code memory is not the agent's
settings.includeGitInstructionsfalseno kit agent commits code, and the git context skewed the reply language
settings.disableClaudeAiConnectorstruethe claude.ai connectors of the account the session runs with (Drive, Gmail…) are the runner's integrations, not the agent's
includePartialMessagestruereplies stream token by token
maxTurns400a generous cap per query

See Permissions and isolation for the reasons.

Subagents​

agents is what spec.buildSubagents(config) returned, with the reply language line appended to each subagent's prompt.

Runs​

With options.run: sessionStore is a run store for run.dir, and resume is run.sessionId when it has one.

Adding your own options​

The result is a plain object: spread it to add or override anything the kit doesn't set for you.

const { options } = await buildSessionOptions(config, runDir, spec);

const session: Options = {
...options,
model: "claude-sonnet-5",
maxTurns: 50,
hooks: {
...options.hooks,
PostToolUse: [...(options.hooks?.PostToolUse ?? []), { hooks: [myAuditHook] }],
},
};

Keep the kit's hooks when you add yours: replacing hooks wholesale would drop every guardrail. See Your own hooks.

Calling it more than once​

Every call builds a fresh set of servers and hooks bound to its runDir. Build the options once per session, and again for another run folder (that's what a session opener does on /resume). The resolved language, the mode control and the transcript logger belong to that call.