Adapto CMS CLI
Command-line interface for the Adapto CMS Management API.
Install
Quick install (macOS/Linux)
curl -sSL https://raw.githubusercontent.com/adaptocms/adapto-cms-cli/main/scripts/install.sh | bash
From source
go install github.com/adaptocms/adapto-cms-cli@latest
From releases
Download the binary for your platform from GitHub Releases.
Quick Start
Existing account:
adapto auth login --email you@example.com --password yourpassword
New account:
adapto auth register --email you@example.com --password yourpassword
# the activation email contains a ready-to-run command:
adapto auth activate --token <token-from-email>
adapto onboard # creates your first project + API key
Credentials are saved to ~/.config/adapto/credentials.json and read automatically. The flow is flag-driven so an agent can run it end to end; the only manual step is pasting the activation token from the email.
Manage content:
adapto articles list --json
adapto articles create --title "My Article" --content "Hello world" --slug my-article --author Jane --language en-US
LLM Integration
The CLI is built to be driven by LLM agents. One command gives an agent full knowledge of every command, flag, and workflow:
adapto llm-info
Pipe it into your agent's context (Claude Code, Cursor, MCP tools) and the agent can manage content end to end. Every command supports --json for machine-readable output.
Configuration
None needed in the common case: adapto auth login stores credentials in ~/.config/adapto/credentials.json and every command reads them from there.
For scripting and overrides:
| Variable |
Description |
ADAPTO_CLI_TOKEN |
Bearer token (overrides stored credentials) |
ADAPTO_CLI_API_URL |
Management API base URL (default: https://api.adaptocms.com) |
ADAPTO_CLI_TENANT_ID |
Tenant ID (overrides stored credentials) |
All variables can also be passed as flags: --token, --api-url, --tenant-id.
Two APIs. The CLI talks only to the Management API (api.adaptocms.com). The ADAPTO_API_URL / ADAPTO_API_KEY variables found in client site .env files configure the read-only Public API and are ignored by the CLI. Never point ADAPTO_CLI_API_URL at public-api.adaptocms.com.
Commands
adapto
├── api-key Manage Public API keys
│ ├── issue Issue a Public API key for the active project
│ ├── list List the active project's API keys
│ └── revoke [api-key-id] Revoke an API key
├── articles Manage articles
│ ├── archive <id> Archive an article
│ ├── categories <id> List categories of an article
│ ├── create Create an article
│ ├── create-translation <source_id> Create an article translation
│ ├── delete <id> Delete an article
│ ├── get <id> Get an article by ID
│ ├── get-by-slug <slug> Get an article by slug
│ ├── list List articles
│ ├── publish <id> Publish an article
│ ├── translations <id> List translations of an article
│ └── update <id> Update an article
├── auth Authentication commands
│ ├── activate Activate account and log in
│ ├── callback-github Complete GitHub OAuth callback
│ ├── change-password Change your password
│ ├── login Login with email and password
│ ├── login-github Login via GitHub OAuth
│ ├── login-google Login via Google credential
│ ├── logout Logout (revoke refresh token)
│ ├── me Get current user info
│ ├── orgs List your organizations and their tenants
│ ├── refresh Refresh access token
│ ├── register Register a new account
│ ├── request-password-reset Request a password reset email
│ ├── resend-activation Resend activation email
│ ├── reset-password Reset password with token
│ └── switch-tenant Switch active tenant/organization
├── categories Manage categories
│ ├── add-article <category_id> <article_id> Add an article to a category
│ ├── articles <category_id> List articles in a category
│ ├── create Create a category
│ ├── create-translation <source_id> Create a category translation
│ ├── delete <id> Delete a category
│ ├── get <id> Get a category by ID
│ ├── get-by-slug <slug> Get a category by slug
│ ├── list List categories
│ ├── remove-article <category_id> <article_id> Remove an article from a category
│ ├── subcategories <id> List subcategories
│ ├── translations <id> List translations of a category
│ └── update <id> Update a category
├── collections Manage custom collections
│ ├── create Create a collection
│ ├── delete <id> Delete a collection
│ ├── get <id> Get a collection by ID
│ ├── get-by-slug <slug> Get a collection by slug
│ ├── items Manage collection items
│ │ ├── archive <collection_id> <item_id> Archive a collection item
│ │ ├── create <collection_id> Create a collection item
│ │ ├── create-batch <collection_id> Create multiple items in batch
│ │ ├── create-translation <collection_id> <source_id> Create an item translation
│ │ ├── delete <collection_id> <item_id> Delete a collection item
│ │ ├── get <collection_id> <item_id> Get a collection item
│ │ ├── get-by-slug <collection_id> <slug> Get a collection item by slug
│ │ ├── list <collection_id> List items in a collection
│ │ ├── publish <collection_id> <item_id> Publish a collection item
│ │ ├── translations <collection_id> <item_id> List translations of an item
│ │ └── update <collection_id> <item_id> Update a collection item
│ ├── list List collections
│ └── update <id> Update a collection
├── files Manage files
│ ├── create-metadata Create file metadata (before upload)
│ ├── delete <id> Delete a file
│ ├── get <id> Get file info by ID
│ ├── list List files
│ ├── multipart-abort <file_id> <upload_id> Abort a multipart upload
│ ├── multipart-complete <file_id> <upload_id> Complete a multipart upload
│ ├── multipart-init <file_id> Initialize a multipart upload
│ ├── multipart-upload <file_id> <upload_id> <part_number> <filepath> Upload a part of a multipart upload
│ ├── update <id> Update file metadata
│ ├── upload <filepath> Upload a file
│ └── upload-by-id <file_id> <filepath> Upload file content for an existing file record
├── llm-info Print full CLI reference for LLM consumption
├── microcopy Manage micro copy entries
│ ├── count Count micro copy entries
│ ├── create Create a micro copy entry
│ ├── create-translation <source_id> Create a micro copy translation
│ ├── delete <id> Delete a micro copy entry
│ ├── get <id> Get micro copy by ID
│ ├── get-by-key <key> Get micro copy by key
│ ├── get-by-language <language> Get all micro copy for a language
│ ├── list List micro copy entries
│ ├── translations <id> List translations of a micro copy entry
│ └── update <id> Update a micro copy entry
├── onboard Set up your first project and API key
├── org Manage organizations
│ ├── create Create an organization
│ └── list List your organizations
├── pages Manage pages
│ ├── archive <id> Archive a page
│ ├── create Create a page
│ ├── create-translation <source_id> Create a page translation
│ ├── delete <id> Delete a page
│ ├── get <id> Get a page by ID
│ ├── get-by-slug <slug> Get a page by slug
│ ├── list List pages
│ ├── publish <id> Publish a page
│ ├── translations <id> List translations of a page
│ └── update <id> Update a page
├── project Manage projects
│ ├── create Create a project
│ ├── delete [project-id] Delete a project and all its content
│ ├── list List your projects
│ ├── update [project-id] Update a project
│ └── use [project-id] Set the active project
├── status API status commands
│ └── version Get API version info
└── version Print the CLI version
Output
By default, commands output formatted tables. Use --json for JSON output:
adapto articles list --json
adapto articles get abc123 --json
Interactive Mode
When running in a terminal (TTY), missing required parameters will be prompted interactively. When piped or in scripts, missing parameters produce an error with usage hints.
File Upload
# Single-step upload (creates metadata + uploads content)
adapto files upload ./photo.jpg
# Two-step: create metadata first, then upload by ID
adapto files create-metadata --filename photo.jpg --content-type image/jpeg
adapto files upload-by-id FILE_ID ./photo.jpg
Articles, pages, and collection items support attaching media (images, videos, embeds) via the --media-json flag on create, update, and create-translation commands:
adapto articles create \
--title "My Post" \
--content "<p>Hello</p>" \
--slug my-post \
--author "Jane" \
--language en-US \
--media-json '[{
"placement_key": "hero_image",
"media_object": {
"id": "m1",
"file_id": "FILE_ID",
"url": "https://cdn.example.com/photo.jpg",
"type": "image"
},
"alt_text": "Hero image"
}]'
Each placement object supports:
placement_key: where the media goes (e.g. hero_image, body_image_1)
media_object: id, file_id, url, type (image/video/audio/document/other/youtube/vimeo/tiktok/instagram_reel/instagram_post), title, description
caption, alt_text, meta_data: optional metadata
The same --media-json flag works on adapto pages create/update and adapto collections items create/update.
Development
Building, testing, and releasing: see DEVELOPMENT.md.
License
MIT, see LICENSE.