# Skill Building

> Design and create agent skill packages — instruction-based and MCP-based skills, manifest format

- Skill: `markus-global/skill-building` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add markus-global/skill-building`
- Raw SKILL.md: https://api.skillmd.com/api/skills/markus-global/skill-building/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: markus-global (https://skillmd.com/u/markus-global)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/markus-global/skill-building

---


# Skill Building

This skill teaches you how to create Markus skill packages — directory-based artifacts that teach agents new capabilities. A skill can work in two ways (or both):

1. **Instruction-based**: A `SKILL.md` file with instructions injected into the agent's context, guiding it to use existing tools in new ways.
2. **MCP-based**: A bundled MCP server (script) that provides entirely new tools to the agent. The skill directory can contain any scripts, config files, or resources the MCP server needs.

Most skills are instruction-based. Use MCP-based skills when the capability requires new tools that don't exist yet (e.g., connecting to an external API, browser automation, hardware control).

## Artifact Directory

**CRITICAL**: Skill artifacts MUST be saved under this exact path — the Builder page, install system, and deliverable detection all depend on it:

```
~/.markus/builder-artifacts/skills/{skill-name}/
├── skill.json       # Manifest (auto-created from your JSON output)
├── SKILL.md         # Instruction document (you write via file_write)
├── README.md        # Human-readable documentation (optional)
├── images/          # Skill icon images (optional)
│   └── icon.png     # Skill icon — used in UI after install
└── ...              # Any other files: scripts, MCP servers, configs, templates, etc.
```

**Do NOT write artifacts to `~/.markus/shared/`, your working directory, or any other location.** Only `~/.markus/builder-artifacts/skills/` is recognized by the system.

A skill directory can contain **any files** needed for the skill to work — not just SKILL.md and README.md. For example:
- **MCP server scripts** (e.g., `server.mjs`) that provide new tools to the agent
- **Configuration templates** or data files
- **Helper scripts** used by the instructions

When the user **installs** the artifact, the **entire directory** (all files) is deployed to `~/.markus/skills/{skill-name}/`. `SKILL.md` is loaded and injected into the agent's context when the skill is activated. If the manifest declares `mcpServers`, those servers are started and their tools registered to the agent. `skill.json` contains metadata used by the skill registry. `README.md` provides documentation for humans browsing or sharing the skill.

## Two-Step Workflow

Output the skill in two steps — manifest first, then content files. **Never put file content inline in the JSON.**

### All modes (chat / task / A2A) — same rule

There is **no** chat auto-save. A JSON code block in your reply does **not** create files.

1. `file_write("~/.markus/builder-artifacts/skills/{name}/skill.json", ...)` for the manifest
2. `file_write` for each content file (SKILL.md, README, …)
3. In task mode, set deliverable references to the artifact directory path

You may preview JSON in chat **in addition to** writing files — never instead of `file_write`.

### Step 1: Write Manifest JSON via file_write

This JSON contains ONLY metadata — **no file content**.

**Instruction-based skill** (most common):
```json
{
  "type": "skill",
  "name": "skill-name-kebab-case",
  "displayName": "Skill Name",
  "version": "1.0.0",
  "description": "When and why an agent should use this skill",
  "author": "Your Name",
  "icon": "images/icon.png",
  "category": "custom",
  "tags": ["tag1", "tag2"],
  "skill": {
    "skillFile": "SKILL.md"
  }
}
```

**MCP-based skill** (provides new tools via a bundled server script):
```json
{
  "type": "skill",
  "name": "my-api-connector",
  "displayName": "My API Connector",
  "version": "1.0.0",
  "description": "Connect to My API for data retrieval and actions",
  "author": "Your Name",
  "icon": "images/icon.png",
  "category": "custom",
  "tags": ["api", "connector"],
  "skill": {
    "skillFile": "SKILL.md",
    "requiredPermissions": ["network"],
    "mcpServers": {
      "my-api": {
        "command": "node",
        "args": ["${SKILL_DIR}/server.mjs"]
      }
    }
  }
}
```

**Notes on MCP servers:**
- `${SKILL_DIR}` is resolved at load time to the skill's actual directory path — use it to reference bundled scripts.
- The `command` can be any executable (`node`, `python3`, `npx`, etc.).
- The MCP server communicates via JSON-RPC 2.0 over stdio (stdin/stdout).
- Tool names exposed by MCP servers are automatically prefixed with the server name (e.g., `my-api__tool_name`). Mention these prefixed names in SKILL.md.
- You can also use externally published MCP servers: `"command": "npx", "args": ["-y", "some-mcp-server@latest"]`.

After `skill.json` is written, proceed to write the remaining files with `file_write`.

### Step 2: Write Files with file_write

After the JSON is saved, write each file individually using `file_write`. The base path is `~/.markus/builder-artifacts/skills/{skill-name}/` (use the `name` from your JSON).

**Write files in this order:**

1. **SKILL.md** (REQUIRED) — The instruction document with YAML frontmatter and comprehensive Markdown body:
   - YAML frontmatter with `name` and `description` (must match manifest)
   - Overview of what the skill does
   - Step-by-step instructions referencing actual tools (or MCP tool names if MCP-based)
   - Error handling guidance
   - Examples of typical input/output

2. **MCP server script** (if MCP-based) — e.g., `server.mjs` implementing the MCP protocol over stdio. Must handle `initialize`, `tools/list`, and `tools/call` JSON-RPC methods.

3. **README.md** (optional) — Human-readable documentation for browsing or sharing.

4. **Any other files** — Helper scripts, templates, config files, data files, etc.

5. **images/icon.png** (optional) — Skill icon for UI display (see [Image Assets](#image-assets)).

## Image Assets

Skill icons are **abstract representations** of the skill's capability — like an app icon or tool symbol. They should be clean, recognizable, and work well at small sizes.

| Image | Location | Style | Purpose |
|:------|:---------|:------|:--------|
| **Skill icon** | `images/icon.png` | Abstract icon / symbol | Skill card in UI, published to Hub as `icon` |

**Do NOT use portraits for skill icons.** Skills are tools, not team members. Portraits belong on agents.

### Image Generation

Prompt style guide for `generate_image`:
```
Good prompt (do this):
  "Clean icon design for a git changelog tool, stylized git branch merging into a document,
   flat vector style, teal and white palette, square format, modern minimal"
  "Minimalist icon for a GitHub automation skill, octagon cat silhouette combined with
   gear, flat design, purple gradients, square format"
  "Abstract icon representing web scraping capability, spider-web pattern with a magnifying
   glass, geometric style, blue and orange accents, square format"

