Docs Release Notes logo

Docs Release Notes

Community
The01Geek
docs-release-notes

Use when a change needs a user-visible release-note, changelog, or changeset entry — "add a release note", "add a changeset for this", "what goes in the changelog?", "write up what shipped", "note this for the next release" — or when finalizing a branch whose customer-visible features, bug fixes, or UI changes should be announced before merge. Narrower than prflow:docs, which sweeps internal docs, external docs, and release notes together.

Overview

PublisherThe01Geek
Repositoryprflow
Skill namedocs-release-notes
Stars
100
Forks
24
Bundled files
Instructions only
LicenseMIT
Links
  • Markdown instructions

    A SKILL.md file the model loads on demand, so it only costs tokens when a request actually matches.

  • Works with any LLM

    AI skills are plain Markdown, not provider-specific code, so this works with GPT, Claude, Gemini, Grok, or a local model.

  • Self-contained

    Everything the model needs lives in the instructions — no extra files to sync.

  • Open source

    Published by The01Geek on GitHub. Read the source before you install it.

Installation

Install the Docs Release Notes AI skill in TypingMind to use it with any LLM, or drop it into another agent that reads SKILL.md.

1

Install in TypingMind

TypingMind installs a skill straight from its GitHub folder — it reads SKILL.md, bundles the resource files, and stores the result locally.

  1. Open the app and go to Plugins → Skills.
  2. Choose "Install from GitHub".
  3. Paste the skill folder URL below and confirm.
    https://github.com/The01Geek/prflow/tree/main/skills/docs-release-notes
  4. Enable the skill in any chat where you want it available.
Plugins → Skills → Add skill → From GitHub URL, then paste the folder URL and press Continue.
2

Install in another agent

Any agent that reads the Agent Skills format can use this skill — copy the folder into that agent's skills directory.

Claude Code — .claude/skills
git clone --depth 1 https://github.com/The01Geek/prflow.git /tmp/prflow
mkdir -p .claude/skills
cp -r /tmp/prflow/skills/docs-release-notes .claude/skills/docs-release-notes
Restart Claude Code after copying so it picks up the new skill.

Use it in TypingMind

Enable Docs Release Notes in any TypingMind chat and the model takes it from there. Its name and description sit in the system prompt, and the moment a request matches, the model loads the full instructions itself — you never invoke it by hand, and it costs no tokens until it is actually used.

The model loads Docs Release Notes on its own as soon as a request matches it.

Works with any AI model

AI skills are plain Markdown instructions rather than provider-specific code, so Docs Release Notes is not tied to the model it was written for. Install it once in TypingMind and use it with GPT-5, Claude, Gemini, Grok, DeepSeek, Mistral, Llama, or a local model you run yourself — all on your own API keys.

  • Loaded only when it is needed

    The system prompt carries just the name and description. The instructions are fetched on the first matching request, so an idle skill costs nothing.

  • Switch models mid-chat

    Because the skill is instructions rather than code, changing model does not break it — the next model reads the same SKILL.md.

Skill instructions

This is the SKILL.md content the model loads. Read it before installing — a skill is instructions your model will follow.

Configuration: Read paths from .prflow/config.json:

  • Internal docs: "${CLAUDE_SKILL_DIR:-<absolute skill base directory this runner reports in context>}"/../../scripts/config-get.sh .docs.internal docs/internal/
  • External docs: "${CLAUDE_SKILL_DIR:-<absolute skill base directory this runner reports in context>}"/../../scripts/config-get.sh .docs.external docs/external/
  • Release notes file: "${CLAUDE_SKILL_DIR:-<absolute skill base directory this runner reports in context>}"/../../scripts/config-get.sh .docs.release_notes_file docs/external/release-notes.md
  • CHANGELOG file: "${CLAUDE_SKILL_DIR:-<absolute skill base directory this runner reports in context>}"/../../scripts/config-get.sh .docs.changelog_file CHANGELOG.md
  • PR number: gh pr view --json number -q '.number' (resolves from current branch)

The config-get.sh helper falls back to the default value when the config file is missing or the key is absent. An empty release_notes_file value also resolves to the default path — it does not disable the artifact; whether this skill runs at all is the caller's decision (the combined docs pass's config gates, or a direct invocation).

Use these values wherever [[INTERNAL_DOC_LOCATION]], [[EXTERNAL_DOC_LOCATION]], [[RELEASE_NOTES_FILE]], [[CHANGELOG_FILE]], and [[PR_NUMBER]] appear below.

