Skip to content

CLI Commands Since 3.5.0

The tcms CLI tool is the command-line interface to Total CMS. It exposes core CMS services as composable terminal commands, designed for both AI coding agents and human developers.

Terminal window
php resources/bin/tcms <command> [options] [arguments]

All commands support a --json flag that outputs valid JSON to stdout. This is the contract AI agents rely on — no decorative output, no progress bars, no color codes.

OptionDescription
--jsonOutput as JSON (for AI agent compatibility)
-vVerbose output
-qQuiet mode (errors only)
-h, --helpDisplay help for a command
-V, --versionDisplay version

Show site status, version, edition, license, collection count, and cache backend.

Terminal window
tcms info
tcms info --json

JSON output:

{
"version": "3.2.2",
"build": "7f080a63",
"edition": "pro",
"license": { "valid": true, "trial": false, "trialDaysRemaining": null },
"domain": "example.com",
"collections": { "total": 12 },
"schemas": { "reserved": 22, "custom": 4 },
"cache": { "backend": "apcu" }
}

List all schemas.

Terminal window
tcms schema:list
tcms schema:list --custom
tcms schema:list --reserved
tcms schema:list --category=Commerce
tcms schema:list --json
OptionDescription
--customOnly show custom schemas
--reservedOnly show reserved (built-in) schemas
--categoryFilter by category

Show full schema definition including properties, types, and field configurations.

Terminal window
tcms schema:get blog
tcms schema:get blog --json
ArgumentRequiredDescription
idYesSchema ID

Export a schema to a JSON file.

Terminal window
tcms schema:export blog --output=blog-schema.json
tcms schema:export blog
ArgumentRequiredDescription
idYesSchema ID
OptionDescription
--output, -oOutput file path (omit for stdout)

Import a schema from a JSON file. Creates or updates the schema.

Terminal window
tcms schema:import my-schema.json
tcms schema:import my-schema.json --json
ArgumentRequiredDescription
fileYesPath to schema JSON file

List all collections with their schema and object count.

Terminal window
tcms collection:list
tcms collection:list --schema=blog
tcms collection:list --category=Content
tcms collection:list --json
OptionDescription
--schemaFilter by schema type
--categoryFilter by category

Show collection metadata including schema, sort order, and object count.

Terminal window
tcms collection:get blog
tcms collection:get blog --json
ArgumentRequiredDescription
idYesCollection ID

Query a collection’s index with filtering, searching, sorting, and pagination.

Terminal window
tcms collection:query posts --search="photography" --limit=5
tcms collection:query posts --include="featured:true" --sort="-date"
tcms collection:query posts --exclude="draft:true" --limit=10 --offset=20
tcms collection:query posts --filter="title:drone" --json
ArgumentRequiredDescription
idYesCollection ID
OptionDescription
--search, -sFull-text search query
--filterContains filter (field:value)
--includeInclude filter (field:value,field:value)
--excludeExclude filter (field:value,field:value)
--sortSort by property (prefix with - for descending)
--limit, -lMaximum results (default: 20)
--offset, -oNumber of results to skip (default: 0)

JSON output:

{
"total": 37,
"offset": 0,
"limit": 5,
"results": [...]
}

Export a collection to JSON, CSV, or ZIP.

Terminal window
tcms collection:export blog --output=blog.json
tcms collection:export blog --format=csv --output=blog.csv
tcms collection:export blog --format=zip --output=blog-backup.zip
ArgumentRequiredDescription
idYesCollection ID
OptionDescription
--format, -fExport format: json, csv, or zip (default: json)
--output, -oOutput file path (omit for stdout; zip generates a default filename)

The zip format includes all object JSON files and their associated media/assets. JSON export uses streaming for large collections when --output is specified.

Import objects into a collection from a JSON or CSV file.

Terminal window
tcms collection:import blog posts.json
tcms collection:import blog data.csv
tcms collection:import blog posts.json --update
tcms collection:import blog posts.json --format=json --json
ArgumentRequiredDescription
idYesCollection ID
fileYesPath to JSON or CSV file
OptionDescription
--format, -fImport format: json or csv (auto-detected from extension)
--updateUpdate existing objects instead of skipping

List object IDs in a collection.

Terminal window
tcms object:list blog
tcms object:list blog --limit=10 --offset=20
tcms object:list blog --json
ArgumentRequiredDescription
collectionYesCollection ID
OptionDescription
--limit, -lMaximum results
--offset, -oNumber of results to skip

Fetch a single object with all its properties.

