> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sensecode.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Skills

> skill(name, description, tools) — a named, reusable bundle of tools, handed to ask_with_tools as one unit.

## The shape of it

```sns theme={null}
tool search(query: String) returns String requires web.search "search the web for a query":
    return "results for " + query

tool fetch_page(url: String) returns String requires web.fetch "fetch the contents of a web page":
    return "contents of " + url

policy:
    allow web.search
    allow web.fetch

web_research = skill("web_research", "search the web and fetch pages to answer questions", [search, fetch_page])

result = ask_with_tools("what's new in AI-native programming languages?", [web_research])
print(result.value)
```

`skill(name, description, tools)` bundles [`tool`](/ai-native/tool)
values you'd otherwise re-list individually every
[`ask_with_tools`](/ai-native/tool-calling) call. There's no dedicated
keyword for this — same reasoning as why there's no `model` keyword: the
builtin's return type (a `Skill` value) already carries the meaning
wherever it's checked.

## When to use this

Reach for `skill(...)` once you find yourself passing the same group of
tools into `ask_with_tools` across multiple calls, or you want to
group related tools under one description so a model reasons about them
as a capability ("web research") rather than as several unrelated
functions. For a single one-off tool, or a handful of tools that don't
share a theme, just pass them to `ask_with_tools` directly — a skill
adds a layer of indirection that only pays for itself once it's reused.

## The description has a real effect, not just documentation

<Note>
  Passing a skill inside `ask_with_tools`'s `tools` array flattens it
  into its component tools *and* prepends its description (alongside every
  other skill's) to the prompt as an "Available skills:" preamble — the
  same "not cosmetic" pattern
  [`ask_with_memory`](/ai-native/memory#reasoning-with-memory-ask_with_memory)'s
  context injection follows.
</Note>

```sns theme={null}
web_research = skill("web_research", "search the web and fetch pages to answer questions", [search, fetch_page])
email_skill = skill("email", "compose and send emails on the user's behalf", [send_email])

result = ask_with_tools("what's the latest news about AI-native programming languages?", [web_research, email_skill])
```

Skills and bare `tool` values mix freely in the same call.

## Validation

<Steps>
  <Step title="tools must be non-empty">
    `skill(name, description, [])` raises `SenseRuntimeError` at
    `skill(...)` call time.
  </Step>

  <Step title="Each tool must already satisfy ask_with_tools's own rules">
    Not async, has a description — checked eagerly at `skill(...)` call
    time, not deferred until the skill is actually used, for the earliest
    possible error.
  </Step>

  <Step title="No name collisions">
    A tool name repeated across two skills — or a skill and a bare tool —
    raises `SenseRuntimeError` in `ask_with_tools` rather than silently
    letting one shadow the other.
  </Step>
</Steps>

`.name`, `.description`, and `.tools` are readable members on a `Skill`
value, same "everything inspectable" pattern as
[Agent](/ai-native/agents)/[Action](/safety/actions)/
[Memory](/ai-native/memory).

## What this doesn't do (yet)

<AccordionGroup>
  <Accordion title="Nested skills, a per-skill capability">
    A skill can only bundle `tool`/`McpTool` values, not other skills.
    Each contained tool is still gated individually — a skill has no
    capability of its own.
  </Accordion>
</AccordionGroup>

## Continue

<CardGroup cols={2}>
  <Card title="Tool-Calling" icon="hand-pointer" href="/ai-native/tool-calling">
    The mechanism a skill's tools are ultimately exposed through.
  </Card>

  <Card title="Tool" icon="wrench" href="/ai-native/tool">
    What each item inside a skill's `tools` list actually is.
  </Card>

  <Card title="MCP" icon="plug" href="/ai-native/mcp">
    A skill can bundle tools from an external MCP server too.
  </Card>
</CardGroup>
