searchCards
Search and retrieve specific cards from Heptabase backups using queries, tags, whiteboard IDs, content types, or date ranges for organized data access.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| contentType | No | ||
| dateRange | No | ||
| query | No | ||
| tags | No | ||
| whiteboardId | No |
Implementation Reference
- src/server.ts:353-397 (handler)Primary handler for the 'searchCards' MCP tool. Processes input parameters, constructs search query, delegates to HeptabaseDataService.searchCards, and formats results as MCP text response.handler: async (params) => { await this.ensureDataServiceInitialized(); const searchQuery: any = {}; if (params.query) { searchQuery.query = params.query; } if (params.tags) { searchQuery.tags = params.tags; } if (params.whiteboardId) { searchQuery.whiteboardId = params.whiteboardId; } if (params.contentType) { searchQuery.contentType = params.contentType; } if (params.dateRange) { searchQuery.dateRange = { start: new Date(params.dateRange.start), end: new Date(params.dateRange.end) }; } const results = await this.dataService!.searchCards(searchQuery); // Due to MCP response size limits, only show basic info in search results // Use getCard for full content const text = `Found ${results.length} cards:\n` + results.map(card => { return `- ${card.title || 'Untitled'} (ID: ${card.id})`; }).join('\n') + '\n\nUse getCard with specific card ID to get full content.'; return { content: [{ type: 'text', text }] }; }
- src/server.ts:340-349 (schema)Zod schema defining the input parameters for the searchCards tool.const searchCardsSchema = z.object({ query: z.string().optional(), tags: z.array(z.string()).optional(), whiteboardId: z.string().optional(), contentType: z.enum(['text', 'image', 'link']).optional(), dateRange: z.object({ start: z.string(), end: z.string() }).optional() });
- src/server.ts:400-402 (registration)MCP server tool registration for 'searchCards', linking schema and handler.this.server.tool('searchCards', searchCardsSchema.shape, async (params) => { return this.tools.searchCards.handler(params); });
- Core implementation of card search logic, including caching, filtering by query, tags (though tags not implemented in filter?), whiteboard, contentType (not in filter?), and date range.async searchCards(query: SearchQuery): Promise<Card[]> { const cacheKey = `cards:${JSON.stringify(query)}`; if (this.config.cacheEnabled) { const cached = this.getFromCache(cacheKey); if (cached) return cached; } const results = Object.values(this.data.cards).filter(card => { // Filter out trashed cards if (card.isTrashed) return false; // Search by query in title and content if (query.query) { const searchTerm = query.query.toLowerCase(); const titleMatch = card.title?.toLowerCase().includes(searchTerm) || false; const contentMatch = card.content.toLowerCase().includes(searchTerm); if (!titleMatch && !contentMatch) { return false; } } // Filter by whiteboard if (query.whiteboardId) { const hasInstance = Object.values(this.data.cardInstances).some( instance => instance.cardId === card.id && instance.whiteboardId === query.whiteboardId ); if (!hasInstance) return false; } // Filter by date range if (query.dateRange) { const createdDate = new Date(card.createdTime); if (createdDate < query.dateRange.start || createdDate > query.dateRange.end) { return false; } } return true; }); if (this.config.cacheEnabled) { this.setCache(cacheKey, results); } return results; }