Base URL http://localhost:3333/api/ · Authentication · Conventions

Skill Routes

Base path: /api/skills

Manage reusable agent skills — named instruction sets that can be assigned to agents.

Get All Skills

GET /

  • Authentication: Required
  • Description: Get all skills for the authenticated user
  • Response:
{
  "skills": [
    {
      "id": "skill-uuid",
      "name": "Code Reviewer",
      "description": "Reviews code for quality and security",
      "instructions": "When reviewing code...",
      "icon": "fas fa-code",
      "category": "development",
      "allowed_tools": "[\"code-search\",\"file-read\"]",
      "license": "",
      "compatibility": "",
      "metadata": "{\"relations\":{\"depends-on\":[\"hyperframes-core\"]},\"provenance\":{\"source-trace\":\"goal-uuid\",\"rationale\":\"...\"}}",
      "created_at": "2024-01-01T00:00:00Z",
      "updated_at": "2024-01-01T00:00:00Z"
    }
  ]
}

Get Skill by ID

GET /:id

  • Authentication: Required
  • Parameters:
    • id (path): Skill ID
  • Response:
{
  "skill": { ... }
}
  • Error (404): Skill not found

Create Skill

POST /

  • Authentication: Required
  • Body:
{
  "skill": {
    "name": "Code Reviewer",
    "description": "Reviews code for quality and security",
    "instructions": "When reviewing code, focus on...",
    "icon": "fas fa-code",
    "category": "development",
    "allowedTools": ["code-search", "file-read"]
  }
}
  • Response (201):
{
  "skill": { ... },
  "skillId": "skill-uuid"
}

Update Skill

PUT /:id

  • Authentication: Required
  • Parameters:
    • id (path): Skill ID
  • Body:
{
  "skill": {
    "name": "Updated Name",
    "description": "Updated description",
    "instructions": "Updated instructions..."
  }
}
  • Response:
{
  "skill": { ... }
}

Delete Skill

DELETE /:id

  • Authentication: Required
  • Parameters:
    • id (path): Skill ID
  • Response:
{
  "message": "Skill deleted"
}
  • Error (404): Skill not found

Export Skill as Markdown

GET /:id/export

  • Authentication: Required
  • Parameters:
    • id (path): Skill ID
  • Description: Export a skill as a .SKILL.md file with YAML frontmatter and markdown body
  • Response: text/markdown file download

Import Skill from Markdown

POST /import

  • Authentication: Required
  • Content-Type: text/plain
  • Description: Import a skill from SKILL.md content (YAML frontmatter + markdown body)
  • Body: Raw text content of a .SKILL.md file
---
name: "My Skill"
description: "Skill description"
category: "general"
icon: "fas fa-puzzle-piece"
allowed-tools:
  - code-search
  - file-read
---

Instructions for the skill go here...
  • Response (201):
{
  "skill": { ... },
  "skillId": "skill-uuid"
}

Skill relations and provenance

Skills can declare how they relate to other skills, and where they came from.
Both live inside the spec's free-form metadata map, so no new frontmatter
fields are introduced and skills stay portable to other agentskills.io clients
(which simply ignore metadata).

In a SKILL.md file:

---
name: hyperframes-cli
description: Use the HyperFrames CLI development loop.
metadata:
  relations:
    depends-on:
      - hyperframes-core        # activate that skill too
    composes-with:
      - media-use               # complementary, often used together
    supersedes:
      - old-render-pipeline     # prefer this skill over that one
  provenance:
    source-trace: 9acd74bc-34e5-4f25-bde2-1aef13965318
    extracted: "2026-08-03"
    rationale: Extracted from the batch-render loop; generalizes to any batch render, fails on multi-repo targets.
    confidence: 0.82
---

Over the API, metadata is a JSON string on database-backed skills
(/api/skills) and a parsed object on filesystem-discovered skills
(/api/skills/discovered). Consumers should handle both.

Relation types

Key Meaning
depends-on This skill requires the target to function. Activating it surfaces a prompt to activate the target as well.
composes-with Complementary skill, frequently useful alongside this one.
supersedes This skill replaces the target. While both are present, the target is omitted from the skill catalog and activating it warns the caller.