Portable helper anchor (single-statement). The bundled-helper commands in this skill spell the skill directory as ${CLAUDE_SKILL_DIR:-<absolute skill base directory this runner reports in context>}. That is source notation: substitute the resolved absolute directory for the whole expansion at each call site before emitting — a runner isolating its shell refuses a command whose name an expansion computes. Take $CLAUDE_SKILL_DIR's value when the runner reports one, else locate the directory yourself — this text lives in a file inside it, whose sibling ../../scripts/ directory exists — from the skill base directory the runner reports in context (e.g. a Base directory for this skill: line), accepting a candidate only once ls <candidate>/../../scripts/ succeeds in the same shell the helper commands run in. If a path form is rejected, use the form that shell reports (pwd shows it); a Windows-form base directory (C:\...) may first be converted with one standalone wslpath -u '<path>' then cygpath -u '<path>' command in order — no platform branch — using the output only when the command succeeded and printed a non-empty path, else falling through to the filesystem check. Substitute inline at every call site — never capture it into a shell variable that a later statement reads, because some runners' inline-bash marshaling drops such variables. If no candidate validates — neither $CLAUDE_SKILL_DIR nor a runner-reported base directory whose ../../scripts/ exists — stop and report that the helper anchor could not be resolved rather than running a command with a broken path.

Consumer prompt extension (load first). Before doing this skill's work, load any consumer-supplied prompt extension for this skill and honor it. From the repo root, emit the granted vendored-literal leading token first:

bash
.prflow/vendor/prflow/scripts/load-prompt-extension.sh docs-release-notes

