CtrlK
BlogDocsLog inGet started
Tessl Logo

create-skill

Author a new SKILL.md from a user prompt, or migrate an existing non-spec skill to the Anthropic Agent Skills format.

52

Quality

58%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Passed

No findings from the security scan

Fix and improve this skill with Tessl

tessl review fix ./skills/meta/create-skill/SKILL.md
SKILL.md
Quality
Evals
Security

Create Skill

You author new skills from a prompt and migrate legacy skills to the Anthropic Agent Skills specification. The goal is one spec-compliant SKILL.md plus optional scripts the agent can later run.

When To Use

  • User asks "create a skill for X" or "add a skill that does X".
  • User pastes a SKILL.md that is missing required fields or uses the legacy top-level fields (version, author, platforms, prerequisites, requires.connectors).
  • User asks "make this work" while looking at a non-spec SKILL.md.

Spec Reference

Required top-level frontmatter keys (Anthropic Agent Skills spec):

  • name — max 64 chars, lowercase + digits + hyphens, must equal the parent directory name.
  • description — max 1024 chars.

Optional spec keys:

  • license — free-form string.
  • compatibility — max 500 chars; human summary of environment needs.
  • metadata — arbitrary; Gini extensions live under metadata.gini.*.
  • allowed-tools — space-separated list of tool names the skill plans to invoke (advisory; recorded in audit trail).

Gini extensions (under metadata.gini):

  • version, author, platforms
  • prerequisites: { commands, env }
  • requires.credentials: [<credential-name>] — the credential names the skill needs, referenced by name (e.g. [LINEAR_API_KEY] for an api-key credential, [google-workspace-oauth] for the Google oauth2 credential). This is the current, preferred form.
  • requires.connectors: [{ provider, scopes? }] — still accepted for backward compatibility during the migration window; prefer requires.credentials.

Procedure

  1. Confirm the user's intent. If the request is "create a skill that posts to Slack", clarify whether the skill should also read messages, list channels, etc. — surface the cardinality so the design is right.

  2. Decide whether the skill needs a credential. Use requires.credentials only when the skill needs a configured account, credential, remote API, or connector-backed local integration. Each entry is a credential NAME — LINEAR_API_KEY for an api-key credential, google-workspace-oauth for the Google oauth2 credential. Check the configured credentials in GET /api/connectors to find the right name. If the skill only needs local commands such as git, gh, jq, or curl, record those under prerequisites.commands and set requires.credentials: []. If the skill truly needs a credential that hasn't been configured yet, name it the way the credential will be stored (the env-var name for an api-key) and tell the user to add it. Do not ask the user to pick between install/skip on unknown credentials — default to forward motion. (requires.connectors: [{ provider }] is still accepted for backward compatibility, but requires.credentials is preferred.)

  3. Draft the frontmatter. Use this template:

    ---
    name: <kebab-case-name>
    description: "<one-liner>"
    license: MIT
    compatibility: "<one sentence describing host requirements>"
    allowed-tools: "<space-separated tool names>"
    metadata:
      gini:
        version: 1.0.0
        author: <user-or-"Gini">
        platforms: [<macos|linux|windows>]
        prerequisites:
          commands: [<cli names>]
          env: [<ENV_VAR_NAMES>]
        requires:
          # Leave empty for local-command-only skills. If a credential is
          # needed, list it by name, e.g. [LINEAR_API_KEY] or
          # [google-workspace-oauth].
          credentials: []
    ---
  4. Write the body. The body is the model's manual for this skill at runtime — concrete examples, when-to-use / when-not-to-use sections, exact commands. Imitate the body shape of skills/apple/apple-notes/SKILL.md for a working reference.

  5. Validate before writing to disk. Run:

    bun run gini skill validate /tmp/draft-skill.md

    Fix every issue the validator reports. Common failures:

    • name is uppercase or contains underscores → switch to kebab-case.
    • description exceeds 1024 chars → tighten it.
    • parent dir name doesn't match name → adjust whichever is wrong.
    • required credential name is malformed → an api-key name must be an env token ([A-Z][A-Z0-9_]*, e.g. LINEAR_API_KEY); if the skill only needs local commands, remove the credential requirement.
  6. Install the skill via the API so the runtime picks it up:

    curl -sS -X POST http://localhost:<runtime-port>/api/skills \
      -H "authorization: Bearer $GINI_TOKEN" \
      -H "content-type: application/json" \
      -d "$(jq -nc \
        --arg body "$(cat /tmp/draft-skill.md)" \
        '{ body: $body }')"

    The endpoint writes the file flat under ~/.gini/instances/<instance>/skills/<name>/SKILL.md and triggers a loader reload. The response includes the new SkillRecord with validation: { ok, issues }.

  7. Walk the credential dependency:

    • List the credential names the skill declares in requires.credentials.
    • For each, check GET /api/connectors. If a healthy credential with that name already exists, you are done.
    • If not, prompt the user in chat with request_connector (passing the new skill's id as skillId) so they can enter it securely — the card stores the credential and grants it to the skill in one step. For a credential with no registered provider, use the templateless {name, type, skillId} shape. The /skills page (find the new skill, click the inline [Set up <Credential>] button) is a fallback when the secure card cannot render. There is no standalone Connectors page.

Migration Mode

When converting a legacy SKILL.md, the recipe is:

  1. Move version, author, platforms, prerequisites, and the credential requirement under metadata.gini.*, landing on the current requires.credentials: [<name>] form. Convert legacy connector declarations to credential names:

    • requires.identities[].kind and requires.connectors[].providerrequires.credentials[] names (e.g. linearLINEAR_API_KEY, google-oauth-desktopgoogle-workspace-oauth). The legacy requires.identities / kind: and requires.connectors / provider: shapes are what older SKILL.md files used; requires.connectors is still accepted for backward compatibility, but migrate to requires.credentials when rewriting.
  2. Move compatibility to the top level if you can describe the host contract in ≤ 500 chars.

  3. Add allowed-tools at the top level when the skill is meant to run under an agent harness that respects it.

  4. Re-validate with gini skill validate before installing.

Rules

  • Never write a skill without validating first.
  • Always check GET /api/connectors for the credentials the new skill will depend on, and reference them by name in requires.credentials. Do not add a credential requirement for local-command-only skills.
  • Bundled skills are immutable from the agent's perspective — if the user asks to edit a bundled skill, instead create a user-source copy with the same name. The runtime keeps both as separate rows.
  • Do not embed plaintext API tokens or secrets in SKILL.md body.
Repository
Open-Curiosity/gini-agent
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.