list_storage_objects
List objects in a specific storage bucket with options to filter by prefix, set limits, and offset results, enabling efficient storage management in self-hosted Supabase instances.
Instructions
Lists objects within a specific storage bucket, optionally filtering by prefix.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| bucket_id | Yes | The ID of the bucket to list objects from. | |
| limit | No | Max number of objects to return | |
| offset | No | Number of objects to skip | |
| prefix | No | Filter objects by a path prefix (e.g., 'public/') |
Implementation Reference
- src/tools/list_storage_objects.ts:50-117 (handler)The complete tool definition object exported as listStorageObjectsTool, containing the execute handler function. The handler uses a PostgreSQL transaction to query the storage.objects table with parameters for bucket_id, optional prefix (using LIKE), limit, and offset. It extracts fields including metadata for mimetype and size, and validates output with Zod schema using handleSqlResponse utility.export const listStorageObjectsTool = { name: 'list_storage_objects', description: 'Lists objects within a specific storage bucket, optionally filtering by prefix.', mcpInputSchema, inputSchema: ListStorageObjectsInputSchema, outputSchema: ListStorageObjectsOutputSchema, execute: async ( input: ListStorageObjectsInput, context: ToolContext ): Promise<ListStorageObjectsOutput> => { const client = context.selfhostedClient; const { bucket_id, limit, offset, prefix } = input; console.error(`Listing objects for bucket ${bucket_id} (Prefix: ${prefix || 'N/A'})...`); if (!client.isPgAvailable()) { context.log('Direct database connection (DATABASE_URL) is required to list storage objects.', 'error'); throw new Error('Direct database connection (DATABASE_URL) is required to list storage objects.'); } // Use a transaction to get access to the pg client for parameterized queries const objects = await client.executeTransactionWithPg(async (pgClient: PoolClient) => { // Build query with parameters let sql = ` SELECT id, name, bucket_id, owner, version, metadata ->> 'mimetype' AS mimetype, metadata ->> 'size' AS size, -- Extract size from metadata metadata, created_at::text, updated_at::text, last_accessed_at::text FROM storage.objects WHERE bucket_id = $1 `; const params: (string | number)[] = [bucket_id]; let paramIndex = 2; if (prefix) { sql += ` AND name LIKE $${paramIndex++}`; params.push(`${prefix}%`); } sql += ' ORDER BY name ASC NULLS FIRST'; sql += ` LIMIT $${paramIndex++}`; params.push(limit); sql += ` OFFSET $${paramIndex++}`; params.push(offset); sql += ';'; console.error('Executing parameterized SQL to list storage objects within transaction...'); const result = await pgClient.query(sql, params); // Raw pg result // Explicitly pass result.rows, which matches the expected structure // of SqlSuccessResponse (unknown[]) for handleSqlResponse. return handleSqlResponse(result.rows as SqlSuccessResponse, ListStorageObjectsOutputSchema); }); console.error(`Found ${objects.length} objects.`); context.log(`Found ${objects.length} objects.`); return objects; }, };
- All schema definitions: Zod input schema (ListStorageObjectsInputSchema with bucket_id required, optional limit/offset/prefix), StorageObjectSchema for output items (including id, name, bucket_id, metadata, timestamps), ListStorageObjectsOutputSchema as array, and static mcpInputSchema JSON for MCP protocol.// Input schema const ListStorageObjectsInputSchema = z.object({ bucket_id: z.string().describe('The ID of the bucket to list objects from.'), limit: z.number().int().positive().optional().default(100).describe('Max number of objects to return'), offset: z.number().int().nonnegative().optional().default(0).describe('Number of objects to skip'), prefix: z.string().optional().describe('Filter objects by a path prefix (e.g., \'public/\')'), }); type ListStorageObjectsInput = z.infer<typeof ListStorageObjectsInputSchema>; // Output schema const StorageObjectSchema = z.object({ id: z.string().uuid(), name: z.string().nullable(), // Name can be null according to schema bucket_id: z.string(), owner: z.string().uuid().nullable(), version: z.string().nullable(), // Get mimetype directly from SQL extraction mimetype: z.string().nullable(), // size comes from metadata size: z.string().pipe(z.coerce.number().int()).nullable(), // Keep raw metadata as well metadata: z.record(z.any()).nullable(), created_at: z.string().nullable(), updated_at: z.string().nullable(), last_accessed_at: z.string().nullable(), }); const ListStorageObjectsOutputSchema = z.array(StorageObjectSchema); type ListStorageObjectsOutput = z.infer<typeof ListStorageObjectsOutputSchema>; // Static JSON schema for MCP export const mcpInputSchema = { type: 'object', properties: { bucket_id: { type: 'string', description: 'The ID of the bucket to list objects from.' }, limit: { type: 'number', description: 'Max number of objects to return', default: 100 }, offset: { type: 'number', description: 'Number of objects to skip', default: 0 }, prefix: { type: 'string', description: "Filter objects by a path prefix (e.g., 'public/')" }, }, required: ['bucket_id'], };
- Detailed output schema: StorageObjectSchema defining the structure of each storage object (mimetype and size extracted from metadata), and ListStorageObjectsOutputSchema as z.array thereof.const StorageObjectSchema = z.object({ id: z.string().uuid(), name: z.string().nullable(), // Name can be null according to schema bucket_id: z.string(), owner: z.string().uuid().nullable(), version: z.string().nullable(), // Get mimetype directly from SQL extraction mimetype: z.string().nullable(), // size comes from metadata size: z.string().pipe(z.coerce.number().int()).nullable(), // Keep raw metadata as well metadata: z.record(z.any()).nullable(), created_at: z.string().nullable(), updated_at: z.string().nullable(), last_accessed_at: z.string().nullable(), }); const ListStorageObjectsOutputSchema = z.array(StorageObjectSchema); type ListStorageObjectsOutput = z.infer<typeof ListStorageObjectsOutputSchema>;
- src/index.ts:33-33 (registration)Import statement that brings in the listStorageObjectsTool from its module.import listStorageObjectsTool from './tools/list_storage_objects.js';
- src/index.ts:119-119 (registration)Registration of listStorageObjectsTool in the availableTools object, which is used to populate MCP server capabilities and handle tool calls.[listStorageObjectsTool.name]: listStorageObjectsTool as AppTool,