Values are arrays of skill slugs (a bare string is accepted and treated as a
single-element array). Unknown relation types and malformed slugs produce
warnings, never errors — the rest of the skill still loads.

Provenance fields

Field Meaning
source-trace Goal or execution ID the skill was extracted from.
extracted YYYY-MM-DD extraction date.
rationale Where the pattern came from, when it generalizes, when it fails.
confidence 0.01.0 judge confidence at extraction time.
history Appended on each SkillForge refinement: one entry per version, giving the skill a lineage.

Skills forged automatically by SkillForge populate
provenance from the trace analysis. Refinements append to provenance.history
rather than overwriting the original extraction record.

Effect on the skill catalog

The <available-skills> catalog injected into agent prompts is relation-aware:

  • A depends-on relation is annotated inline — - hyperframes-cli: … [needs: hyperframes-core].
  • A skill is omitted from the catalog when another skill present in the same
    catalog
    declares that it supersedes it. If the successor is absent the
    superseded skill is still listed, so a capability is never orphaned.

Relations and provenance survive a full GET /:id/exportPOST /import
round-trip.


SkillForge Routes

Base path: /api/skillforge

SkillForge is the skill evolution subsystem within the unified evolution engine. It analyzes goal execution traces via the TraceAnalyzer, extracts patterns and anti-patterns, evolves skills with improved instructions, and tracks performance over time using a Skill Evolution Score (SES). Runs automatically after goal completion when autoAnalyze is enabled, or can be triggered manually.

Get Eligible Goals

GET /eligible-goals

  • Authentication: Required
  • Description: List completed goals that are available for skill forging/analysis
  • Response:
{
  "success": true,
  "goals": [
    {
      "id": "goal-id",
      "title": "Goal Title",
      "status": "completed",
      "completedAt": "2024-01-01T00:00:00Z"
    }
  ]
}

Analyze Goal Trace

POST /analyze/:goalId

  • Authentication: Required
  • Parameters:
    • goalId (path): Goal ID
  • Body (optional):
{
  "provider": "anthropic",
  "model": "claude-sonnet-4-20250514"
}
  • Description: Analyze a goal's execution trace using LLM-as-judge to extract patterns, anti-patterns, and a reusable skill candidate. Provider/model override the user's defaults for the LLM analysis call.
  • Response:
{
  "success": true,
  "analysis": {
    "patterns": [],
    "antipatterns": [],
    "insights": [],
    "skillCandidate": {}
  }
}

Evolve Skill

POST /evolve/:goalId

  • Authentication: Required
  • Parameters:
    • goalId (path): Goal ID
  • Body (optional):
{
  "provider": "anthropic",
  "model": "claude-sonnet-4-20250514"
}
  • Description: Full analysis and skill evolution — analyzes the goal trace, creates or updates a skill with merged instructions, and records the evolution with SES tracking. Provider/model are forwarded to trace analysis and skill instruction merging.
  • Response:
{
  "success": true,
  "result": {
    "skillId": "skill-id",
    "previousVersion": 1,
    "newVersion": 2,
    "sesDelta": 0.15,
    "improvements": []
  }
}

Get All Evaluations

GET /evaluations

  • Authentication: Required
  • Parameters:
    • limit (query, optional): Max results (default: 50)
  • Description: List all skill evaluations for the authenticated user
  • Response:
{
  "success": true,
  "evaluations": [
    {
      "id": "eval-id",
      "skillId": "skill-id",
      "score": 85,
      "sesDelta": 0.12,
      "createdAt": "2024-01-01T00:00:00Z"
    }
  ]
}

Get Evaluations for Skill

GET /evaluations/:skillId

  • Authentication: Required
  • Parameters:
    • skillId (path): Skill ID
  • Description: Get all evaluations for a specific skill
  • Response:
{
  "success": true,
  "evaluations": [
    {
      "id": "eval-id",
      "skillId": "skill-id",
      "score": 85,
      "sesDelta": 0.12,
      "version": 2,
      "createdAt": "2024-01-01T00:00:00Z"
    }
  ]
}

