You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
[Server] Fix: standardize error handling across handlers with MCP specificatio… (#124)
* fix: standardize error handling across handlers with MCP specification compliance
* Update mcp-elements.md
Co-authored-by: Christopher Hertel <mail@christopher-hertel.de>
* docs: clarify error handling behavior for all element types
* docs: remove unnecessary whitespace in mcp-elements.md
* fix: simplify exception signatures to accept simple messages
* refactor: use specific exceptions in examples for better error handling
* feat: throw exceptions from reference provider instead of returning null
---------
Co-authored-by: Christopher Hertel <mail@christopher-hertel.de>
Copy file name to clipboardExpand all lines: docs/mcp-elements.md
+36-19Lines changed: 36 additions & 19 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -154,31 +154,37 @@ public function getMultipleContent(): array
154
154
155
155
#### Error Handling
156
156
157
-
Tools can throw exceptions which are automatically converted to proper JSON-RPC error responses:
157
+
Tool handlers can throw any exception, but the type determines how it's handled:
158
+
159
+
-**`ToolCallException`**: Converted to JSON-RPC response with `CallToolResult` where `isError: true`, allowing the LLM to see the error message and self-correct
160
+
-**Any other exception**: Converted to JSON-RPC error response, but with a generic error message
158
161
159
162
```php
163
+
use Mcp\Exception\ToolCallException;
164
+
160
165
#[McpTool]
161
166
public function divideNumbers(float $a, float $b): float
162
167
{
163
168
if ($b === 0.0) {
164
-
throw new \InvalidArgumentException('Division by zero is not allowed');
169
+
throw new ToolCallException('Division by zero is not allowed');
165
170
}
166
-
171
+
167
172
return $a / $b;
168
173
}
169
174
170
175
#[McpTool]
171
176
public function processFile(string $filename): string
172
177
{
173
178
if (!file_exists($filename)) {
174
-
throw new \InvalidArgumentException("File not found: {$filename}");
179
+
throw new ToolCallException("File not found: {$filename}");
175
180
}
176
-
181
+
177
182
return file_get_contents($filename);
178
183
}
179
184
```
180
185
181
-
The SDK will convert these exceptions into appropriate JSON-RPC error responses that MCP clients can understand.
186
+
**Recommendation**: Use `ToolCallException` when you want to communicate specific errors to clients. Any other exception will still be converted to JSON-RPC compliant errors but with generic error messages.
187
+
182
188
183
189
## Resources
184
190
@@ -298,24 +304,31 @@ public function getMultipleResources(): array
298
304
299
305
#### Error Handling
300
306
301
-
Resource handlers can throw exceptions for error cases:
307
+
Resource handlers can throw any exception, but the type determines how it's handled:
308
+
309
+
-**`ResourceReadException`**: Converted to JSON-RPC error response with the actual exception message
310
+
-**Any other exception**: Converted to JSON-RPC error response, but with a generic error message
302
311
303
312
```php
313
+
use Mcp\Exception\ResourceReadException;
314
+
304
315
#[McpResource(uri: 'file://{path}')]
305
316
public function getFile(string $path): string
306
317
{
307
318
if (!file_exists($path)) {
308
-
throw new \InvalidArgumentException("File not found: {$path}");
319
+
throw new ResourceReadException("File not found: {$path}");
309
320
}
310
-
321
+
311
322
if (!is_readable($path)) {
312
-
throw new \RuntimeException("File not readable: {$path}");
323
+
throw new ResourceReadException("File not readable: {$path}");
313
324
}
314
-
325
+
315
326
return file_get_contents($path);
316
327
}
317
328
```
318
329
330
+
**Recommendation**: Use `ResourceReadException` when you want to communicate specific errors to clients. Any other exception will still be converted to JSON-RPC compliant errors but with generic error messages.
331
+
319
332
## Resource Templates
320
333
321
334
Resource templates are **dynamic resources** that use parameterized URIs with variables. They follow all the same rules
@@ -449,40 +462,44 @@ public function explicitMessages(): array
449
462
}
450
463
```
451
464
465
+
The SDK automatically validates that all messages have valid roles and converts the result into the appropriate MCP prompt message format.
466
+
452
467
#### Valid Message Roles
453
468
454
469
-**`user`**: User input or questions
455
470
-**`assistant`**: Assistant responses/system
456
471
457
472
#### Error Handling
458
473
459
-
Prompt handlers can throw exceptions for invalid inputs:
474
+
Prompt handlers can throw any exception, but the type determines how it's handled:
475
+
-**`PromptGetException`**: Converted to JSON-RPC error response with the actual exception message
476
+
-**Any other exception**: Converted to JSON-RPC error response, but with a generic error message
460
477
461
478
```php
479
+
use Mcp\Exception\PromptGetException;
480
+
462
481
#[McpPrompt]
463
482
public function generatePrompt(string $topic, string $style): array
464
483
{
465
484
$validStyles = ['casual', 'formal', 'technical'];
466
-
485
+
467
486
if (!in_array($style, $validStyles)) {
468
-
throw new \InvalidArgumentException(
487
+
throw new PromptGetException(
469
488
"Invalid style '{$style}'. Must be one of: " . implode(', ', $validStyles)
470
489
);
471
490
}
472
-
491
+
473
492
return [
474
493
['role' => 'user', 'content' => "Write about {$topic} in a {$style} style"]
475
494
];
476
495
}
477
496
```
478
497
479
-
The SDK automatically validates that all messages have valid roles and converts the result into the appropriate MCP prompt message format.
498
+
**Recommendation**: Use `PromptGetException` when you want to communicate specific errors to clients. Any other exception will still be converted to JSON-RPC compliant errors but with generic error messages.
480
499
481
500
## Completion Providers
482
501
483
-
Completion providers help MCP clients offer auto-completion suggestions for Resource Templates and Prompts. Unlike Tools
484
-
and static Resources (which can be listed via `tools/list` and `resources/list`), Resource Templates and Prompts have
485
-
dynamic parameters that benefit from completion hints.
502
+
Completion providers help MCP clients offer auto-completion suggestions for Resource Templates and Prompts. Unlike Tools and static Resources (which can be listed via `tools/list` and `resources/list`), Resource Templates and Prompts have dynamic parameters that benefit from completion hints.
0 commit comments