balatd / typo3-dev-mcp
AI development helper for TYPO3 v13/v14 — an MCP server exposing TCA, database schema, sites, TypoScript, logs and the core changelog to Claude Code and other MCP clients. Inspired by laravel/boost.
Package info
github.com/balatD/typo3-dev-mcp
Type:typo3-cms-extension
pkg:composer/balatd/typo3-dev-mcp
Requires
- php: ^8.2
- mcp/sdk: ^0.7
- typo3/cms-core: ^13.4 || ^14.0
Requires (Dev)
- friendsoftypo3/content-blocks: ^1.6 || ^2.4
- phpstan/phpstan: ^2.0
- phpunit/phpunit: ^11.0
- typo3/coding-standards: ^0.8
- typo3/testing-framework: ^9.0 || ^10.0
This package is auto-updated.
Last update: 2026-08-12 15:02:11 UTC
README
typo3-dev-mcp gives Claude Code (and any MCP client) live insight into your TYPO3
v13/v14 installation: instead of guessing versions, TCA columns, CTypes or config keys
from files, the AI reads them from the running application. Inspired by
laravel/boost.
Development-only tooling. Do not install or enable in production.
Status: alpha — verified live against TYPO3 13.4 and 14.3, but APIs and tool output formats may still change between releases.
Does it actually help?
Measured, not asserted. 170 benchmark runs on claude-opus-5 against a real TYPO3 13.4
installation, comparing a plain Claude Code session against the same session after
devmcp:install:
| Task family | Baseline | With typo3-dev-mcp |
|---|---|---|
| Live-state questions (TCA, compiled TypoScript, FlexForm, site sets) | $0.208 · 10 turns | $0.097 · 4 turns |
| Code changes | $0.236 · 13 turns | $0.212 · 13 turns |
| Debugging a seeded fault | $0.164 · 8 turns · 7% hallucination | $0.205 · 9 turns · 0% hallucination |
| Control (pure refactoring, no live state) | $0.107 · 5.5 turns | $0.088 · 4 turns |
On questions about the running installation: 53% cheaper, 60% fewer turns. The largest
single case was resolving lib.contentElement.templateRootPaths after site-set merging —
a value that exists in no single file — where the baseline burned 458,000 more tokens
reconstructing it by reading across extensions.
Two things this benchmark does not show, stated plainly:
- Task success was 100% in both arms, on all 17 tasks. A competent agent with grep and a shell solved everything. This is a measure of efficiency and reliability, not capability — the tools make the agent faster and steadier, not smarter.
- The tool schemas cost ~6,800 tokens on every request, whether or not a tool is used. On short, non-TYPO3 work that is pure overhead.
Full methodology, per-task results, per-tool usage and limitations: Tests/Benchmark/README.md.
Installation
composer require --dev "balatd/typo3-dev-mcp:^0.1@alpha" vendor/bin/typo3 devmcp:install # or: ddev exec vendor/bin/typo3 devmcp:install
devmcp:install
- registers the MCP server in the project's
.mcp.json— when DDEV is detected the server is started viaddev exec vendor/bin/typo3 devmcp:serve, otherwise via local PHP; - composes version-specific AI guidelines into
.ai/guidelines/typo3.mdand links them fromCLAUDE.md/AGENTS.md(between idempotent markers, existing content is kept).
Then restart your AI assistant (or run /mcp in Claude Code).
Claude Code is supported out of the box via the project-scoped
.mcp.json. Support for other AI CLIs (Codex, Gemini CLI, …) is coming. Meanwhile any MCP client can be pointed atvendor/bin/typo3 devmcp:servemanually — and the composed guidelines already land inAGENTS.md, which most agents read.
Tools
Application and data
| Tool | What it does |
|---|---|
application_info |
TYPO3/PHP version, context, DB platform, active extensions, composer packages |
database_schema |
Live schema: tables, columns, indexes, foreign keys |
database_query |
Run a single SQL query (read-only unless DEV_MCP_ALLOW_WRITE=1) |
site_info |
Sites, base URLs, root pages, languages, error handling |
tca_schema |
The TCA: tables, columns, types, relations, record types, palettes |
content_elements |
Registered CTypes (+ legacy list_type plugins where present) |
content_blocks |
Registered Content Blocks with type name, table and YAML field definitions |
get_url |
Real routed frontend URL for a page + backend login URL |
Resolved configuration
The backend-module-only corners of TYPO3 — core ships no CLI for any of these.
| Tool | What it does |
|---|---|
typoscript |
Compiled frontend TypoScript for a page (setup / constants / config) |
page_tsconfig |
Resolved Page TSconfig for a page — mod.*, TCEFORM, TCEMAIN |
site_sets |
Site sets, dependency order, settings definitions, effective site settings |
flexform_schema |
Resolved FlexForm data structures: sheets, fields, per-field TCA |
middleware_stack |
PSR-15 stacks in execution order with package and before/after |
get_config |
TYPO3_CONF_VARS subtrees, feature toggles, extension configuration (secrets masked) |
API discovery
| Tool | What it does |
|---|---|
viewhelper_lookup |
Every available ViewHelper with its exact arguments, types and defaults |
list_events |
PSR-14 events and the listeners actually registered for them |
backend_modules |
Registered backend modules: identifier, parent, path, access, routes |
list_commands |
All vendor/bin/typo3 console commands with synopsis |
Documentation and diagnostics
| Tool | What it does |
|---|---|
search_docs |
Search docs.typo3.org, pinned to the installed major version |
search_changelog |
Search the core changelog (Breaking/Deprecation/Feature/Important) of the installed version — offline and exact |
extension_info |
An extension here vs. in the TER and on Packagist — including TYPO3 compatibility |
read_log_entries |
Recent log entries — file logs, deprecation log or sys_log |
last_error |
The most recent error-level log entry |
flush_cache |
Flush all caches or a cache group |
content_blocks is only announced when friendsoftypo3/content-blocks is installed.
Because the DI container is cached, installing that package later needs a
vendor/bin/typo3 cache:flush before the tool appears.
Safety model
- Everything is read-only by default; results carry MCP
readOnlyHintannotations.flush_cacheis the only tool that changes state. - Secret-looking configuration values (
password,encryptionKey, tokens, …) are masked before they leave the server. database_queryaccepts onlySELECT/SHOW/EXPLAIN/DESCRIBE/WITHunless the developer setsDEV_MCP_ALLOW_WRITE=1.search_docsandextension_infoare the only tools that reach the network (docs.typo3.org, extensions.typo3.org, Packagist). They use TYPO3's own HTTP client, so proxy and TLS settings apply. SetDEV_MCP_NO_NETWORK=1to keep the server fully offline — those two tools then fail with an explanatory message and everything else is unaffected.- There is deliberately no code-execution tool: nothing this server exposes can run arbitrary PHP.
Extending
Custom tools from your extension or sitepackage
Implement BalatD\DevMcp\Mcp\ToolInterface — that's it. With standard
autoconfiguration (autoconfigure: true in your Services.yaml, the default in
every modern extension) the service is tagged and announced automatically:
final class ProjectInfoTool implements ToolInterface { public function getName(): string { return 'project_info'; } public function getDescription(): string { return 'Project-specific conventions the AI should know.'; } public function getInputSchema(): array { return ['type' => 'object', 'properties' => new \stdClass()]; } public function isReadOnly(): bool { return true; } public function execute(array $arguments): mixed { return ['deployTarget' => 'staging.example.com']; } }
Constructor injection works as in any TYPO3 service. Throw a
\RuntimeException with an actionable message on failure — it reaches the AI
as a readable error. After adding a tool, flush the DI cache
(vendor/bin/typo3 cache:flush) and restart the MCP server.
PSR-14 events
| Event | Dispatched | Use it to |
|---|---|---|
CollectToolsEvent |
once at server start | add, remove or replace tools before they are announced |
BeforeToolExecutionEvent |
before every tool call | adjust arguments, short-circuit with your own result, or veto by throwing |
AfterToolExecutionEvent |
after every successful call | post-process results (extra masking, audit logging) |
#[AsEventListener] public function __invoke(BeforeToolExecutionEvent $event): void { if ($event->getTool()->getName() === 'flush_cache') { throw new \RuntimeException('Cache flushing is disabled in this project.'); } }
Requirements
- TYPO3 13.4 LTS or 14, Composer mode
- PHP 8.2, 8.3 or 8.4 — every PHP/TYPO3 combination is tested in CI
Development
The repository ships a DDEV harness with TYPO3 v13 and v14 side by side:
ddev start ddev install-v13 # TYPO3 13.4 + this extension at /var/www/html/v13 ddev install-v14 # TYPO3 14 + this extension at /var/www/html/v14
Backends: https://v13.typo3-dev-mcp.ddev.site/typo3/ /
https://v14.typo3-dev-mcp.ddev.site/typo3/ (admin / Joh316!!).
Protocol smoke test without an MCP client:
printf '%s\n' \ '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"smoke","version":"0"}}}' \ '{"jsonrpc":"2.0","method":"notifications/initialized"}' \ '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \ | ddev exec -d /var/www/html/v13 vendor/bin/typo3 devmcp:serve
Benchmark
Tests/Benchmark/ holds the A/B harness behind the numbers above — a separate,
host-mounted TYPO3 project, a fixture extension seeding the live state the tasks
interrogate, 17 graded tasks, and a blind judge. See
Tests/Benchmark/README.md.
composer bench:setup # build the benchmark TYPO3 project (once) composer bench:verify # prove the two arms differ only as intended composer bench:tax # measure the fixed context cost of the tool schemas composer bench # run the sweep
License
MIT