Get Leaderboard

GET /leaderboard

  • Authentication: Required
  • Parameters:
    • limit (query, optional): Max results (default: 20)
  • Description: Get top skills ranked by average SES delta
  • Response:
{
  "success": true,
  "leaderboard": [
    {
      "skillId": "skill-id",
      "skillName": "Code Reviewer",
      "avgSesDelta": 0.25,
      "totalEvolutions": 8,
      "currentVersion": 5
    }
  ]
}

Get Skill Version History

GET /skill/:skillId/versions

  • Authentication: Required
  • Parameters:
    • skillId (path): Skill ID
  • Description: Get the version history for a skill's evolution
  • Response:
{
  "success": true,
  "versions": [
    {
      "version": 3,
      "sesDelta": 0.15,
      "changes": "Improved error handling patterns",
      "createdAt": "2024-01-01T00:00:00Z"
    }
  ]
}

Get Skill Lineage

GET /skill/:skillId/lineage

  • Authentication: Required
  • Parameters:
    • skillId (path): Skill ID
  • Description: Get the full evolutionary lineage of a skill — every ancestor, mutation, and stats
  • Response:
{
  "success": true,
  "lineage": [
    {
      "version": 1,
      "parentGoalId": "goal-id",
      "sesDelta": 0.0,
      "createdAt": "2024-01-01T00:00:00Z"
    }
  ],
  "stats": {
    "totalEvolutions": 5,
    "avgSesDelta": 0.18,
    "bestVersion": 4
  }
}

Get Aggregate Stats

GET /stats

  • Authentication: Required
  • Description: Get aggregate SkillForge statistics for the user
  • Response:
{
  "success": true,
  "stats": {
    "totalSkills": 12,
    "totalEvolutions": 45,
    "totalEvaluations": 120,
    "avgSesDelta": 0.15,
    "topSkill": "Code Reviewer"
  }
}

Get SkillForge Settings

GET /settings

  • Authentication: Required
  • Description: Get SkillForge configuration settings
  • Response:
{
  "success": true,
  "settings": {
    "autoAnalyze": false,
    "evaluationThreshold": 0.7,
    "maxVersions": 50
  }
}

Update SkillForge Settings

POST /settings

  • Authentication: Required
  • Body:
{
  "autoAnalyze": true,
  "evaluationThreshold": 0.8,
  "maxVersions": 100
}
  • Response:
{
  "success": true,
  "settings": {
    "autoAnalyze": true,
    "evaluationThreshold": 0.8,
    "maxVersions": 100
  }
}

Skill Discovery Routes

Base path: /api/skills/discovered

