by Yanick Witschi

Recap of the second Contao Core Developers Meeting 2026

Every year, the Contao Core development team meets twice for a short code sprint of four days. This time, we met again at the Unperfekthaus in Essen, Germany.

Obligatory note: The developer meetings are crucial for the further development of Contao and therefore, as always, I call attention to the fact that the Contao Association funds these meetings. As a Supporter you can do your part.

Now There Are Nine of Us

Apparently, the meeting in spring was not enough to scare him off because, much to our delight, Lukas Bableck joined us again. At the start of the meeting, that meant eight core developers plus Lukas working on Contao almost continuously for four days.

That calculation was no longer correct by Wednesday evening though. We welcomed Lukas into the core team! Anyone who has followed his many contributions over the past few months will probably not be entirely surprised. Dear Lukas, welcome to the core team! We are very happy to have you with us! From now on, there are nine core developers.

If you would like to learn more about Lukas, you can also find him in the "We are Contao" format.

A New Reality

Traditionally, our developer meetings start on Sunday evening with the big topics. Before the first pull requests appear on Monday, we discuss where we actually want to take Contao. Usually, the question is something along the lines of "What's next?" This time, it was more like "What exactly is happening here?"

Only a few months passed between our two meetings, yet the way we write code has completely turned on its head in that short time. AI-powered tools have gone from interesting experiments to everyday companions. They explain code, write tests, find bugs and take on tasks for which we would have planned hours or days only a few months ago. And by the time I write this, it is probably already out of date again.

On the one hand, that is fantastic. As an open source project with limited resources, we can suddenly tackle things that had been left behind for all kinds of reasons. A lack of time was one of them. It is fun, it releases an incredible amount of energy and it surely explains part of the absurd number of pull requests at this meeting.

On the other hand, it would be dishonest to write only about the excitement. We sat there as a group of experienced developers and suddenly questioned things that had seemed obvious for years. Which skills will still matter in the future? What will our profession look like in a few years? Why do we need a content management system at all if content and applications can seemingly be generated on demand? Why Contao? And if you follow that thought all the way through, why should anyone still do anything as a developer?

We are not alone in asking these questions and they are certainly not specific to Contao. The entire software industry is trying to understand the consequences of this development. And yes, at times that felt rather unsettling.

Of course, we did not find a definitive answer. Too much is changing too quickly. But after many hours of discussion, one thing was clear to us: burying our heads in the sand is not an option. We do not want to merely watch this change. We want to help shape it.

And perhaps a CMS is more important in this new reality than it may seem at first glance. Just because content can be generated automatically does not make structure, responsibilities, permissions and reliable sources disappear. Quite the opposite. The more systems generate and process content, the more important it becomes to have one place that knows what is valid, who may change something and how everything fits together.

That is exactly the role Contao can play: a reliable hub through which people and machines can work with content together. Without sacrificing security, control, extensibility or stability.

Is that the final answer? Certainly not. But it is a direction we can work with. Which brings us to the main topic of this meeting.

API and MCP

We had already announced that API and Model Context Protocol, or MCP for short, would be a focus throughout the Contao 6 series. After all, we have known for years that Contao needs an API. Before we could build one that was both useful and secure, however, we had to address numerous internal issues.

Throughout the entire Contao 5 series, we laid crucial foundations for this work: the permission system in DC_Table, reloadable DCAs and the DcaRequestSwitcher. The switch from input encoding to output encoding means that the database finally contains the actual values. The move to Twig required for this, in turn, made additional tools necessary: the Template Studio and numerous Contao-specific filters and functions. All these efforts now feed into API and MCP. What we have wanted for years is finally becoming a reality.

We did not start entirely from scratch in Essen. In the weeks and months before the meeting, I had already worked on the first versions of the API bundle and MCP bundle as well as the foundation for our end-to-end testing. Bringing these foundations to the meeting meant we could spend the four days building on them together right away.

What emerged during those four days still surprised us. We did not merely extend and connect API and MCP in countless places. Their requirements also gave rise to the OAuth server bundle and the foundation for a future webhooks bundle, two additional building blocks in their own right. Arriving with three prepared foundations and leaving with two additional building blocks? It is quite impressive what a team can achieve in four days!

