October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PCOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk5 min

Building a Conformant stdio MCP Server in PHP

A conformant stdio MCP server in PHP keeps stdout limited to JSON-RPC messages and follows the lifecycle of the protocol revision its client uses. Here is how to build and check one with the official PHP SDK.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A stdio MCP server written in PHP is conformant when two things hold at once: stdout carries only valid JSON-RPC messages, and the startup behavior matches the protocol revision the client negotiates. The official PHP MCP SDK (mcp/sdk) is the most direct documented route to both, and most of the work is in keeping the protocol channel clean rather than in the PHP API itself.

What a stdio client expects from your process

In stdio mode the MCP client launches your server as a child process. The client writes requests and notifications to the server’s stdin, and the server writes responses and notifications to its stdout. Nothing else is part of the conversation. The MCP specification’s Transports section, version 2025-11-25, sets the rules that matter for PHP code:

  • Messages are JSON-RPC and UTF-8 encoded.
  • Each message is newline-delimited and must not contain embedded newlines. Pretty-printed JSON is therefore not an option, even though it is valid JSON.
  • The server must not write anything to stdout that is not a valid MCP message. The specification states this as: “The server MUST NOT write anything to its stdout that is not a valid MCP message.”
  • Stderr is the channel for informational, debug, and error logs. Clients may capture it or ignore it, so output on stderr does not by itself mean the server failed.

Prerequisites and installation

  1. Confirm that the runtime is PHP 8.1 or newer. This is the requirement listed on the official PHP SDK landing page.
  2. In the project root, run composer require mcp/sdk.
  3. Note the SDK’s status before you build anything long-lived. The SDK identifies itself as a collaboration between the PHP Foundation and Symfony, and it describes itself as experimental until version 1.0. Method names and builder calls can change, so check the SDK’s current documentation before you rely on a specific API.

Build the entry point

Put the server script beside Composer’s vendor/ directory, for example server.php. The SDK’s first-server guide follows this pattern, and the steps below mirror it:

  1. Load Composer’s autoloader with require __DIR__ . '/vendor/autoload.php';.
  2. Set the server’s name and version in the server builder.
  3. Register the tools, resources, or prompts you want to expose. Use the builder calls shown in the SDK’s current first-server guide, since those names follow the SDK version you install.
  4. Build the server object.
  5. Run it with McpServerTransportStdioTransport. The transport owns stdin and stdout, so nothing else in the script should write to them.

Keep the script free of any code that runs before the transport starts. A stray echo in a config file or an included bootstrap file will break the first exchange just as thoroughly as one inside a tool handler.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Keep stdout limited to protocol messages

Stdout discipline is where most stdio servers fail, and PHP makes it easy to break. The following sources of stray output are the usual ones:

Source of output Where it goes by default in the PHP CLI Fix
echo, print, print_r, var_dump Stdout Remove them, or write diagnostics with fwrite(STDERR, $message . PHP_EOL);
Warnings, notices, and deprecations shown because display_errors is enabled Stdout Run the server with php -d display_errors=stderr server.php, or set display_errors to stderr in the PHP configuration used by the client’s launch command
error_log() Stderr when no error_log destination is configured Safe to use. Set an explicit error_log file if you want logs to persist
Leading whitespace, a byte-order mark, or a closing ?> followed by a newline in a PHP file Stdout Save files without a BOM, omit the closing tag in PHP-only files, and check that the first byte of the entry point is <?php
Output from a third-party library during construction Stdout Find the call with a search for echo or printf in the vendor code, and redirect or suppress it before the transport starts

Each of these produces output that a client reads as a malformed message, even when the server’s logic is correct. If a client reports a parse error on a response it has never seen, check stdout first.

Match the lifecycle to the client’s protocol revision

Initialization is the second conformance question, and it depends on which revision the client uses. The PHP SDK’s protocol documentation separates the 2026-07-28 modern lifecycle from the earlier handshake family, so an implementation cannot assume a single flow works everywhere.

Aspect Handshake lifecycle (MCP specification, Lifecycle section, version 2025-11-25) Modern lifecycle (PHP SDK protocol documentation, revision 2026-07-28)
First exchange The client sends initialize, and the server responds with a negotiated protocol version and its capabilities No initialize handshake. Each request carries version and capability information
Readiness signal The client sends notifications/initialized before normal operation Not required, because no handshake exists
Shutdown behavior Described in the Lifecycle section for this revision Not stated in the sources consulted for this article

For a server that targets clients speaking the 2025-11-25 revision, the legacy flow is:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. The client starts the server process and sends initialize on stdin.
  2. The server replies on stdout with the negotiated protocol version and its capabilities.
  3. The client sends notifications/initialized.
  4. Normal requests such as tool listing and tool calls begin.

Do not describe this sequence as universal. The 2026-07-28 revision removes the handshake, so a server that waits for initialize will stall against a client that never sends it. Identify the revision your target client uses, and test against that client rather than assuming one exchange covers every version.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Check the server with the MCP Inspector

The SDK documentation describes the MCP Inspector as the interactive way to inspect a server’s exposed elements. From the project root, run:

npx @modelcontextprotocol/inspector php server.php

The Inspector lists the tools, resources, and prompts the server exposes and lets you invoke them. Use it as a manual check of the wire behavior:

  • Every tool, resource, or prompt you registered appears in the list.
  • Invoking a tool returns a well-formed result rather than a parse error.
  • Diagnostic messages you wrote appear as stderr output, not inside the protocol stream.

If the Inspector cannot connect or reports malformed responses, the most likely cause is stray output on stdout, so start with the table in the stdout section above.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

When stdio is the wrong transport

Stdio fits a local server that a desktop or command-line host launches for its own use. The SDK also supports Streamable HTTP, which suits remote or web-hosted integrations. The two differ in deployment model, message channel, and session handling:

Transport Deployment model Message channel Lifecycle and session notes
stdio Local child process launched by the client stdin for client messages, stdout for server messages Governed by the stdout rules and the revision-specific lifecycle described above
Streamable HTTP Remote or web-hosted service HTTP Covered by the SDK’s HTTP documentation; not covered in this article

If your server runs on the user’s machine and the host starts it, stdio is the right transport. A deployment that other machines reach over a network needs the HTTP route instead, with its own setup.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.