Think of it as your skill's passport. It tells SXM what your skill does, how it works, and what it needs.
A single JSON file called sxm-manifest.json that you put in your project's root folder. It describes your AI skill so our evaluator knows how to test it.
Without the manifest, we don't know what your skill is supposed to do. We can't test inputs if we don't know what they are. We can't check security if we don't know what permissions it needs. The manifest is how your skill tells us "here's what I am, test me."
You need to know what your skill does. That's it. The manifest is just a structured way of writing that down. If you can describe your skill in plain English, you can write a manifest.
sxm-manifest.json in your project rootPro tip: Start with a minimal manifest (just the required fields). You can add optional fields later. A simple honest manifest scores better than a complex dishonest one.
This is the absolute minimum you need. Copy it, change the values, done.
{
"name": "My AI Skill",
"version": "1.0.0",
"description": "What your skill does in one sentence",
"platform": "generic",
"category": "other",
"inputs": [
{
"name": "text",
"type": "string",
"required": true,
"description": "The text to process"
}
],
"outputs": [
{
"name": "result",
"type": "string",
"description": "The processed output"
}
],
"failure_modes": [
{
"condition": "Invalid input",
"behaviour": "Returns error message"
}
],
"data_handling": "No data stored. All processing in memory.",
"author": "Your Name",
"author_email": "you@example.com"
}
{
"name": "My Threat Detector",
"version": "1.2.0",
"description": "Real-time prompt injection detection and content safety scoring",
"platform": "claude",
"category": "security",
"inputs": [
{
"name": "prompt",
"type": "string",
"required": true,
"description": "The user prompt to analyse"
}
],
"outputs": [
{
"name": "safety_score",
"type": "number",
"description": "0-100 safety rating"
},
{
"name": "flagged_patterns",
"type": "array",
"description": "List of detected threat patterns"
}
],
"dependencies": [
{ "name": "@anthropic-ai/sdk", "version": "^0.30.0" }
],
"permissions": [
"network:api.anthropic.com",
"filesystem:read:/tmp"
],
"failure_modes": [
{
"condition": "API timeout",
"behaviour": "Returns error with retry suggestion"
},
{
"condition": "Malformed input",
"behaviour": "Returns validation error with schema"
}
],
"data_handling": "No data persisted. All processing in-memory. No external logging.",
"author": "Your Name",
"author_email": "you@example.com",
"source_url": "https://github.com/you/your-skill",
"licence": "MIT"
}
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Required | Human-readable name of your skill. Maximum 200 characters. |
version | string | Required | Semantic version (e.g. 1.2.0). Must follow semver format. |
description | string | Required | What your skill does. Plain language, maximum 2000 characters. |
platform | string | Required | Target platform. One of: claude, openclaw, mcp, cursor, generic. |
category | string | Required | Skill category. One of: security, coding, automation, data, financial, research, content, other. |
| Field | Type | Required | Description |
|---|---|---|---|
inputs | array | Required | Array of input definitions. Each must have name, type, required, and description. |
outputs | array | Required | Array of output definitions. Each must have name, type, and description. |
Why inputs and outputs matter: The evaluator generates test cases from your declared inputs and validates responses against your declared outputs. Incomplete or inaccurate schemas will cause functional verification failures.
| Field | Type | Required | Description |
|---|---|---|---|
dependencies | array | Optional | External packages your skill uses. Each entry needs name and version. Used for dependency vulnerability scanning. |
permissions | array | Optional | Resources your skill accesses. Format: type:target (e.g. network:api.anthropic.com, filesystem:read:/tmp). Used for permission scope validation. |
| Field | Type | Required | Description |
|---|---|---|---|
failure_modes | array | Required | How your skill handles errors. Each entry has condition and behaviour. The evaluator tests these failure scenarios. |
data_handling | string | Required | How your skill handles data. Be specific: does it persist data? Log externally? Process in-memory only? |
| Field | Type | Required | Description |
|---|---|---|---|
test_endpoint | string | Optional | HTTPS URL of your skill’s test endpoint. The evaluator sends POST requests with JSON bodies here. Required for scores above 85. |
test_auth_header | string | Optional | Authentication header for test requests. Format: HeaderName: value (e.g. Authorization: Bearer xxx). |
test_timeout_ms | number | Optional | Timeout per request in milliseconds. Default: 10000. Maximum: 30000. |
test_cases | array | Optional | Author-provided test cases. Each has name, input (JSON object), optional expected_status (HTTP status code), and optional expected_output_contains (array of strings that must appear in the response). |
Why live testing matters: Skills without a test_endpoint are evaluated by manifest analysis only and capped at 85/100. Live testing verifies actual behaviour: functional correctness, security resistance (20+ attack payloads), and performance under load (p50/p95/p99 latency). Final score with live testing = 70% live + 30% static.
| Field | Type | Required | Description |
|---|---|---|---|
author | string | Required | Author or organisation name. |
author_email | string | Required | Contact email. Used for certification notifications. |
source_url | string | Optional | URL to the source repository. Required for CI/CD webhook integration (stale detection on push). |
licence | string | Optional | Software licence (e.g. MIT, Apache-2.0). |
version must follow semver format: MAJOR.MINOR.PATCHplatform must be one of the supported values listed aboveinputs must contain at least one entryfailure_modes must contain at least one entryauthor_email must be a valid email addresssource_url must be a valid URL if provided