Skip to main content
This guide walks you through building a minimal Agent Application package from scratch. By the end, you’ll have a working package with a conformant APP.md, a CLI that returns JSON, and a local skill. The agentic-to-do example in the repository is a full reference implementation of these same patterns.

Conformance checklist

A v1-conformant package requires:
  • APP.md present
  • app/ directory present
  • skills/ directory present
  • A documented CLI entrypoint
  • JSON output by default
The steps below satisfy all five requirements.
1

Create the package directory

Create a folder for your package. Give it a name that matches the slug you’ll use in APP.md.
mkdir my-app
cd my-app
Create the required top-level directories:
mkdir app
mkdir -p skills/my-app-usage
Your package root now looks like this:
my-app/
├── app/
└── skills/
    └── my-app-usage/
2

Write the APP.md manifest

Create APP.md at the package root. Start with the YAML frontmatter, then add the body sections that document your CLI contract.
APP.md
---
schema: agentapplications/v1
kind: app
slug: my-app
name: My App
description: A minimal Agent Applications v1 package
version: 0.1.0
entry:
  command: node app/cli.js
commands:
  - greet
skills:
  - my-app-usage
scheduling: notSupported
---

# My App

## Purpose

My App is a minimal Agent Applications v1 example.

## CLI

- Entrypoint: `node app/cli.js`
- Default output: JSON on stdout

## Commands

### `greet [--name <text>]`

Returns a greeting. Defaults to `"world"` if no name is provided.

## Output

Successful commands return structured JSON:

\`\`\`json
{
  "ok": true,
  "command": "greet",
  "message": "Hello, world!"
}
\`\`\`

## State

This application is stateless.

## Skills

Load `skills/my-app-usage/SKILL.md` for concise operating guidance.
The entry.command value is whatever CLI command your runtime should invoke. It can be a binary, a shell command, or a script runner like node app/cli.js — as long as calling it produces JSON on stdout.
Key frontmatter fields:
FieldRequiredDescription
entry.commandYesThe callable CLI entrypoint
commandsYesList of supported command names
skillsYesList of local skill shortnames
schedulingNosupported or notSupported
confirmationRequiredNoCommands that need explicit user confirmation
3

Create the CLI inside app/

Add a CLI script at app/cli.js. The CLI must write JSON to stdout by default and exit with a non-zero code on failure.
app/cli.js
#!/usr/bin/env node

const [,, command, ...args] = process.argv;

function respond(data) {
  process.stdout.write(JSON.stringify(data, null, 2) + '\n');
}

function fail(code, message) {
  respond({ ok: false, error: { code, message } });
  process.exit(1);
}

if (command === 'greet') {
  const nameFlag = args.indexOf('--name');
  const name = nameFlag !== -1 ? args[nameFlag + 1] : 'world';

  if (!name) {
    fail('MISSING_VALUE', '--name requires a value.');
  }

  respond({
    ok: true,
    command: 'greet',
    message: `Hello, ${name}!`
  });
} else {
  fail('UNKNOWN_COMMAND', `Unknown command: ${command}`);
}
Test it locally:
node app/cli.js greet
node app/cli.js greet --name Alice
You should see JSON on stdout:
{
  "ok": true,
  "command": "greet",
  "message": "Hello, world!"
}
Human-readable output is allowed but must be opt-in (for example, a --human flag). JSON must be the default.
4

Create a SKILL.md in skills/

Create skills/my-app-usage/SKILL.md. The skill shortname in APP.mdmy-app-usage — resolves to this path by convention.
skills/my-app-usage/SKILL.md
---
name: my-app-usage
description: Operate my-app safely through its JSON-first CLI
---

# My App Usage

Use this skill when you need to interact with my-app through its CLI.

## Entry command

Run the app from the package root:

\`\`\`bash
node app/cli.js <command> [...args]
\`\`\`

## Safe operating rules

1. Expect JSON on stdout by default.
2. Treat non-zero exit codes as failures and read the structured `error` payload.

## Common commands

\`\`\`bash
node app/cli.js greet
node app/cli.js greet --name Alice
\`\`\`
SKILL.md files follow the Agent Skills format. Agent Applications does not redefine SKILL.md — it references the same format.
5

Verify conformance

Check that your package meets all five v1 conformance requirements.1. Required files and directories exist:
ls APP.md app/ skills/
2. The entry command runs and returns JSON:
node app/cli.js greet
Expected output:
{
  "ok": true,
  "command": "greet",
  "message": "Hello, world!"
}
3. The CLI exits non-zero on failure:
node app/cli.js unknown-command; echo "Exit code: $?"
Expected output:
{
  "ok": false,
  "error": {
    "code": "UNKNOWN_COMMAND",
    "message": "Unknown command: unknown-command"
  }
}
Exit code: 1
4. Your final package structure:
my-app/
├── APP.md
├── app/
│   └── cli.js
└── skills/
    └── my-app-usage/
        └── SKILL.md
Your package is now v1-conformant.

Next steps

Package structure

Learn what each part of the package is responsible for.

APP.md reference

See all supported frontmatter fields and body sections.

Authoring best practices

Write packages that stay portable, legible, and testable.

Example app

Explore the full agentic-to-do reference package.