Wenn Sie jahrelang Geschäftslogik in PHP-Anwendungen gepflegt haben, kann es sich wie das Stehen vor einer verschlossenen Tür anfühlen, wenn Sie Model Context Protocol-Tutorials ansehen. Fast jeder Leitfaden setzt TypeScript oder Python voraus. Sie führen durch offizielle SDKs, npm-Installationen und pip-Pakete. Das lässt eine enorme Menge an Geschäftsdaten – Kundendaten, Bestellhistorien, Inventarsysteme – in PHP-Codebasen zurück, die für die aktuelle Welle der KI-Tools unsichtbar erscheinen.
Die gute Nachricht ist, dass MCP keine dieser SDKs benötigt. MCP ist keine Bibliothek. Es ist ein Wire-Protokoll. Wenn Ihre Laufzeitumgebung eine Textzeile von der Standardeingabe lesen, JSON parsen und JSON wieder ausgeben kann, kann sie das Protokoll sprechen. PHP tut genau das schon lange bevor LLMs existierten.
Was MCP eigentlich ist
MCP steht für Model Context Protocol. Im Kern ist es ein offener Standard, um KI-Assistenten mit Daten, Tools und externen APIs zu verbinden. Anstatt für jeden Assistenten oder jedes Modell eine individuelle Integration zu bauen, erstellen Sie eine einzige konforme Schnittstelle. Jeder Client, der MCP versteht, kann dann mit Ihrem Server kommunizieren, ohne etwas über PHP, Laravel oder Ihr spezifisches Datenbankschema wissen zu müssen.
Im Hintergrund nutzt MCP JSON-RPC 2.0. Das bedeutet, dass jede Anfrage ein einfaches JSON-Objekt ist, das einen Methodennamen, Parameter und eine ID enthält. Der Server antwortet mit einem weiteren JSON-Objekt, das entweder ein Ergebnis oder einen Fehler enthält.
Ein Server stellt drei Primitiven bereit:
- Tools: Aktionen, die das Modell aufrufen kann. Ein Tool könnte eine Datenbank abfragen, einen Status aktualisieren oder eine API eines Drittanbieters aufrufen.
- Resources: Statische oder semi-statische Daten, auf die das Modell über eine URI verweisen kann. Denken Sie an Dateien, Konfigurationsdokumente oder Referenzdatensätze.
- Prompts: Vordefinierte Vorlagen, die dem Benutzer helfen, mit dem System zu interagieren.
Es gibt einen wichtigen Unterschied in der Steuerung, den man beachten sollte. Tools werden vom Modell gesteuert. Der Assistent entscheidet, wann er eines aufruft. Resources werden von der Anwendung gesteuert. Der Server entscheidet, welche Daten verfügbar sind, und das Modell liest einfach, was angeboten wird. Wenn man dies richtig umsetzt, bleibt die Architektur vorhersehbar. Man möchte nicht, dass ein Modell nach Ressourcen sucht, die eigentlich Tools hätten sein sollen, oder umgekehrt.
Wie der Transport funktioniert
MCP definiert zwei Transportmethoden, und Ihre Wahl bestimmt, wie Sie die PHP-Seite schreiben.
stdio ist am einfachsten. Der MCP-Client startet Ihr PHP-Skript als Unterprozess. Der Client schreibt JSON-RPC-Nachrichten in die Standardeingabe Ihres Skripts, und Ihr Skript schreibt Antworten in die Standardausgabe. Es müssen keine Sockets verwaltet, keine Ports geöffnet und keine Authentifizierungs-Header geparst werden. Wenn Ihr Tool und Ihr Client auf derselben Maschine laufen, ist dies in der Regel der richtige Ausgangspunkt.
Der Betrieb über stdio stellt zwei strenge Regeln für Ihren PHP-Prozess auf. Erstens darf Ihre Anwendung niemals Nicht-Protokoll-Daten an stdout schreiben. Wenn Sie eine Debug-Anweisung ausgeben oder eine PHP-Meldung (Notice) durchsickern lassen, beschädigen Sie den Parser des Clients. Leiten Sie jegliches Logging und jegliche Diagnosedaten an stderr weiter. Zweitens sollten Sie das Output-Buffering vollständig deaktivieren. PHP neigt dazu, stdout zu puffern, insbesondere in CGI- oder Web-Kontexten, aber selbst CLI-Skripte können Daten zurückhalten. Leeren Sie jede Antwort sofort. Wenn Sie Streams verwenden, setzen Sie stream_set_write_buffer(STDOUT, 0) oder schalten Sie das implizite Buffering aus, damit der Client den Zeilenumbruch in dem Moment erhält, in dem Sie ihn senden.
Streamable HTTP funktioniert anders. Ihre PHP-Anwendung läuft als persistenter HTTP-Endpunkt, der normalerweise über POST-Anfragen erreicht wird. Dies ist nützlich, wenn der Server auf einem anderen Host liegt oder wenn Sie einen langlaufenden Daemon möchten, den mehrere Clients erreichen können. In PHP bedeutet dies in der Regel, dass die Anwendung unter RoadRunner, FrankenPHP oder einem ähnlichen Prozessmanager läuft, anstatt im traditionellen Request-Response-Zyklus, der nach jedem Aufruf endet.
Die Umsetzung in PHP
Sie benötigen kein Framework für den Anfang. Ein minimaler MCP-Server in PHP ist eine Schleife, die von STDIN liest, JSON dekodiert, an einen Handler weiterleitet und das Ergebnis kodiert.
while ($line = fgets(STDIN)) {
$request = json_decode($line, true);
// route to tool or resource handler
// write JSON-RPC response to STDOUT
}
Innerhalb dieser Schleife besteht die eigentliche Arbeit darin, Schnittstellen zu bauen, die für ein Modell sinnvoll sind.
Generate tool schemas from code. One of the fastest ways to cause trouble is hand-writing JSON Schemas for your tool parameters and letting them drift out of sync with your actual validation logic. PHP has rich reflection capabilities. Inspect your method signatures, read existing validation rules from your forms or command objects, and generate the schema from those constraints. If your internal code requires a valid email format, your MCP schema should say the same thing. When validation rules change, the schema updates automatically. No drift, no silent failures.
Separate protocol errors from tool errors. JSON-RPC has its own error space. Use it for broken protocol: malformed JSON, unknown methods, or missing request IDs. When a tool executes correctly but encounters a business problem, return a normal result with an error flag inside the payload. If a customer lookup tool finds no matching record, that is not a protocol crash. Returning a structured result like {"found": false} lets the model understand what happened and choose the next step. It might try a broader search, or it might ask the user for clarification. If you throw a JSON-RPC error instead, the model often loses context.
Plan for long-running work. PHP is built for short requests. A web request might time out in thirty seconds, and even CLI scripts can exhaust memory or patience. If a tool needs minutes to finish—perhaps it compiles a large report or syncs data across systems—do not make the model wait. Return a job identifier immediately. Then expose a second tool for checking status by that ID. You can store progress in Redis, a database table, or even a flat file if the volume is low. The model receives the ID, checks back later, and eventually picks up the completed result.
Security When the Model Has Keys
Giving an AI model access to a tool is not like giving it to a human user. A model acts fast, literally, and it can misinterpret descriptions. Treat every exposed tool as a privilege escalation risk.
Limit scope aggressively. Never expose a generic run_sql tool. Build specific, narrow tools like find_customer_by_email or update_order_status. The model should only be able to do exactly what you name, with parameters you have defined.
Separate read and write paths. Read-only tools carry lower risk. Put any destructive action behind an explicit confirmation mechanism, or restrict it to a second server entirely. If your client supports it, require a human approval step before a write tool executes.
Write tool descriptions as if they are additional instructions, because they are. Be precise about when the model should call a tool. If a tool looks up pricing, say so. If it should only be used after verifying the customer ID, state that clearly. Vague descriptions lead to vague behavior.
Filter your output. Do not serialize an entire Eloquent model or Doctrine entity and dump it into the result. Return only the fields the model actually needs. Internal fields—cost prices, employee notes, database IDs that should stay internal—have no business crossing the wire. Be explicit about your return shape.
Finally, log everything. Record the tool name, the arguments passed, and the outcome. If a model starts looping on an expensive query or probing tools in an unexpected order, your logs are the only way you will see it.
Where to Start
You do not need permission from an SDK maintainer to connect your PHP application to an AI assistant. You need JSON-RPC, a loop, and some discipline around stdout.
Resist the urge to rebuild your entire API as MCP tools on day one. Pick three read-only operations that someone in your organization actually asks about repeatedly. Maybe it is checking an order status, pulling a customer summary, or listing recent invoices. Wrap those as tools, serve them over stdio, and let one colleague use them. Watch what the model does well and where it stumbles. You will learn more from those three tools than you will from planning thirty.
MCP is a bridge, not a replacement for your application. Your PHP code already knows your business. The protocol just lets the model cross over and ask it questions.