Why an API Matters So Much Right Now

A modern API allows other applications to communicate with Contao in a structured and controlled way. Of course, APIs were not invented for AI. Headless websites, mobile apps, automations and third-party systems all benefit when content is available through a clearly defined interface.

AI does make this much more urgent though. If an assistant is supposed to find content, modify templates or inspect a website, it needs context. That context should not come from direct database access or a collection of project-specific scripts. It should come from an interface that understands Contao.

More importantly, that interface must understand rules, not just data. A back end user is not automatically allowed to edit every page, see every file or perform every operation. Why should an AI assistant be allowed to do more? Exactly the same permissions must apply when access happens through an API or an AI-powered tool. The API is not just another representation of our database. It is a controlled front door to Contao's capabilities.

We worked intensively on that front door during the meeting.

From Tables to Actual Contao Resources

Data containers describe fields, operations, relations and permissions. They already contain almost everything we need for an API. That is great because we do not have to build a separate interface for every table and extensions can hook into the same mechanisms.

"Table in, JSON out, done" would still be too easy, of course. Pages form a tree, articles belong to pages, content elements can themselves be nested and numerous records refer to other resources. The API needs to understand all these relationships. Otherwise, where would the fun be?

And this is exactly where we made major progress. The data container API now represents hierarchies and resolves relations to unique resource references. Sorting, moving, nested content elements, date fields, descriptions from the DCA and so on. Individually, these things may not sound spectacular. Together, they make the difference between "We return data" and an API that accurately represents Contao's concepts and relationships.

The Virtual Filesystem is available through the API. Files in Contao are much more than paths on some hard drive. The VFS knows about public and protected files, metadata, mounts and different storage locations. That is precisely why we built it. A client neither needs nor should know which physical file system a file lives on.

By the end of the meeting, we had added even more important details. File uploads now work through the generic MCP tools and respect the configured size limits. An assistant therefore cannot quietly leave us a multi-gigabyte gift. Downloads through API and MCP as well as support for file UUIDs were also already in progress on Wednesday evening.

The same applies to the Template Studio. Templates can be found, read, created and edited through defined endpoints. These reuse the existing Template Studio operations and metadata. We are not building a second, simplified template world next to the back end. Instead, we are making the existing capabilities available externally in a controlled way.

Authentication and Security

An API with write access is only useful if we pay as much attention to securing it as we do to its features. Otherwise, we would have a great new interface and a great new security problem to go with it. A lot of work therefore went into authentication.

The new OAuth server bundle created at the meeting primarily gives MCP clients a standardized authorization flow. In parallel, we are working on personal access tokens for back end users. These are intended for direct API access and can be revoked more easily than a user password.

Most importantly, the authenticated user's permissions continue to apply after authentication. The API must not provide a shortcut around our security logic. A large part of the work at the meeting therefore went into permissions, authentication and consistent behavior outside regular back end requests. Not necessarily the kind of work that looks amazing in a screenshot, but exactly the work that makes all the difference in the end.

MCP in Contao

In a very short time, MCP has established itself as a standard through which applications provide AI assistants with tools and context. An MCP server describes what an assistant may do and which information it receives. The assistant does not have to guess how Contao works and we do not need to build a custom integration for every project.

Our MCP implementation builds on the API and existing Contao services. Anything else would make little sense because we only want to implement the domain logic properly once. Whether an action is triggered from the back end, through the API or by an MCP tool must make no difference to permissions and data integrity.

One of the first tools connects the back end search. Rather than searching arbitrary database rows, an assistant can find the results available to the authenticated user. Other tools can discover, read, validate and manage templates. They know which templates override or extend other templates and can therefore assess the consequences of a change far more accurately. There is also guidance for working with Contao. Template snapshots are available both through MCP and in the user interface.

The Template Studio is a great example of where this can lead. Instead of handing an assistant the contents of a single file, we can provide the actual Contao context. Which theme is active? Which original is being overridden? Which blocks are available? Which other templates are affected by a change? This allows the assistant to make changes based on the actual Contao context.

