# MCP servers, skills and commands

> Extend Kaitoi Code with MCP servers, skills in SKILL.md folders, your own slash commands and hooks, each under your control.

Source: https://kaitoi.io/docs/cli/mcp-skills-and-commands/
Section: Kaitoi CLI / Extending Kaitoi Code
Written for: Anyone who wants Kaitoi Code to use more tools, or to follow their own project's workflow.
Prerequisites: Kaitoi CLI installed
Last reviewed: 2026-10-23

---

Kaitoi Code can be extended in four ways: MCP servers give it more tools,
skills teach it how to do one kind of task, project commands add your own slash
commands, and hooks run your own scripts at fixed points of a session.
Anything that comes from a repository only works in a folder you trust.

This overview keeps the setup choices together. For the detailed guides and
diagrams, see [MCP servers](/docs/cli/mcp-servers/),
[Skills and project commands](/docs/cli/skills-and-commands/),
[Hooks](/docs/cli/hooks/), and
[Project instructions and memory](/docs/cli/instructions-and-memory/).

## MCP servers

An MCP server gives Code more tools, such as a database, an issue tracker or
a design app. Code connects to servers you add to your settings, and to the
servers a trusted project lists in its `.mcp.json` or `.kaitoi/mcp.json`.

Each external server you configure must be approved by you at a terminal, on
a screen that shows what will run. A changed launch specification needs fresh
approval. Kaitoi's built-in server uses your session login without this launch
approval; its individual tool calls still follow their own permission rules.

### Add a server

From a shell, `kaitoi mcp add` takes a server in one of these forms:

```bash
# A program, after --
kaitoi mcp add fs --read workspace -- npx -y @modelcontextprotocol/server-filesystem@2026.8.31 '${workspace}'

# An npm or PyPI package, installed once at an exact version
kaitoi mcp add fs --npm @modelcontextprotocol/server-filesystem@2026.8.31 --read workspace -- '${workspace}'
kaitoi mcp add fetch --pypi mcp-server-fetch==2025.4.7 --network on

# A remote server
kaitoi mcp add docs --url https://example.com/mcp --header 'Authorization: Bearer ${secret:DOCS_TOKEN}'

# A snippet copied from another app's mcpServers settings
kaitoi mcp add --json '{"mcpServers": {"fs": {"command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem@2026.8.31"]}}}'
```

`kaitoi mcp add --help` lists every option. Then:

- `kaitoi mcp list` shows each server and whether it is approved.
- `kaitoi mcp approve <name>` approves a server a project added, and
  `kaitoi mcp revoke <name>` takes an approval back.
- `kaitoi mcp remove <name>` removes a server.

**Keep secrets out of the settings file.** Save one with
`kaitoi mcp secret set NAME` and write `${secret:NAME}` where the server needs
it. The secret is kept in your keychain or, where there is none, in a file only
you can read. `${env:NAME}` reads an environment variable and `${workspace}` is
the trusted folder.

### Packages installed once

With `--npm PACKAGE@VERSION` or `--pypi PACKAGE==VERSION`, Code installs the
server once, without running install scripts or building from source, and
only from a version that has been published for at least a week (for npm, with
npm 11.10 or later; Code warns when yours is older). The server then starts
from those files with nothing downloaded. If the installed files change, the
server stops until you reinstall it with `kaitoi mcp update <name>`, which can
also move it to another version.

### What a server can reach

On macOS and Linux, a server that runs on your computer runs in the same
sandbox as Code's commands, with its own data folder. By default it has no
network and none of your folders. `--read` and `--write` give it folders,
`workspace` for the trusted folder, and `--network off`, `localhost` or `on`
sets its network. On Linux, `localhost` is the same as `on`, because the
sandbox there cannot limit the network to this computer.

Some servers reach more, and their approval screen says so:

- A server started through a package runner such as `npx` or `uvx` has the
  network on, so it can download its package when it starts.
- A server started through Docker or Podman, such as with `docker run`,
  `podman run` or `docker mcp gateway run`, is not sandboxed by Code: the
  container engine runs it, and it can reach whatever the command gives it,
  such as the folders it mounts.

A remote server must use https, unless it runs on this computer. If it asks
you to sign in, run `kaitoi mcp login <name>`: it opens your browser, and the
sign-in is kept in your keychain (or, where there is none, in a file only you
can read) and renewed when it expires.
`kaitoi mcp logout <name>` deletes it.

### Using a server's tools

A server's tools appear to Code as `mcp.<server>.<tool>`. When the effective
decision is **ask**, a call shows a card with the arguments:

- **Allow once** (`a`)
- **Always allow** that tool from that server (`s`)
- **Deny** (`d`)
- **Never allow** that tool (`n`)

You can also save a choice ahead of time, which is how a headless run gets to
use a tool:

```bash
kaitoi mcp grant github create_issue --ask
kaitoi mcp grant fs read_text_file --allow --read-only
```

