Skip to main content
Glama
plone

Plone MCP Server

Official
by plone

Plone MCP Server

Talk to your Plone website instead of clicking through it. Plone MCP lets AI assistants like Claude create and edit pages, publish content, search the site, and manage translations on your behalf, in plain language - no coding required to use it, and nothing to change on your Plone site to enable it.

It's built on the Model Context Protocol (MCP), an open standard that lets AI assistants safely connect to external tools and data. Plone MCP exposes Plone's REST API as a set of MCP tools, so any MCP-compatible client - Claude Desktop, Claude Code, and others - can drive your site, and developers can script, automate, or build on top of the same tools.

Quickstart

Requires Node.js 22+. Add this to Claude Desktop's config file, then restart Claude Desktop:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "plone": {
      "command": "npx",
      "args": ["-y", "@plone/mcp"]
    }
  }
}

Now ask Claude to connect to your Plone site, e.g. "Connect to https://demo.plone.org as admin/admin".

Related MCP server: optimizely-cms-mcp

Prerequisites

  • Node.js 22+ - Required to run the server (^20.19.0 || >=22.12.0; install: brew install node on macOS or from nodejs.org)

  • Plone 6.0+ site with REST API - The CMS you'll be connecting to

pnpm is only needed if you want to clone the repo and develop locally (see Local Development). The recommended setup below uses npx and doesn't require cloning anything.

Transports

The server ships two entry points:

  • STDIO (plone-mcp bin / dist/stdio-server.js) - for local MCP clients such as Claude Desktop.

  • HTTP (dist/http-server.js) - a streamable-HTTP server with per-session state, listening on PORT (default 3001) at /mcp. Start it with make start.

Quick Start using Claude Desktop as an example

The @plone/mcp package is published on npm, so there's nothing to install or build - npx fetches and runs it on demand.

  1. Configure Claude Desktop

Add to Claude's configuration file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json

  • Windows: %APPDATA%\Claude\claude_desktop_config.json

With environment variables (optional):

{
  "mcpServers": {
    "plone": {
      "command": "npx",
      "args": ["-y", "@plone/mcp"],
      "env": {
        "PLONE_BASE_URL": "https://demo.plone.org",
        "PLONE_USERNAME": "admin",
        "PLONE_PASSWORD": "admin"
      }
    }
  }
}

Without environment variables (useful if you connect to different Plone sites and prefer to pass credentials per session via plone_configure):

{
  "mcpServers": {
    "plone": {
      "command": "npx",
      "args": ["-y", "@plone/mcp"]
    }
  }
}
  1. Restart Claude Desktop

  2. Connect to Plone

Call plone_configure once per session:

// Using environment variables
plone_configure({});

// OR providing credentials/token directly to the LLM
plone_configure({
  baseUrl: "https://demo.plone.org",
  username: "admin",
  password: "admin",
});

plone_configure({
  baseUrl: "https://demo.plone.org",
  token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
});

Note: Arguments take precedence over environment variables.

Local Development

Clone the repo if you want to modify the server, debug it, or run it with the MCP Inspector:

git clone https://github.com/plone/plone-mcp.git
cd plone-mcp
make install
make build

Point Claude Desktop at your local build instead of the npx command:

{
  "mcpServers": {
    "plone": {
      "command": "node",
      "args": ["/absolute/path/to/plone-mcp/dist/index.js"]
    }
  }
}

Development commands:

# Install the dependencies
make install

# Build for production (compiles TypeScript and copies blocks.json)
make build

# Run the HTTP server / the STDIO server from the build
make start
make stdio

# Debug with the MCP Inspector
make inspector

# Tests (Vitest)
make test-all       # everything
make test           # unit tests only
make test-coverage  # with coverage

# Static checks
make lint           # ESLint over src/ and __tests__/
make format         # ESLint with --fix
make type-check     # tsc over sources and tests

Run make help to list every available target.

Core Features

  • Content Management: CRUD operations on all Plone content types

  • Block System: Create and manage Volto blocks

  • Search: Full-text search with filtering and sorting

  • Workflow: Manage publication states and transitions

  • Site Info: Access content types, vocabularies, and site configuration

Essential Tools

Tool

Description

Example

plone_configure

Connect to Plone (call once per session)

plone_configure({baseUrl, username, password}) or plone_configure({}) for env vars

plone_get_content

Get content by path

