silverstripe-mcp
Click on "Install 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., "@silverstripe-mcpValidate this PHP code for Silverstripe 6 compatibility"
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.
Silverstripe MCP Server
A Model Context Protocol server that provides real-time validation feedback when AI assistants generate Silverstripe 6 PHP code. Catches common migration issues from Silverstripe 5 to 6 before they reach your codebase.
Documentation: Architecture | Agent Instructions Setup
The Problem
When using AI coding assistants like Claude Code with Silverstripe 6 projects, they often generate code with outdated patterns:
// AI generates this (SS5 style):
use SilverStripe\ORM\ArrayList;
use SilverStripe\View\ArrayData;
class MyTask extends BuildTask {
public function run(HTTPRequest $request) {
echo "Processing...";
}
}This MCP server catches these issues immediately, allowing the AI to self-correct:
// After validation, AI generates this (SS6 style):
use SilverStripe\Model\List\ArrayList;
use SilverStripe\Model\ArrayData;
class MyTask extends BuildTask {
protected static string $commandName = 'my-task';
protected function execute(InputInterface $input, PolyOutput $output): int {
$output->writeln('Processing...');
return Command::SUCCESS;
}
}How It Works
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ AI generates │────▶│ MCP validates │────▶│ AI fixes and │
│ PHP code │ │ against SS6 │ │ re-validates │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│
▼
┌─────────────────┐
│ PHP Analyzer │
│ (AST-based) │
└─────────────────┘
│
┌───────────┴───────────┐
▼ ▼
┌─────────────┐ ┌─────────────┐
│ Namespace │ │ BuildTask │
│ Validator │ │ Validator │
└─────────────┘ └─────────────┘The server exposes an ss-validator tool that:
Parses PHP code into an Abstract Syntax Tree (AST)
Runs plugin-based validators against the code
Returns issues with line numbers and suggested fixes
The AI iterates until no issues remain
Quick Start
Installation
git clone https://github.com/sandervanscheepen/silverstripe-mcp
cd silverstripe-mcp
# Install dependencies
npm install
cd php && composer install && cd ..
# Build
npm run buildThen add to your MCP client (e.g., Claude Code):
claude mcp add silverstripe-mcp -- node /path/to/silverstripe-mcp/dist/index.jsOr add to your MCP client configuration file:
{
"mcpServers": {
"silverstripe": {
"command": "node",
"args": ["/path/to/silverstripe-mcp/dist/index.js"]
}
}
}Agent Instructions Setup
To get the most out of this MCP server, add instructions to your AI agent's project instructions file (e.g., CLAUDE.md, .cursorrules, .github/copilot-instructions.md) that tell it to use the ss-validator tool on all generated PHP code. See Recommended Agent Instructions for full, minimal, and project-specific templates you can copy into your project.
Built-in Validators
Namespace Validator
Detects outdated Silverstripe 5 imports and suggests their Silverstripe 6 equivalents:
SS5 Namespace | SS6 Namespace |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
BuildTask Validator
Detects old BuildTask patterns that need migration to PolyCommand:
Issue | Detection | Suggestion |
Deprecated method signature |
|
|
Missing command name | No |
|
Output via echo |
|
|
Output via print |
|
|
FormField Value Validator
Detects usage of FormField::Value() which was split into three methods in SS6:
// Detects this:
$value = $field->Value();
// Suggests using one of:
$value = $field->dataValue(); // Raw data value
$value = $field->presentedValue(); // Value for display
$value = $field->processedValue(); // Value after form processingRemoved Method Validator
Detects calls to methods that were removed in Silverstripe 6:
Removed Method | Suggestion |
| Use |
| Use |
| Use |
| Use |
| Use Injector configuration instead |
Deprecated Config API (deprecated-config)
Detects usage of the deprecated Config::inst()->get() pattern:
// Detects this:
$value = Config::inst()->get('SilverStripe\CMS\Model\SiteTree', 'allowed_children');
// Suggests this:
$value = SiteTree::config()->get('allowed_children');Context-Aware Validators
The following validators auto-enable based on code context, minimizing overhead when analyzing code that doesn't need them:
Extension Hook Visibility (extension-hook-visibility)
Auto-enabled when: Class extends Extension, DataExtension, or SiteTreeExtension
SS6 changed many extension hook methods to protected. Detects public hooks in Extension classes:
class MyExtension extends DataExtension {
// Detects: should be protected
public function onBeforeWrite() { }
public function updateCMSFields($fields) { }
}Configurable prefixes: onBefore, onAfter, update, augment (add more via additionalPrefixes).
Elemental Namespace (elemental-namespace)
Auto-enabled when: Any import starts with DNADesign\Elemental
For projects using dnadesign/silverstripe-elemental. Detects namespace changes in Elemental 6:
SS5 Namespace | SS6 Namespace |
|
|
|
|
|
|
|
|
Also detects removed classes (GraphQL, ElementalLeftAndMainExtension, etc.).
Forcing All Plugins
To force-enable all validators regardless of context:
Via config (silverstripe-mcp.json):
{
"enableAllPlugins": true
}Via tool argument:
{
"code": "<?php ...",
"enableAllPlugins": true
}You can also explicitly enable individual auto-plugins to always run:
{
"plugins": {
"elemental-namespace": {
"enabled": true,
"additionalMappings": {
"Custom\\Old\\Class": "Custom\\New\\Class"
}
}
}
}Configuration
Create silverstripe-mcp.json in your project root to customize behavior:
{
"phpBinary": "/path/to/php",
"targetVersion": "6.0",
"plugins": {
"namespace-validator": {
"enabled": true,
"additionalMappings": {
"App\\Legacy\\MyClass": "App\\Modern\\MyClass"
}
},
"buildtask-validator": {
"enabled": true
},
"deprecated-config": {
"enabled": true
},
"extension-hook-visibility": {
"enabled": true,
"additionalPrefixes": ["can", "provide"]
}
},
"customPlugins": [
"./my-plugins/CustomValidator.php"
]
}See silverstripe-mcp.example.json for a complete example.
Configuration Options
Option | Type | Description |
|
| Path to PHP 8.3+ executable (auto-detected if not specified) |
|
| Silverstripe version to validate against (default: |
|
| Force-enable all plugins including context-aware ones (default: |
|
| Per-plugin configuration |
|
| Enable/disable a specific plugin |
|
| Custom namespace migrations |
|
| Paths to custom validator plugins |
PHP Binary Resolution
The server requires PHP 8.3+ (Silverstripe 6's minimum version). It resolves the PHP binary in this order:
Config file:
phpBinaryinsilverstripe-mcp.jsonEnvironment variable:
PHP_BINARY(if version >= 8.3)Auto-detect: Common locations (Laragon, XAMPP, Homebrew, system paths)
System PHP: Falls back to
phpcommand (if version >= 8.3)
If your system PHP is below 8.3, specify the path in your config:
{
"phpBinary": "C:/laragon/bin/php/php-8.3.22-Win32-vs16-x64/php.exe"
}Or set the PHP_BINARY environment variable in your MCP client config:
{
"mcpServers": {
"silverstripe": {
"command": "node",
"args": ["/path/to/silverstripe-mcp/dist/index.js"],
"env": {
"PHP_BINARY": "/usr/local/bin/php8.3"
}
}
}
}Writing Custom Plugins
Create a PHP class implementing ValidatorPluginInterface:
<?php
namespace MyOrg\MCPPlugins;
use SilverstripeMCP\Contracts\ValidatorPluginInterface;
use SilverstripeMCP\AnalysisContext;
use SilverstripeMCP\Issue;
use PhpParser\NodeVisitorAbstract;
use PhpParser\Node;
class DeprecatedMethodPlugin implements ValidatorPluginInterface
{
public function getName(): string
{
return 'deprecated-method-validator';
}
public function getDescription(): string
{
return 'Detects usage of deprecated methods';
}
public function getTargetVersions(): array
{
return ['6.*']; // Applies to all SS6.x versions
}
public function configure(array $options): void
{
// Handle configuration options
}
public function getVisitor(AnalysisContext $context): \PhpParser\NodeVisitor
{
return new class($context) extends NodeVisitorAbstract {
public function __construct(private AnalysisContext $context) {}
public function enterNode(Node $node): ?int
{
// Detect deprecated method calls
if ($node instanceof Node\Expr\MethodCall) {
$methodName = $node->name->toString();
if ($methodName === 'deprecatedMethod') {
$this->context->addIssue(new Issue(
type: 'deprecated_method',
message: 'deprecatedMethod() is deprecated in SS6',
line: $node->getLine(),
suggestion: 'Use newMethod() instead',
docsUrl: 'https://docs.silverstripe.org/...'
));
}
}
return null;
}
};
}
}
// Return the class name for auto-loading
return DeprecatedMethodPlugin::class;Register in your configuration:
{
"customPlugins": [
"./plugins/DeprecatedMethodPlugin.php"
],
"plugins": {
"deprecated-method-validator": {
"enabled": true
}
}
}Testing
The project includes comprehensive test suites for both PHP and TypeScript:
# Run PHP tests (PHPUnit)
cd php && composer test
# Run TypeScript tests (Vitest)
npm test
# Run all tests
npm run test:all
# Watch mode for development
npm run test:watchProject Structure
silverstripe-mcp/
├── src/ # TypeScript MCP server
│ ├── index.ts # Entry point, stdio transport
│ ├── tools/
│ │ └── ss-validator.ts # Main validation tool
│ └── lib/
│ └── php-bridge.ts # PHP subprocess communication
│
├── php/ # PHP analyzer
│ ├── bin/
│ │ └── analyze # CLI entry point
│ ├── src/
│ │ ├── AnalyzerRunner.php # Plugin orchestration
│ │ ├── AnalysisContext.php # Shared analysis state
│ │ ├── Issue.php # Issue data structure
│ │ ├── Contracts/
│ │ │ └── ValidatorPluginInterface.php
│ │ ├── Plugins/ # Validator plugins
│ │ │ ├── NamespaceValidatorPlugin.php (core)
│ │ │ ├── BuildTaskValidatorPlugin.php (core)
│ │ │ ├── FormFieldValuePlugin.php (core)
│ │ │ ├── RemovedMethodPlugin.php (core)
│ │ │ ├── HookRenamePlugin.php (core)
│ │ │ ├── DeprecatedConfigPlugin.php (core)
│ │ │ ├── ExtensionHookVisibilityPlugin.php (auto: Extension classes)
│ │ │ └── ElementalNamespacePlugin.php (auto: Elemental imports)
│ │ └── Config/
│ │ ├── namespace-mappings.php
│ │ ├── removed-methods.php
│ │ ├── hook-renames.php
│ │ └── elemental-mappings.php
│ └── tests/ # PHPUnit tests
│
├── tests/ # Vitest tests
│ ├── php-bridge.test.ts
│ ├── ss-validator.test.ts
│ └── fixtures/
│
├── docs/
│ ├── architecture.md # Technical architecture
│ └── recommended-agent-instructions.md # Setup for AI agents
├── silverstripe-mcp.example.json # Example configuration
├── CLAUDE.md # Development instructions
└── README.mdDevelopment
# Build and watch for changes
npm run dev
# Test PHP analyzer directly
cd php && php bin/analyze '{"code": "<?php use SilverStripe\\ORM\\ArrayList;"}'
# Example output:
{
"issues": [{
"type": "deprecated_import",
"message": "'SilverStripe\\ORM\\ArrayList' has moved to 'SilverStripe\\Model\\List\\ArrayList' in Silverstripe 6",
"line": 1,
"suggestion": "use SilverStripe\\Model\\List\\ArrayList;",
"docsUrl": "https://docs.silverstripe.org/en/6/changelogs/6.0.0/#renamed-classes"
}],
"suggestions": [],
"rerun": true
}See CONTRIBUTING.md for detailed development instructions.
Requirements
Node.js 18.0 or higher
PHP 8.3 or higher
Composer for PHP dependency management
Contributing
Contributions are welcome! See CONTRIBUTING.md for development setup, architecture details, and testing guidelines.
Credits
Inspired by the Svelte MCP server which provides similar functionality for Svelte 5
Built with nikic/php-parser for robust AST analysis
Uses the Model Context Protocol specification
License
MIT License - see LICENSE for details.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
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/sandervanscheepen/silverstripe-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server