`--allow` runs without a card, `--ask` asks for each call, and `--deny` refuses
without a card. Headless runs cannot answer an **ask** decision. `'*'` applies
the choice to every tool of that server unless a tool-specific grant overrides
it. `--read-only` marks a tool as only reading so Plan and Crew can offer it;
it does not change its allow/ask/deny decision. `kaitoi mcp grants` lists your
saved choices. Saved choices are cleared when the server changes.

A server can also offer resources, whose reads follow the same grant rules,
and prompts, which become slash commands named
`/mcp:<server>:<prompt>`.

### In a session

`/mcp` lists the servers, their state and their tools. `/mcp approve <name>`,
`/mcp enable <name>` and `/mcp disable <name>` act on one, `/mcp login <name>`
signs in, `/mcp tools <server>` and `/mcp grant` show and save choices, and
`/mcp reload` restarts the servers after you edit their settings.

### Creative apps

`/mcp presets` lists ready-made setups for Blender, DaVinci Resolve and Comfy,
and `/mcp preset add <id>` or `kaitoi mcp add --preset blender` adds one after
its setup steps. The Comfy preset connects to Comfy Cloud: generating there
needs a Comfy subscription and is billed by Comfy, not in Kaitoi credits.

### Kaitoi's own server

When you are signed in, Kaitoi's own MCP server is built in as `kaitoi`, with
nothing to add. See [Kaitoi Code](/docs/cli/code/) for what it does, and
`/mcp disable kaitoi` to turn it off.

## Skills

A skill is a folder with a `SKILL.md` file that teaches Code one kind of task,
plus any templates, examples or scripts it uses. The file starts with a name
and a description of when to use it:

```markdown
---
name: release-notes
description: Use when the user asks for release notes.
---

Read CHANGELOG.md, then write the notes in this shape: ...
```

Code finds skills in a trusted project's `.kaitoi/skills`, `.claude/skills`
and `.agents/skills` folders, then in `.kaitoi/skills` in your home folder.
The first one found with a name wins. Code sees each skill's name and
description and loads its instructions when a task matches, and you can run
one yourself as `/<name>`. `/skills` lists what Code found.

## Project commands

A trusted project can add its own slash commands as Markdown files in
`.kaitoi/commands` or `.claude/commands`. Each file is one command, named
after its path: `review.md` is `/review`, and `frontend/component.md` is
`/frontend:component`. Running the command sends the file's text as your
message, with `$ARGUMENTS` replaced by everything you typed after the name, and
`$1` to `$9` by its words.

An optional front matter block gives a `description` and an `argument-hint`
for `/help`:

```markdown
---
description: Review the staged changes
argument-hint: <focus>
---

Review the staged changes, paying attention to $ARGUMENTS.
```

Other front matter keys do nothing in Kaitoi Code, and a line starting with
`!` is sent as text, never run.

## Hooks

Hooks run your own commands at five points of a session: `PreToolUse` and
`PostToolUse` around each tool call, `UserPromptSubmit` when you send a
message, `Stop` when a turn ends, and `SessionStart`. The settings shape is
compatible with supported Claude Code **command hooks** (`type: command`),
not every Claude hook type or event. Adapt the event and matcher to Kaitoi
Code's supported events and tool names; see [Hooks](/docs/cli/hooks/).

Your own hooks go in `hooks.json` in your Kaitoi Code settings folder. A
trusted project's go in `.kaitoi/hooks.json`, and they run only after you
approve that exact file with `/hooks approve`. Any change to the file needs
your approval again. `/hooks` lists them.

```json
{
	"hooks": {
		"PreToolUse": [
			{
				"matcher": "local.run_command",
				"hooks": [{ "type": "command", "command": "./scripts/check-command.sh", "timeout": 60 }]
			}
		]
	}
}
```

- The matcher is a pattern the tool's name must match; empty or `*` matches
  every tool.
- Each command runs in the workspace with the event as JSON on standard input,
  and `KAITOI_PROJECT_DIR`, `KAITOI_SESSION_ID` and `KAITOI_HOOK_EVENT` set.
- Exit 0 is success. Exit 2 blocks the tool call, the message or the end of
  the turn, with standard error as the reason. Any other exit is shown as a
  warning and blocks nothing.
- A hook stops after its timeout, 60 seconds unless it says otherwise and 10
  minutes at most.
- A hook can block, but never approve: the permission rules decide as always.

Hooks are your own automation, like Git hooks: they run outside the sandbox,
with your permissions.

## Current limitations

- Approving a server, saving a tool choice and signing in all need you at a
  terminal. A headless run never asks; it refuses a tool you have not
  allowed.
- On Windows there is no sandbox, so a server that runs on your computer runs
  with your full permissions, as its approval screen says. On macOS or Linux
  without a working sandbox, it does not start unless you set
  `sandbox.enabled` to `false` for it in `mcp.json` and approve it again.