plone_get_content({path: "/news"})

plone_create_content

Create new content

plone_create_content({parentPath: "/", type: "Document", title: "Page"})

plone_update_content

Update existing content

plone_update_content({path: "/page", title: "New Title"})

plone_delete_content

Delete content

plone_delete_content({path: "/old-page"})

plone_search

Search content

plone_search({query: "news", portal_type: ["Document"]})

plone_transition_workflow

Change workflow state

plone_transition_workflow({path: "/page", transition: "publish"})

plone_get_navigation_tree

Get hierarchical site structure

plone_get_navigation_tree({root_path: "/", depth: 2})

plone_get_translation

List translations of a content item

plone_get_translation({path: "/en/my-page"})

plone_link_translation

Link existing content as a translation

plone_link_translation({path: "/en/my-page", id: "/de/meine-seite"})

plone_unlink_translation

Remove a translation link

plone_unlink_translation({path: "/en/my-page", language: "de"})

Block Management

Creating Content with Blocks

// 1. Prepare blocks (60-second TTL - meant to be used inmediatly before content creation/editing)
plone_create_blocks_layout({
  blocks: [
    {
      type: "text",
      data: { text: "Welcome to our site!" },
    },
    {
      type: "teaser",
      data: {
        href: "/about",
        title: "Learn More",
        description: "Discover what we do",
      },
    },
  ],
});

// 2. Create content (within 60 seconds), the previously prepared blocks will automatically be included in the request
plone_create_content({
  parentPath: "/",
  type: "Document",
  title: "Homepage",
});

Managing Individual Blocks

// Add a single block
plone_add_single_block({
  path: "/homepage",
  blockType: "text",
  blockData: { text: "New paragraph" },
  position: 1,
});

// Update a block
plone_update_single_block({
  path: "/homepage",
  blockId: "51176ead-7b59-402d-9412-baed46821b36", // Get ID from plone_get_content
  blockData: { text: "Updated text" },
});

// Remove a block
plone_remove_single_block({
  path: "/homepage",
  blockId: "51176ead-7b59-402d-9412-baed46821b36",
});

Available Block Types

  • text: Rich text content

  • teaser: Link preview card with image

  • __button: Call-to-action button

  • separator: Visual divider line

Use plone_get_block_schemas() to see all block types and their properties.

Common Workflows

Create and Publish a Page

// Configure connection
plone_configure({
  baseUrl: "https://mysite.com",
  username: "editor",
  password: "secret",
});

// Create with blocks
plone_create_blocks_layout({
  blocks: [{ type: "text", data: { text: "Article content..." } }],
});
plone_create_content({
  parentPath: "/news",
  type: "News Item",
  title: "Breaking News",
});

// Publish
plone_transition_workflow({
  path: "/news/breaking-news",
  transition: "publish",
});

Search and Filter

plone_search({
  query: "annual report",
  portal_type: ["Document", "File"],
  review_state: ["published"],
  sort_on: "modified",
  sort_order: "descending",
  b_size: 10,
});

Important Notes

⚠️ Prepared blocks expire after 60 seconds - Always call plone_create_blocks_layout immediately before creating/updating content.

⚠️ Configure once per session - Run plone_configure once at the start of each session before using other tools. Once configured, you can use all other tools without reconfiguring.

Troubleshooting

Issue

Solution

command not found when using npx

Make sure the args in your config use plone-mcp as the binary name (not plone-mcp-server) — this was renamed in the package.

"Plone client not configured"

Run plone_configure once at the start of your session

"Block not found"

Use plone_get_content to get valid block IDs

Connection errors

Verify Plone URL and credentials are correct

Blocks not applied

Call plone_create_blocks_layout immediately before create/update (60s TTL)

TypeScript errors during local build

Run make install to ensure all dependencies are installed

Resources

License

MIT

Install Server
A
license - permissive license
A
quality
C
maintenance

Maintenance

Maintainers
<1hResponse time
Release cycle
3Releases (12mo)
Commit activity
Issues opened vs closed

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Connect AI assistants to GitHub - manage repos, issues, PRs, and workflows through natural language.

  • Security-first WordPress MCP server. 129 tools for Claude, ChatGPT, Gemini. Free on wp.org.

  • Connect AI assistants to your GitHub-hosted Obsidian vault to seamlessly access, search, and analy…

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/plone/plone-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server