The Total CMS plugin for the three AI plugin directories:
- Claude — Anthropic's directory (claude.ai, the desktop and mobile apps, Cowork, and Claude Code), which reads the plugin straight from this repo
- OpenAI — the directory shared by ChatGPT and Codex, which takes a ZIP upload
- Cursor — Cursor's marketplace, which reads the plugin from this repo
All three get the same plugin: a read-only connection to the public Total CMS
documentation server at https://totalcms.co/mcp, and the Total CMS agent
skill. The MCP server itself is the Total CMS docs extension running on
totalcms.co; changes to its tools reach every directory without a new plugin
version.
This repo holds no Total CMS code. Core is proprietary and is never part of a plugin; the plugin is only manifests, a server URL, a logo and the skill text.
- ChatGPT (approved 2026-10-22): https://chatgpt.com/plugins/plugin_asdk_app_6abdb19953248191932b75de95b06dbd
- Claude (approved): the directory has no public page per listing. Users find it by searching for "Total CMS" in the directory inside Claude, so link to the plugin by name rather than by URL.
.cursor-plugin/marketplace.json # points Cursor at package/
package/ # the plugin folder, shared by all three directories
.claude-plugin/plugin.json # Claude manifest
.codex-plugin/plugin.json # OpenAI manifest: listing, review test cases, demo URL, release notes
.cursor-plugin/plugin.json # Cursor manifest
.mcp.json # the one MCP server: https://totalcms.co/mcp
skills/totalcms/ # synced from core's resources/skill — don't edit here
assets/logo.png # square icon (1024×1024)
README.md # user-facing: Claude shows it as the listing description
LICENSE # Claude requires one in the plugin folder
bin/
build.sh # sync skill → validate → dist/totalcms-openai-plugin-<version>.zip
validate.py # every directory's submission requirements
review/
tool-justifications.md # OpenAI annotation justifications, paste-ready
.mcp.json carries "type": "http" because Claude requires it; the build drops
it from the OpenAI ZIP, whose Codex format doesn't use it. The OpenAI ZIP also
leaves out the Claude and Cursor manifests, README, and LICENSE.
Cursor's default MCP file is mcp.json, so its manifest names ./.mcp.json
explicitly. It finds the skill in skills/ on its own.
Keep the plugin name as totalcms in all three manifests — it's the listing's
identity in both directories.
bin/build.shThe skill is copied from ../totalcms/resources/skill (set TOTALCMS_CORE for
another checkout), so build from a core checkout on the release you want the
skill to describe. With Claude Code installed, the build also runs
claude plugin validate.
Commit the synced skill: Claude installs the plugin from this repo, not from a build.
Claude's directory follows a branch or tag of this repo and publishes each new
commit on it after scanning it. Point the listing at a release tag, not
master, so a commit only reaches users when it's tagged.
- Bump
versioninpackage/.claude-plugin/plugin.json— users stay on a version until it changes. - Run
bin/build.sh, commit, and push. - Tag the release and push the tag.
- Follow the scan in the developer portal at https://claude.ai/directory/manage.
The first submission is made from that portal: Submit new → Plugin bundle,
repository totalcms/totalcms-plugins, plugin folder package.
- Edit
package/.codex-plugin/plugin.json: bumpversion, updateextensions.com.openai.publication.release_notes, and re-check the test cases against the live server. - Run
bin/build.sh. - At https://platform.openai.com/plugins, open Total CMS → Upload plugin
and choose the ZIP from
dist/. - Resolve anything under Metadata & Skills → Issues detected, confirm the imported demo recording URL in Review details, then Submit for review.
- Once approved, choose Publish plugin.
Test cases and the demo recording URL (review.demo_recording_url) are imported
from the ZIP and read-only in the dashboard — change them here and upload again.
The dashboard refuses to submit without the demo URL in the package.
The manifests version independently; each directory has its own release history.
Cursor reads this repo and reviews each update by hand before publishing it.
- Bump
versioninpackage/.cursor-plugin/plugin.json. - Run
bin/build.sh, commit, and push. - Test locally: copy
package/to~/.cursor/plugins/local/totalcms, run Developer: Reload Window, and confirm the skill and MCP server both load. - First listing: apply at https://cursor.com/marketplace/publish. After that, send Cursor a re-index request instead of a new application.
The repo must stay public and open source: Cursor requires both. The application
form's logo is assets/logo-plate.png, because Cursor asks for a 1:1 image on a
background plate. It's kept outside package/ so it doesn't ship in any plugin.
The MCP server is also listed on its own in Claude's directory as a connector
(Submit new → MCP connector, URL https://totalcms.co/mcp). It isn't part
of this repo; the plugin's .mcp.json points at the same URL so the two
listings can be paired.
What the connector receives and returns is covered by the Total CMS privacy
policy: https://totalcms.co/privacy (see "AI connector"). Keep that policy in
step with what https://totalcms.co/mcp exposes anonymously — OpenAI rejected the
first plugin because the connector returned customer names the policy didn't
disclose (see CHANGELOG). OAuth must stay off on totalcms.co: with OAuth
discoverable, both directories try to make users sign in.