Skill Discovery scans the filesystem for skill definitions (e.g., a user's ~/.claude/skills/ directory or a project-local skills folder) and exposes them as a read-only catalog. Discovered skills are separate from database-backed skills until imported. Use these endpoints to browse filesystem skills and promote them into the user's skill library.

List Discovered Skills

GET /

  • Authentication: Required
  • Description: Get the catalog of all filesystem-discovered skills (summary only — no instructions body)
  • Response:
{
  "skills": [
    {
      "name": "hyperframes-cli",
      "description": "Skill description",
      "source": "filesystem",
      "scope": "user",
      "client": "agnt",
      "trusted": true,
      "metadata": { "relations": { "depends-on": ["hyperframes-core"] } }
    }
  ],
  "lastScan": "2024-01-01T00:00:00Z",
  "scanLocations": [
    { "path": "/home/user/.agnt/skills", "scope": "user", "client": "agnt", "priority": 8 }
  ],
  "total": 42,
  "parseFailures": []
}
  • source is always "filesystem" (it distinguishes these entries from database-backed skills). The project-vs-user distinction is scope.
  • metadata is the parsed frontmatter metadata map, or null. This is where
    relations and provenance live — note that it is a parsed
    object here, whereas /api/skills returns it as a JSON string.
  • parseFailures lists skills found on disk that could not be loaded — see below.

Parse failures

A SKILL.md that fails to parse is skipped, which used to be invisible: the
skill simply never appeared and nothing said why. Every scan now records its
failures and both list endpoints return them:

{
  "parseFailures": [
    {
      "name": "broken-skill",
      "path": "/home/user/.agnt/skills/broken-skill/SKILL.md",
      "errors": ["Missing required \"description\" (no ## Description section found)"],
      "skipped": true,
      "at": "2026-08-04T01:22:33.000Z"
    }
  ]
}

skipped: true means the skill was dropped from the catalog entirely; false
means it loaded with degraded metadata. The list is rebuilt on every scan, so a
repaired skill disappears from it on the next rescan.

Name collisions across clients

The same skill name may exist in several client directories (~/.agnt/skills,
~/.claude/skills, ~/.agents/skills, …). Discovery keys skills by name and the
highest-priority copy wins — project-level beats ancestor-level beats
~/.agnt/skills beats other user-level client dirs. When editing skills on disk,
edit every copy: an unedited higher-priority copy silently shadows the change.

Rescan Skill Locations

POST /rescan

  • Authentication: Required
  • Body (optional):
{
  "projectRoot": "/optional/project/root/path"
}
  • Description: Trigger a fresh scan of the filesystem skill locations. If projectRoot is provided, also scan that project for local skills.
  • Response: same entry shape as GET /, including parseFailures
{
  "skills": [],
  "lastScan": "2024-01-01T00:00:00Z",
  "total": 42,
  "parseFailures": []
}

Get Discovered Skill

GET /:name

  • Authentication: Required
  • Parameters:
    • name (path): Skill name (kebab-case, matches directory name)
  • Description: Get the full content (metadata + instructions + frontmatter) of a discovered skill
  • Response:
{
  "skill": {
    "name": "skill-name",
    "description": "Skill description",
    "instructions": "Full skill instructions markdown...",
    "frontmatter": {
      "name": "skill-name",
      "license": "MIT",
      "compatibility": "...",
      "metadata": { "relations": {}, "provenance": {} },
      "allowed-tools": []
    },
    "dirPath": "/path/to/skill/dir",
    "skillMdPath": "/path/to/skill/dir/SKILL.md",
    "scope": "user",
    "client": "agnt",
    "priority": 8,
    "trusted": true,
    "validName": true,
    "discoveredAt": "2024-01-01T00:00:00Z"
  }
}

frontmatter.metadata carries relations and provenance.

Encoding note. SKILL.md files are parsed as UTF-8 and a leading byte
order mark is stripped before parsing. A BOM used to defeat the frontmatter
delimiter, which made a valid skill fail with a misleading "missing
description" error.

List Skill Resources

GET /:name/resources

  • Authentication: Required
  • Parameters:
    • name (path): Skill name
  • Description: List bundled resource files (non-instruction files) shipped with a skill, e.g. templates, scripts, example data
  • Response:
{
  "resources": [
    { "path": "templates/prompt.md", "size": 1234, "type": "file" }
  ]
}

Read Skill Resource

GET /:name/resources/*

  • Authentication: Required
  • Parameters:
    • name (path): Skill name
    • * (wildcard path): Relative path to the resource file within the skill directory
  • Description: Read the raw content of a bundled resource file. Paths are validated to prevent escaping the skill directory.
  • Response: text/plain; charset=utf-8 with the file contents
  • Errors:
    • 400 if the resource path is missing
    • 403 if the path escapes the skill directory
    • 404 if the resource is not found

Import Discovered Skill

POST /:name/import

  • Authentication: Required
  • Parameters:
    • name (path): Skill name (kebab-case)
  • Description: Import a filesystem-discovered skill into the user's database-backed skill library. The kebab-case name is converted to Title Case for display; the original slug is preserved for lookups. Frontmatter fields (license, compatibility, metadata, allowed-tools) are copied into the skill record.
  • Response: 201 Created
{
  "skill": {
    "id": "new-skill-id",
    "name": "Skill Name",
    "slug": "skill-name",
    "description": "...",
    "instructions": "..."
  },
  "skillId": "new-skill-id",
  "importedFrom": "/path/to/source/skill/dir"
}