Create skills
Adds or revises one of the caller org's own skills, and answers 201 with the stored record.
POST /v1/tool/skills
| Address | https://api.hanzo.ai/v1/tool/skills |
| Method | POST |
| Operation | post_tool_skills |
| Auth | Authorization: Bearer $HANZO_API_KEY |
Adds or revises one of the caller org's own skills, and answers 201 with the stored record. The id is derived from the name, so writing the same name again REVISES that skill rather than accumulating near-duplicates that would then collide in the registry. An org's skills are private to it by construction — they live in a different store from the brand's embedded catalogue and have no path into the public gallery — and a brand skill always wins a name collision against an org's.
An activated skill is carried into every agent run in the org, so writing one takes an admin of the org or a SuperAdmin; a member is refused 403. The write is on the org's audit trail before it is made, and one the trail cannot record is refused 503.
Request
3 fields, body application/json (required).
| Field | In | Type | Required | Description |
|---|---|---|---|---|
content | body | string | — | Content is the SKILL.md body. |
description | body | string | — | Description is the one-line summary discovery shows for the skill. |
name | body | string | — | Name is the skill's id within the org: one lowercase path segment (a-z0-9, _ or -). |
Response
| Status | Body | Meaning |
|---|---|---|
201 | tool.skillWritten | created |
default | problem-details | refused |
201 body — 9 fields.
| Field | In | Type | Always | Description |
|---|---|---|---|---|
skill | body | tool.Skill | — | |
skill.admitted | body | boolean | — | Admitted is whether an admin of the org, or a SuperAdmin, wrote this content. |
skill.content | body | string | — | Content is the SKILL.md body, markdown. |
skill.createdAt | body | integer (int64) | — | CreatedAt is when the skill was last written, Unix seconds. |
skill.description | body | string | — | Description is the one-line summary discovery shows for the skill. |
skill.id | body | string | — | ID is the skill's id within the org. |
skill.name | body | string | — | Name is the skill's name: one lowercase path segment (a-z0-9, _ or -). |
skill.org | body | string | — | Org is the org that authored the skill — the validated caller's, never a value the body supplied. |
skill.source | body | string | — | Source is the repository the skill was read from, "<project>/<name>" or "<name>"; empty for a skill written through the API. |
Failure carries the platform error shape — see Errors.
Examples
hanzo tool skills createimport { Configuration, ToolApi } from 'hanzoai';
const api = new ToolApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.postToolSkills({ content: "<content>", description: "<description>" });from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import ToolApi
client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = ToolApi(client).post_tool_skills(content="<content>", description="<description>")cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)
resp, _, err := client.ToolAPI.PostToolSkills(context.Background()).Execute()
if err != nil {
return err
}use hanzo_client::apis::{configuration::Configuration, tool_api};
let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();
let result = tool_api::post_tool_skills(&cfg, Default::default()).await?;import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.ToolApi;
ApiClient client = new ApiClient();
client.setBearerToken(System.getenv("HANZO_API_KEY"));
var result = new ToolApi(client).postToolSkills();curl -X POST https://api.hanzo.ai/v1/tool/skills \
-H "Authorization: Bearer $HANZO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "<content>",
"description": "<description>"
}'MCP reaches tool through the tool tool, which names its 17 operations with its own verbs — this one among them, under a name only MCP declares. describe explains any of them:
curl -X POST https://api.hanzo.ai/v1/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "describe",
"arguments": {
"op": "list_tools"
}
}
}'