Another MCP tool connects the front end preview. With it, an assistant can, for example, find an image in the right file system, modify a template and then inspect the unpublished result in the preview. That creates a mini workflow. It already sounds very powerful, which is exactly why clear boundaries, permissions and good tests matter so much.

The current state is already advanced enough that we expect to ship these features with Contao 6.1. From there, we can expand them step by step and improve them based on feedback from the community.

During this meeting, we worked on more than 100 pull requests.

Webhooks: When Contao Talks to Other Systems

Speaking of communication with other systems, Lukas casually laid the foundation for incoming and outgoing webhooks during the meeting. Webhooks allow systems to respond automatically to events without constantly checking for changes.

In the future, Contao should be able to receive events from external services and securely send its own events to connected systems. Processing happens asynchronously through Symfony Messenger. The implementation also includes signed requests, encrypted secrets, rate limits and safeguards for outgoing connections. Endpoints and subscriptions can be configured in the back end.

The implementation is not finished yet, but it already provides a remarkably comprehensive foundation. We still need to decide which events the core itself will offer and how flexibly custom payloads can be configured. But I think it is fair to say already: this is going to be powerful!

A Faster and More Modern Back End

API and MCP were our biggest focus, but obviously not our only topics. You know us. The mountain of work is enormous and when nine people sit in the same room working together for four days, one or two other things tend to happen along the way.

Faster Hierarchies

Before the meeting, I had already created a new hierarchy helper that I had wanted to implement for a long time. It uses recursive common table expressions whenever the database supports them. This allows hierarchical data to be retrieved with far fewer and much faster database queries than the previous combination of iterative queries and UNION statements.

This benefits not only the tree views in the back end but also navigation menus and sitemaps. Basically, anywhere Contao has to work its way through a tree. The tree views now load up to five times faster. And because this is Contao, older database systems retain a fallback to the previous implementation.

Less MooTools, More Convenience

Sebastian is continuing his personal campaign against the last remaining MooTools dependencies. Drag and drop in the file manager has already been migrated to Stimulus and the TableWizard has been almost completely rebuilt. It provides the foundation for our table content element and comes not only with a more modern technical basis but also with a whole range of new features. Columns can be sorted, rows can be added or removed conveniently and individual cells can be navigated with the keyboard. Editing cells with a rich text editor is planned as well. A table content element that could suddenly be fun to use. Who would have thought?

And while we are at it, the ListWizard on which the list content element is based is becoming much more powerful too. Nested lists can be created directly in the widget while the ListWizard itself can be used with the keyboard. Both changes are still under review, but they nicely demonstrate that replacing old technology is not an end in itself. If we have to touch all this stuff anyway, it had better be an improvement afterwards.

Another change brings true drag and drop to the page tree and article view. Yes, you read that correctly! Instead of cutting elements and pasting them elsewhere, pages and articles can be dragged directly to the desired position. The existing permissions and the special rules for website roots are respected, of course.

A Time Machine for the Front End Preview

Anyone preparing content for a specific date knows the problem. A content element is configured correctly, but it will not be published until next week. To check the result, you previously had to change the publication time temporarily. Or wait a week. Neither option is particularly practical.

The front end preview is therefore getting a small time machine. You can select any date and time and Contao will show the website as it will look at that moment. Next Tuesday at 2:42 p.m.? No problem. Editors can finally preview scheduled publications without also seeing content, pages or articles that should remain hidden. Great!

More Accurate Facets in the Back End Search

The back end search has been improved as well. Previously, the displayed facets could suggest results that the logged-in user was not allowed to access because of their user groups. Frustrating, because what good is a filter with five results if you cannot open any of them? During indexing, Contao now determines which groups may see a document. The search can take this information into account directly and displays only facets that actually contain accessible results.

This may sound like a small change, but it required important foundations under the hood. During indexing, Contao must be able to check the permissions of virtual users even though the process runs on the command line and therefore outside a regular back end request.

End-to-End Tests

Now for a topic that may not sound quite as exciting to users, but was enormously important for our future development. A first foundation for genuine end-to-end tests had already been prepared. During the meeting, we integrated it into the Contao monorepository, extended it and most importantly started filling it with real tests.

