Skip to content

Commit 14c5091

Browse files
committed
Implemented MCP logging specification with auto-injection
1 parent 345b94d commit 14c5091

26 files changed

+2204
-22
lines changed

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
"Mcp\\Example\\StdioDiscoveryCalculator\\": "examples/stdio-discovery-calculator/",
6161
"Mcp\\Example\\StdioEnvVariables\\": "examples/stdio-env-variables/",
6262
"Mcp\\Example\\StdioExplicitRegistration\\": "examples/stdio-explicit-registration/",
63+
"Mcp\\Example\\StdioLoggingShowcase\\": "examples/stdio-logging-showcase/",
6364
"Mcp\\Tests\\": "tests/"
6465
}
6566
},

examples/stdio-discovery-calculator/McpElements.php

Lines changed: 74 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@
1313

1414
use Mcp\Capability\Attribute\McpResource;
1515
use Mcp\Capability\Attribute\McpTool;
16-
use Psr\Log\LoggerInterface;
17-
use Psr\Log\NullLogger;
16+
use Mcp\Capability\Logger\McpLogger;
1817

1918
/**
2019
* @phpstan-type Config array{precision: int, allow_negative: bool}
@@ -29,27 +28,28 @@ final class McpElements
2928
'allow_negative' => true,
3029
];
3130

32-
public function __construct(
33-
private readonly LoggerInterface $logger = new NullLogger(),
34-
) {
35-
}
36-
3731
/**
3832
* Performs a calculation based on the operation.
3933
*
4034
* Supports 'add', 'subtract', 'multiply', 'divide'.
4135
* Obeys the 'precision' and 'allow_negative' settings from the config resource.
4236
*
43-
* @param float $a the first operand
44-
* @param float $b the second operand
45-
* @param string $operation the operation ('add', 'subtract', 'multiply', 'divide')
37+
* @param float $a the first operand
38+
* @param float $b the second operand
39+
* @param string $operation the operation ('add', 'subtract', 'multiply', 'divide')
40+
* @param McpLogger $logger Auto-injected MCP logger
4641
*
4742
* @return float|string the result of the calculation, or an error message string
4843
*/
4944
#[McpTool(name: 'calculate')]
50-
public function calculate(float $a, float $b, string $operation): float|string
45+
public function calculate(float $a, float $b, string $operation, McpLogger $logger): float|string
5146
{
52-
$this->logger->info(\sprintf('Calculating: %f %s %f', $a, $operation, $b));
47+
$logger->info('🧮 Calculate tool called', [
48+
'operand_a' => $a,
49+
'operand_b' => $b,
50+
'operation' => $operation,
51+
'auto_injection' => 'McpLogger auto-injected successfully',
52+
]);
5353

5454
$op = strtolower($operation);
5555

@@ -65,25 +65,48 @@ public function calculate(float $a, float $b, string $operation): float|string
6565
break;
6666
case 'divide':
6767
if (0 == $b) {
68+
$logger->warning('Division by zero attempted', [
69+
'operand_a' => $a,
70+
'operand_b' => $b,
71+
]);
72+
6873
return 'Error: Division by zero.';
6974
}
7075
$result = $a / $b;
7176
break;
7277
default:
78+
$logger->error('Unknown operation requested', [
79+
'operation' => $operation,
80+
'supported_operations' => ['add', 'subtract', 'multiply', 'divide'],
81+
]);
82+
7383
return "Error: Unknown operation '{$operation}'. Supported: add, subtract, multiply, divide.";
7484
}
7585

7686
if (!$this->config['allow_negative'] && $result < 0) {
87+
$logger->warning('Negative result blocked by configuration', [
88+
'result' => $result,
89+
'allow_negative_setting' => false,
90+
]);
91+
7792
return 'Error: Negative results are disabled.';
7893
}
7994

80-
return round($result, $this->config['precision']);
95+
$finalResult = round($result, $this->config['precision']);
96+
$logger->info('✅ Calculation completed successfully', [
97+
'result' => $finalResult,
98+
'precision' => $this->config['precision'],
99+
]);
100+
101+
return $finalResult;
81102
}
82103

83104
/**
84105
* Provides the current calculator configuration.
85106
* Can be read by clients to understand precision etc.
86107
*
108+
* @param McpLogger $logger Auto-injected MCP logger for demonstration
109+
*
87110
* @return Config the configuration array
88111
*/
89112
#[McpResource(
@@ -92,9 +115,12 @@ public function calculate(float $a, float $b, string $operation): float|string
92115
description: 'Current settings for the calculator tool (precision, allow_negative).',
93116
mimeType: 'application/json',
94117
)]
95-
public function getConfiguration(): array
118+
public function getConfiguration(McpLogger $logger): array
96119
{
97-
$this->logger->info('Resource config://calculator/settings read.');
120+
$logger->info('📊 Resource config://calculator/settings accessed via auto-injection!', [
121+
'current_config' => $this->config,
122+
'auto_injection_demo' => 'McpLogger was automatically injected into this resource handler',
123+
]);
98124

99125
return $this->config;
100126
}
@@ -103,8 +129,9 @@ public function getConfiguration(): array
103129
* Updates a specific configuration setting.
104130
* Note: This requires more robust validation in a real app.
105131
*
106-
* @param string $setting the setting key ('precision' or 'allow_negative')
107-
* @param mixed $value the new value (int for precision, bool for allow_negative)
132+
* @param string $setting the setting key ('precision' or 'allow_negative')
133+
* @param mixed $value the new value (int for precision, bool for allow_negative)
134+
* @param McpLogger $logger Auto-injected MCP logger
108135
*
109136
* @return array{
110137
* success: bool,
@@ -113,18 +140,37 @@ public function getConfiguration(): array
113140
* } success message or error
114141
*/
115142
#[McpTool(name: 'update_setting')]
116-
public function updateSetting(string $setting, mixed $value): array
143+
public function updateSetting(string $setting, mixed $value, McpLogger $logger): array
117144
{
118-
$this->logger->info(\sprintf('Setting tool called: setting=%s, value=%s', $setting, var_export($value, true)));
145+
$logger->info('🔧 Update setting tool called', [
146+
'setting' => $setting,
147+
'value' => $value,
148+
'current_config' => $this->config,
149+
'auto_injection' => 'McpLogger auto-injected successfully',
150+
]);
119151
if (!\array_key_exists($setting, $this->config)) {
152+
$logger->error('Unknown setting requested', [
153+
'setting' => $setting,
154+
'available_settings' => array_keys($this->config),
155+
]);
156+
120157
return ['success' => false, 'error' => "Unknown setting '{$setting}'."];
121158
}
122159

123160
if ('precision' === $setting) {
124161
if (!\is_int($value) || $value < 0 || $value > 10) {
162+
$logger->warning('Invalid precision value provided', [
163+
'value' => $value,
164+
'valid_range' => '0-10',
165+
]);
166+
125167
return ['success' => false, 'error' => 'Invalid precision value. Must be integer between 0 and 10.'];
126168
}
127169
$this->config['precision'] = $value;
170+
$logger->info('✅ Precision setting updated', [
171+
'new_precision' => $value,
172+
'previous_config' => $this->config,
173+
]);
128174

129175
// In real app, notify subscribers of config://calculator/settings change
130176
// $registry->notifyResourceChanged('config://calculator/settings');
@@ -138,10 +184,19 @@ public function updateSetting(string $setting, mixed $value): array
138184
} elseif (\in_array(strtolower((string) $value), ['false', '0', 'no', 'off'])) {
139185
$value = false;
140186
} else {
187+
$logger->warning('Invalid allow_negative value provided', [
188+
'value' => $value,
189+
'expected_type' => 'boolean',
190+
]);
191+
141192
return ['success' => false, 'error' => 'Invalid allow_negative value. Must be boolean (true/false).'];
142193
}
143194
}
144195
$this->config['allow_negative'] = $value;
196+
$logger->info('✅ Allow negative setting updated', [
197+
'new_allow_negative' => $value,
198+
'updated_config' => $this->config,
199+
]);
145200

146201
// $registry->notifyResourceChanged('config://calculator/settings');
147202
return ['success' => true, 'message' => 'Allow negative results set to '.($value ? 'true' : 'false').'.'];

examples/stdio-discovery-calculator/server.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
->setServerInfo('Stdio Calculator', '1.1.0', 'Basic Calculator over STDIO transport.')
2323
->setContainer(container())
2424
->setLogger(logger())
25+
->enableMcpLogging() // Enable MCP logging capability and auto-injection!
2526
->setDiscovery(__DIR__, ['.'])
2627
->build();
2728

0 commit comments

Comments
 (0)