Bad prompt (don't do this):
  "Developer sitting at a computer" ✗ — portraits are for agents, not skills
  "Abstract colorful splash without meaning" ✗ — too vague, no clear concept
  "Screenshot of a terminal window" ✗ — not an icon
```

Key rules:
- **Style**: flat vector / geometric / minimal — NOT photographic, NOT portraits
- **Subject**: abstract concept representing the skill's capability
- **Format**: square, clean background, recognizable at small sizes (64×64)
- **Match skill function**: git → branching, browser → window/globe, API → connector/plug

### Image Size & Compression

| Property | Value |
|:---------|:------|
| **Final resolution** | 512×512 (square) |
| **File format** | PNG (recommended for icons — crisp lines, transparency) |
| **Max file size** | ≤30KB |
| **Compression method** | Python Pillow (`pip3 install Pillow`) resize + save |

Compression procedure:
```python
python3 -c "
from PIL import Image
img = Image.open('source.png')
img = img.resize((512, 512), Image.LANCZOS)
img.save('icon.png', 'PNG', optimize=True)
"
```

**Always** place images under an `images/` subdirectory — NOT at the artifact root.

**Example file_write calls:**

```
file_write("~/.markus/builder-artifacts/skills/git-changelog/SKILL.md", "---\nname: git-changelog\ndescription: Generate changelogs from git history\n---\n\n# Git Changelog\n\n## Overview\n...\n\n## Instructions\n...\n\n## Examples\n...")
file_write("~/.markus/builder-artifacts/skills/git-changelog/README.md", "# Git Changelog\n\nA skill that helps agents generate changelogs from git history...\n")
```

## Package Slug (`name`) — REQUIRED

The manifest `name` is the **package slug**: directory name, Hub URL segment (`/@user/{slug}`), SKILL.md frontmatter `name`, and share/publish id.

**Rules (hard — invalid manifests are rejected on write / save / share):**
- English **kebab-case** only: lowercase letters `a-z`, digits `0-9`, hyphens `-`
- 2–64 characters; must **start with a letter**
- Pattern examples: `git-changelog`, `web-scraper`, `pdf-summarizer`
- **NOT allowed**: Chinese (`网页抓取器`), spaces, underscores, UPPERCASE, emoji, or empty
- Put the human-readable title (any language) in **`displayName`**, never in `name`
- Manifest `name` and `SKILL.md` frontmatter `name` must match **exactly**

| User language | `name` (slug) | `displayName` |
|---|---|---|
| Chinese “网页抓取” | `web-scraper` | `网页抓取` |
| English “Git Changelog” | `git-changelog` | `Git Changelog` |

If the user only gives a Chinese title, **you invent an English kebab slug**, set `displayName` to their title, and use the slug for `~/.markus/builder-artifacts/skills/{name}/`.

## Field Reference

### Top-level fields
- **`type`**: Always `"skill"`
- **`name`**: **Package slug** — English kebab-case only (see [Package Slug](#package-slug-name--required)). Write/save/share reject Chinese or invalid slugs. Must match `SKILL.md` frontmatter `name`.
- **`displayName`**: Human-readable skill name, can be in any language
- **`version`**: Semver (default `"1.0.0"`)
- **`description`**: When and why an agent should use this skill (can be in any language)
- **`category`**: Typically `"custom"` for user-created skills
- **`tags`**: Array of descriptive tags

### `skill` section (REQUIRED)
- **`skillFile`**: Always `"SKILL.md"` — the entry point instruction document
- **`requiredPermissions`**: (optional) Array of permissions: `"shell"`, `"file"`, `"network"`, `"browser"`
- **`mcpServers`**: (optional) Map of MCP server name → config. Each config has `command`, `args?`, `env?`. Use `${SKILL_DIR}` in args/env to reference the skill directory.
- **`alwaysOn`**: (optional, boolean) If `true`, the skill is listed in every agent's discoverable catalog as a foundational skill (e.g., Learning Habits). Full instructions are **not** auto-injected — agents activate via `discover_tools({ name: [...] })` (Hermes progressive disclosure). Default is `false`.

## After Creation

> **CRITICAL**: Creating an artifact is NOT the same as installing/deploying it. Creating writes files to `builder-artifacts/`; installing makes the skill available to agents in the live org. **NEVER auto-install.** Only install when the user explicitly asks. This applies to ALL modes (chat, task, A2A).

Once all files are written, tell the user:

1. **The skill has been created and saved** — summarize what was created (name, purpose, what agents can do with it).
2. **Ready to install** — the user can install from the Builder page, or ask you to install it (you would use `package_install`). Do NOT install unless asked.
3. **To modify or improve** this skill (e.g., add more instructions, update examples, fix edge cases), just continue the conversation here — describe what you want to change and I'll update the files directly.

## Guidelines

- Instructions in SKILL.md should reference actual tools: `shell_execute`, `file_read`, `file_write`, `file_edit`, `grep_search`, `glob_find`, `list_directory`, `web_fetch`, `web_search`, `gui` — or MCP tool names if the skill provides its own tools
- For MCP-based skills, document every tool with its prefixed name (e.g., `my-api__search`) in SKILL.md so the agent knows how to use them
- Be specific — include actual CLI commands, file paths, and URL patterns
- Include error handling: what to do when commands fail, pages don't load, etc.
- Provide examples of typical input/output for each workflow step
- Skills should be self-contained: an agent reading the instructions should know exactly what to do
- Consider composability: skills that work well alongside other skills
- After outputting the JSON, immediately proceed to write files via `file_write` — announce what you're writing
- When creating MCP server scripts, use only Node.js built-in modules (no npm dependencies) for maximum portability, or use `npx` to reference published packages

## Rules

- **DO NOT** use names that conflict with built-in skills. Check the dynamic context for existing skill names.
- **DO NOT** put file content in the JSON. Always use `file_write` for files.
- **DO NOT** write artifacts to `~/.markus/shared/` or your working directory. Always use `~/.markus/builder-artifacts/skills/{name}/`.
- **The `name` field MUST be a valid English kebab-case slug** (see Package Slug). Never use Chinese as `name`. Invalid `name` → write/save/share fails.
- The `name` field and `SKILL.md` frontmatter `name` must match exactly.
- **All top-level fields must be the correct type**: `author` must be a plain string (your name, e.g. `"John"`) — NOT an object. `tags` must be an array of strings. `version` must be semver string. `description` must be a string. The system validates the manifest on write and will reject malformed files.

