Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/custom-mcp-tools.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ Content-Type: application/json
| `append_workspace_roots` | If true, append container paths (`/app/...`) to the argv (for servers that expect roots as trailing args). |
| `direct_return` | If true, tool results go straight to the user without a second model pass. |

**Bundled catalog (`tools/mcp-tools.json`):** the Fetch entry uses `ignore_robots_txt` (default `false`) so robots.txt is honored unless you opt in. Setting it to `true` appends `--ignore-robots-txt` for that tool. The `robots_ignore_allowlist` field is reserved for future per-host behavior and is informational today.

Set **`workspace_roots`** (dashboard: File Manager / filesystem folders, or **`PUT /v1/mcp/filesystem`**) before relying on mounts.

**Remove:**
Expand Down
144 changes: 144 additions & 0 deletions doc/skills.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# Skills

Skills are lightweight context templates the agent can read before making a request. They are **secondary** to MCP tools — MCP servers run in containers and offer real capabilities, while skills are just markdown that tells the agent *how to call a public endpoint and what the response will look like*.

Think **OpenAPI-lite in a README.md**.

---

## Why skills exist

Small local models can't interpret complex tools quickly. Skills solve this by giving the model a short, pre-shaped template instead of a full tool definition:

- A concrete `curl` / `fetch` example it can copy.
- An expected response schema so it knows which fields to extract.
- A one-line "when to use" hint.

They stay cheap on tokens because the content is hand-written for the task, not auto-generated.

---

## Folder layout

```text
tools/skills/ # bundled with the app (read-only examples)
weather/
README.md
mandatory.md # optional; extra rules appended to the agent hint (not shown in UI)

$APP_DATA/skills/ # user-editable; ClawHub installs land here too
<slug>/
README.md
mandatory.md # optional
```

One folder per skill. One `README.md` per folder. That's it.

- **Bundled** skills ship with the app and can't be edited in-place. Copy them to your custom dir to tweak.
- **Custom** skills are yours. Edit freely.

On macOS the custom dir resolves to `~/Library/Application Support/pengine/skills/`. The exact path is shown in the Dashboard panel.

---

## Skill file format

Each `README.md` starts with a YAML frontmatter block:

```markdown
---
name: weather
description: Get current weather and forecasts — no API key required.
version: 1.0.0
author: Your Name
source: https://clawhub.ai/you/weather
license: MIT-0
tags: [weather, forecast]
requires: [curl]
---

# Weather

<free-form markdown body…>
```

### Required fields

| field | purpose |
|---|---|
| `name` | Short slug the agent uses to refer to the skill. |
| `description` | One-line summary shown in the UI and prepended to the model prompt. |

### Optional fields

`version`, `author`, `source`, `license`, `tags` (string[]), `requires` (string[] — host binaries needed like `curl`).

### Body convention

Write the body for a reader who will execute the request by hand. The agent treats it the same way — it reads the body as context, extracts the request pattern, and runs it.

A good skill body has three sections:

1. **Request** — the exact `curl` (or `fetch`) line, with query params explained in a table.
2. **Response schema** — a trimmed JSON example + a field-level cheatsheet.
3. **When to use** — 1–3 bullets about which question this skill answers.

See `tools/skills/weather/README.md` for a worked example.

---

## Adding a skill

### From the Dashboard

1. Open the **Skills** panel on the Dashboard.
2. Click **Add custom skill**.
3. Provide a slug and the full README markdown. The app writes it to `$APP_DATA/skills/<slug>/README.md`.

### By hand

Drop a folder into `$APP_DATA/skills/`. The Dashboard picks it up on reload.

### From ClawHub

1. Click **Browse ClawHub** in the Skills panel.
2. Pick a skill and hit **Install**. The app fetches the README from ClawHub and writes it to your custom dir.

> ClawHub is the community registry. Skills there are plain markdown with the same frontmatter shape as local ones — no special magic.

---

## Editing a skill

Open the file at `$APP_DATA/skills/<slug>/README.md` in any editor. Changes are picked up on the next dashboard refresh. There is no compile step.

To tweak a **bundled** skill, click **Fork to custom** in the panel (or copy the folder manually). Edits to `tools/skills/` inside the app bundle will not persist across reinstalls.

---

## Sharing a skill

1. Put the skill folder in a public repo (or submit it to ClawHub).
2. Set `source:` in the frontmatter to the canonical URL.
3. Others can install via Dashboard → Browse ClawHub, or clone the repo into their `$APP_DATA/skills/`.

---

## Skills vs MCP tools — when to use which

| | Skill | MCP tool |
|---|---|---|
| Runtime | Agent executes a `fetch`/`curl` inline | Separate MCP server (often containerised) |
| Cost | Free — just text context | Container memory + startup time |
| Best for | Read-only public APIs, templated fetches | Stateful tools, filesystem, long-running workers |
| Editability | Edit a markdown file | Rebuild container image |

Reach for a skill first if the task is "call this URL, return this JSON". Reach for an MCP tool if the agent needs to write to disk, keep state, or call something that doesn't fit in one HTTP request.

---

## Wiring into the agent

The agent receives the `description` of every skill as part of its system context, plus the full body of any skill whose `name` appears in the user message. This keeps the prompt small: a user asking about weather pulls in only `weather`'s README, not every skill in the catalog.

*(Injection is handled by `src-tauri/src/modules/skills/service.rs`; see the code for the exact selection rule.)*
50 changes: 50 additions & 0 deletions src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ tokio-stream = { version = "0.1", features = ["sync"] }
socket2 = "0.5"
fastrand = "2"
tauri-plugin-dialog = "2"
zip = { version = "2", default-features = false, features = ["deflate"] }

[dev-dependencies]
tempfile = "3"
Expand Down
Loading