Skip to main content

cascade-cms-rest-mcp

A local, read-only MCP server exposing a Hannon Hill Cascade CMS server to MCP clients (Claude Desktop, Claude Code, etc.), built on top of cascade-cms-rest.

Seven tools, all read-only — no tool in this server can perform a write operation, even indirectly:

Tool Purpose
cascade_search Search a site for assets by text
cascade_read_asset Read a single asset by id or by site+path
cascade_query_asset A narrowed read of one part of any asset, by path query — works on any asset shape, not just data-bound ones
cascade_get_data_structure A data-bound asset's field schema, resolved from its bound content type/data definition
cascade_get_page_config A data-bound asset's page configuration names/regions
cascade_root_container_id The root container id (e.g. Data Definitions folder) for an asset type on a site
cascade_list_sites List every site on the server

cascade_query_asset exists because cascade_read_asset's concise mode only collapses top-level fields, and its only narrowing hints are two page/content-type-specific field names (structuredData, pageConfigurations) — every other shape (metadata sets in particular, whose nested layout varies per metadata set definition) otherwise has no narrowed-read option short of format="detailed" dumping the entire payload. cascade_query_asset takes a small, safe path-query string — parsed via Python's ast module (never eval'd) — such as metadata.dynamicFields[0].value, metadata["dynamicFields"][0], a "*" wildcard over a list/dict, or find("identifier") to search the whole asset for a key by name at any depth — and returns only the matched sub-value(s), each tagged with its resolved path for a follow-up query.

cascade_get_data_structure and cascade_get_page_config are schema-authoritative: they resolve field/group/config names from the asset's bound content type or data definition, not by sampling the one asset instance you point them at — so the result is the full schema-valid set, not just whatever happens to be populated on that instance.

This is a different, easily-confused thing from the library's Asset.get_data_structure() method (used inside generated scripts, not by this server) — that one is instance/leaf-only. See the skill's references/asset_api.md for that distinction, and note that this server is read-only by design: writing structured data still goes through the skill's script-writing path (see its callback-structured-data-edit.py template).

Known limitation

resolve_data_definition() (src/cascade_cms_rest_mcp/resolution.py) resolves a data-bound asset's data definition two ways: via contentTypeId → contentType.dataDefinitionId (confirmed against a real payload), and via a direct dataDefinitionId field on the asset itself (present in the code as a fallback, but not yet confirmed against any real fixture — harmless no-op if the field is absent). If you hit a data-bound asset where resolution fails unexpectedly, this direct-field path is the first thing to check.

Configuration

Required environment variables (same names CascadeWrapperBase already expects — no new credential-naming surface):

Variable Required Purpose
CASCADE_API_KEY Yes Cascade API key
CASCADE_URL Yes e.g. https://your-cascade-host:8443
SERVER No Cosmetic — log-file naming, defaults to default
CASCADE_MCP_LOG_DIR No Overrides the default ~/.local/state/cascade-cms-mcp/logs log directory

The server fails fast at startup (not on first tool call) if CASCADE_API_KEY or CASCADE_URL is missing.

Client configuration

Install from PyPI (pip install cascade-cms-rest-mcp) or run it directly with uvx — no local checkout needed — then point your MCP client at it:

{
  "mcpServers": {
    "cascade-cms": {
      "command": "uvx",
      "args": ["cascade-cms-rest-mcp"],
      "env": {
        "CASCADE_API_KEY": "...",
        "CASCADE_URL": "https://your-cascade-host:8443"
      }
    }
  }
}

To run against a local checkout of this repo instead of the published package (e.g. testing an unreleased change), use uvx --from ./mcp cascade-cms-rest-mcp or point args at ["--from", "/path/to/cascade-cms-tools/mcp", "cascade-cms-rest-mcp"].

Development

pip install -e "./mcp[dev]"   # from the repo root
pytest
ruff check .
mypy mcp/src/

tests/smoke_test.py is a manual, human-run script against a real dev Cascade site (not collected by pytest) — see its own docstring.

Metadata

Release files for cascade-cms-rest-mcp 0.4.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cascade-cms-rest-mcp 0.4.3
File Size Uploaded Provenance Actions
cascade_cms_rest_mcp-0.4.3.tar.gz 38.6 kB With provenance Details for cascade_cms_rest_mcp-0.4.3.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for cascade-cms-rest-mcp 0.4.3
File Interpreter ABI Platform Actions
cascade_cms_rest_mcp-0.4.3-py3-none-any.whl Python 3 none any Details for cascade_cms_rest_mcp-0.4.3-py3-none-any.whl

Total release size: 65.4 kB

Release files / cascade_cms_rest_mcp-0.4.3.tar.gz

Download URL cascade_cms_rest_mcp-0.4.3.tar.gz
Size 38.6 kB
Tags Source
SHA-256 checksum
How to use checksums
99585be7ee550f4d50f59610980d98a3126115d9ef2cd07a23d840e794e791f0
BLAKE2b-256 checksum
How to use checksums
4d470da60408dfde5690a53a673dff356c9da42a26169a9483831dc25fae35c6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 30, 2026.

Transparency log

Release files / cascade_cms_rest_mcp-0.4.3-py3-none-any.whl

Download URL cascade_cms_rest_mcp-0.4.3-py3-none-any.whl
Size 26.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
19f7451f396caab98240bfa094baf0c8873774f62014821dba7a2e69e54dc001
BLAKE2b-256 checksum
How to use checksums
660fbf586dcbed50017544999a6a069588f356acf96adf61cacbc4f5a25e1712
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 30, 2026.

Transparency log

Security for cascade-cms-rest-mcp 0.4.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for cascade_cms_rest_mcp-0.4.3.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 30, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page