fix(api): pass MCP tool version through execution

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-01 18:03:26 +00:00
parent db787a799b
commit ee83aabca0
2 changed files with 69 additions and 12 deletions

View file

@ -271,7 +271,8 @@ class McpApiController extends Controller
$result = $this->executeToolViaArtisan(
$validated['server'],
$validated['tool'],
$validated['arguments'] ?? []
$validated['arguments'] ?? [],
$toolVersion?->version
);
$durationMs = (int) ((microtime(true) - $startTime) * 1000);
@ -538,23 +539,14 @@ class McpApiController extends Controller
/**
* Execute tool via artisan MCP server command.
*/
protected function executeToolViaArtisan(string $server, string $tool, array $arguments): mixed
protected function executeToolViaArtisan(string $server, string $tool, array $arguments, ?string $version = null): mixed
{
$command = $this->resolveMcpServerCommand($server);
if (! $command) {
throw new \RuntimeException("Unknown server: {$server}");
}
// Build MCP request
$mcpRequest = [
'jsonrpc' => '2.0',
'id' => uniqid(),
'method' => 'tools/call',
'params' => [
'name' => $tool,
'arguments' => $arguments,
],
];
$mcpRequest = $this->buildToolCallRequest($tool, $arguments, $version);
// Execute via process
$process = proc_open(
@ -590,6 +582,28 @@ class McpApiController extends Controller
return $response['result'] ?? null;
}
/**
* Build the JSON-RPC payload for an MCP tool call.
*/
protected function buildToolCallRequest(string $tool, array $arguments, ?string $version = null): array
{
$params = [
'name' => $tool,
'arguments' => $arguments,
];
if ($version !== null && $version !== '') {
$params['version'] = $version;
}
return [
'jsonrpc' => '2.0',
'id' => uniqid(),
'method' => 'tools/call',
'params' => $params,
];
}
/**
* Read resource via artisan MCP server command.
*/

View file

@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
use Core\Api\Controllers\McpApiController;
it('includes the requested tool version in the MCP JSON-RPC payload', function () {
$controller = new class extends McpApiController
{
public function payload(string $tool, array $arguments, ?string $version = null): array
{
return $this->buildToolCallRequest($tool, $arguments, $version);
}
};
$payload = $controller->payload('search', ['query' => 'status'], '1.2.3');
expect($payload['jsonrpc'])->toBe('2.0');
expect($payload['method'])->toBe('tools/call');
expect($payload['params'])->toMatchArray([
'name' => 'search',
'arguments' => ['query' => 'status'],
'version' => '1.2.3',
]);
});
it('omits the version field when one is not requested', function () {
$controller = new class extends McpApiController
{
public function payload(string $tool, array $arguments, ?string $version = null): array
{
return $this->buildToolCallRequest($tool, $arguments, $version);
}
};
$payload = $controller->payload('search', ['query' => 'status']);
expect($payload['params'])->toMatchArray([
'name' => 'search',
'arguments' => ['query' => 'status'],
]);
expect($payload['params'])->not->toHaveKey('version');
});