Contao has, of course, had thousands of automated tests for a long time. Unit tests check small isolated building blocks while our functional tests exercise larger parts of the system together with Symfony and a database. That already sounds pretty good, does it not? So why do we need this end-to-end thing as well?

What we were missing was a reusable way to automatically test a complete Contao installation from the first step to the last. Not just a few services in an artificial test setup, but a real installation. The whole thing.

That is exactly what the new infrastructure provides. It creates an isolated Contao Managed Edition, installs its Composer dependencies, automatically provides the required database through Docker, runs the migrations, loads defined test data and starts a local web server. It can then be controlled through Symfony BrowserKit or with Playwright in a real browser. This means the test does not see only individual services. It sees Contao as it will actually be used.

The first migrated tests demonstrate the value very nicely. Routing tests now send real HTTP requests to a fully configured installation. Other tests log into the back end with demo users, create a website, upload an image, select it in a content element and then verify the result in the front end. A little robot that installs Contao and then clicks around the back end. I think that is pretty cool.

Sebastian immediately picked up the new infrastructure and is working on testing our new API completely from end to end. The tests have already exposed several real bugs. That is precisely what the infrastructure is for. We know about the remaining gaps before we release the whole thing to the community.

New end-to-end tests for the RowWizard also found two real bugs when copying rows. A new test infrastructure could hardly prove its value any better.

That sounds like quite a lot of effort for a test. It is. That is why reusable packages manage the installation, test data, files and browser drivers. The framework is not intended only for the core either. Extension developers can add it to their extension and get a complete Contao Managed Edition with a database, fixture support and files. This allows an extension to be tested automatically against every supported Contao version. Each test starts from a defined state and leaves no data behind for the next one. In the future, several tests may even run in parallel. At least once we have thrown enough resources at our CI.

Why This Is Crucial for API and MCP

With a traditional back end feature, we can catch many errors in an isolated test. An API request, on the other hand, passes through routing, the firewall, authentication, permission checks, serialization and the actual Contao logic. MCP adds another layer on top. Every individual component can work perfectly on its own while the overall system still explodes because of some inconspicuous configuration difference. Software.

End-to-end tests allow us to reproduce exactly the workflows that an API client or MCP assistant will use later. Log in, retrieve permitted resources, perform an operation and verify the result. And, of course, the opposite case as well. Another user without the required permissions must not be allowed to perform the same operation. Tests for "must not" are at least as important as tests for "works".

Care Package

Once again, the project team thought of us and Marcus put together a care package containing everything nine developers need for four days of Contao. In other words, mostly snacks.

To mark the farewell to input encoding, Hagen provided edible special characters. Thanks to Claude, there were also Twig bars again, this time with even more Twig references. A heartfelt thank-you to you, dear Marcus, for organizing everything and for the personal letter. And many thanks to Hagen, the entire project team and everyone else involved! You can find photos in the attachment to the blog post.

Looking Ahead to Contao 6.1

And when will you be able to use all of this? Most of the features presented here are planned for release with Contao 6.1 in February 2027. Until then, there is still plenty to review, test and refine here and there. API and MCP in particular are new territory for Contao, so we want to develop these new possibilities with the necessary care.

February feels too far away? Perfect, because you do not have to wait that long to bring your questions, ideas or concerns. Simply come to the Contao Summit in Leipzig on October 15 and 16!

We want to do more than present results there. We want to discuss with you what Contao should look like in this new reality. I do not think there has ever been a better time for the community to come together and exchange ideas. So, seriously: come to Leipzig!

That's all Folks!

– Yanick

Yanick Witschi

About Yanick Witschi

Yanick is Contao's caching and resolver hero and is partly responsible for making your coffee break a lot shorter since the switch to Composer 2. He was co-founder and the first president of the predecessor of the Contao Association. As a core developer, he puts a lot of heart and soul into Contao. At terminal42, he regularly takes off with clients. He also loves cooking, basketball, tennis, politics, the African continent and astrophysics.

Add a comment

Please calculate 6 plus 8.