Terminal window
tcms object:get blog my-post
tcms object:get blog my-post --json
ArgumentRequiredDescription
collectionYesCollection ID
idYesObject ID

Export a single object as JSON or ZIP (with assets).

Terminal window
tcms object:export blog my-post --output=my-post.json
tcms object:export blog my-post --format=zip --output=my-post.zip
tcms object:export blog my-post
ArgumentRequiredDescription
collectionYesCollection ID
idYesObject ID
OptionDescription
--format, -fExport format: json or zip (default: json)
--output, -oOutput file path (omit for stdout; zip generates a default filename)

Delete a single object. The deletion goes through the same index-aware path as the admin UI, so the collection’s .index.json and object count stay consistent — unlike removing the flat file by hand, which leaves them stale.

Terminal window
tcms object:delete blog my-post
tcms object:delete blog my-post --force
ArgumentRequiredDescription
collectionYesCollection ID
idYesObject ID
OptionDescription
--force, -fSkip the confirmation prompt (required for non-interactive/CI use)

Import items into a deck property from a JSON or CSV file.

Terminal window
tcms deck:import invoices inv-001 items line-items.json
tcms deck:import invoices inv-001 items line-items.csv --update
ArgumentRequiredDescription
collectionYesCollection ID
objectYesObject ID
propertyYesDeck property name
fileYesPath to JSON or CSV file
OptionDescription
--format, -fImport format: json or csv (auto-detected from extension)
--updateUpdate existing deck items instead of skipping

Queue every entry from an RSS, Atom, or JSON feed into a target collection. The CLI counterpart to the Utilities → Import RSS admin page. Designed for cron — the admin form has a “Schedule with cron” panel that builds the exact command line for the configured import so operators can paste it directly into crontab.

Terminal window
# Basic import — auto field mapping, items queued as drafts
tcms rss:import https://example.com/feed.xml blog
# Publish immediately
tcms rss:import https://example.com/feed.xml blog --no-draft
# Drain the queue in the same cron run
tcms rss:import https://example.com/feed.xml blog && tcms jobs:process
ArgumentRequiredDescription
urlYesRSS / Atom / JSON Feed URL
collectionYesTarget collection ID
OptionDescription
--draft / --no-draftQueue items as drafts (default) or publish immediately
--map, -mField mapping in the form feedField=collectionField. Repeat the option or comma-separate within one value. See below.
--jsonOutput JSON (success status + count)

The importer maps these eight feed-side fields to your collection’s properties:

Feed fieldDefault collection property
titletitle
contentcontent
summarysummary
datedate
authorauthor
categoriescategories
linkmedia
imageimage

To override a default mapping, pass --map feedField=collectionProperty. To drop a field entirely (don’t write it to the object), map it to an empty string with --map feedField=.

Terminal window
# Map the feed's `title` into your schema's `heading` property,
# and the feed's `content` into your schema's `body` property.
tcms rss:import https://example.com/feed.xml blog \
--map title=heading \
--map content=body
# Same thing, comma-separated single argument (handy in crontab one-liners).
tcms rss:import https://example.com/feed.xml blog --map "title=heading,content=body"
# Drop the link/categories fields entirely; remap the rest.
tcms rss:import https://example.com/feed.xml news \
--map title=headline \
--map content=body \
--map image=hero \
--map link= \
--map categories=
# Realistic news-import recipe targeting a schema with
# `heading`, `body`, `excerpt`, `published`, `byline`, `tags`, `hero`.
tcms rss:import https://example.com/feed.xml news --no-draft \
--map title=heading \
--map content=body \
--map summary=excerpt \
--map date=published \
--map author=byline \
--map categories=tags \
--map image=hero
# Hourly RSS pull — drain the queue right after queuing
0 * * * * /usr/local/bin/php /var/www/site/resources/bin/tcms rss:import "https://example.com/feed.xml" blog --no-draft --map "title=heading,content=body" && /usr/local/bin/php /var/www/site/resources/bin/tcms jobs:process

The admin UI’s “Schedule with cron” panel under Utilities → Import RSS prints this command for you with your site’s PHP and install paths already filled in — open the panel, copy, paste into crontab.


Export all site data (schemas, collections, objects, templates) as a JumpStart file.

Terminal window
tcms jumpstart:export --output=my-site.json
tcms jumpstart:export --name="My Site" --description="Full site export"
tcms jumpstart:export --json
OptionDescription
--nameName for the export
--descriptionDescription for the export
--output, -oOutput file path (generates default filename if omitted)

Import a JumpStart file to set up schemas, collections, objects, and templates.

