This guide explains how to validate AURA manifests to ensure they comply with the protocol specification and work correctly with AI agents.
AURA manifest validation ensures your aura.json file:
- Follows the AURA v1.0 specification
- Has valid structure with all required fields
- Works with AI agents effectively
- Adheres to RFC 6570 (URI Templates) and RFC 6901 (JSON Pointer)
# Install AURA protocol package
npm install aura-protocol
# Validate local manifest
npx -y -p aura-protocol aura-validate .well-known/aura.json
# Note: Remote URL validation (--url) is currently disabled.
# Download the manifest first, then validate locally:
curl -fsSL https://example.com/.well-known/aura.json -o aura.json
npx -y -p aura-protocol aura-validate aura.json
# Detailed validation
npx -y -p aura-protocol aura-validate --verbose .well-known/aura.json
# Machine-readable output
npx -y -p aura-protocol aura-validate --json .well-known/aura.jsonimport Ajv from 'ajv';
import addFormats from 'ajv-formats';
import { AuraManifest } from 'aura-protocol';
// Setup validator
const ajv = new Ajv({ allErrors: true, strict: false });
addFormats(ajv);
const validate = ajv.compile(schema);
function validateManifest(manifest: any): { valid: boolean; errors: any[] } {
const valid = validate(manifest);
return { valid, errors: validate.errors || [] };
}Required Fields:
-
$schema: Schema URL (usehttps://unpkg.com/aura-protocol@1.0.5/dist/aura-v1.0.schema.jsonor bundled schema) -
protocol: Must be"AURA" -
version: Must be"1.0" -
site: Site information object -
resources: Resources dictionary (can be empty) -
capabilities: Capabilities dictionary (can be empty)
Site Object:
-
name: Site name (string) -
url: Canonical site URL (valid URI) -
description: Optional site description (string)
Each resource must have:
-
uriPattern: Valid RFC 6570 URI Template -
description: Descriptive and clear -
operations: Maps HTTP methods to valid capability IDs - All referenced
capabilityIds exist in capabilities section
Each capability must have:
-
id: Unique identifier -
v: Positive integer version number -
description: Explains what the capability does -
action: Valid HttpAction -
parameters: Valid JSON Schema (if present)
-
type: Exactly"HTTP" -
method: Valid HTTP method (GET, POST, PUT, DELETE) -
urlTemplate: Valid RFC 6570 URI Template -
parameterMapping: Uses valid JSON Pointer syntax - Parameter mappings reference fields in
parametersschema - URI template variables match parameter mapping keys
{
"error": "Missing required property: version",
"path": "/"
}Solution:
{
"$schema": "https://unpkg.com/aura-protocol@1.0.5/dist/aura-v1.0.schema.json",
"protocol": "AURA",
"version": "1.0"
}{
"error": "Invalid URI template: /api/posts/{id",
"path": "/capabilities/read_post/action/urlTemplate"
}Solution:
{
"urlTemplate": "/api/posts/{id}" // Fixed: added closing brace
}{
"error": "Invalid JSON Pointer: #/id",
"path": "/capabilities/read_post/action/parameterMapping/id"
}Solution:
{
"parameterMapping": {
"id": "/id" // Fixed: starts with /
}
}{
"error": "Undefined capability reference: create_post",
"path": "/resources/posts/operations/POST/capabilityId"
}Solution: Add the missing capability:
{
"capabilities": {
"create_post": {
"id": "create_post",
"v": 1,
"description": "Create a new post"
}
}
}{
"error": "Parameter mapping 'title' not found in parameters schema"
}Solution: Ensure mappings match schema:
{
"parameters": {
"type": "object",
"properties": {
"title": { "type": "string" }
}
},
"action": {
"parameterMapping": {
"title": "/title"
}
}
}import { describe, it, expect } from 'vitest';
import { validateManifest } from '../src/validation';
describe('Manifest Validation', () => {
it('should validate complete manifest', () => {
const validManifest = { /* valid manifest structure */ };
expect(validateManifest(validManifest).valid).toBe(true);
});
it('should reject invalid manifests', () => {
const invalidManifest = { protocol: 'AURA' }; // Missing required fields
const result = validateManifest(invalidManifest);
expect(result.valid).toBe(false);
expect(result.errors.length).toBeGreaterThan(0);
});
});# .github/workflows/validate-manifest.yml
name: Validate AURA Manifest
on: [push, pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- name: Install dependencies
run: npm install aura-protocol
- name: Validate manifest
run: |
npx -y -p aura-protocol aura-validate public/.well-known/aura.json
npx -y -p aura-protocol aura-validate --verbose public/.well-known/aura.jsonimport { parseTemplate } from 'url-template';
function validateUriTemplate(template: string): { valid: boolean; error?: string } {
try {
const parsed = parseTemplate(template);
// Test expansion with sample data
const expanded = parsed.expand({
id: 'test',
limit: 10,
tags: ['tag1', 'tag2']
});
return { valid: true };
} catch (error) {
return {
valid: false,
error: `Invalid URI template: ${error.message}`
};
}
}function validateJsonPointer(pointer: string): { valid: boolean; error?: string } {
if (!pointer.startsWith('/')) {
return {
valid: false,
error: 'JSON Pointer must start with /'
};
}
const segments = pointer.split('/').slice(1);
for (const segment of segments) {
if (segment.includes('~') && !segment.match(/~[01]/)) {
return {
valid: false,
error: 'Invalid escape sequence in JSON Pointer'
};
}
}
return { valid: true };
}interface ValidationRule {
name: string;
check: (manifest: AuraManifest) => ValidationError[];
}
const customRules: ValidationRule[] = [
{
name: 'capability-naming',
check: (manifest) => {
const errors: ValidationError[] = [];
Object.keys(manifest.capabilities).forEach(capId => {
if (!capId.match(/^[a-z][a-z0-9_]*$/)) {
errors.push({
rule: 'capability-naming',
path: `/capabilities/${capId}`,
message: 'Capability IDs should use snake_case',
severity: 'warning'
});
}
});
return errors;
}
}
];- Development: Validate on every save
- Testing: Include validation in test suite
- CI/CD: Validate before deployment
- Production: Monitor manifest accessibility
function formatValidationError(error: any): string {
const location = error.instancePath || 'root';
const field = error.schemaPath?.split('/').pop() || 'unknown';
return `${location}: ${error.message} (${field})`;
}function checkVersionCompatibility(manifest: AuraManifest): boolean {
const supportedVersions = ['1.0'];
return supportedVersions.includes(manifest.version);
}Proper manifest validation ensures your AURA implementation works reliably with AI agents and follows protocol standards. Use these tools and techniques to catch errors early and maintain quality across deployments.