# Publishing skills

A skill tells agents how your organization works: a process, a policy, or when
and how to use your tools. Zenitya serves [Agent Skills](https://agentskills.io/specification)
from your projects to every agent connected over MCP, and asks agents to check
them at the start of every task.

## Add a skill to a project

```
orders/
├── zenitya.json
├── src/index.ts
└── skills/
    └── refund-late-orders/
        ├── SKILL.md
        └── references/policy.md
```

Each folder in `skills/` is one skill. Its `SKILL.md` starts with YAML
frontmatter:

```markdown
---
name: refund-late-orders
description: Use when a customer asks for a refund on a late order. Covers when to refund and when to escalate, using orders.findLateOrders and orders.refund.
---

Check the delivery date with `orders.findLateOrders` first, then follow
[the policy](references/policy.md).
```

- `name`: 1 to 64 lower-case letters, digits and single hyphens, the same as
  the folder name. Unique across your organization, including the skills of
  connected MCP servers.
- `description`: 1 to 1,024 characters. Agents pick skills by this text alone,
  so say what the skill covers and when to use it.
- Optional: `compatibility`, `license`, `metadata` and `allowed-tools`.

Refer to tools by their full name, `<project>.<tool>`.

`zya deploy` publishes skills together with the project's tools, and checks
them before uploading: an invalid skill fails with `error[SKILL_INVALID]` and
names the file. A name that another project or a connected MCP server already
serves fails the build, and the message names who holds it.

## What is published

Only text files agents can read: `.md`, `.txt`, `.json`, `.yaml`, `.yml`,
`.csv` and `.py`. `deploy` lists any other files it leaves out. Every relative
link in a skill's markdown must point to a file inside the skill's folder that
is published; a link to a left-out file, such as a PDF, fails the deploy.

A project can have up to 64 skills; each skill up to 64 files and 1 MiB, and
each file up to 256 KiB.

## Skills without tools

A project can publish only skills. Its `zenitya.json` has `skillsOnly` instead
of `entrypoint`:

```json
{ "configVersion": 1, "name": "playbooks", "skillsOnly": true }
```

Such a project needs no `package.json`; `deploy` uploads only `zenitya.json`
and `skills/`.

## Who sees a skill

Grant skills to groups in the Zenitya app, like tools. Agents read them
through two tools on the MCP connection, `list_skills` and `load_skill`. Every
member can browse all skills in the app.

## Skills from connected MCP servers

A connected MCP server brings its own skills, refreshed every time it syncs:

- **Its instructions.** The guidance a server sends its clients becomes a skill
  named after the server, such as `linear`. If a project already has a skill
  with that name, it is named `linear-instructions` instead.
- **Skills it publishes.** If the server's website publishes skills at
  `/.well-known/agent-skills/index.json`, the
  [Agent Skills discovery](https://github.com/cloudflare/agent-skills-discovery-rfc)
  format (v0.2.0), Zenitya serves each single-file skill from it.

You don't grant these skills: everyone granted at least one of the server's
tools sees them. A skill whose name is already taken is skipped. The server's
page in the Zenitya app shows a warning and lists each skipped skill with the
reason, and Zenitya tries again at the next sync.
