Concrete CMS MCP Server
This server acts as an interface between AI agents/LLMs and Concrete CMS, enabling programmatic management of sites via its REST API.
Core capabilities:
Account & System: Retrieve account details and system info.
Pages: List, get, create, update, delete, and traverse child pages; include attributes, areas, files, and content.
Page Content Helpers: Read page as sanitized HTML, raw HTML, and plain text; safely update content by creating new versions and remapping block IDs.
Page Versions: List, get, update (approve, set publish end date), and delete specific versions.
Blocks: Add, update, delete blocks in areas, find/delete by ID.
Files: List, upload, update, delete, move files with metadata.
Users: List, get, create, update, delete, change passwords, manage attributes.
Groups: List, get, create user groups.
Sites: List sites, get by ID or default site.
Extensibility: Custom OpenAPI specs allow additional endpoints.
Deployment: Install locally for Claude Desktop or remotely via systemd/Docker; OAuth2 auth with token encryption.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Concrete CMS MCP Server show me the page tree"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Concrete CMS MCP Server
A Model Context Protocol (MCP) server for Concrete CMS built with TypeScript.

Installation
Enable API in Concrete CMS
Since the MCP server uses the Concrete CMS API, you need to enable it in your Concrete CMS installation first. The Concrete CMS documentation provides an introduction to the REST API and to its configuration.
When you create the API Integration in Concrete CMS (System & Settings > API > Integrations), you have to set the Redirect URI to the address where the MCP server receives the OAuth callback.
If you run the MCP server locally (for example with Claude Desktop, or with the prebuilt .mcpb extension), the redirect URI is:
http://localhost:3000/callback3000 is the default port: if you customize it with the HTTP_PORT setting, adjust the redirect URI accordingly.
If you instead run the MCP server remotely (HTTP transport), the redirect URI is ${PUBLIC_BASE_URL}/oauth/callback — see the Remote MCP Server Guide for the details.
Take note of the resulting Client ID and Client Secret: you'll need them when configuring the MCP server (see Settings below).
Install the MCP Server
Via a prebuilt extension
The easiest way to use the Concrete CMS MCP Server with Claude Desktop is to install the prebuilt .mcpb extension:
Go to the Releases page and download the latest
concretecms-mcp-server.mcpbfile.In Claude Desktop, navigate to Settings > Extensions.
Click Advanced settings.
In the Extension Developer section, click the Install Extension button and select the downloaded
concretecms-mcp-server.mcpbfile.
Claude Desktop will then ask you for the configuration (Concrete CMS URL, API client ID and secret, and scopes). See Settings below for what to enter.
From source
You have to clone this repo and compile it:
git clone https://github.com/concrete5-community/concretecms-mcp-server.git
cd concretecms-mcp-server
npm ci && npm run buildIf you use Claude Desktop:
Navigate to Settings > Extensions
Click Advanced settings
In the Extension Developer section, click Install Unpacked Extension
Choose the
concretecms-mcp-serverdirectory
You can also add this MCP server via JSON. For example:
{
"mcpServers": {
"concretecms": {
"command": "node",
"args": ["/path/to/concretecms-mcp-server/dist/index.js"],
"env": {
"CONCRETE_CANONICAL_URL": "https://your-concrete.example",
"CONCRETE_API_CLIENT_ID": "YOUR_API_CLIENT_ID",
"CONCRETE_API_CLIENT_SECRET": "YOUR_API_CLIENT_SECRET",
"CONCRETE_API_SCOPE": "account:read system:info:read"
}
}
}
}This uses the standard mcpServers format understood by most MCP clients (Claude Desktop, Cursor, Cline, and others).
It goes in that client's MCP configuration file; if the file already defines other servers, add concretecms as another entry under mcpServers rather than replacing the whole object.
The exact file and its location depend on the client — check the client's documentation.
For Claude Desktop, open it via Settings > Developer > Edit Config (this creates the file if it does not exist yet), or edit claude_desktop_config.json directly (%APPDATA%\Claude\ on Windows, ~/Library/Application Support/Claude/ on macOS).
Restart the client after saving.
Related MCP server: WordPress MCP Server
Usage
Settings
Set
CONCRETE_CANONICAL_URLto the URL of your Concrete CMS installation.Set
CONCRETE_API_CLIENT_IDandCONCRETE_API_CLIENT_SECRETto the credentials of a registered API integration.Set
CONCRETE_API_SCOPEto the scopes you want to request. You can find a list of available scopes fromhttps://your-concrete.example/index.php/dashboard/system/api/scopes.
After you've configured the MCP server, please restart Claude Desktop. On the first tool call, it will open an authorization window — sign in and authorize the requested scopes.
Now you should be able to get information about your Concrete CMS in a chat. A refresh token will be saved under ~/.concretecms-mcp/tokens/<site>/local.tokens.json (one directory per CONCRETE_CANONICAL_URL), so you don't need to sign in again.
Use separate MCP server entries in Claude Desktop for each Concrete CMS site — each site's tokens are stored independently.
Optionally set TOKEN_ENCRYPTION_KEY in the env block to encrypt tokens at rest. See the Security Guide for details.
For more information about local MCP servers, please refer to the Claude Desktop documentation.
Security
OAuth refresh tokens are stored on disk under ~/.concretecms-mcp/tokens/<site>/ by default (namespaced per CONCRETE_CANONICAL_URL). See the Security Guide for the threat model, chmod 600 behavior, encryption, cleanup commands, and remote deployment guidance.
Run as a remote MCP server
To host the MCP server on a remote Linux server, see the Remote MCP Server Guide.
It covers systemd deployment, reverse proxy setup, OAuth configuration, and Docker as an alternative.
To connect a local desktop client (ChatGPT Streamable HTTP, Claude Desktop via mcp-remote, or another remote MCP client) to that server, see Connect Local MCP Clients to a Remote Server.
For developers: build an MCP client or AI agent
If you are building a programmatic MCP client or AI agent (backend service, web app with chat UI, or Concrete CMS package) that connects to a remote MCP server over HTTP, see the MCP Client Developer Guide.
It covers the HTTP API, per-user OAuth, agent loops, and implementation patterns. For end-user desktop apps talking to a remote server, see docs/local-clients.md. For local stdio Claude Desktop, use the section above.
Use your own OpenAPI specification
The MCP server is loading openapi.yml to know which endpoints are available in the Concrete CMS API.
The bundled openapi.yml file is generated from the Concrete CMS default installation, but you can also use your own OpenAPI specification.
If you added some Express Objects to your Concrete CMS installation and want to use them in your chat, you can generate a new OpenAPI specification from your installation and use it instead.
Check "Include this entity in REST API integrations." in the Express Object settings.
Open
https://your-concrete.example/index.php/ccm/system/api/openapi.jsonin your browser, and copy the JSON output.Replace the
openapi.ymlfile in theconcretecms-mcp-serverdirectory with your own OpenAPI specification.
Features
This MCP server is depended on the Concrete CMS API, so it supports all features that are available through the API. For example:
Get information about your Concrete CMS installation.
Get content from your Concrete CMS installation.
Update content in your Concrete CMS installation.
Upload files to your Concrete CMS installation.
Get a list of users in your Concrete CMS installation.
And more!
You can find a list of all available endpoints in Concrete CMS REST API - Endpoints
High-level page tools
In addition to OpenAPI-generated tools, the server exposes helpers for common page workflows:
get_page_content— read a page as a document (html,html_raw, and plaintext) viaincludes=contentupdate_page_content— create an editable page version, remap block IDs, then update specific blocks (PUT page + PUT area)
Prefer these when reviewing or editing page copy. Use the raw OpenAPI tools (getPageById, updateBlockInPageArea, etc.) for lower-level control.
Required OAuth scopes for the update helper: pages:read, pages:update, pages:areas:update_blocks.
ToDos
Test with other MCP clients.
Add useful prompts.
Support another authentication method than OAuth2.
License
MIT
Available Tools
37 toolsadd-block-to-page-areaDDestructive
Adds a block to a page area.
Inputs: pageID (required), areaHandle (required), type, value.
add-fileDDestructive
Adds a file object.
Inputs: file, folder.
add-groupCDestructive
Adds a Group object.
Inputs: name.
add-pageCDestructive
Adds a page object.
Inputs: name, type, parent, template, +2 more.
add-userDDestructive
Adds a user object.
Inputs: email, language, password, username.
change-user-passwordCDestructive
Change a user's password
Inputs: userID (required), password.
delete-block-by-idCDestructive
Delete a block by its ID
Inputs: blockID (required).
delete-block-from-page-areaCDestructive
Deletes a block from a page area.
Inputs: pageID (required), blockID (required), areaHandle (required).
delete-file-by-idCDestructive
Delete a file by its ID
Inputs: no named parameters.
delete-page-by-idCDestructive
Delete a page by its ID
Inputs: pageID (required).
delete-page-version-by-page-id-and-version-idCDestructive
Delete a page version.
Inputs: pageID (required), versionID (required).
delete-user-by-idCDestructive
Delete a user by its ID
Inputs: userID (required).
get-accountCRead-only
Make a GET request to /ccm/api/1.0/account
Inputs: no named parameters.
get-block-by-idCRead-only
Find a block by its ID
Inputs: blockID (required), includes.
get-child-pagesARead-only
Allows the traversal of the sitemap by showing child pages of a particular page.
Inputs: pageID (required), includes.
get-default-siteBRead-only
Retrieve the default site for your Concrete installation
Inputs: includes.
get-file-by-idCRead-only
Find a file by its ID
Inputs: includes.
get-filesBRead-only
Returns a list of file objects, sorted by last updated descending. The most recent file objects appear first.
Inputs: limit, includes.
get-group-by-idBRead-only
Find a user group by its ID
Inputs: groupID (required).
get-groupsBRead-only
Returns a list of Group objects, sorted by ID ascending.
Inputs: after, limit.
get-page-by-idCRead-only
Find a page by its ID
Inputs: pageID (required), version, includes.
get_page_contentARead-only
Review a Concrete CMS page as a document. Returns sanitized HTML, raw HTML, and plain text. Prefer this over getPageById with includes=content when summarizing or reading page copy. Does not return areas/blocks.
Inputs: pageID (required), version.
get-pagesBRead-only
Returns a list of page objects, sorted by last updated descending. The most recent Page objects appear first.
Inputs: after, limit, includes.
get-page-version-by-page-id-and-version-idCRead-only
Find a page version by its ID and the ID of its page.
Inputs: pageID (required), versionID (required).
get-page-versions-by-page-idARead-only
Returns a list of page version objects for a given page ID, sorted by date created descending.
Inputs: pageID (required), limit, resultsPage.
get-site-by-idCRead-only
Find a site by its ID
Inputs: siteID (required).
get-sitesBRead-only
Returns a list of site objects, sorted by date added ascending.
Inputs: includes.
get-system-infoCRead-only
Make a GET request to /ccm/api/1.0/system/info
Inputs: no named parameters.
get-user-by-idCRead-only
Find a user by its ID
Inputs: userID (required), includes.
get-usersBRead-only
Returns a list of user objects, sorted by date added descending. The most recent user objects appear first.
Inputs: after, limit, includes.
move-file-to-locationCDestructive
Move a file to a new location
Inputs: folder.
update-block-in-page-areaCDestructive
Updates a block within a page area.
Inputs: pageID (required), blockID (required), areaHandle (required), value.
update-file-by-idDDestructive
Update a file by its ID
Inputs: tags, title, attributes, description.
update-page-by-idCDestructive
Update a page by its ID
Inputs: pageID (required), name, type, template, +2 more.
update_page_contentADestructive
Update page block content safely. Creates a new editable page version (PUT page), remaps block IDs, then updates each block (PUT area). Provide blockID values from the version you inspected. Does not approve the new version.
Inputs: blocks (required), pageID (required), page.
update-page-version-by-page-id-and-version-idDDestructive
Update a page version
Inputs: pageID (required), versionID (required), is_approved, publish_end_date.
update-user-by-idCDestructive
Update a user by its ID
Inputs: userID (required), email, language, username, +1 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 37 tools
Most tools map cleanly to a single resource+action (file, page, user, group, site, block, page version), and the content tools explicitly warn against using get-page-by-id for reading copy. However, there are two block delete tools (delete-block-from-page-area vs delete-block-by-id) with no guidance on which to use, and update-page-by-id vs update_page_content overlap in intent, as do get-page-by-id (with content includes) and get_page_content.
The dominant convention is kebab-case verb_noun (add-file, get-users, delete-page-by-id), which is readable and predictable. But two tools break it with snake_case (get_page_content, update_page_content), and a few tools lack the resource suffix pattern (get-account, get-system-info), so the set is mixed.
37 tools is heavy for a single CMS surface and well above the comfortable 3-15 range. While the resources are real, the page/block/page-version cluster in particular has accumulated many near-adjacent operations that inflate the surface.
Files, pages, users, blocks, and page versions all have solid create/read/update/delete lifecycles, including content read/write and sitemap traversal. Gaps remain: groups have add/get/list but no update or delete, and sites are entirely read-only (get-sites, get-site-by-id, get-default-site with no create/update/delete).
Maintenance
Related MCP Connectors
Manage your WordPress site from your AI assistant: posts, pages, media, comments and WooCommerce.
Manage WordPress blogs and WooCommerce shops from Claude, ChatGPT, Cursor and other MCP apps.
Manage FireCMS Cloud from an AI agent: Firestore data, collections, schemas and users.
Lets your AI build and edit websites in Xodia, a visual website builder for real code (Vite, React, Tailwind CSS or plain HTML in your own git repo): read and write site files, create pages and CMS collections, run typecheck, design and link checks, take screenshots, manage forms and translations, and pick up change requests the user sends from the visual editor. Sign in once with your Xodia account (OAuth). Free plan, no card needed. Setup: https://xodia.ai/ai/mcp
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to interact with WordPress sites through the REST API. Supports multiple WordPress sites with secure authentication, enabling content management, post operations, and site configuration through natural language.34 npmMIT
- AlicenseAqualityDmaintenanceEnables AI assistants to manage WordPress sites through natural conversation, supporting post creation, content updates, site queries, and draft-to-publish workflows via the WordPress REST API.9MIT
- FlicenseBqualityDmaintenanceEnables interaction with Frappe and ERPNext sites through their REST API endpoints. It supports standard HTTP methods for performing CRUD operations and managing site data using natural language.12-
- AlicenseNot gradedqualityBmaintenanceEnables interaction with WordPress sites through the WordPress REST API via natural language, supporting single and multi-site management, content and taxonomy operations, media uploads, and more.154 npm99GPL 3.0