A lightweight SDK and spec that lets an AI agent declare what it can do in a machine-readable capability manifest, and lets other systems validate, discover, and reason about agent behavior before execution.
Right now, AI agents are black boxes.
- Their capabilities live in README files or system prompts.
- Orchestrators guess what agents can do.
- Marketplaces cannot compare agents.
- Enterprises cannot review agents safely.
ACDS provides a pre-execution contract: a small, strict JSON manifest that describes what an agent claims it can do. Any system can read, validate, and reason about this manifest without running the agent.
- Not an execution framework. ACDS does not run agents.
- Not an orchestrator. ACDS does not route requests.
- Not a marketplace. ACDS does not host or sell agents.
- Not a trust system. ACDS does not score or verify claims.
- Not a runtime dependency. ACDS does not require anything at runtime.
This is a declaration SDK. It defines what agents say they can do, and validates those declarations against a strict schema.
- Python SDK: Python 3.9+
- TypeScript SDK: Node.js 16+ and npm
- CLI: Python 3.9+ (no install required)
git clone https://github.com/cmaliwal/agent-capability-declaration-sdk.git
cd agent-capability-declaration-sdkpython cli/validate.py validate examples/calculator-agent.jsonOutput:
VALID examples/calculator-agent.json
Agent: calculator-agent
Capabilities: 4
That's it. No setup, no config, no dependencies.
Option A — Install from GitHub (recommended)
pip install git+https://github.com/cmaliwal/agent-capability-declaration-sdk.git#subdirectory=pythonOption B — Install locally for development
git clone https://github.com/cmaliwal/agent-capability-declaration-sdk.git
cd agent-capability-declaration-sdk/python
pip install -e .Option C — Use without installing
The CLI works standalone with no installation. Just clone the repo and run:
python cli/validate.py validate path/to/agent.capabilities.jsonAfter installation (Option A or B), you can import the SDK in your code:
from acds import validate_manifest, list_capabilities, validate_input, get_pricingZero runtime dependencies. Works with Python 3.9, 3.10, 3.11, 3.12, and 3.13.
Option A — Install from GitHub
npm install cmaliwal/agent-capability-declaration-sdkOption B — Install locally for development
git clone https://github.com/cmaliwal/agent-capability-declaration-sdk.git
cd agent-capability-declaration-sdk/typescript
npm install
npm run buildAfter building, import the SDK:
import {
validateManifest,
listCapabilities,
validateInput,
getPricing,
} from "./dist/validator";Zero runtime dependencies. Only typescript and @types/node as dev dependencies.
Every agent creates a file called agent.capabilities.json:
{
"agent_id": "calculator-agent",
"version": "1.0.0",
"capabilities": [
{
"name": "add",
"description": "Add two numbers",
"inputs": {
"a": "number",
"b": "number"
},
"outputs": {
"result": "number"
},
"pricing": {
"type": "per_call",
"cost": "0.001",
"currency": "USD"
},
"latency_class": "fast",
"requires_payment": false
}
]
}| Field | Type | Description |
|---|---|---|
agent_id |
string | Unique agent identifier |
version |
string | Semver version of the manifest |
capabilities |
array | List of declared capabilities (min 1) |
| Field | Type | Description |
|---|---|---|
name |
string | Snake_case capability name |
description |
string | What the capability does |
inputs |
object | Input parameter names → types |
outputs |
object | Output parameter names → types |
pricing |
object | { type, cost, currency } |
latency_class |
enum | fast, medium, or slow |
requires_payment |
boolean | Whether payment is required |
| Field | Type | Example |
|---|---|---|
type |
string | "per_call", "per_token", "flat" |
cost |
string | "0.001" (decimal string) |
currency |
string | "USD" |
string, number, boolean, object, array
The formal schema is at spec/schema.json. You can use it with any JSON Schema validator.
from acds import validate_manifest, list_capabilities, validate_input, get_pricingValidate a manifest file. Raises ManifestError on any schema violation. Returns None on success.
from acds import validate_manifest
from acds.validator import ManifestError
try:
validate_manifest("agent.capabilities.json")
print("Manifest is valid")
except ManifestError as e:
print(f"Invalid: {e}")Return capability names from a parsed manifest dict.
import json
from acds import list_capabilities
with open("agent.capabilities.json") as f:
manifest = json.load(f)
names = list_capabilities(manifest)
# ["add", "subtract", "multiply", "divide"]Validate an input payload against a capability's declared inputs. Returns True if valid. Raises ValidationError if not.
from acds import validate_input
from acds.validator import ValidationError
try:
validate_input("add", {"a": 1, "b": 2}, manifest)
print("Input is valid")
except ValidationError as e:
print(f"Invalid input: {e}")Return the pricing dict for a capability.
from acds import get_pricing
pricing = get_pricing("add", manifest)
# {"type": "per_call", "cost": "0.001", "currency": "USD"}| Error | When |
|---|---|
ManifestError |
Manifest structure is invalid (missing fields, wrong types, bad semver, etc.) |
ValidationError |
Input payload doesn't match declared types, or capability not found |
Both are importable from acds.validator.
import {
validateManifest,
listCapabilities,
validateInput,
getPricing,
ManifestError,
ValidationError,
} from "./dist/validator";try {
validateManifest("agent.capabilities.json");
console.log("Manifest is valid");
} catch (e) {
if (e instanceof ManifestError) {
console.error(`Invalid: ${e.message}`);
}
}import * as fs from "fs";
const manifest = JSON.parse(
fs.readFileSync("agent.capabilities.json", "utf-8")
);
const names = listCapabilities(manifest);
// ["add", "subtract", "multiply", "divide"]validateInput(capabilityName: string, payload: Record<string, unknown>, manifest: Manifest): boolean
try {
validateInput("add", { a: 1, b: 2 }, manifest);
console.log("Input is valid");
} catch (e) {
if (e instanceof ValidationError) {
console.error(`Invalid input: ${e.message}`);
}
}const pricing = getPricing("add", manifest);
// { type: "per_call", cost: "0.001", currency: "USD" }interface Manifest {
agent_id: string;
version: string;
capabilities: Capability[];
}
interface Capability {
name: string;
description: string;
inputs: Record<string, string>;
outputs: Record<string, string>;
pricing: Pricing;
latency_class: string;
requires_payment: boolean;
}
interface Pricing {
type: string;
cost: string;
currency: string;
}The CLI is a single Python script with no installation required.
python cli/validate.py validate path/to/agent.capabilities.jsonVALID examples/calculator-agent.json
Agent: calculator-agent
Capabilities: 4
INVALID bad-manifest.json
Error: capabilities[0].name: name must be a non-empty snake_case string
| Code | Meaning |
|---|---|
0 |
Manifest is valid |
1 |
Manifest is invalid or file not found |
The examples/ directory contains ready-to-use manifests:
| File | Agent | Capabilities |
|---|---|---|
calculator-agent.json |
Calculator | add, subtract, multiply, divide |
weather-agent.json |
Weather | get_current_weather, get_forecast |
Use them as templates for your own agent:
cp examples/calculator-agent.json my-agent.capabilities.json
# Edit the file with your agent's capabilities
python cli/validate.py validate my-agent.capabilities.jsonagent-capability-declaration-sdk/
├── spec/
│ └── schema.json # JSON Schema for capability manifests
├── python/
│ ├── acds/
│ │ ├── __init__.py
│ │ └── validator.py # Python validation library
│ └── pyproject.toml
├── typescript/
│ ├── src/
│ │ └── validator.ts # TypeScript validation library
│ ├── package.json
│ └── tsconfig.json
├── cli/
│ └── validate.py # CLI validation tool
├── examples/
│ ├── calculator-agent.json
│ └── weather-agent.json
├── README.md
├── BLOG.md
└── LICENSE
Declarations are claims, not guarantees.
An agent that declares "latency_class": "fast" might actually be slow. An agent that declares an add capability might return wrong results. That is fine.
The purpose of a declaration is to enable reasoning before execution. Systems can:
- Filter agents by declared capability before calling them.
- Compare pricing across agents without running them.
- Review manifests for dangerous capabilities before approving them.
Verification, trust scoring, and runtime validation are separate concerns that can be layered on top. They are not part of this SDK.
OpenAPI describes HTTP APIs — endpoints, methods, request/response schemas. It is API-centric. ACDS describes agent-level capabilities — what an agent can do, not how to call it. They are complementary.
MCP is tool-centric. It describes tools that models can use during execution. ACDS is agent-centric. It describes capabilities that an agent declares before execution. An agent using MCP tools could also have an ACDS manifest.
Plugin manifests are platform-locked. They only work within the platform that defines them. ACDS is platform-independent. Any system can read and validate an ACDS manifest.
There is no agent-level capability standard today. OpenAPI describes APIs. MCP describes tools. Plugin manifests are locked to platforms. ACDS fills the gap between "what does this agent do?" and "let me call this API."
- Agent frameworks load manifests, expose declared capabilities, validate inputs before execution.
- Orchestrators read manifests, select agents by capability, avoid failed calls.
- Marketplaces index capabilities, compare agents, display pricing.
- Enterprises review manifests, approve changes, detect dangerous capabilities.
- Fork the repo
- Create your feature branch (
git checkout -b feature/my-feature) - Make your changes
- Validate the example manifests still pass:
python cli/validate.py validate examples/*.json - Commit and push
- Open a Pull Request
MIT — see LICENSE.