Skip to content

Commit db45077

Browse files
committed
feat: add 'application info' tool
1 parent 688830d commit db45077

File tree

2 files changed

+103
-0
lines changed

2 files changed

+103
-0
lines changed

src/Mcp/Tools/ApplicationInfo.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
namespace Laravel\Boost\Mcp\Tools;
4+
5+
use Laravel\Mcp\Server\Tool;
6+
use Laravel\Mcp\Server\Tools\Annotations\IsReadOnly;
7+
use Laravel\Mcp\Server\Tools\ToolInputSchema;
8+
use Laravel\Mcp\Server\Tools\ToolResult;
9+
use Laravel\Roster\Roster;
10+
11+
#[IsReadOnly]
12+
class ApplicationInfo extends Tool
13+
{
14+
public function __construct(protected Roster $roster)
15+
{
16+
}
17+
18+
public function description(): string
19+
{
20+
return 'Get comprehensive application information including PHP version, Laravel version, database engine, and all installed packages with their versions. You should use this tool on each new chat, and use the package & version data to write version specific code for the packages that exist.';
21+
}
22+
23+
public function schema(ToolInputSchema $schema): ToolInputSchema
24+
{
25+
return $schema;
26+
}
27+
28+
/**
29+
* @param array<string> $arguments
30+
*/
31+
public function handle(array $arguments): ToolResult
32+
{
33+
$packages = [];
34+
foreach ($this->roster->packages() as $package) {
35+
$packages[] = [
36+
'name' => $package->name(),
37+
'version' => $package->version(),
38+
];
39+
}
40+
41+
return ToolResult::json([
42+
'php_version' => PHP_VERSION,
43+
'laravel_version' => app()->version(),
44+
'database_engine' => config('database.default'),
45+
'packages' => $packages,
46+
]);
47+
}
48+
}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
use Laravel\Boost\Mcp\Tools\ApplicationInfo;
4+
use Laravel\Mcp\Server\Tools\ToolResult;
5+
use Laravel\Roster\Enums\Packages;
6+
use Laravel\Roster\Package;
7+
use Laravel\Roster\Roster;
8+
9+
test('it returns application info with packages', function () {
10+
$packages = collect([
11+
new Package(Packages::LARAVEL, '11.0.0'),
12+
new Package(Packages::PEST, '2.0.0'),
13+
]);
14+
15+
$roster = Mockery::mock(Roster::class);
16+
$roster->shouldReceive('packages')->andReturn($packages);
17+
18+
$tool = new ApplicationInfo($roster);
19+
$result = $tool->handle([]);
20+
21+
expect($result)->toBeInstanceOf(ToolResult::class);
22+
23+
$data = $result->toArray();
24+
expect($data['isError'])->toBeFalse();
25+
26+
$content = json_decode($data['content'][0]['text'], true);
27+
expect($content['php_version'])->toBe(PHP_VERSION);
28+
expect($content['laravel_version'])->toBe(app()->version());
29+
expect($content['database_engine'])->toBe(config('database.default'));
30+
expect($content['packages'])->toHaveCount(2);
31+
expect($content['packages'][0]['name'])->toBe('LARAVEL');
32+
expect($content['packages'][0]['version'])->toBe('11.0.0');
33+
expect($content['packages'][1]['name'])->toBe('PEST');
34+
expect($content['packages'][1]['version'])->toBe('2.0.0');
35+
});
36+
37+
test('it returns application info with no packages', function () {
38+
$roster = Mockery::mock(Roster::class);
39+
$roster->shouldReceive('packages')->andReturn(collect([]));
40+
41+
$tool = new ApplicationInfo($roster);
42+
$result = $tool->handle([]);
43+
44+
expect($result)->toBeInstanceOf(ToolResult::class);
45+
expect($result)->toBeInstanceOf(ToolResult::class);
46+
47+
$data = $result->toArray();
48+
expect($data['isError'])->toBeFalse();
49+
50+
$content = json_decode($data['content'][0]['text'], true);
51+
expect($content['php_version'])->toBe(PHP_VERSION);
52+
expect($content['laravel_version'])->toBe(app()->version());
53+
expect($content['database_engine'])->toBe(config('database.default'));
54+
expect($content['packages'])->toHaveCount(0);
55+
});

0 commit comments

Comments
 (0)