-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathCalculatorTool.php
More file actions
87 lines (75 loc) · 2.84 KB
/
Copy pathCalculatorTool.php
File metadata and controls
87 lines (75 loc) · 2.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
<?php
declare(strict_types=1);
namespace Tinywan\Mcp\Examples\Calculator;
use Tinywan\Mcp\Contracts\ToolInterface;
use Tinywan\Mcp\Runtime\ExecutionContext;
use Tinywan\Mcp\Tool\Content\TextContent;
use Tinywan\Mcp\Tool\ToolCall;
use Tinywan\Mcp\Tool\ToolDefinition;
use Tinywan\Mcp\Tool\ToolResult;
final class CalculatorTool implements ToolInterface
{
public function definition(): ToolDefinition
{
return new ToolDefinition(
'calculate',
'Perform one arithmetic operation on two numbers.',
[
'type' => 'object',
'properties' => [
'operation' => ['type' => 'string', 'enum' => ['add', 'subtract', 'multiply', 'divide']],
'left' => ['type' => 'number'],
'right' => ['type' => 'number'],
],
'required' => ['operation', 'left', 'right'],
'additionalProperties' => false,
],
[
'type' => 'object',
'properties' => ['value' => ['type' => 'number']],
'required' => ['value'],
'additionalProperties' => false,
],
'Calculator',
);
}
public function call(ToolCall $call, ExecutionContext $context): ToolResult
{
$operation = $this->stringArgument($call, 'operation');
$left = $this->numberArgument($call, 'left');
$right = $this->numberArgument($call, 'right');
if ($operation === null || $left === null || $right === null) {
return ToolResult::error([new TextContent('Invalid calculator arguments.')]);
}
if ($operation === 'divide' && $right === 0.0) {
return ToolResult::error([new TextContent('Division by zero is not allowed.')]);
}
$value = match ($operation) {
'add' => $left + $right,
'subtract' => $left - $right,
'multiply' => $left * $right,
'divide' => $left / $right,
default => null,
};
if ($value === null) {
return ToolResult::error([new TextContent('Unsupported calculator operation.')]);
}
return ToolResult::success([new TextContent((string) $value)], ['value' => $value]);
}
private function stringArgument(ToolCall $call, string $name): ?string
{
return array_key_exists($name, $call->arguments) && is_string($call->arguments[$name])
? $call->arguments[$name]
: null;
}
private function numberArgument(ToolCall $call, string $name): ?float
{
if (!array_key_exists($name, $call->arguments)) {
return null;
}
if (is_int($call->arguments[$name]) || is_float($call->arguments[$name])) {
return (float) $call->arguments[$name];
}
return null;
}
}