If you have spent years maintaining business logic inside PHP applications, watching Model Context Protocol tutorials can feel like standing outside a locked door. Nearly every guide assumes TypeScript or Python. They walk through official SDKs, npm installs, and pip packages. That leaves an enormous amount of business data—customer records, order histories, inventory systems—sitting in PHP codebases that look invisible to the current wave of AI tooling.
The good news is that nothing about MCP requires those SDKs. MCP is not a library. It is a wire protocol. If your runtime can read a line of text from standard input, parse JSON, and write JSON back out, it can speak the protocol. PHP has been doing exactly that since long before LLMs existed.
What MCP Actually Is
MCP stands for Model Context Protocol. At its core, it is an open standard for connecting AI assistants to data, tools, and external APIs. Instead of building a custom integration for every assistant or model, you build one compliant interface. Any client that understands MCP can then talk to your server without knowing anything about PHP, Laravel, or your specific database schema.
Underneath, MCP uses JSON-RPC 2.0. That means every request is a simple JSON object containing a method name, parameters, and an ID. The server responds with another JSON object carrying either a result or an error.
A server exposes three primitives:
- Tools: Actions the model can invoke. A tool might query a database, update a status, or call a third-party API.
- Resources: Static or semi-static data the model can reference through a URI. Think of files, configuration documents, or reference datasets.
- Prompts: Predefined templates that help the user interact with the system.
There is an important control distinction to remember. Tools are model-controlled. The assistant decides when to call one. Resources are application-controlled. The server decides what data is available and the model simply reads what is offered. Getting this right keeps your architecture predictable. You do not want a model hunting for resources that should have been tools, or vice versa.
How the Transport Works
MCP defines two transport methods, and your choice shapes how you write the PHP side.
stdio is the simplest. The MCP client launches your PHP script as a subprocess. The client writes JSON-RPC messages to your script’s standard input, and your script writes responses to standard output. There are no sockets to manage, no ports to open, and no authentication headers to parse. If your tool and your client live on the same machine, this is usually the right place to start.
Running over stdio imposes two strict rules on your PHP process. First, your application must never write non-protocol data to stdout. If you echo a debug statement or let a PHP notice leak through, you will break the client’s parser. Route all logging and diagnostics to stderr. Second, disable output buffering entirely. PHP likes to buffer stdout, especially in CGI or web contexts, but even CLI scripts can hold data. Flush every response immediately. If you are using streams, set stream_set_write_buffer(STDOUT, 0) or turn off implicit buffering so the client receives the newline the instant you send it.
Streamable HTTP works differently. Your PHP application runs as a persistent HTTP endpoint, usually reached via POST requests. This is useful when the server lives on a different host, or when you want a long-running daemon that multiple clients can reach. In PHP, this typically means running under RoadRunner, FrankenPHP, or a similar process manager rather than the traditional request-response cycle that dies after every call.
Building It in PHP
You do not need a framework to start. A minimal MCP server in PHP is a loop reading from STDIN, decoding JSON, dispatching to a handler, and encoding the result.
while ($line = fgets(STDIN)) {
$request = json_decode($line, true);
// route to tool or resource handler
// write JSON-RPC response to STDOUT
}
Inside that loop, the real work is building interfaces that make sense to a model.
Jana skema alatan daripada kod. Salah satu cara terpantas untuk menimbulkan masalah adalah dengan menulis JSON Schema secara manual untuk parameter alatan anda dan membiarkannya tidak selaras dengan logik pengesahan sebenar anda. PHP mempunyai keupayaan refleksi yang kaya. Periksa tandatangan kaedah anda, baca peraturan pengesahan sedia ada daripada borang atau objek arahan anda, dan jana skema daripada kekangan tersebut. Jika kod dalaman anda memerlukan format e-mel yang sah, skema MCP anda harus menyatakan perkara yang sama. Apabila peraturan pengesahan berubah, skema akan dikemas kini secara automatik. Tiada ketidakselarasan, tiada kegagalan senyap.
Asingkan ralat protokol daripada ralat alatan. JSON-RPC mempunyai ruang ralatnya sendiri. Gunakan ia untuk protokol yang rosak: JSON yang tidak sah, kaedah yang tidak dikenali, atau ID permintaan yang hilang. Apabila sesuatu alatan dilaksanakan dengan betul tetapi menghadapi masalah perniagaan, kembalikan hasil biasa dengan bendera ralat di dalam payload. Jika alatan carian pelanggan tidak menemui rekod yang sepadan, itu bukan kegagalan protokol. Mengembalikan hasil berstruktur seperti {"found": false} membolehkan model memahami apa yang berlaku dan memilih langkah seterusnya. Ia mungkin cuba carian yang lebih luas, atau ia mungkin meminta penjelasan daripada pengguna. Jika anda sebaliknya mencetuskan ralat JSON-RPC, model sering kali kehilangan konteks.
Rancang untuk kerja yang berjalan lama. PHP dibina untuk permintaan yang singkat. Permintaan web mungkin mengalami masa tamat (timeout) dalam masa tiga puluh saat, dan skrip CLI pun boleh menghabiskan memori atau kesabaran. Jika sesuatu alatan memerlukan masa beberapa minit untuk selesai—mungkin ia menyusun laporan besar atau menyelaraskan data merentasi sistem—jangan biarkan model menunggu. Kembalikan pengenal pasti tugasan (job identifier) dengan segera. Kemudian dedahkan alatan kedua untuk menyemak status menggunakan ID tersebut. Anda boleh menyimpan kemajuan dalam Redis, jadual pangkalan data, atau pun fail rata (flat file) jika volumnya rendah. Model menerima ID tersebut, menyemak semula kemudian, dan akhirnya mengambil hasil yang telah selesai.
Keselamatan Apabila Model Mempunyai Kunci
Memberi akses kepada alatan kepada model AI tidak sama seperti memberikannya kepada pengguna manusia. Model bertindak pantas, secara literal, dan ia boleh tersalah tafsir penerangan. Anggap setiap alatan yang didedahkan sebagai risiko peningkatan keistimewaan (privilege escalation).
Hadkan skop secara agresif. Jangan sesekali dedahkan alatan run_sql yang generik. Bina alatan yang khusus dan sempit seperti find_customer_by_email atau update_order_status. Model sepatutnya hanya boleh melakukan apa yang anda namakan, dengan parameter yang telah anda tetapkan.
Asingkan laluan baca dan tulis. Alatan baca-sahaja membawa risiko yang lebih rendah. Letakkan sebarang tindakan pemusnah di sebalik mekanisme pengesahan eksplisit, atau hadkan ia kepada pelayan kedua sepenuhnya. Jika klien anda menyokongnya, perlukan langkah kelulusan manusia sebelum alatan tulis dilaksanakan.
Tulis penerangan alatan seolah-olah ia adalah arahan tambahan, kerana memang itulah fungsinya. Bersikap tepat tentang bila model harus memanggil sesuatu alatan. Jika sesuatu alatan menyemak harga, nyatakan begitu. Jika ia hanya boleh digunakan selepas mengesahkan ID pelanggan, nyatakan dengan jelas. Penerangan yang samar-samar membawa kepada tingkah laku yang samar-samar.
Tapis output anda. Jangan serialisasikan keseluruhan model Eloquent atau entiti Doctrine dan masukkan begitu sahaja ke dalam hasil. Kembalikan hanya medan yang sebenarnya diperlukan oleh model. Medan dalaman—harga kos, nota pekerja, ID pangkalan data yang sepatutnya kekal dalaman—tidak sepatutnya dihantar keluar. Bersikap eksplisit tentang bentuk pemulangan (return shape) anda.
Akhir sekali, logkan segalanya. Rekodkan nama alatan, argumen yang dihantar, dan hasilnya. Jika model mula melakukan gelung (looping) pada pertanyaan (query) yang mahal atau menyiasat alatan dalam urutan yang tidak dijangka, log anda adalah satu-satunya cara untuk anda mengetahuinya.
Di Mana Hendak Bermula
Anda tidak memerlukan kebenaran daripada penyelenggara SDK untuk menyambungkan aplikasi PHP anda kepada pembantu AI. Anda memerlukan JSON-RPC, satu gelung, dan sedikit disiplin berkaitan stdout.
Tahan keinginan untuk membina semula keseluruhan API anda sebagai alatan MCP pada hari pertama. Pilih tiga operasi baca-sahaja yang sering ditanya oleh seseorang dalam organisasi anda secara berulang kali. Mungkin ia adalah menyemak status pesanan, mengambil ringkasan pelanggan, atau menyenaraikan invois terkini. Bungkus perkara tersebut sebagai alatan, sediakan melalui stdio, dan biarkan seorang rakan sekerja menggunakannya. Perhatikan apa yang dilakukan dengan baik oleh model dan di mana ia tersandung. Anda akan belajar lebih banyak daripada tiga alatan tersebut berbanding merancang tiga puluh alatan.
MCP adalah jambatan, bukan pengganti aplikasi anda. Kod PHP anda sudah pun mengetahui perniagaan anda. Protokol tersebut hanya membolehkan model melintas dan mengajukan soalan kepadanya.
