Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.qoder.com/llms.txt

Use this file to discover all available pages before exploring further.

options.skills controls which skills the Skill tool can invoke in the current session. The SDK compiles it into the CLI’s Skill allowlist and merges it with allowedTools before passing to qodercli.

SDK Does Not Load Built-in Skills

When the SDK launches the CLI it always appends --disable-builtin-skills, so the session never sees the CLI’s factory built-in skills (simplify, debug, security-review, quest, batch, agent-creator, hook-config, mcp-config, skill-creator, …). No source: 'built-in' entries appear in init.skills, and the model’s system prompt does not see them either. This is fixed SDK behavior with no opt-in; if you want the capability of a CLI built-in skill, either ship your own copy of the SKILL.md via a plugin / user dir / project dir, or run the CLI directly outside the SDK. The session can still pick up skills contributed from these sources:
  • plugin skills: loaded via options.plugins, addressed with the plugin-qualified name (plugin:skill).
  • user / project skills: discovered when you opt into user / project / local via options.settingSources.
  • agent-preloaded skills: declared on options.agents[name].skills, scoped to that sub-agent only.
To reliably confirm what was discovered in a session, run query() once and read init.skills — don’t hard-code the set.

Using CLI Default Policy

When skills is not passed, the SDK does not inject an additional Skill allowlist, leaving everything to the CLI’s own policy. Because built-ins are disabled, a session with no settingSources / plugins will see an empty init.skills array.
import { query } from '@qoder-ai/qoder-agent-sdk';

const q = query({
  prompt: 'Analyze the test coverage of this project',
  options: {
    cwd: '/path/to/project',
  },
});

Enabling All Discovered Skills

const q = query({
  prompt: 'Use an appropriate skill to perform a code review',
  options: {
    cwd: '/path/to/project',
    settingSources: ['project'],
    skills: 'all',
  },
});
skills: 'all' allows the Skill tool to invoke every skill the CLI currently discovers (sources are determined by settingSources / plugins; built-ins are no longer included).

Enabling Only Specific Skills

const q = query({
  prompt: 'Use the review skill to inspect recent changes',
  options: {
    cwd: '/path/to/project',
    settingSources: ['project'],
    skills: ['review'],
  },
});

Enabling Plugin Skills

Plugin skills use plugin-qualified names. For plugin loading methods, see Plugins documentation.
const q = query({
  prompt: 'Use the echo skill provided by the plugin to handle this input',
  options: {
    plugins: [{ type: 'local', path: '/path/to/sdk-test-plugin' }],
    skills: ['sdk-test-plugin:sdk-echo'],
  },
});

Merging with Explicit Tool Allowlist

const q = query({
  prompt: 'Read the source and use the review skill to produce a list of issues',
  options: {
    cwd: '/path/to/project',
    settingSources: ['project'],
    allowedTools: ['Read', 'Grep'],
    skills: ['review'],
  },
});
The above configuration ultimately allows Read, Grep, and Skill(review).

Hiding Discovered Skills

options.skills controls tool permissions, not discovery filtering. To truly keep a plugin / user / project skill out of init.skills and the model’s system prompt, use settings.skillOverrides.
const q = query({
  prompt: 'Handle this task',
  options: {
    plugins: [{ type: 'local', path: '/path/to/sdk-test-plugin' }],
    settings: {
      skillOverrides: {
        'sdk-test-plugin:sdk-echo': 'off',
      },
    },
  },
});
  • 'off': Completely hidden — not in init.skills, not in model system prompt, Skill tool invocations are also rejected.
  • Other values: 'on' (default), 'name-only' (only shows name, not description), 'user-invocable-only' (invisible to model, user can still trigger via /name).
  • Scope of effect: every SDK-visible source (plugin, user, project, …) respects this override; CLI built-ins are already blocked by --disable-builtin-skills, so overrides for them have nothing to act on.
  • Key naming rules: Plugin skills use the plugin-qualified name plugin:skill; non-plugin skills use bare names. Both forms can be written simultaneously; matching is attempted against the fully qualified name first, then falls back to the bare name.
options.skills only controls tool invocation permissions, it cannot be used to hide skill discovery / context exposure.

Reading Skills Discovered in the Current Session

The initialization result includes skills discovered by the CLI in this session, which the host UI can use to display “currently available capabilities.”
const q = query({
  prompt: 'Do not execute any task yet',
  options: {
    cwd: '/path/to/project',
    settingSources: ['project'],
    skills: 'all',
  },
});

const init = await q.initializationResult();
console.log(init.skills?.map((skill) => skill.name));
skills is context and tool visibility control, not a security boundary. Unlisted skills won’t be exposed to the model via the Skill tool, but skill files are still on disk and can still be accessed by regular file reading tools.

Custom Agent Preloading Skills

If you define custom sub-Agents via options.agents, you can declare skills in the Agent definition. When the main session invokes the Agent tool, the sub-Agent will run with the specified skills loaded.
const q = query({
  prompt: 'Dispatch a helper agent that uses the sdk-agent-marker skill to return the marker',
  options: {
    cwd: '/path/to/project',
    allowedTools: ['Agent'],
    agents: {
      'sdk-skill-helper': {
        description: 'Invoke when the sdk-agent-marker skill is needed.',
        prompt: 'You are a helper agent that only reads and runs the specified skill.',
        skills: ['sdk-agent-marker'],
        maxTurns: 2,
      },
    },
  },
});
These skills only affect that Agent’s context and are not equivalent to enabling the same-named skill for the main session.

Options Reference

FieldTypeDescription
skillsstring[] | 'all'Controls which skills the main session can invoke via the Skill tool
agentsRecord<string, AgentDefinition>Custom Agents; each Agent can declare an independent skills preload list
allowedToolsstring[]Tool allowlist; merged with Skill(...) entries compiled from skills with deduplication
settingSources('user' | 'project' | 'local')[]Controls whether the CLI scans user / project dirs for skills (default empty = sandboxed)
pluginsPluginSpec[]Loads plugins; skills inside contribute to the discovered set
settings also has several skill-related fields that the SDK passes through; actual effects depend on whether the CLI version implements them:
FieldPurpose
skillOverridesSet 'on' | 'name-only' | 'user-invocable-only' | 'off' per skill name; plugin, user, project sources all respect this override
skillListingMaxDescCharsCharacter limit per description in skill listing (SDK default 1536); exceeding it triggers truncation
skillListingBudgetFractionContext window fraction reserved for skill listing (SDK default 0.01 = 1%); exceeding it triggers compression
strictPluginOnlyCustomizationRestrict one or more of skills, agents, hooks, mcp to only accept contributions from plugin sources

Return Value Reference

type SDKControlInitializeResponse = {
  skills?: Array<{ name: string; description?: string; source?: string }>;
  // ...also returns commands / agents / plugins and similar fields
};

Best Practices

  • Enable skills as needed: skills: 'all' is ideal for development and debugging; end-user-facing products should typically pass an explicit list.
  • Want a CLI built-in’s behavior? Ship your own copy: the SDK will not inject simplify / security-review and the rest. Provide your own SKILL.md via a plugin or a settingSources-visible directory.
  • Don’t treat skills as a sandbox: Security boundaries should be controlled collectively by allowedTools, disallowedTools, canUseTool, permission mode, and sandboxing.
  • Use initializationResult().skills for UI: This is the stable entry point for the CLI discovery pipeline, used to display “currently available skills.”
  • Manage sub-Agent skills separately: They are independent lists from the main session’s options.skills and do not override each other.