PHPackages                             kaufmanndigital/neos-mcp - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. kaufmanndigital/neos-mcp

ActiveNeos-package[API Development](/categories/api)

kaufmanndigital/neos-mcp
========================

Neos MCP Server — exposes Neos Content Repository actions via Model Context Protocol

1.0.1(1mo ago)020↓100%GPL-3.0-or-laterPHPPHP &gt;=8.1

Since Mar 16Pushed 1mo agoCompare

[ Source](https://github.com/KaufmannDigital/KaufmannDigital.MCP)[ Packagist](https://packagist.org/packages/kaufmanndigital/neos-mcp)[ Docs](https://github.com/KaufmannDigital/KaufmannDigital.MCP)[ RSS](/packages/kaufmanndigital-neos-mcp/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (2)Dependencies (2)Versions (3)Used By (0)

KaufmannDigital.MCP — Neos MCP Server
=====================================

[](#kaufmanndigitalmcp--neos-mcp-server)

> **⚠ Work in Progress**This package is experimental and under active development. It is not recommended for production use. APIs and tool signatures may change without notice. Use at your own risk.

A [Model Context Protocol](https://modelcontextprotocol.io/) server for Neos CMS. Allows AI assistants (Claude Code, Codex, etc.) to directly access and manipulate the Neos Content Repository via a simple HTTP+JSON-RPC interface.

**USE WITH CAUTION!!!**

> **Giving an AI direct access to your CR could end in absolute chaos. Know what AI is doing and double-check everything, before allowing AI to do changes. Be sure to have Backups available!**

---

Prerequisites
-------------

[](#prerequisites)

- **Neos CMS** 7.x or 8.x
- **Flowpack.ElasticSearch.ContentRepositoryAdaptor** — required for `search_nodes` and `find_by_property`
- PHP 8.1+

---

Security Considerations
-----------------------

[](#security-considerations)

> **Read this section before deploying.**

- **The API token (and IP-Filter) is the only access control.** Anyone who obtains the token has full read/write access to your Neos content repository, including the ability to create, update, and publish nodes.
- **Use a strong, randomly generated token** (at minimum 32 characters). Never commit it to version control.
- **The `upload_asset` tool accepts local filesystem paths.** If enabled, a token holder can import any file readable by the web server process (e.g. config files). Restrict access to trusted users only.
- **All write operations bypass Flow's authorization checks** (`withoutAuthorizationChecks`). This is intentional for AI-driven automation, but means no Neos backend role restrictions apply.
- **Only expose the `/mcp` endpoint in development environments** or behind a firewall. Do not expose it on a public production server.
- **Use HTTP only within ddev/localhost.** If you expose the endpoint over a network, use HTTPS to protect the token in transit.

---

Installation
------------

[](#installation)

```
composer require kaufmanndigital/mcp
```

---

Configuration
-------------

[](#configuration)

**1. Set the API token and optionally restrict access by IP** in `Configuration/Development/Settings.yaml` (never `Settings.yaml` — to keep it out of version control):

```
KaufmannDigital:
  MCP:
    Token: 'your-strong-random-token-here'
    allowedIps:
      - '127.0.0.1'       # localhost IPv4
      - '::1'             # localhost IPv6
      - '172.16.0.0/12'   # Docker bridge (ddev, docker-compose, ...)
      - '1.2.3.4'         # your office IP
```

> **`allowedIps` is required — an empty list blocks all requests (deny by default).**Supports exact IPs and CIDR notation for both IPv4 and IPv6.
>
> **Note on ddev:** Requests from the host arrive at PHP with a Docker bridge IP (`172.x.x.x`), not your machine's actual IP. The `172.16.0.0/12` CIDR covers the entire Docker bridge range and is the recommended way to allow local ddev access.

**2. Configure MCP (example for Claude Code)** (`~/.claude.json`):

```
{
  "mcpServers": {
    "neos": {
      "type": "http",
      "url": "https:///mcp",
      "headers": { "X-Api-Token": "your-strong-random-token-here" }
    }
  }
}
```

> **Note:** Use HTTP (not HTTPS) when connecting from Claude Code via ddev — ddev's self-signed certificates are not trusted by Bun's HTTP client.

---

Tools
-----

[](#tools)

### `get_node`

[](#get_node)

Loads a single node by its UUID.

ParameterTypeRequiredDescription`nodeIdentifier`string✓Node UUID`workspaceName`stringWorkspace (default: `live`)`includeChildren`booleanInclude direct child nodes (default: `false`)`responseProperties`arrayFields to return (default: `identifier` only)---

### `search_nodes`

[](#search_nodes)

Full-text search across all nodes via Elasticsearch.

ParameterTypeRequiredDescription`query`stringSearch term (optional if `nodeType` is set)`nodeType`stringFilter by node type, e.g. `Neos.Neos:Document``workspaceName`stringWorkspace (default: `live`)`limit`integerMax results (default: `10`)`responseProperties`arrayFields to return (default: `identifier` only)---

### `find_by_property`

[](#find_by_property)

Finds nodes with an exact property value match via Elasticsearch.

ParameterTypeRequiredDescription`propertyName`string✓Property name to match`propertyValue`any✓Exact value to search for`nodeType`stringFilter by node type (optional)`workspaceName`stringWorkspace (default: `live`)`limit`integerMax results (default: `10`)`responseProperties`arrayFields to return (default: `identifier` only)---

### `get_children`

[](#get_children)

Returns direct child nodes of a given node.

ParameterTypeRequiredDescription`nodeIdentifier`string✓Parent node UUID`nodeTypeFilter`stringNode type filter, e.g. `Neos.Neos:Document``workspaceName`stringWorkspace (default: `live`)`responseProperties`arrayFields to return (default: `identifier` only)---

### `create_node`

[](#create_node)

Creates a new node under a given parent node.

ParameterTypeRequiredDescription`parentNodeIdentifier`string✓Parent node UUID`nodeType`string✓Node type name, e.g. `Neos.Neos:Document``properties`objectKey/value map of properties to set`workspaceName`stringWorkspace (default: `live`)`responseProperties`arrayFields to return (default: `identifier` only)---

### `update_property`

[](#update_property)

Sets a single property on a node.

ParameterTypeRequiredDescription`nodeIdentifier`string✓Node UUID`propertyName`string✓Property name`propertyValue`any✓New value`workspaceName`string✓Workspace to write to`responseProperties`arrayFields to return (default: `identifier` only)---

### `batch_update_property`

[](#batch_update_property)

Sets properties on multiple nodes in a single call.

ParameterTypeRequiredDescription`nodes`array✓List of `{nodeIdentifier, properties}` objects`workspaceName`string✓Workspace to write to`responseProperties`arrayFields per node (default: `identifier` only)---

### `publish_nodes`

[](#publish_nodes)

Publishes nodes from a user workspace to the base workspace (usually `live`).

ParameterTypeRequiredDescription`nodeIdentifiers`array✓UUIDs of nodes to publish`workspaceName`string✓Source workspace`responseProperties`arrayFields per node (default: `identifier` only)---

### `upload_asset`

[](#upload_asset)

Imports a file into the Neos media library from a URL or a local absolute path.

> **Security note:** Local path access is restricted to the directory configured via `localImportBasePath` in `Settings.yaml` (default: `Data/MCP-Import`). Files outside that directory are rejected.

ParameterTypeRequiredDescription`url`string✓URL or absolute local path (e.g. `/var/www/html/images/file.jpg`)`filename`stringOriginal filename — required when using a local path`title`stringTitle/label for the asset in the media library`tag`stringTag to assign (created if it does not exist)---

responseProperties — Minimizing token costs
-------------------------------------------

[](#responseproperties--minimizing-token-costs)

All tools return **only the `identifier` by default**. Use `responseProperties` to request additional fields — keeping this minimal significantly reduces AI context usage.

**Available values:**

- Node properties: any property name defined on the node type, e.g. `"title"`, `"releaseDate"`, `"uriPathSegment"`
- Meta fields: `"nodeType"`, `"label"`, `"name"`, `"path"`, `"workspace"`, `"hidden"`

**Examples:**

```
// Search: request title and date for identification
"responseProperties": ["title", "releaseDate"]

// After write operations: omit responseProperties entirely — only identifier is needed
```

---

Architecture
------------

[](#architecture)

```
McpController
  └── McpHandler          JSON-RPC dispatcher
        └── Tool/*        One class per operation (Flow Singletons)
              └── NodeSerializer   Shared node serialization

```

- **Write tools** bypass Flow's authorization via `SecurityContext::withoutAuthorizationChecks()`
- **Asset resolution:** UUID strings are automatically resolved to Asset objects (`EntityManager::find(Asset::class, $uuid)`)
- **DateTime resolution:** ISO-8601 strings are automatically converted to `DateTime` objects
- **ElasticSearchQueryBuilder** is prototype-scoped — always instantiate via `$objectManager->get()` for a fresh instance per call

---

Maintainer
----------

[](#maintainer)

This package is maintained by the [Neos Agency Kaufmann Digital](https://www.kaufmann.digital).
Feel free to send us your questions or requests to

### Issues and Pull-Requests are welcome!

[](#issues-and-pull-requests-are-welcome)

You got stuck while installing or configuring? You are missing something? You found a bug?
No problem, just create an issue or open a pull request. We'll have a look at it ASAP.

License
-------

[](#license)

Licensed under GPL-3, see [LICENSE](LICENSE)

###  Health Score

39

—

LowBetter than 86% of packages

Maintenance89

Actively maintained with recent releases

Popularity9

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity43

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

2

Last Release

56d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/1ec6c2ae665e40ee04396a70c824f37be27b5f98330b66c18256ebd21dfb52b5?d=identicon)[kaufmanndigital](/maintainers/kaufmanndigital)

---

Top Contributors

[![Nikdro](https://avatars.githubusercontent.com/u/9807101?v=4)](https://github.com/Nikdro "Nikdro (6 commits)")

### Embed Badge

![Health badge](/badges/kaufmanndigital-neos-mcp/health.svg)

```
[![Health](https://phpackages.com/badges/kaufmanndigital-neos-mcp/health.svg)](https://phpackages.com/packages/kaufmanndigital-neos-mcp)
```

###  Alternatives

[twilio/sdk

A PHP wrapper for Twilio's API

1.6k92.9M272](/packages/twilio-sdk)[knplabs/github-api

GitHub API v3 client

2.2k15.8M187](/packages/knplabs-github-api)[facebook/php-business-sdk

PHP SDK for Facebook Business

90121.9M34](/packages/facebook-php-business-sdk)[meilisearch/meilisearch-php

PHP wrapper for the Meilisearch API

73813.7M114](/packages/meilisearch-meilisearch-php)[google/common-protos

Google API Common Protos for PHP

173103.7M50](/packages/google-common-protos)[hubspot/api-client

Hubspot API client

23414.2M16](/packages/hubspot-api-client)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
