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

> ## Agent Instructions
> Unmute compiles to exactly three targets. Pipecat and LiveKit are code targets: compile writes a Python project you run. SLNG is a hosted target: compile writes a deployment body and SLNG runs the agent, so it has no `unmute dev`. Those three are the only values `provider` accepts in `targets.yaml`. Deepgram and ElevenLabs appear in these docs as model vendors, which is not the same thing as a target, and `slng` is both.
> The Go structs in `internal/spec` and `internal/ir` are the schema truth. Check a field against them, or run `unmute validate`, rather than against what you remember.

# Coding agents

> Optional setup for supported coding assistants, followed by one checked voice-agent build.

Unmute ships an optional skill that teaches a supported coding assistant how to
write an Unmute package.

The skill carries the schema, the model catalog, the tool kinds, how to shape a
prompt for speech, and what each target refuses. Install it once, then describe
the agent you want in a sentence and check what comes back. Setup is quick, and
talking to the agent it builds takes a bit longer.

An assistant is not required. If you would rather write the YAML yourself, the
[quickstart](/start/quickstart) is the same journey by hand, and it is the
better page if you want to understand every field as you go. If your assistant
is not one of the four below, you can still use Unmute: you just do not get the
skill, and the rest of this site is written for you.

On this page:

* [Set it up](#set-it-up) - one command, every assistant
* [Check it took](#check-it-took) - prove the skill loaded
* [Read this site as Markdown](#read-this-site-as-markdown) - the endpoints an assistant fetches
* [Build the salon agent](#build-the-salon-agent) - one build, start to finish
* [Change an existing package](#change-an-existing-package) - a different order
* [Ask for more](#ask-for-more) - what your request has to carry
* [Habits](#habits) - six things that help

## Set it up

You need the `unmute` binary. See [installation](/start/installation).

From the root of your project:

```sh theme={null}
unmute skill install
```

```text expandable theme={null}
  .agents/skills/unmute/
    SKILL.md                         written
    references/conversation.md       written
    references/deploy.md             written
    references/examples.md           written
    references/latency.md            written
    references/models.md             written
    references/orchestration.md      written
    references/package.md            written
    references/prompting.md          written
    references/telephony.md          written
    references/tools.md              written
    references/transfers.md          written
    references/variables.md          written
    references/workflow.md           written
  .claude/skills/unmute/
    SKILL.md                         written

Installed the Unmute skill for claude, codex, copilot, cursor.
Commit these files so your team's assistants get them too.
Next: ask your assistant to build a voice agent, in a sentence.
```

One command covers every assistant, because they read different directories
but the same instructions. Commit both directories. Then anyone who clones the
repository has an assistant that knows Unmute, with nothing to install.

| Assistant      | Reads                    |
| -------------- | ------------------------ |
| Claude Code    | `.claude/skills/unmute/` |
| Codex          | `.agents/skills/unmute/` |
| Cursor         | `.agents/skills/unmute/` |
| GitHub Copilot | `.agents/skills/unmute/` |

`.claude/skills/unmute/SKILL.md` is a pointer at the full bundle, so the
instructions exist once no matter how many assistants you set up. Two
assistants in the same project is fine and normal.

<Tip>
  The skill ships inside the binary. Installing it downloads nothing and works
  offline. It writes only the two directories above, so if your assistant
  cannot run shell commands, run the command yourself in a terminal and the
  result is exactly the same.
</Tip>

Re-run it whenever you upgrade the CLI. It reports what it changed, and it
refuses to overwrite a file you edited by hand unless you pass `--force`. Full
flags are on the [skill command](/reference/cli/skill) page.

## Check it took

A skill that silently did not load looks exactly like an assistant that is bad
at Unmute, so prove it before you build anything.

A tool is an action the voice agent can call, such as checking appointment
slots or booking one. Its YAML file describes what the model may send and has
exactly one execution block that says where the action runs.

Ask:

```text theme={null}
In Unmute, what are the six ways a tool can run?
```

A correct answer names all six. Three of them say where an action runs: an HTTP
`webhook:`, a `local:` Python handler in the package, and a remote `mcp:`
server. The other three point at something that already exists. `builtin:`
selects a tool the runtime already has by id. `knowledge:` is a search over a
folder of your own documents. `slng:` is a reference to a tool the SLNG platform
already hosts. A very good answer also mentions the two blocks that exist in the
schema but no target emits.

This question is the check because it cannot be guessed. It is a closed list
out of this project's own schema, so a model that has not read the skill either
hedges or invents kinds that sound right. If you get a vague paragraph about
function calling, the skill did not load.

When it fails: run `unmute skill install` again, confirm the directory for your
assistant from the table above exists, and start a new session so the
assistant picks it up.

## Read this site as Markdown

The skill teaches an assistant how to write a package. This section is the other
half: how an assistant reads the site itself. Every page here is served as
Markdown as well as HTML, so an assistant does not have to work from scraped
HTML.

| What                 | Where                                                                                                        | Use it for                                                                            |
| -------------------- | ------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------- |
| One page as Markdown | add `.md` to any page URL, for example [`/start/coding-agents.md`](https://unmute.ai/start/coding-agents.md) | pointing an assistant at the one page that answers the question in front of it        |
| The index            | [`/llms.txt`](https://unmute.ai/llms.txt)                                                                    | letting an assistant see every page and its description, then fetch the ones it needs |
| The whole site       | [`/llms-full.txt`](https://unmute.ai/llms-full.txt)                                                          | one file with every page in it, for a tool that wants the lot in a single fetch       |

Prefer `/llms.txt` and then one page. It is a few kilobytes, and it lets the
assistant choose. `/llms-full.txt` is the entire site in one file, which is
hundreds of kilobytes and will crowd out the rest of a context window.

Every page also carries a menu in its top right corner that copies the page as
Markdown, opens the Markdown, or opens the page in a chat with ChatGPT or
Claude. That is the fastest way to hand one page to an assistant that cannot
fetch a URL itself.

<Tip>
  These endpoints are the current site, so they always match what is published.
  The installed skill is version matched to your binary and works offline. Use
  the skill for how to author a package, and these endpoints when you want the
  page a reader would see.
</Tip>

## Build the salon agent

This is one build, start to finish. It is the shape `unmute init` scaffolds:
one agent, browser audio, local tools, no phone number.

<Steps>
  <Step title="Ask in a sentence">
    ```text theme={null}
    Build me a voice agent for a hair salon. It answers in the browser, greets
    the caller by name, and can check appointment slots and book one.
    ```

    You do not need to name files, fields, or models. The skill carries the
    schema. What you supply is the job.

    **Check:** before writing anything, the assistant should tell you what it
    is about to do. Which target, which models by vendor and role, and which
    channel. If it starts writing files without saying any of that, stop it and
    ask, because a silent choice here is one you will find out about later.
  </Step>

  <Step title="Read what it wrote">
    ```text theme={null}
    salon/
    ├── agent.yaml
    ├── instructions.md
    ├── targets.yaml
    └── tools/
        ├── check_slots.yaml
        ├── check_slots.py
        ├── book_appointment.yaml
        └── book_appointment.py
    ```

    **Check three things, in this order.** They take a minute and they catch
    most of what goes wrong.

    `agent.yaml`: is `channels:` what you asked for? A browser agent is
    `web: realtime_audio` and needs no phone route.

    `instructions.md`: read it out loud. It should sound like something a
    person says, with no bullet lists to read out, no markdown, and no raw
    URLs. It should also tell the model how to speak times and names. If it
    reads like documentation, the agent will sound like documentation.

    `tools/*.yaml`: each tool file has exactly one execution block, and the
    `description` reads as an instruction about when to call it, not as a
    label. Local Python handlers are fixtures until you wire them up, and the
    assistant should have said so.

    Use block-style YAML sequences in assistant-authored packages. Do not use anchors or aliases.
    This makes every list and task definition readable where it appears. It is
    a rule for assistant-written packages, not a claim that Unmute rejects
    other valid YAML.
  </Step>

  <Step title="Add your keys">
    Create `salon/.env` with `OPENAI_API_KEY` for the model that thinks and
    `SLNG_API_KEY` for the speech models. `.env.local` is also supported for
    local development. `unmute dev` reads your shell, then `.env` and
    `.env.local` in the current directory, then both files in the package
    directory. Later files win.

    Which names a package needs is not something to guess at. Every compile
    writes `salon/build/<target>/.env.example` listing the values you supply,
    so compile once and read that file.

    **Check:** no key, token, or phone number appears in any package file. A
    package carries environment variable names only, in `UPPER_SNAKE`, and the
    `secrets:` block in `agent.yaml` is where they are declared. If you find a
    literal value in the YAML, tell the assistant, because the compiler refuses
    them and it should not have written one.
  </Step>

  <Step title="Let it check its own work">
    ```sh theme={null}
    unmute validate salon
    ```

    The package is a directory beside you, so it is named on the command line.
    Inside `salon` you could run `unmute validate` with no argument and get the
    same result. It reports one row per target in `targets.yaml`, whichever
    ones the assistant put there.

    Ask the assistant to run this itself and fix what it finds. Reading a
    refusal is the fastest path it has, and the messages name the file and the
    line.

    **Check:** warnings are not errors, and they are not noise either. If
    validate prints one, the assistant should read it to you rather than move
    past it.
  </Step>

  <Step title="Talk to it">
    ```sh theme={null}
    unmute dev salon
    ```

    ```text theme={null}
    compiled salon/build/livekit
    building and starting the container...

      ▸ http://localhost:8765/?agent=salon-livekit
        ctrl-c to stop  ·  logs: salon/build/livekit/dev.log
    ```

    Open the link and speak. Docker has to be running, and this step is the
    only one that needs a network.

    **Check:** this is the check no test can do for you. Does it interrupt
    well? Does it say times like a person? Does it call the tool at the right
    moment? A green validate means the package is legal. It does not mean the
    agent is good, and the difference is only audible.
  </Step>
</Steps>

## Change an existing package

An existing package needs a different order from a new build. Ask the assistant
to keep current behavior until it has separated invalid definitions from
unneeded structure:

1. **Inspect the existing package.** Read the agent, target, prompt, and loaded
   tool files before changing them.
2. **Run `unmute validate` before editing.** Save the errors and warnings as the
   baseline.
3. **Fix invalid definitions.** Make the package legal before changing its
   structure.
4. **Simplify.** Remove only structure the requested behavior does not need.
5. **Run `unmute validate` again.** Fix every error and report every warning.
6. **Run `unmute compile`.** Regenerate `build/` from the corrected package.

This order matters. If validation and simplification happen together, you
cannot tell whether a failure was already present or came from the rewrite.

## Ask for more

The build above is one agent with two tools. Everything after it is a
conversation with your assistant. What you get back depends on what your
request carries.

Describe required order, separate roles, and server-directed next steps in
plain words. You do not need to ask for tasks or <Tooltip tip="Several tasks that run one after another, in the order you wrote them.">task groups</Tooltip> by name. The
assistant should infer the smallest Unmute structure before writing files and
tell you what it chose.

| You want            | Say                                                                                    | It should tell you                                                                                                                                                                       |
| ------------------- | -------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| a tool              | what it does, where the data comes from, and whether there is an HTTP endpoint already | which of the five kinds it chose, and why                                                                                                                                                |
| an ordered workflow | which stages must happen in order and which parts are server-directed                  | which tasks and task groups it chose, and what context the steps share                                                                                                                   |
| a second agent      | what each one owns, and when control moves between them                                | what context crosses the <Tooltip tip="One agent gives the caller to another agent. The first agent does not get the caller back.">handoff</Tooltip>, and whether the handoff comes back |
| a phone number      | inbound, outbound, or both, and which carrier you have                                 | which route, and what that route cannot do                                                                                                                                               |

Ask what it decided, every time. The skill tells it to state the target, the
models, the context across every handoff, and what it actually checked. If any
of those is missing from the answer, ask, because a decision nobody named is a
default nobody chose.

Expect it to refuse things. Unmute does not support every vendor for every role
on every target, and some shapes are gated on some targets. A good answer says
plainly that something is not available and names what is. If your assistant
invents a provider name instead, that is the failure to watch for, and it shows
up as a validation error with the target named.

## Habits

Six things that separate a good session from a frustrating one.

1. **Let it run `unmute validate` and read the error.** Guessing at a schema
   costs more turns than checking.
2. **Never edit anything under `build/`.** The next compile overwrites it.
   Change the package and compile again.
3. **Name the target, or one gets picked for you.** Pipecat and LiveKit both
   compile to a project you run, and they refuse different things.
4. **Trust the references over what the assistant remembers, and `unmute
   validate` over both.** Model memory of a fast moving schema is the single
   biggest source of confident wrong answers.
5. **Ask what it decided.** Structure, target, models, and the context across
   each task, group, or handoff. A silent default is the bug you find a week
   later.
6. **Listen to the agent before you ship it.** A green check is not a good
   call.

## Where to go next

<Columns cols={2}>
  <Card title="How Unmute works" icon="settings" href="/start/how-unmute-works">
    What the compiler did between the package and that container.
  </Card>

  <Card title="Orchestration" icon="git-branch" href="/build/orchestration/overview">
    Tasks, task groups, and handoffs.
  </Card>

  <Card title="Tools" icon="wrench" href="/build/tools/overview">
    The five active kinds in full.
  </Card>

  <Card title="Telephony" icon="phone" href="/telephony/overview">
    Put the agent on a real phone number.
  </Card>

  <Card title="Deployment" icon="cloud-upload" href="/deploy/going-live">
    Get the agent off your laptop.
  </Card>
</Columns>
