Skills
Skill manifests, authentication, credential resolution, and role-skill assignments.
Skills are instruction packs that extend an agent's capabilities. A skill can provide behavioral instructions (prompt injections), API-backed tools, and documentation references.
Skill Manifest
Every skill has a manifest (stored as JSONB) that defines its contents:
{
"schema_version": 1,
"instructions": {
"system": "You have access to GitHub tools...",
"guidelines": [
"Always confirm the repository before creating issues",
"Format issue bodies with Markdown"
],
"examples": [
{
"input": "Create an issue for the login bug",
"output": "I'll create an issue in the repo..."
}
]
},
"tools": [
{
"name": "github_create_issue",
"description": "Create a new GitHub issue",
"inputSchema": {
"type": "object",
"properties": {
"owner": { "type": "string" },
"repo": { "type": "string" },
"title": { "type": "string" }
},
"required": ["owner", "repo", "title"]
},
"endpoint": {
"method": "POST",
"url_template": "https://api.github.com/repos/{owner}/{repo}/issues",
"headers": {
"Authorization": "Bearer {{credentials.token}}"
}
},
"rate_limit": {
"requests_per_minute": 30
}
}
],
"docs": [
{
"url": "https://docs.github.com/en/rest",
"fetch_strategy": "cache",
"ttl_hours": 168
}
]
}Instructions
The instructions block is injected into the agent's system prompt when the skill is active:
| Field | Type | Description |
|---|---|---|
system | string or null | Text appended to the agent's system prompt |
guidelines | string[] | Behavioral guidelines for the agent |
examples | object[] | Few-shot input/output examples |
Tools
Each tool in the manifest is MCP-compatible with Nenjo extensions:
| Field | Type | Description |
|---|---|---|
name | string | Unique tool name |
description | string | What the tool does |
inputSchema | object | JSON Schema for tool parameters |
endpoint | object or null | HTTP endpoint configuration |
rate_limit | object or null | Rate limiting (requests_per_minute) |
Tool endpoint URLs must use HTTPS. Supported HTTP methods are GET, POST, PUT, PATCH, and DELETE.
Documentation References
Skills can reference external documentation that the agent can access:
| Field | Type | Description |
|---|---|---|
url | string | HTTPS URL to the documentation |
fetch_strategy | string | cache (fetch and store), on_demand, or none |
ttl_hours | number or null | Cache TTL in hours |
Authentication Types
Skills support the following auth types:
| Auth Type | Description |
|---|---|
none | No authentication required (instruction-only skills) |
bearer | Bearer token authentication |
The credential_schema field defines what credentials the skill needs:
[
{
"key": "token",
"label": "Personal Access Token",
"type": "secret",
"required": true
},
{
"key": "org",
"label": "Organization",
"type": "text",
"required": false
}
]Credential Resolution
When the worker needs credentials for a skill, it checks three sources in order:
1. Local File
Reads from ~/.nenjo/credentials.toml on the worker machine:
[github]
token = "ghp_xxxxxxxxxxxx"
[slack]
bot_token = "xoxb-xxxxxxxxxxxx"2. Environment Variables
Checks for NENJO_SKILL_{SKILL_NAME}_{FIELD_KEY} (uppercased):
export NENJO_SKILL_GITHUB_TOKEN="ghp_xxxxxxxxxxxx"
export NENJO_SKILL_SLACK_BOT_TOKEN="xoxb-xxxxxxxxxxxx"3. Backend (Encrypted)
Credentials stored via the API are encrypted at rest using NEN_SKILL_ENCRYPTION_KEY and decrypted by the backend on demand.
The resolution chain is configurable via the worker's skills.credential_sources config (default: ["local", "env", "backend"]). The first source that provides a value wins.
Upload Formats
Skills can be created via file upload in multiple formats:
| Format | Extension | Size Limit |
|---|---|---|
| Markdown | .md | 5 MB |
| JSON | .json | 5 MB |
| YAML | .yaml, .yml | 5 MB |
| ZIP bundle | .zip | 50 MB |
Markdown Format
---
name: github
display_name: GitHub
description: Create issues, manage PRs
auth_type: bearer
credential_schema:
- key: token
label: Personal Access Token
type: secret
required: true
tools:
- name: github_create_issue
description: Create a new issue
inputSchema:
type: object
properties:
owner: { type: string }
required: [owner]
endpoint:
method: POST
url_template: "https://api.github.com/repos/{owner}/issues"
---
You have access to GitHub tools. Use them for repository management.
## Guidelines
- Always confirm the repository before creating issues
- Format issue bodies with MarkdownThe markdown body becomes instructions.system, and lines under ## Guidelines become instructions.guidelines.
ZIP Bundle
A ZIP file must contain manifest.json (or manifest.yaml). An optional instructions.md file overrides the manifest's instruction fields.
Role-Skill Assignments
Skills are assigned to roles to make them available to agents.
# List skills assigned to a role
curl -H "Authorization: Bearer $TOKEN" \
https://your-instance.com/api/v1/agent-roles/:id/skills
# Assign a skill to a role
curl -X POST -H "Authorization: Bearer $TOKEN" \
https://your-instance.com/api/v1/agent-roles/:id/skills/:skill_id
# Remove a skill from a role
curl -X DELETE -H "Authorization: Bearer $TOKEN" \
https://your-instance.com/api/v1/agent-roles/:id/skills/:skill_id
# Toggle or update a skill assignment
curl -X PATCH -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"enabled": false}' \
https://your-instance.com/api/v1/agent-roles/:id/skills/:skill_idSkill CRUD
# List all skills
curl -H "Authorization: Bearer $TOKEN" \
https://your-instance.com/api/v1/skills
# Create a skill
curl -X POST -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "github", "display_name": "GitHub", "auth_type": "bearer"}' \
https://your-instance.com/api/v1/skills
# Upload a skill from file
curl -X POST -H "Authorization: Bearer $TOKEN" \
-F "file=@github-skill.md" \
https://your-instance.com/api/v1/skills/upload
# Store credentials for a skill
curl -X PUT -H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"credentials": {"token": "ghp_xxx"}}' \
https://your-instance.com/api/v1/skills/:id/credentials
# Check credential status
curl -H "Authorization: Bearer $TOKEN" \
https://your-instance.com/api/v1/skills/:id/credentials/status
# Revoke credentials
curl -X DELETE -H "Authorization: Bearer $TOKEN" \
https://your-instance.com/api/v1/skills/:id/credentials