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.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -73,6 +73,8 @@ Route::middleware(['throttle:120,1', McpApiKeyAuth::class, 'api.scope.enforce'])
|
|||
->name('servers.show');
|
||||
Route::get('/servers/{id}/tools', [McpApiController::class, 'tools'])
|
||||
->name('servers.tools');
|
||||
Route::get('/servers/{id}/resources', [McpApiController::class, 'resources'])
|
||||
->name('servers.resources');
|
||||
|
||||
// Tool version history (read)
|
||||
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