list
Retrieve saved music patterns from the Strudel MCP Server, optionally filtering by tag to organize your TidalCycles compositions.
Instructions
List saved patterns
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| tag | No | Filter by tag |
Implementation Reference
- Schema definition for the 'list' MCP tool, specifying name, description, and optional 'tag' input parameter.{ name: 'list', description: 'List saved patterns', inputSchema: { type: 'object', properties: { tag: { type: 'string', description: 'Filter by tag' } } } },
- Handler implementation in executeTool switch that validates input, calls PatternStore.list(), formats and returns the list of saved patterns.case 'list': if (args?.tag) { InputValidator.validateStringLength(args.tag, 'tag', 100, false); } const patterns = await this.store.list(args?.tag); return patterns.map(p => `• ${p.name} [${p.tags.join(', ')}] - ${p.timestamp}` ).join('\n') || 'No patterns found';
- src/PatternStore.ts:80-121 (helper)Core helper method in PatternStore that reads pattern JSON files from disk, applies tag filtering if provided, sorts by timestamp, implements caching for unfiltered lists, and returns PatternData array.async list(tag?: string): Promise<PatternData[]> { // Use cached list if available and not expired const now = Date.now(); if (!tag && this.listCache && (now - this.listCache.timestamp) < this.LIST_CACHE_TTL) { return this.listCache.patterns; } try { const files = await fs.readdir(this.basePath); const patterns: PatternData[] = []; // Parallel file reading for better performance const readPromises = files .filter(file => file.endsWith('.json')) .map(async (file) => { const filepath = path.join(this.basePath, file); const data = await fs.readFile(filepath, 'utf-8'); return JSON.parse(data) as PatternData; }); const allPatterns = await Promise.all(readPromises); // Filter and sort const filteredPatterns = tag ? allPatterns.filter(p => p.tags.includes(tag)) : allPatterns; const sorted = filteredPatterns.sort((a, b) => b.timestamp.localeCompare(a.timestamp) ); // Update cache only for non-filtered lists if (!tag) { this.listCache = { patterns: sorted, timestamp: now }; } return sorted; } catch (error) { this.logger.warn(`Failed to list patterns${tag ? ` with tag: ${tag}` : ''}`, error); return []; } }