Skip to content
Development
Skill

/working-with-skills

Best practices for agents managing PostHog skills via the MCP `skill-*` tools — how to discover, read, create, update, and refactor skills efficiently, especially large skills with many bundled files. Use whenever you are about to call any `skill-*` tool, asked to author or edit

From plugin
ai-plugin
95180 skills1 agent3 commands3 hooks
+1

Claude Code

$ npx -y skills add PostHog/ai-plugin --skill working-with-skills --agent claude-code

SKILL.md

working-with-skills.SKILL.md
name: working-with-skills
description: >-
  Best practices for agents managing PostHog skills via the MCP `skill-*` tools —
  how to discover, read, create, update, and refactor skills efficiently, especially
  large skills with many bundled files. Use whenever you are about to call any
  `skill-*` tool, asked to author or edit a shared skill, or troubleshoot
  why a skill write was rejected. Also use when asked what skills are good for
  or how to shape one (project hub, runbook, catalog, handover, daily driver).
  Pairs with `skills-store` (which covers the raw tool surface) by adding the
  decision-tree, efficiency, pattern, and pitfall guidance.

Working with PostHog skills

This skill teaches agents how to use the `skill-*` MCP tools well — minimum context, minimum round-trips, minimum mistakes. If you are not yet familiar with the tool surface itself, read the `skills-store` skill first for the catalog. This document is about _how to choose between the tools_ and _how to scale the workflow_ when skills get big.

Operating principles

1. **Progressive disclosure is non-negotiable.** Lists return descriptions, get returns body + manifest, file-get returns one file. Never preload bundled files "just in case" — every preloaded script is wasted context for the actual task. 2. **Pick the smallest write primitive that does the job.** A targeted `edits` or `file_edits` is cheaper, safer, and clearer in version history than a full body or full bundle replacement. 3. **Reads are cheap; concurrent overwrites are not.** Always have a recent `version` from `skill-get` (or from the response of the previous write) before calling any write tool, and pass it as `base_version`. 4. **Authoring follows the [Agent Skills spec](https://agentskills.io/specification).** Keep `name` kebab-case, descriptions trigger-rich, body short, bulky material in bundled files.

Decision tree: which tool do I call?

Need to know what's available?
  └─► skill-list                    (names + descriptions only)

Need to use / inspect a specific skill?
  └─► skill-get                     (body + file manifest, NO file contents)
        └─► skill-file-get          (one file, on demand, only as referenced)

Authoring a brand new skill?
  └─► skill-create                  (body + all initial files in one call)

Editing an existing skill?
  ├─ Body change?
  │    ├─ Substantial rewrite ............. update(body=...)
  │    └─ Surgical tweak .................. update(edits=[{old, new}, ...])
  ├─ Bundled file content change?
  │    └─ update(file_edits=[{path, edits:[...]}, ...])
  ├─ Add / remove / rename a file?
  │    ├─ Add ............................. skill-file-create
  │    ├─ Delete .......................... skill-file-delete
  │    └─ Rename .......................... skill-file-rename
  └─ Wholesale bundle reset (rare!) ....... update(files=[...])  # replaces ALL files

Renaming the skill itself?
  └─► skill-rename                  (keeps versions, files, and owners)

Want a fork as the starting point?
  └─► skill-duplicate               (then update the copy)

Done with a skill entirely?
  └─► skill-archive                 (hides ALL versions; cannot be undone)

If you find yourself reaching for `update(body=...)` plus a sprawling `files=[...]` to change one paragraph and one script, stop — that's two narrower calls (`update(edits=[...])` plus `update(file_edits=[...])`) or even a single `update` carrying both `edits` and `file_edits`.

Discover before you fetch

posthog:skill-list
{ "search": "fractal" }

`skill-list` is the right tool to "find a skill" — it returns names and descriptions only. Reading the descriptions is the entire point: pick the right skill before pulling any body. If `search` doesn't narrow it enough, list without it and scan, but do not start fetching candidate bodies blindly.

`skill-get` should be called **once per skill per task**, not per question. Cache the body in your working memory; fetch again only if you suspect the skill changed under you (e.g. a `409` on write — see "Concurrency" below).

Reading a large skill efficiently

Big skills (long body, many bundled files) are the case where lazy loading matters most.

1. `skill-get(skill_name=...)` — read `body` + `files[]` manifest. 2. Scan the body's table of contents / headings. The body should already tell you which file goes with which task — that's why bodies stay short and reference files by path. 3. For each file the body explicitly points at for _the current task_, call `skill-file-get(file_path=...)`. Skip everything else. 4. If the body references "see scripts/X for the rare case Y" and you are not in case Y, do not fetch `scripts/X`.

When in doubt, fewer files. You can always fetch one more on the next turn.

Authoring a new skill

Use a single `skill-create` call with body **and** initial files — the skill lands at `version: 1` complete. Do not create the skill empty and then make N follow-up `skill-file-create` calls; that's N extra versions and N extra round-trips for no benefit.

posthog:skill-create
{
  "name": "my-skill",
  "description": "What it does AND when to use it. Include trigger keywords.",
  "body": "# my-skill\n\n## When to use\n...\n## Workflow\n...",
  "license": "MIT",
  "compatibility": "Requires Python 3.10+",
  "allowed_tools": ["Bash", "Write"],
  "metadata": { "author": "me", "category": "..." },
  "files": [
    { "path": "scripts/foo.py", "content": "...", "content_type": "text/x-python" },
    { "path": "references/primer.md", "content": "...", "content_type": "text/markdown" }
  ]
}

Authoring rules of thumb

  • **`description` is the discovery surface.** It is the only thing

`skill-list` returns. Make it trigger-rich (what the user might say) and scope-honest (what the skill does and does not do).

  • **`name`** — kebab-case, max 64 chars, no leading/trailing/consecutive

hyphens. The spec

Read more
@posthog
Ships withai-plugin

Official PostHog plugin for AI clients. Access PostHog products directly from your AI coding tool.

95180 skills1 agent1 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
95
Star history of PostHog/ai-plugin on GitHub, a chart by star-history.com

Other skills on ai-plugin.

analyzing-ai-citations

analyzing-ai-citations

Answer AI citation and answer engine optimization (AEO) questions in PostHog: whether AI answer engines (ChatGPT, Claude, and an…

@posthog@posthogInstall Skill

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills10d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc12d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react1d252k
@facebook@facebookInstall Skill

Questions about working-with-skills.

Which coding agents can use working-with-skills?
working-with-skills installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.