PHPackages                             code-wheel/mcp-events - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. code-wheel/mcp-events

ActiveLibrary

code-wheel/mcp-events
=====================

Standardized event classes for MCP (Model Context Protocol) tool execution lifecycle

v2.1.1(3mo ago)1734↓67.9%MITPHPPHP &gt;=8.1CI passing

Since Jan 9Pushed 3mo agoCompare

[ Source](https://github.com/code-wheel/mcp-events-php)[ Packagist](https://packagist.org/packages/code-wheel/mcp-events)[ RSS](/packages/code-wheel-mcp-events/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (3)Dependencies (1)Versions (5)Used By (0)

MCP Events
==========

[](#mcp-events)

[![CI](https://github.com/code-wheel/mcp-events/actions/workflows/ci.yml/badge.svg)](https://github.com/code-wheel/mcp-events/actions/workflows/ci.yml)[![codecov](https://camo.githubusercontent.com/504b29d401fa3b953caf7325192b18492f0a54a703f15c5b8f09774e1dcc5615/68747470733a2f2f636f6465636f762e696f2f67682f636f64652d776865656c2f6d63702d6576656e74732f67726170682f62616467652e737667)](https://codecov.io/gh/code-wheel/mcp-events)[![Latest Stable Version](https://camo.githubusercontent.com/7d05864b29837d11ce4d5ea35d25f9505918ddf87c8cfb2ac52ff5a2d2a27e51/68747470733a2f2f706f7365722e707567782e6f72672f636f64652d776865656c2f6d63702d6576656e74732f76)](https://packagist.org/packages/code-wheel/mcp-events)[![PHP Version](https://camo.githubusercontent.com/30dfe2a2ffe6887bce0ce3f09212c67aac89b9491f27abdf89d253c55c9e29e0/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f636f64652d776865656c2f6d63702d6576656e74732e737667)](https://packagist.org/packages/code-wheel/mcp-events)[![License](https://camo.githubusercontent.com/d0b5c593d437b2760b4f3f7d83a3f2346d35e06caa63e43ce71c4d342656a60f/68747470733a2f2f706f7365722e707567782e6f72672f636f64652d776865656c2f6d63702d6576656e74732f6c6963656e7365)](https://packagist.org/packages/code-wheel/mcp-events)

Standardized event classes for MCP (Model Context Protocol) tool execution lifecycle in PHP.

**Zero dependencies** - pure PHP 8.1+, framework-agnostic.

Installation
------------

[](#installation)

```
composer require code-wheel/mcp-events
```

Usage
-----

[](#usage)

These events follow a standard structure for MCP tool execution observability. Use them with any PSR-14 compatible event dispatcher.

### Dispatching Events

[](#dispatching-events)

```
use CodeWheel\McpEvents\ToolExecutionStartedEvent;
use CodeWheel\McpEvents\ToolExecutionSucceededEvent;
use CodeWheel\McpEvents\ToolExecutionFailedEvent;

// When tool execution starts
$startEvent = new ToolExecutionStartedEvent(
    toolName: 'create_user',
    pluginId: 'my_module.create_user',
    arguments: ['username' => 'john', 'email' => '[redacted]'],
    requestId: 'req-123',
    timestamp: microtime(true),
);
$dispatcher->dispatch($startEvent);

// On success
$successEvent = new ToolExecutionSucceededEvent(
    toolName: 'create_user',
    pluginId: 'my_module.create_user',
    arguments: ['username' => 'john', 'email' => '[redacted]'],
    result: $callToolResult,
    durationMs: 45.2,
    requestId: 'req-123',
);
$dispatcher->dispatch($successEvent);

// On failure
$failEvent = new ToolExecutionFailedEvent(
    toolName: 'create_user',
    pluginId: 'my_module.create_user',
    arguments: ['username' => 'john'],
    reason: ToolExecutionFailedEvent::REASON_VALIDATION,
    result: null,
    exception: $validationException,
    durationMs: 12.5,
    requestId: 'req-123',
);
$dispatcher->dispatch($failEvent);
```

### Listening to Events

[](#listening-to-events)

```
use CodeWheel\McpEvents\ToolExecutionStartedEvent;
use CodeWheel\McpEvents\ToolExecutionSucceededEvent;
use CodeWheel\McpEvents\ToolExecutionFailedEvent;

class ToolExecutionLogger {

    public function onStart(ToolExecutionStartedEvent $event): void {
        $this->logger->info('Tool started', [
            'tool' => $event->toolName,
            'request_id' => $event->requestId,
        ]);
    }

    public function onSuccess(ToolExecutionSucceededEvent $event): void {
        $this->metrics->histogram('tool_duration_ms', $event->durationMs, [
            'tool' => $event->toolName,
        ]);
    }

    public function onFailure(ToolExecutionFailedEvent $event): void {
        $context = [
            'tool' => $event->toolName,
            'reason' => $event->reason,
            'duration_ms' => $event->durationMs,
        ];

        if ($event->hasException()) {
            $context['exception'] = $event->exception->getMessage();
        }

        if ($event->isPolicyFailure()) {
            $this->logger->warning('Tool blocked by policy', $context);
        } else {
            $this->logger->error('Tool execution failed', $context);
        }
    }
}
```

Events
------

[](#events)

### ToolExecutionStartedEvent

[](#toolexecutionstartedevent)

Dispatched when tool execution begins.

PropertyTypeDescription`toolName`stringMCP tool name`pluginId`stringImplementation plugin ID`arguments`arraySanitized tool arguments`requestId`string|int|nullMCP request correlation ID`timestamp`floatStart timestamp (microtime)### ToolExecutionSucceededEvent

[](#toolexecutionsucceededevent)

Dispatched when tool execution completes successfully.

PropertyTypeDescription`toolName`stringMCP tool name`pluginId`stringImplementation plugin ID`arguments`arraySanitized tool arguments`result`objectResult object (e.g., CallToolResult from mcp/sdk)`durationMs`floatExecution duration in ms`requestId`string|int|nullMCP request correlation ID### ToolExecutionFailedEvent

[](#toolexecutionfailedevent)

Dispatched when tool execution fails.

PropertyTypeDescription`toolName`stringMCP tool name`pluginId`stringImplementation plugin ID`arguments`arraySanitized tool arguments`reason`stringFailure reason constant`result`object|nullResult object if available`exception`Throwable|nullException if thrown`durationMs`floatDuration until failure in ms`requestId`string|int|nullMCP request correlation IDFailure Reasons
---------------

[](#failure-reasons)

ConstantDescription`REASON_VALIDATION`Input validation failed`REASON_ACCESS_DENIED`Permission denied`REASON_INSTANTIATION`Failed to create tool instance`REASON_INVALID_TOOL`Tool not found or invalid`REASON_RESULT`Result processing failed`REASON_EXECUTION`General execution failure`REASON_POLICY`Blocked by policy`REASON_POLICY_APPROVAL`Requires approval`REASON_POLICY_BUDGET`Budget exceeded`REASON_POLICY_DRY_RUN`Dry run mode`REASON_POLICY_SCOPE`Insufficient scopeHelper Methods
--------------

[](#helper-methods)

```
// Check if failure was policy-related
if ($event->isPolicyFailure()) {
    // Handle policy block differently
}

// Check if exception was thrown
if ($event->hasException()) {
    $exception = $event->exception;
}

// Get all valid failure reasons
$allReasons = ToolExecutionFailedEvent::allReasons();
// ['REASON_VALIDATION' => 'validation_failed', ...]

// Validate a reason string
if (ToolExecutionFailedEvent::isValidReason($reason)) {
    // Valid reason
}
```

JSON Serialization
------------------

[](#json-serialization)

All events implement `JsonSerializable` for easy logging:

```
// Direct serialization
$json = json_encode($event);

// Or get the array
$data = $event->jsonSerialize();

// Example output for ToolExecutionFailedEvent:
// {
//   "event": "tool_execution_failed",
//   "tool_name": "create_user",
//   "plugin_id": "my_module.create_user",
//   "reason": "validation_failed",
//   "duration_ms": 12.5,
//   "request_id": "req-123",
//   "is_policy_failure": false,
//   "has_exception": true,
//   "exception_class": "InvalidArgumentException",
//   "exception_message": "Email is required"
// }
```

Note: The `result` object is intentionally excluded from serialization as it may contain sensitive data.

Framework Integration
---------------------

[](#framework-integration)

This package has zero dependencies. When using with `mcp/sdk`, the `result` object will be a `CallToolResult`:

```
// With mcp/sdk (optional)
use Mcp\Schema\Result\CallToolResult;

$event = new ToolExecutionSucceededEvent(
    toolName: 'my_tool',
    pluginId: 'my_module.my_tool',
    arguments: [],
    result: $callToolResult, // CallToolResult from mcp/sdk
    durationMs: 10.5,
    requestId: null,
);

// Access result properties
$structured = $event->result->structuredContent;
```

License
-------

[](#license)

MIT

###  Health Score

42

—

FairBetter than 89% of packages

Maintenance83

Actively maintained with recent releases

Popularity21

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

4

Last Release

119d ago

Major Versions

v1.0.0 → v2.0.02026-01-09

### Community

Maintainers

![](https://www.gravatar.com/avatar/4cb6eebdce9234e8ad086e2786111257d1f959a3f7323c9fdae46c600082f646?d=identicon)[mowens3](/maintainers/mowens3)

---

Top Contributors

[![mowens3](https://avatars.githubusercontent.com/u/1635473?v=4)](https://github.com/mowens3 "mowens3 (10 commits)")

---

Tags

mcpaieventsobservabilityllmModel Context Protocol

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/code-wheel-mcp-events/health.svg)

```
[![Health](https://phpackages.com/badges/code-wheel-mcp-events/health.svg)](https://phpackages.com/packages/code-wheel-mcp-events)
```

###  Alternatives

[php-mcp/laravel

Laravel SDK for building Model Context Protocol (MCP) servers - Seamlessly integrate MCP tools, resources, and prompts into Laravel applications

47283.1k1](/packages/php-mcp-laravel)[vizra/vizra-adk

Vizra Agent Development Kit - A comprehensive Laravel package for building intelligent AI agents.

29026.1k](/packages/vizra-vizra-adk)[wordpress/mcp-adapter

Adapter for Abilities API, letting WordPress abilities to be used as MCP tools, resources or prompts

74855.8k1](/packages/wordpress-mcp-adapter)[klapaudius/symfony-mcp-server

Build your own LLM tools inside your symfony project by adding to it a Model Context Protocol Server

2716.5k](/packages/klapaudius-symfony-mcp-server)[mischasigtermans/laravel-toon

Token-Optimized Object Notation encoder/decoder for Laravel with intelligent nested object handling

13113.1k](/packages/mischasigtermans-laravel-toon)[symfony/ai-mate

AI development assistant MCP server for Symfony projects

1624.9k10](/packages/symfony-ai-mate)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
