Skip to main content

REST API

Base URL: http://127.0.0.1:<port>/api

Default port: 3921 (CLI uses the next free port if busy)

Endpoints

MethodPathDescription
GET/statusServer info, ides, defaultProjectPath, version, npmUpdate
GET/settingsides, folder-based defaults, home, version, npmUpdate
PUT/settingsUpdate ides (then re-apply from UI)
GET/reposList repos with git status, skill/agent counts, and skillLayout
POST/reposClone repo { url, ref?, id? }; bootstraps empty clones
DELETE/repos/:idRemove repo from config
POST/repos/:id/bootstrapApply starter template to an empty repo
POST/repos/:id/fetchgit fetch (updates remote refs)
POST/repos/:id/check-updatesgit fetch, then compare local to origin
POST/repos/:id/pullgit pull
GET/repos/:id/artifactsScan skills and agents
GET/installationsinstallations and recentProjects
PUT/installationsReplace installations array
POST/applyApply symlinks for all enabled IDEs

Query parameters

GET /repos/:id/artifacts?projectPath=/path — include target path status for project scope.

Examples

Status

curl http://127.0.0.1:3921/api/status
{
"home": "/Users/me/.ide-agents",
"port": 3921,
"version": "0.7.0",
"npmUpdate": {
"current": "0.7.0",
"latest": "0.7.0",
"updateAvailable": false,
"installCommand": "npm update -g ide-agents"
},
"defaultProjectPath": "/Users/me/code/my-app",
"ides": {
"opencode": { "enabled": true, "configPath": "/Users/me/.config/opencode" },
"cursor": { "enabled": true, "configPath": "/Users/me/.cursor" },
"claude": { "enabled": false, "configPath": "/Users/me/.claude" },
"codex": { "enabled": true, "configPath": "/Users/me/.codex" }
}
}

Settings

curl http://127.0.0.1:3921/api/settings
curl -X PUT http://127.0.0.1:3921/api/settings \
-H 'Content-Type: application/json' \
-d '{"ides":{"opencode":{"enabled":true,"configPath":"~/.config/opencode"},"cursor":{"enabled":true,"configPath":"~/.cursor"},"claude":{"enabled":false,"configPath":"~/.claude"},"codex":{"enabled":true,"configPath":"~/.codex"}}}'

Apply

curl -X POST http://127.0.0.1:3921/api/apply
{
"results": [
{ "path": "/Users/me/.cursor/skills/hello", "action": "created" },
{ "path": "/Users/me/.claude/skills/hello", "action": "created" },
{ "path": "/Users/me/code/app/.cursor/skills/hello", "action": "removed" }
]
}

Actions: created, removed, skipped. Skipped may include error when target is not a symlink.

Clone (with bootstrap)

curl -X POST http://127.0.0.1:3921/api/repos \
-H 'Content-Type: application/json' \
-d '{"url":"https://github.com/you/empty-skills.git","ref":"main"}'
{
"repo": {
"id": "github-com-you-empty-skills",
"url": "https://github.com/you/empty-skills.git",
"ref": "main",
"slug": "github-com-you-empty-skills",
"localPath": "/Users/me/.ide-agents/repos/github-com-you-empty-skills",
"skillCount": 1,
"agentCount": 1,
"skillLayout": "nested",
"git": { "branch": "main", "sha": "abc123", "dirty": false, "behind": 0, "ahead": 1 }
},
"bootstrap": {
"applied": true,
"pushed": true,
"skillCount": 1,
"agentCount": 1,
"skillLayout": "nested"
}
}

When the repo already has artifacts, bootstrap.applied is false and counts reflect the existing catalog. If push fails, bootstrap.pushed is false and pushError explains why.

Bootstrap empty repo

curl -X POST http://127.0.0.1:3921/api/repos/my-repo/bootstrap

Returns { repo, bootstrap } on success. HTTP 409 if the repo is not empty (Repository is not empty — bootstrap skipped).

Artifacts

curl 'http://127.0.0.1:3921/api/repos/main/artifacts?projectPath=/Users/me/code/my-app'
{
"artifacts": [
{
"id": "gh-fix-ci",
"kind": "skill",
"sourcePath": "skills/.curated/gh-fix-ci",
"name": "gh-fix-ci",
"description": "Fix failing GitHub Actions workflows.",
"allowedScope": "any",
"bucket": ".curated",
"codexMeta": {
"displayName": "GitHub Fix CI",
"shortDescription": "Fix failing GitHub Actions workflows.",
"defaultPrompt": "Fix the CI failure in this repo."
},
"targets": {
"global": { "exists": false, "isSymlink": false, "blocked": false },
"project": { "exists": true, "isSymlink": true, "blocked": false }
}
}
]
}

Optional fields: bucket (bucketed layouts), codexMeta (from agents/openai.yaml), dependsOnSkills / skillDependencies (agents), dependsOnSubagents / subagentDependencies (router agents). See Data model.

Installations

curl http://127.0.0.1:3921/api/installations
{
"installations": [],
"recentProjects": ["/Users/me/code/my-app"]
}

Errors

HTTP 4xx/5xx with body:

{ "error": "Human-readable message" }