feat(api): add MCP resource listing endpoint
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
2d8bb12311
commit
4efa435a47
3 changed files with 59 additions and 0 deletions
|
|
@ -110,6 +110,50 @@ class McpApiController extends Controller
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List resources for a specific server.
|
||||||
|
*
|
||||||
|
* GET /api/v1/mcp/servers/{id}/resources
|
||||||
|
*
|
||||||
|
* Query params:
|
||||||
|
* - include_content: bool - include resource content when the definition already contains it
|
||||||
|
*/
|
||||||
|
public function resources(Request $request, string $id): JsonResponse
|
||||||
|
{
|
||||||
|
$server = $this->loadServerFull($id);
|
||||||
|
|
||||||
|
if (! $server) {
|
||||||
|
return $this->notFoundResponse('Server');
|
||||||
|
}
|
||||||
|
|
||||||
|
$includeContent = $request->boolean('include_content', false);
|
||||||
|
|
||||||
|
$resources = collect($server['resources'] ?? [])
|
||||||
|
->filter(fn ($resource) => is_array($resource))
|
||||||
|
->map(function (array $resource) use ($includeContent) {
|
||||||
|
$payload = array_filter([
|
||||||
|
'uri' => $resource['uri'] ?? null,
|
||||||
|
'path' => $resource['path'] ?? null,
|
||||||
|
'name' => $resource['name'] ?? null,
|
||||||
|
'description' => $resource['description'] ?? null,
|
||||||
|
'mime_type' => $resource['mime_type'] ?? ($resource['mimeType'] ?? null),
|
||||||
|
], static fn ($value) => $value !== null);
|
||||||
|
|
||||||
|
if ($includeContent && $this->resourceDefinitionHasContent($resource)) {
|
||||||
|
$payload['content'] = $this->normaliseResourceContent($resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $payload;
|
||||||
|
})
|
||||||
|
->values();
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'server' => $id,
|
||||||
|
'resources' => $resources,
|
||||||
|
'count' => $resources->count(),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute a tool on an MCP server.
|
* Execute a tool on an MCP server.
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,8 @@ Route::middleware(['throttle:120,1', McpApiKeyAuth::class, 'api.scope.enforce'])
|
||||||
->name('servers.show');
|
->name('servers.show');
|
||||||
Route::get('/servers/{id}/tools', [McpApiController::class, 'tools'])
|
Route::get('/servers/{id}/tools', [McpApiController::class, 'tools'])
|
||||||
->name('servers.tools');
|
->name('servers.tools');
|
||||||
|
Route::get('/servers/{id}/resources', [McpApiController::class, 'resources'])
|
||||||
|
->name('servers.resources');
|
||||||
|
|
||||||
// Tool version history (read)
|
// Tool version history (read)
|
||||||
Route::get('/servers/{server}/tools/{tool}/versions', [McpApiController::class, 'toolVersions'])
|
Route::get('/servers/{server}/tools/{tool}/versions', [McpApiController::class, 'toolVersions'])
|
||||||
|
|
|
||||||
|
|
@ -87,3 +87,16 @@ it('reads a resource from the server definition', function () {
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('lists resources for a server', function () {
|
||||||
|
$response = $this->getJson('/api/mcp/servers/test-resource-server/resources', [
|
||||||
|
'Authorization' => "Bearer {$this->plainKey}",
|
||||||
|
]);
|
||||||
|
|
||||||
|
$response->assertOk();
|
||||||
|
$response->assertJsonPath('server', 'test-resource-server');
|
||||||
|
$response->assertJsonPath('count', 1);
|
||||||
|
$response->assertJsonPath('resources.0.uri', 'test-resource-server://documents/welcome');
|
||||||
|
$response->assertJsonPath('resources.0.path', 'documents/welcome');
|
||||||
|
$response->assertJsonPath('resources.0.name', 'welcome');
|
||||||
|
$response->assertJsonMissingPath('resources.0.content');
|
||||||
|
});
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue