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 undermetadata.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,platformsprerequisites: { 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; preferrequires.credentials.
Procedure
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.
Decide whether the skill needs a credential. Use
requires.credentialsonly when the skill needs a configured account, credential, remote API, or connector-backed local integration. Each entry is a credential NAME —LINEAR_API_KEYfor an api-key credential,google-workspace-oauthfor the Google oauth2 credential. Check the configured credentials inGET /api/connectorsto find the right name. If the skill only needs local commands such asgit,gh,jq, orcurl, record those underprerequisites.commandsand setrequires.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, butrequires.credentialsis preferred.)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: [] ---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.mdfor a working reference.Validate before writing to disk. Run:
bun run gini skill validate /tmp/draft-skill.mdFix every issue the validator reports. Common failures:
nameis uppercase or contains underscores → switch to kebab-case.descriptionexceeds 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.
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.mdand triggers a loader reload. The response includes the newSkillRecordwithvalidation: { ok, issues }.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 asskillId) 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/skillspage (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.
- List the credential names the skill declares in
Migration Mode
When converting a legacy SKILL.md, the recipe is:
Move
version,author,platforms,prerequisites, and the credential requirement undermetadata.gini.*, landing on the currentrequires.credentials: [<name>]form. Convert legacy connector declarations to credential names:requires.identities[].kindandrequires.connectors[].provider→requires.credentials[]names (e.g.linear→LINEAR_API_KEY,google-oauth-desktop→google-workspace-oauth). The legacyrequires.identities/kind:andrequires.connectors/provider:shapes are what older SKILL.md files used;requires.connectorsis still accepted for backward compatibility, but migrate torequires.credentialswhen rewriting.
Move
compatibilityto the top level if you can describe the host contract in ≤ 500 chars.Add
allowed-toolsat the top level when the skill is meant to run under an agent harness that respects it.Re-validate with
gini skill validatebefore installing.
Rules
- Never write a skill without validating first.
- Always check
GET /api/connectorsfor the credentials the new skill will depend on, and reference them by name inrequires.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.