Summary
src/Protocol.php:123 accesses ->id on a PhpMcp\Schema\JsonRpc\Notification, which by JSON-RPC 2.0 spec has no id (that's exactly what distinguishes a notification from a request). In a strict/production PHP environment this "Undefined property" notice is promoted to an ErrorException, so the request aborts with an HTTP 500. Any MCP client that sends a notification (e.g. notifications/initialized immediately after the initialize handshake) trips it, which can take down the whole session — every subsequent method call then 500s.
Error
production.ERROR: Undefined property: PhpMcp\Schema\JsonRpc\Notification::$id
{"exception":"[object] (ErrorException(code: 0): Undefined property: PhpMcp\Schema\JsonRpc\Notification::$id
at .../vendor/php-mcp/server/src/Protocol.php:123)
#0 .../Illuminate/Foundation/Bootstrap/HandleExceptions.php(256):
Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(2, 'Undefined prope...', '.../Protocol.php', 123)
Version
php-mcp/server dev-main (as vendored by the Leantime MCP-server plugin).
Environment / how it surfaced
- Self-hosted Leantime (Laravel 11) with its MCP-server plugin, PHP 8.x,
APP_ENV=production (where undefined-property notices become ErrorExceptions and fault the request).
- The MCP protocol endpoint returns HTTP 500 on every method call from a client that sends a notification. Observed with a standard MCP stdio bridge that sends
notifications/initialized right after initialize.
- Leantime's separate non-MCP JSON-RPC endpoint (
/api/jsonrpc) is unaffected — only the MCP protocol path (Protocol.php) fails, which points at notification handling rather than the app.
Likely cause / suggested fix
Protocol.php reads $message->id without distinguishing a Request (has id) from a Notification (no id). A guard before the property access would fix it — e.g. branch on the message type (instanceof Request) before reading id, or read it defensively ($id = $message instanceof Notification ? null : $message->id;). Notifications should be dispatched without ever touching id.
Happy to test a patch against this setup if useful.
Summary
src/Protocol.php:123accesses->idon aPhpMcp\Schema\JsonRpc\Notification, which by JSON-RPC 2.0 spec has noid(that's exactly what distinguishes a notification from a request). In a strict/production PHP environment this "Undefined property" notice is promoted to anErrorException, so the request aborts with an HTTP 500. Any MCP client that sends a notification (e.g.notifications/initializedimmediately after theinitializehandshake) trips it, which can take down the whole session — every subsequent method call then 500s.Error
Version
php-mcp/serverdev-main(as vendored by the Leantime MCP-server plugin).Environment / how it surfaced
APP_ENV=production(where undefined-property notices becomeErrorExceptions and fault the request).notifications/initializedright afterinitialize./api/jsonrpc) is unaffected — only the MCP protocol path (Protocol.php) fails, which points at notification handling rather than the app.Likely cause / suggested fix
Protocol.phpreads$message->idwithout distinguishing aRequest(hasid) from aNotification(noid). A guard before the property access would fix it — e.g. branch on the message type (instanceof Request) before readingid, or read it defensively ($id = $message instanceof Notification ? null : $message->id;). Notifications should be dispatched without ever touchingid.Happy to test a patch against this setup if useful.