Concrete CMS MCP server

Hello community!

  • Want to publish blog posts to Concrete CMS directly from Claude?
  • Want to let an AI agent suggest improvements to the content on your Concrete CMS site?

If you’ve ever thought “It would be great if AI could just talk to my CMS” –
that’s exactly what an MCP server for Concrete CMS is for.

I’ve built one and released it as open source under the MIT License :rocket:
Feel free to try it out, experiment, and see what kinds of workflows you can unlock.

Feedback, ideas, and contributions are more than welcome.
Hope it’s helpful to make your life easier!

Japanese blog post:

I used this for the first time this week.

It enabled Claude to quickly provide a long list of .htaccess redirects for an updated site when compared to the indexed pages from Google Search Console.

Lots of time saved – what a useful tool! Looking forward to exploring it further - thank you @hissy

Wow, what an impressive use case!

Hey there @hissy — I’ve been trying out the concretecms-mcp-server and hit a wall on the build (`npm run build` fails with 17 TypeScript errors out of the box). I dug in, and it came down to a few small things, so I’ve put up two PRs against MacareuxDigital/concretecms-mcp-server:

#6 — Fix dependency vulnerabilities and resync lockfile: the committed `package-lock.json` is out of sync (so `npm ci` fails), and `npm audit` flagged 10 vulnerabilities (6 high, 4 moderate). This resyncs the lockfile and clears all of them — no changes to the declared dependencies.

#7 — Fix TypeScript build (17 errors) + add CI: adds the missing `@types/node`, fixes a `toolMode` → `toolsMode` config typo, tightens the env-var typing, and adds a GitHub Actions build (Node 20 / 22 / 24) so this kind of breakage gets caught automatically.

After both, `npm ci && npm run build` are green, and `npm audit` is clean.

Credit where due — @mlocati had already spotted the stale lockfile (#1) and proposed the `node:` import prefixes (#4) back in March; my PRs build on those findings. Would love a maintainer’s eyes on these when there’s a chance. Happy to

adjust anything.

thanks for the fast response! Now onto testing!

Great news! :tada:

The Concrete CMS MCP Server now supports Streamable HTTP transport in addition to the original stdio transport.

This is an important milestone because it means the MCP server is no longer limited to local development. With Streamable HTTP, it can now be deployed as a network service, making it suitable for production environments and remote AI clients.

If you’re interested in building AI assistants, AI-powered content workflows, or MCP integrations for Concrete CMS, now is a great time to give it a try.

As always, feedback, issues, and pull requests are very welcome!

Should have checked Trivago…:rofl:

Maybe read the docs once in a while.
AI didn’t get me the right answer.

@c5dragon

If you want to use it from your local Claude Desktop, you can follow the “Connect your LLM to the local Concrete CMS MCP Server” section in the README.

Works with (mcp local + claude desktop + remote website)
Added the following in Redirect URI on the API page.

http://localhost:3000/callback

Redacted screenshot info

I’m trying to figure out how to upload files through (this) MCP.

Made (Codex made) a separate part which connects through the API directly.
Connects as user which is allowed to upload.

:+1: It seems your previous problem was related to the permission issue.

:+1: The error was misleading, and got in the wrong rabbit hole.

For future reference:
The REST controller executes this check:

if (!$fp->canAddFileType(
    $cf->getExtension($uploadedFile->getClientOriginalName())
)) {
    return $this->error(
        Importer::getErrorMessage(Importer::E_FILE_INVALID_EXTENSION),
        403
    );
}

Therefore, 403: “Invalid file extension” actually means:

The current API user is not permitted to add a .jpg file to this folder.

For this MCP the scope: files:add files:update is not enough.
It needs a user to verify against. + the actual file. Claude corrupts the file.

Maybe somethings to add later in this MCP / Or allow the api to do this without the user?

Good point, but that is a topic on the REST API side. I believe we have an issue to discuss about this, but I forgot the URL… :sweat_smile: