1313
1414use Mcp \Capability \Attribute \McpResource ;
1515use 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 ' ).'. ' ];
0 commit comments