Terminal window
tcms jumpstart:import my-site.json
tcms jumpstart:import my-site.json --json
ArgumentRequiredDescription
fileYesPath to JumpStart JSON file

Push and pull schemas and templates between a local development instance and a production server. Configure the production server URL and API key in Settings > Sync in the admin dashboard.

Push schemas and templates to the production server.

Terminal window
tcms push
tcms push --dry-run
tcms push --schemas=blog,products
tcms push --templates=blog-post,sidebar
tcms push --schemas=blog --templates=blog-post --dry-run
OptionDescription
--schemasComma-separated schema IDs to push (default: all custom)
--templatesComma-separated template IDs to push (default: all custom)
--dry-runPreview what would be pushed without sending

Pull schemas and templates from the production server.

Terminal window
tcms pull
tcms pull --dry-run
tcms pull --schemas=blog
tcms pull --templates=blog-post,sidebar
OptionDescription
--schemasComma-separated schema IDs to pull (default: all)
--templatesComma-separated template IDs to pull (default: all)
--dry-runPreview what would be pulled without applying

What gets synced: Custom schemas and custom templates only.

What never gets synced: Content/objects, media/images, system settings, API keys, reserved schemas.


Clear all caches. When run from CLI, a signal file is written so the web process clears its APCu cache on the next request.

Terminal window
tcms cache:clear
tcms cache:clear --json

Process the pending job queue. This is typically run via cron.

Terminal window
tcms jobs:process
tcms jobs:process -v
tcms jobs:process --memory=1G
tcms jobs:process --json
OptionDescription
--memory, -mMemory limit (default: 512M)
-vVerbose output with per-job details

Cron setup:

Terminal window
* * * * * php /path/to/resources/bin/tcms jobs:process

Fire due scheduled automations. Runs on its own cron line, parallel to jobs:process, so a large import backlog in the job queue never delays a time-sensitive scheduled automation. Single-flight locked, so overlapping cron ticks can’t double-fire the same run.

Terminal window
tcms automations:process
tcms automations:process --json

Webhook and event triggers do not depend on this command — webhooks fire on HTTP request and events fire when the originating write happens; their async runs are drained on the next tick.

Cron setup (add this as a second line, alongside jobs:process):

Terminal window
* * * * * php /path/to/resources/bin/tcms automations:process

Rebuild a collection’s .index.json and totalObjects count from the objects on disk. Use this when the index has drifted from the actual files — for example after an object’s flat file was added or removed out-of-band. (search:reindex only touches the search provider; repair:files only rebuilds file/image metadata.)

Terminal window
tcms repair:index blog
tcms repair:index --all
ArgumentRequiredDescription
collectionNoCollection ID (omit and use --all to rebuild every collection)
OptionDescription
--allRebuild the index for every collection

Check for available updates from the license server.

Terminal window
tcms update:check
tcms update:check --json

JSON output:

{
"current": "3.2.2",
"available": true,
"version": "3.5.0",
"releaseDate": "2026-04-10",
"severity": "minor",
"changelog": "New features and improvements",
"downloadUrl": "/version/download/3.5.0"
}

Download and apply an available update. The site enters maintenance mode during the swap.

Terminal window
tcms update:apply
tcms update:apply --force
tcms update:apply --json
OptionDescription
--forceSkip confirmation prompt

The previous version is backed up automatically for rollback.

Roll back to the previous version after a failed or unwanted update.

Terminal window
tcms update:rollback
tcms update:rollback --force
OptionDescription
--forceSkip confirmation prompt

Restores the backup directory created during the most recent update.


List all discovered extensions with their status.

Terminal window
tcms extension:list
tcms extension:list --json

JSON output:

[
{
"id": "acme/seo-pro",
"name": "SEO Pro",
"version": "1.2.0",
"enabled": true,
"error": null
}
]

Enable a discovered extension.

Terminal window
tcms extension:enable acme/seo-pro
tcms extension:enable acme/seo-pro --json
ArgumentRequiredDescription
idYesExtension ID (e.g. vendor/extension-name)

Disable an extension without removing it.

Terminal window
tcms extension:disable acme/seo-pro
tcms extension:disable acme/seo-pro --json
ArgumentRequiredDescription
idYesExtension ID (e.g. vendor/extension-name)

Remove an extension’s files. Extension data in tcms-data is preserved.

Terminal window
tcms extension:remove acme/seo-pro
tcms extension:remove acme/seo-pro --force
ArgumentRequiredDescription
idYesExtension ID (e.g. vendor/extension-name)
OptionDescription
--force, -fSkip confirmation prompt