Symfony AI splits PHP model access into five components and two bundles
Symfony AI is a set of components that integrate AI capabilities into PHP applications
At a glance
- What is it?
- Symfony AI is a set of PHP components and bundles that put one interface in front of OpenAI, Anthropic, Azure, Gemini and VertexAI, with agent, chat and store layers above it. The layering is deliberate and the API is not settled: three version bumps in about six weeks, and two ownership questions the top-level README leaves open.
- Who is it for?
- Symfony AI is worth adopting when the application is already PHP and already Symfony, and the work is real: several providers, agents that need memory, or an MCP surface for coding agents you do not own. It is the wrong tool for a single provider call in a single file, where the interface removes a mismatch that never appears.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 3 days ago.
- What is it written in?
- Mainly PHP, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Platform puts five named providers behind one PHP interface
Model APIs differ in request shape, in authentication and in how they stream a response, and a PHP team inherits that difference in every file that talks to a vendor. Symfony AI answers it with the Platform component, presented as a unified interface to various AI platforms like OpenAI, Anthropic, Azure, Gemini, VertexAI, and more. Five providers are named. The list then closes with the words and more, so the set is open rather than fixed.
The problem being solved is narrow. Write against one interface instead of one client per vendor, and the vendor-specific code collects inside a component that somebody else maintains. The audience is just as narrow: this is a PHP project whose topics are ai, php and symfony, and the default branch is main, so the assumption underneath every piece is a PHP application rather than a script that calls an API once.
Read the boundary honestly. The abstraction stops at the vendor edge. Nothing in the component list covers token accounting, retries, failover or caching, and the phrase and more says nothing about whether the extra providers are written by the Symfony team or contributed from elsewhere. Treat the five names as a starting set, not as a compatibility guarantee you can build a plan on.
Store and Chat both reach for persistent state
Two components hold memory, and the README does not say how they divide it. Store is a data storage abstraction with indexing and retrieval for AI applications, which is the retrieval half of a grounded answer. Chat is a unified interface to send messages to agents and store long-term context, which is the conversation half. Indexing a document set and remembering what a user said last week are different jobs, and both components sit on the persistence layer.
What is missing is the seam between them. No top-level document states whether Chat writes through Store, keeps its own persistence, or expects the application to hand it one. An engineer who picks badly here ends up with two storage systems, two histories and no way to reconcile them later.
The practical consequence is small when you need only one. Retrieval without a conversation layer is an indexing job, and nothing in the README forces you to take both components together. It is not small when you build an assistant that has to remember a user across sessions, because that is the case where the undocumented boundary is exactly the thing you are standing on.
The AI Bundle covers three components, the MCP bundle two directions
Components and bundles are two tiers, and the README puts them on separate lines: several lower and higher level components and the respective integration bundles. The AI Bundle is named as the Symfony integration for AI Platform, Store and Agent components.
Count them. Three of five components have a bundle. Chat has none in the list, and neither does Mate, and the README does not explain how a Symfony application registers the Chat component or what it would take to wire one into a container by hand. The component list is the map of what exists; the bundle list is the supported way to reach it, and where the two disagree you are reading documentation instead of following a recipe. That documentation sits at https://symfony.com/doc/current/ai/index.html, with a separate site at https://ai.symfony.com for everything that is not a manual page.
The MCP Bundle is a different job again: it integrates the official MCP SDK and allows an application to act as an MCP server or as an MCP client. As a server, your application exposes project-aware capabilities to coding agents that are not written in PHP; as a client, it calls tools somebody else published. No transport, no tool list and no authentication story appear in the README for either direction.
Put the two side by side and the difference is exact. Platform decides who you call when you want a model. The MCP bundle decides who is allowed to call you when you want tools. Taking the AI Bundle does not give you an MCP surface, and taking the MCP bundle does not give you a provider interface. They are separate decisions, and a project that needs one has no reason to pay for the other before it needs it.
Mate is a developer tool filed beside the libraries
One of the five components is not a layer your application imports. Mate is a command-line assistant that lets coding agents inspect a running PHP application through project-aware tools, so the consumer is an agent and the subject is your running app.
It keeps its own README at src/mate/README.md, next to src/platform/README.md and src/store/README.md, and it has no bundle. It is versioned and documented with the libraries while being operated from a terminal, which is a different lifecycle from a service your app wires in the container. The demo application carries its own mate/ directory, so the tool is exercised inside the sample app rather than only described in prose.
The repository root repeats the theme. AGENTS.md, CLAUDE.md and a .claude/ directory sit next to composer.json, and the demo directory repeats all three. Whatever the project's own development workflow is, it is arranged to be driven by coding agents, and Mate is the component that hands those agents a view of a running PHP process.
No composer command, so start from the examples directory
Here is the honest part. The README contains no install command: no composer require line, no version constraint, and no minimum PHP version anywhere in the text. A reader who copies a package name from a blog post is guessing at it, and nothing in this repository's own text settles the guess.
Three starting points are given instead. The examples directory shows the components in smaller snippets. The demo application runs them together in a full Symfony web application. The documentation page is the third stop, and each component also keeps its own README at a predictable path:
examples/
demo/
src/platform/README.md
src/store/README.md
src/chat/README.md
src/agent/README.md
src/mate/README.md
src/ai-bundle/README.md
src/mcp-bundle/README.mdThe root also shows how the project is managed rather than only what it contains:
composer.json
UPGRADE.md
deptrac.yaml
splitsh.json
.phpstan/
.php-cs-fixer.dist.phpNot one of those filenames is explained above. deptrac.yaml, .phpstan/ and .php-cs-fixer.dist.php are static analysis and style configuration, which means the boundaries between the components are checked by tools rather than left to review; the rules themselves live in those files. splitsh.json sits beside composer.json without a word of explanation anywhere in the README, and that silence is itself a clue that the repository layout, not the README, is the thing worth reading.
The demo ships compose files, env files and prompt files
The demo is the only place in the repository where the pieces appear working together, and its file list says more than the README does. Two compose files, compose.yaml and compose.override.yaml, mean the sample expects containerised backing services plus a local override on top of the base file. Which services those are, which ports they bind and which credentials they need: the README never says, and the answer is inside those two files.
Then there are demo/.env and demo/.env.test, the ordinary split between runtime configuration and the configuration a test run reads, together with demo/phpunit.xml and demo/phpstan.dist.neon. The sample is written like application code that gets tested and analysed, not like a script that runs once. demo/importmap.php puts the frontend assets on import maps, and demo/prompts/ keeps prompt text in files instead of inside PHP classes. demo/symfony.lock records the recipes the application locked.
That is what a first pass should look for: a web application with a test suite, a container definition and a prompt directory. A reader who expects a package with a one-line quick start will not find one in this directory, and the two compose files are the reason a copy of the demo will not come up on its own.
Three 0.x bumps in six weeks, with UPGRADE.md left unlinked
The version line is short. Three bumps in about six weeks: v0.11.1 on 2026-07-16, v0.12.0 on 2026-07-22 and v0.13.0 on 2026-08-30. The last push was on 2026-09-20, three weeks after the newest of those, so the tip of main runs ahead of any published version.
Under a 0.x line, a minor bump is where breaking changes are allowed to land, and UPGRADE.md in the repository root is where they land. The README does not link that file, does not summarise it and does not tell you to read it before pinning, so an application that pins a minor version has to open the file on its own and judge the cost.
A single licence fact settles ownership for most teams: the code is MIT, which lets a component sit inside a proprietary PHP application without a copyleft obligation reaching that application, and the LICENSE file in the root is where to check whether each component ships under exactly those terms.
Where the interface pays, and where it does not
Write the comparison against the obvious alternative: calling OpenAI, Anthropic, Azure, Gemini or VertexAI straight from your own code with that vendor's own client. The difference is where the vendor-specific code lives. Direct calls bind your request shape, your authentication and your response parsing to one company, and a second provider means a second client in a second corner of your codebase. Platform moves that code into one component you do not maintain, at the price of an abstraction that only covers what its authors put in it.
Two costs are worth naming. The README documents no retry, timeout, streaming or cost accounting behaviour, so each of those stays unanswered until you read the documentation. And a script that talks to one provider gains very little, because the mismatch the interface removes never shows up in the first place.
The wrong-tool case is a small team wanting one model call in one file. This pays off when the application is already PHP, already has more than one provider or plans to, and needs agents with memory. It does not pay off as a wrapper for a single request, and the 0.x line is a fair reason to keep your own thin interface in front of it until the version numbers settle.
Editorial conclusion
Symfony AI is worth adopting when the application is already PHP and already Symfony, and the work is real: several providers, agents that need memory, or an MCP surface for coding agents you do not own. It is the wrong tool for a single provider call in a single file, where the interface removes a mismatch that never appears. Verify three things before pinning a minor version: what UPGRADE.md says about moving off 0.13.0, how Chat and Store divide persistent state, and which providers the Platform component covers beyond the five the README names.
Frequently asked questions
Which model providers does the Symfony AI Platform component support?
The README names OpenAI, Anthropic, Azure, Gemini and VertexAI, then adds the words and more. No other provider is named anywhere in the text, so the current list belongs to the documentation page rather than to the README.
Do I need Symfony to use Symfony AI?
The README treats components and bundles as two tiers, and the bundles are the Symfony integration: the AI Bundle for AI Platform, Store and Agent, the MCP Bundle for the official MCP SDK. Whether a plain PHP application can use a component on its own is not addressed by the README.
How do I install Symfony AI?
The README gives no composer command and no version constraint. It points at an examples directory for smaller snippets, a demo application for a full Symfony web application, and the documentation page.
What is the Symfony AI Mate component, and is it part of the AI Bundle?
Mate is a command-line assistant that lets coding agents inspect a running PHP application through project-aware tools. It is listed as a component, and the AI Bundle covers AI Platform, Store and Agent only, so Mate is not in it.
Which Symfony AI component should store the conversation history?
The README does not divide that job. Store is a data storage abstraction with indexing and retrieval, and Chat is a unified interface to send messages to agents and store long-term context, so both touch persistent state and no document says which one owns it.
How often does Symfony AI change?
Three versions are visible: v0.11.1 on 2026-07-16, v0.12.0 on 2026-07-22 and v0.13.0 on 2026-08-30. The last push was on 2026-09-20, ahead of the newest of those, and the repository root carries an UPGRADE.md for moving between them.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/symfony-ai)Was this useful?