Skip to main content
POST
/
api
/
v1
/
skills
Add Skill
curl --request POST \
  --url https://api.example.com/api/v1/skills \
  --header 'Content-Type: application/json' \
  --data '
{
  "data": {},
  "wait": true,
  "timeout": 123
}
'
{
  "status": "ok",
  "result": {
    "status": "success",
    "uri": "viking://agent/skills/search-web/",
    "name": "search-web",
    "auxiliary_files": 0
  },
  "time": 0.15
}
Add a skill to the knowledge base. Skills define capabilities that agents can invoke. OpenViking automatically detects and converts MCP tool definitions to skill format.
Skills are vectorized and indexed for semantic retrieval. Use wait=true or call /api/v1/system/wait to ensure processing completes.

Authentication

Requires API key authentication via X-API-Key header.

Request Body

data
object | string
required
Skill data in one of four supported formats:
  1. Skill format (dict with name, description, content)
  2. MCP Tool format (dict with inputSchema - auto-converted)
  3. String (SKILL.md content with YAML frontmatter)
  4. Path (file or directory path)
wait
boolean
default:"false"
Wait for vectorization to complete before returning
timeout
number
default:"null"
Timeout in seconds when wait=true

Skill Data Formats

Format 1: Skill Dict

{
  "name": "search-web",
  "description": "Search the web for current information",
  "content": "# search-web\n\nSearch the web for current information.\n\n## Parameters\n- **query** (string, required): Search query\n- **limit** (integer, optional): Max results, default 10",
  "allowed_tools": ["HttpClient", "JsonParser"],
  "tags": ["web", "search"]
}

Format 2: MCP Tool (Auto-Converted)

{
  "name": "calculator",
  "description": "Perform mathematical calculations",
  "inputSchema": {
    "type": "object",
    "properties": {
      "expression": {
        "type": "string",
        "description": "Mathematical expression to evaluate"
      }
    },
    "required": ["expression"]
  }
}
OpenViking detects MCP format by the presence of inputSchema and automatically converts it to skill format with generated markdown documentation.

Format 3: SKILL.md String

---
name: code-runner
description: Execute code in various languages
allowed-tools:
  - FileSystem
  - ProcessRunner
tags:
  - code
  - execution
---

# code-runner

Execute code in various languages safely.

## Parameters
- **language** (string, required): Programming language
- **code** (string, required): Code to execute
- **timeout** (integer, optional): Timeout in seconds

Format 4: File Path

{
  "data": "./skills/search-web/SKILL.md"
}
Or for directories with auxiliary files:
{
  "data": "./skills/code-runner/"
}

Response

status
string
Response status (ok or error)
result
object
Skill creation result
time
number
Request processing time in seconds

Examples

curl -X POST http://localhost:1933/api/v1/skills \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-key" \
  -d '{
    "data": {
      "name": "search-web",
      "description": "Search the web for current information",
      "content": "# search-web\n\nSearch the web for current information.\n\n## Parameters\n- **query** (string, required): Search query\n- **limit** (integer, optional): Max results, default 10"
    }
  }'
{
  "status": "ok",
  "result": {
    "status": "success",
    "uri": "viking://agent/skills/search-web/",
    "name": "search-web",
    "auxiliary_files": 0
  },
  "time": 0.15
}

MCP Tool Conversion

When you provide a dict with inputSchema, OpenViking automatically converts it to skill format: Input (MCP):
{
  "name": "search_web",
  "description": "Search the web",
  "inputSchema": {
    "type": "object",
    "properties": {
      "query": {"type": "string", "description": "Search query"},
      "limit": {"type": "integer", "description": "Max results"}
    },
    "required": ["query"]
  }
}
Output (Skill):
---
name: search-web
description: Search the web
---

# search-web

Search the web

## Parameters

- **query** (string) (required): Search query
- **limit** (integer) (optional): Max results

## Usage

This tool wraps the MCP tool `search-web`. Call this when the user needs functionality matching the description above.

Best Practices

# Good - specific and actionable
skill = {
    "name": "search-web",
    "description": "Search the web for current information using Google",
    ...
}

# Less helpful - too vague
skill = {
    "name": "search",
    "description": "Search",
    ...
}
  • search-web
  • searchWeb
  • search_web
  • Clear parameter descriptions with types
  • When to use the skill
  • Concrete examples
  • Edge cases and limitations