On a command not found / No such file / exit-127 reading (a checkout where .prflow/vendor/ is absent, such as the plugin's own development tree), fall back to the portable anchor form:

bash
"${CLAUDE_SKILL_DIR:-<absolute skill base directory this runner reports in context>}"/../../scripts/load-prompt-extension.sh docs-release-notes

If the invocation fails because the helper path does not exist (No such file, exit 127, or the platform equivalent) on every form above, that is the anchor-resolution failure described in the Portable helper anchor note above — fix the anchor, don't report a missing extension. If instead the harness refuses the command outright — a permission denial rather than a missing file — the extension's state is unestablished: report that in the run's output and never treat it as a clean policy pass (unknown is not zero). Otherwise, if the helper exits non-zero, a consumer extension exists but could not be loaded — surface its stderr message and do not silently proceed as if none existed. If it exits 0 and prints text, treat that text as additional instructions appended to the end of this skill's own prompt for this run — it is upgrade-safe, consumer-owned customization committed under .prflow/skill-extensions/. If it exits 0 and prints nothing, proceed unchanged.

Release Notes Agent

Objective

You are an AI Release Notes Agent for a code repository. Your task is to review the code changes in a pull request and, if they have customer-visible impact, draft a brief customer-facing release note entry and append it to [[RELEASE_NOTES_FILE]]. Independently of customer-visibility, if the branch bumped the version you also reconcile that version's CHANGELOG entry against the shipped diff (Step 4b) — a second, always-on output that writes a different file ([[CHANGELOG_FILE]]).

[[RELEASE_NOTES_FILE]] is owned by this skill — no other documentation pass edits it, so report (rather than absorb) edits to it that arrive from another pass. Write for the product's users, not its maintainers: who those users are is repository-specific (developers for a developer tool, employees of customer companies for enterprise software), and the external-documentation pass records that audience when it runs in the same session — reuse its determination when available.

If the PR has no customer-visible impact (e.g., refactors, CI changes, documentation-only, test-only, internal tooling), skip Steps 3, 3b, and 4 — do not write a release note or modify [[RELEASE_NOTES_FILE]] — and proceed directly to Step 4b (CHANGELOG reconciliation still runs for all PRs).

Execution Steps

Step 1: Understand the Changes

Resolve the configured base branch by printing it, then substituting the printed value as a literal into the git commands in this step and Step 4b:

bash
"${CLAUDE_SKILL_DIR:-<absolute skill base directory this runner reports in context>}"/../../scripts/config-get.sh .base_branch main

Read the printed base branch from the tool result. On a non-zero exit or an empty value, fall back to main and log docs-release-notes: could not read .base_branch — falling back to main. Substitute the printed value as a LITERAL into each git fence below (e.g. git diff origin/<base>...HEAD) — never through a shell-variable capture (VAR=$(...)) and never as an origin/$VAR expansion. <base> below is that printed literal (default main).

Run:

bash
git diff origin/<base>...HEAD

Also read any updated internal or external documentation in [[INTERNAL_DOC_LOCATION]] and [[EXTERNAL_DOC_LOCATION]] for additional context about what changed.

Step 1b: Look Up the Associated GitHub Issue

Use the GitHub CLI to find the issue linked to this pull request:

gh pr view [[PR_NUMBER]] --json body,title

Extract the linked issue number from the PR body (look for patterns like Closes #123, Fixes #123, or Resolves #123), then fetch the issue:

gh issue view <ISSUE_NUMBER> --json title

Use the issue title as the basis for the release note's Short Title in Step 3. This ensures the release note title matches the original issue description.

Step 2: Determine Customer-Visible Impact

Ask yourself: Would a customer notice this change?

Customer-visible (write a release note):

  • New features or capabilities
  • Bug fixes that affected customer workflows
  • Changes to commands, output, behavior, or the user interface — whichever surfaces the product actually has
  • Changes to API behavior
  • Performance improvements customers would notice
  • New configuration options or settings

Not customer-visible (skip Steps 3, 3b, and 4; proceed to Step 4b):

  • Code refactors with no behavior change
  • CI/CD pipeline changes
  • Internal documentation updates
  • Test additions or modifications
  • Developer tooling changes
  • Dependency updates with no behavior change

If the PR is not customer-visible, skip Steps 3, 3b, and 4 — do not write a release note or modify [[RELEASE_NOTES_FILE]]. Proceed directly to Step 4b.

Step 3: Draft the Release Note Entry

An entry is three parts in one bullet, in this order: the user-visible outcome stated in present tense, then the action the reader takes (omitted when there is none), then one linked tracker reference. Write it as:

- **Short user-outcome title** — Two to three sentence description of what changed and why it matters to customers. ([#<number>](<issue or PR URL>))
  • Short user-outcome title: Start from the GitHub Issue title from Step 1b, rephrased into the outcome a user sees; keep it faithful to the original issue title.
  • Description: The entry IS the TLDR — the shared writing standard's TLDR-opening rule is satisfied by the entry itself, so never write a separate opening sentence before the substance.
  • Reference: One linked issue or PR number, so a reader can click through — a bare (#123) renders as plain text in most viewers.
  • Closer: Where no user action is required, end with the exact sentence "You get this through the normal plugin update." (or the repository's equivalent update sentence, chosen once and reused verbatim); where the user must act, state the action instead — never both.

Write the current behavior, not the change history: each sentence states what the product does now and why that matters. The words "no longer", "used to", "previously", and "silently" signal you are narrating the prior behavior for someone who remembers it — recast such a sentence as the outcome a first-time reader sees today.

The change's kind (feature, fix, improvement) guides Step 2's visibility call and your emphasis; it does not appear in the entry text. Example entries at the target length:

- **Cloud runs retry a failed checkout** — A cloud run that fails while checking out the repository now retries once before reporting an error. Runs interrupted by a transient network fault complete on their own. You get this through the normal plugin update. ([#NNN](https://github.com/example/repo/issues/NNN))
- **Review comments show the exact failing line** — Review findings link the precise line they refer to instead of the file top. You can jump straight from a finding to the code it describes. ([#NNN](https://github.com/example/repo/issues/NNN))
- **Issue titles keep their original wording in release notes** — A fix stops release-note titles from being rewritten away from the issue's own words. Entries now match what you filed. You get this through the normal plugin update. ([#NNN](https://github.com/example/repo/issues/NNN))

After drafting (and again after Step 3b's corrections), count the description's sentences: more than three means rewrite until the entry fits the cap — trim qualifications, not accuracy.

Step 3b: Verify Every Factual Claim in the Draft Against the Code

⚠️ MANDATORY — do not skip. Write the release note from the diff you read in Step 1, never from the issue body, the PR description, the implementation plan, or your memory of what the change "should" do.

A release note copied from issue, PR, or plan prose inherits every contradiction between that prose and the shipped diff, and ships those errors to customers. Before appending, re-open the actual changed source from the Step-1 diff and confirm each concrete assertion in the entry you drafted:

  • Gating / visibility / permission claims ("shows only for users with the X permission", "available to admins", "behind feature flag Y") — open the file that renders or guards the feature in the post-change diff and confirm the condition still exists and is spelled exactly as written. If the diff removed the guard, the release note must not claim it.
  • Names and identifiers (permission keys, feature-flag names, route paths, file names, setting keys, menu labels) — grep the changed code and confirm the identifier exists exactly as written and lives where the note implies. Use the key the code actually checks (e.g. reports/comparison-report), not a shortened guess (report).
  • Scope of the change — if the diff removed or added more than one user-visible thing (e.g. two files removed, two settings deleted), the release note must account for each one, or you must consciously decide one is not customer-visible and say so in the Step-3 reasoning. A release note covering only the first of two shipped removals is a half-edit.
  • Described behavior — confirm the "what changed and why it matters" sentence matches the post-change implementation, not a draft of it.

If any drafted assertion cannot be confirmed against the changed code, rewrite the entry until it can — never ship a customer-facing claim on faith. If verification reveals the change is not actually customer-visible after all, discard the draft release note, skip Step 4, and proceed directly to Step 4b (per Step 2).

Step 4: Append to Release Notes File

Read [[RELEASE_NOTES_FILE]]. Determine today's date and format it as ## Month Day, Year (e.g., ## March 4, 2026).

  • If the date heading does not exist, add it at the top of the file directly below the first H1 heading (e.g., # Release Notes), with a blank line before and after. If the file is empty or has no H1 heading, add # Release Notes as the first line, then the date heading below it.
  • If the date heading already exists, append the new entry under it (after any existing entries for that date).

After appending, check the file's growth: when it holds more than roughly 50 entries, or its oldest date heading is more than about 90 days old, move the older date sections whole into a dated archive page beside the file (e.g. release-notes-archive-2026.md), keep the newest releases in place, and register the archive page in the site's navigation manifest where the docs tree has one (e.g. a docs.json) — an unregistered page is invisible to readers. An unbounded single page eventually exceeds what a reader (or a reviewing agent) can load at once.

Step 4b: Reconcile the CHANGELOG Entry

This step runs regardless of the Step 2 customer-visibility decision — after appending a release note (Step 4) or after the non-customer-visible skip in Step 2, proceed here.

First read this repository's release convention from the prompt extension — the bump-commit subject prefix to scan for and the version-manifest path to read the version from are repository-specific, not hardcoded. Emit the granted vendored-literal leading token first (anchor fallback on a command not found / No such file / exit-127 reading, as in the load-first step at the top of this skill):

bash
.prflow/vendor/prflow/scripts/load-prompt-extension.sh docs-release-notes --section "## Release convention"

The section, when declared, carries exactly two labeled lines — bump-commit-subject-prefix: <prefix> and version-manifest: <path>. Classify the read by what you observed:

  • Exit 0 and it printed nothing (no section declared): log "no release convention declared — Step 4b skipped", append the loader's stderr breadcrumb line verbatim when one was emitted, and proceed to Step 5. A repository that declares no convention opts out of CHANGELOG reconciliation.
  • Neither stdout nor an exit status was observed (a harness refusal — --section mode emits no status token, so a refused-by-path invocation is silent): log "Step 4b: release convention read unestablished — CHANGELOG reconciliation NOT performed" and surface it to the caller (fail-loud; unknown is not zero). Do not fold this into the "skipped" no-op above.
  • Exactly one of the two labels is present, either label appears more than once, or either line's value is empty: log "Step 4b: release convention half-declared — CHANGELOG reconciliation NOT performed" and surface it to the caller (fail-loud). A half-written convention never silently proceeds on a guessed operand.
  • Both labels are present with non-empty values: note the bump-commit-subject-prefix value and the version-manifest value, and continue below. Substitute those two printed values as literals into the fences below wherever a <bump-commit-subject-prefix> or <version-manifest> placeholder appears — never capture them into a shell variable and never write a $VAR expansion in a fence, since each fence is a separate invocation where such a variable is unset and, on the cloud tiers this skill runs on, a $VAR in a fence is silently denied.

Confirm a version bump happened, then read the version from the manifest — not the commit subject. Run:

bash
git log --oneline origin/<base>..HEAD

Look for a commit whose message begins with <bump-commit-subject-prefix> (the literal value read from the section). This commit's only role here is to confirm that this branch bumped the version — do not read the version string from its free-text subject. A rebase or version collision can re-version <version-manifest> in a later commit without re-wording the bump commit, so reconciling from that subject would correct the wrong, already-shipped entry and leave the entry this PR ships untouched. First confirm the scan itself succeeded: if git log exits non-zero, or origin/<base> will not resolve (not fetched, detached state), that is a failed determination (the fail-loud path below) — never read its empty output as "no bump commit". Only when the scan ran cleanly and shows no commit whose subject begins with <bump-commit-subject-prefix> did this PR not bump the version — log "no version-bump commit found on branch" and proceed to Step 5.

Where the repository produces its version bump and CHANGELOG entry at merge time from pending release artifacts (rather than an in-PR bump), a branch normally carries no bump commit — the "no version-bump commit found" outcome is then the expected result of this step, not a smell. In that case, when Step 2 found customer-visible changes, verify the branch carries the release artifact the project's convention requires and report its absence to the caller — do not author one yourself, since the implementing change owns it.

Read the authoritative shipped version from the manifest at <version-manifest> (the bump, and any later re-version, both update it) — fill the placeholder with the literal path read from the version-manifest: line of the ## Release convention section you already read:

bash
"${CLAUDE_SKILL_DIR:-<absolute skill base directory this runner reports in context>}"/../../scripts/run-jq.sh -r .version <version-manifest>

Inspect the result: a non-zero jq exit, empty output, or a value that is not an N.N.N version string (e.g. null from an absent key) — while a bump commit is present — is a failed determination (the fail-loud path below), not a clean version; only a well-formed N.N.N value continues. Then read [[CHANGELOG_FILE]] and search for the bracketed Keep-a-Changelog heading ## [<version>] for that manifest version (e.g., ## [2.8.26]). If [[CHANGELOG_FILE]] itself cannot be read (missing, permission, IO) while a bump commit and a valid manifest version are both present, that too is a failed determination, not "no matching section". If the file reads cleanly but has no section heading matching the manifest version, this step is a no-op — log "no CHANGELOG section found for version X" and proceed to Step 5.

Distinguish a failed determination from a legitimate no-op. The two no-op logs above ("no version-bump commit found", "no CHANGELOG section found") are only for legitimately empty results. If the jq manifest read errors, prints empty, or prints null / a non-version string while a bump commit IS present, or if git log / origin/<base> cannot be resolved, do not fold that into a reassuring no-op log. Log a distinct error ("Step 4b: could not determine the shipped version / scan the branch — CHANGELOG reconciliation NOT performed") and surface it to the caller, so a swallowed failure is never indistinguishable from a clean no-op.

Enumerate every factual claim. Re-read the body of the located ## [version] section. A factual claim is any concrete assertion: coverage counts, enumerated sites, completeness phrases ("all X were done", "Y and Z are now..."), named identifiers (file paths, key names, step or phase numbers, agent names), or specific behavioral guarantees. The entry may predate later review-and-fix corrections, so its assertions may be stale relative to the final shipped diff.

Trace each claim against the Step-1 diff. For each enumerated claim, confirm it against the diff already read in Step 1. Do not re-run git diff. (Step 1 runs unconditionally at the top of every invocation — before the Step 2 customer-visibility branch — so the Step-1 diff is always available here, including on the non-customer-visible path that skipped Steps 3–4.) A claim is accurate if every concrete detail (count, identifier, behavioral guarantee) matches the shipped code exactly. A claim is stale if the diff shows a different count, a renamed identifier, a reverted piece of scope, or a corrected approach. Distinguish stale from unconfirmable, and never rewrite on a missing operand. "Stale" means the diff positively shows a different value; "unconfirmable" means the Step-1 diff is empty, or does not cover the file the claim names, so it neither confirms nor contradicts the claim. Correct only the positively-contradicted claims; leave an unconfirmable claim unchanged and log it — an empty or truncated Step-1 diff must never turn an accurate claim into a "correction". If the Step-1 diff is empty while a CHANGELOG section was located, treat that as a failed determination — log it and make no edits.

Correct stale claims in place. Rewrite only the specific sentence or clause that is stale, using the same tense, format, and surrounding context as the rest of the entry. If all claims are accurate, make no changes to [[CHANGELOG_FILE]]. In all cases, log a brief summary — for example: "Step 4b: enumerated N claims; M corrected, N−M confirmed accurate." Do not commit — leave committing to the caller, consistent with Step 5.

Step 5: Do Not Commit

Do not commit any files modified above. Leave committing to the caller.


Style and Writing Standards

Release-note entries are customer-facing, so follow the one customer-facing Style Guide — Tone and Voice, AP style, the Oxford-comma rule, and preferred word choices — in skills/docs-sync-external/SKILL.md, reached through the portable skill-directory anchor as "${CLAUDE_SKILL_DIR:-<absolute skill base directory this runner reports in context>}"/../docs-sync-external/SKILL.md. For the audience-neutral rules, follow the shared writing standard "${CLAUDE_SKILL_DIR:-<absolute skill base directory this runner reports in context>}"/../../lib/writing-standard.md. A failed load of either emits a breadcrumb naming the file and the failure kind, and you compose without it. The release-note-specific constraint — each entry is two to three sentences — is stated under Important Constraints below.


Important Constraints

  • Scope: Only write release notes for customer-visible changes
  • Brevity: Each entry should be two to three sentences
  • No duplicates: If a release note for the same PR number already exists — or an existing entry already describes the same user-visible behavior (a rebase, follow-up PR, or squashed pair changes the number without changing the outcome) — do not add another
  • Tone: Professional and customer-friendly
  • Do not commit: Leave committing to the caller

Verification Checklist

Before completing, verify:

  • Entry matches the format: bolded user-outcome title, — separator, linked tracker reference
  • Description is two to three sentences — counted, not estimated
  • Entry states current behavior; no prior-behavior narration ("no longer", "used to", "previously", "silently")
  • Step 3b performed: every factual claim in the entry confirmed against the Step-1 diff
  • Duplicate check covered both the PR number and the described behavior
  • Archive check performed on [[RELEASE_NOTES_FILE]] (entry count / oldest-heading age)
  • Step 4b outcome logged as exactly one of: reconciled, expected changeset-model no-op, legitimate no-op, or failed determination
  • Nothing committed

Frequently asked questions

What does the Docs Release Notes AI skill do?

Use when a change needs a user-visible release-note, changelog, or changeset entry — "add a release note", "add a changeset for this", "what goes in the changelog?", "write up what shipped", "note this for the next release" — or when finalizing a branch whose customer-visible features, bug fixes, or UI changes should be announced before merge. Narrower than prflow:docs, which sweeps internal docs, external docs, and release notes together.

Why use Docs Release Notes on TypingMind?

Because you install it once and use it with any model. Docs Release Notes is plain Markdown rather than provider-specific code, so the same skill runs on GPT-5, Claude, Gemini, Grok, or a local model — and you can switch model mid-chat without it breaking. TypingMind runs on your own API keys, so you pay providers directly instead of a per-seat subscription, and your skills and chats stay in your own storage.

How do I install Docs Release Notes in TypingMind?

Open Plugins → Skills → Install from GitHub in TypingMind and paste https://github.com/The01Geek/prflow/tree/main/skills/docs-release-notes. TypingMind reads its SKILL.md and installs it as a skill you can enable per chat.

Which AI models can use Docs Release Notes?

Any model you connect in TypingMind. AI skills are plain Markdown instructions rather than provider-specific code, so GPT, Claude, Gemini, Grok, and local models can all load this skill when a request matches it.

How many AI models can I use with Docs Release Notes?

As many as you like. As long as a model supports skills, you can use Docs Release Notes with it — GPT, Claude, Gemini, Grok, DeepSeek, Mistral, Llama and more — all on TypingMind with your own API keys.

Is the Docs Release Notes AI skill free?

Yes. It is published on GitHub by The01Geek under the MIT license. You only pay your own AI provider for the tokens you use.

What are AI skills?

An AI skill is a reusable instruction bundle that teaches an AI model how to do one specific task. It follows the open Agent Skills format: a SKILL.md file with a name and description, plus any scripts, templates or reference files the model may need. The model reads the instructions only when your request matches the skill, so an installed skill costs nothing until it is used.

How are AI skills different from plugins or MCP servers?

A plugin or MCP server gives a model new tools to call — code that runs somewhere and returns a result. An AI skill gives the model knowledge and process instead: how to approach a task, which steps to follow, what good output looks like. Skills are plain Markdown, so they need no server, no API key and no runtime, and they work with any model.

View all

Set up your own AI workspace now

Get notified about new features and future giveaways by subscribing to our newsletter 👇