Skip to main content
Glama
by RadonX
search-notes.js•4.11 kB
import { validators, ValidationError } from '../utils/validation.js'; import { TriliumAPIError } from '../utils/trilium-client.js'; import { logger } from '../utils/logger.js'; export async function searchNotes(triliumClient, args) { try { // Validate inputs const query = validators.searchQuery(args.query); const limit = validators.limit(args.limit); logger.debug(`Searching notes: query="${query}", limit=${limit}`); // Prepare search parameters for TriliumNext API const params = new URLSearchParams({ search: query, limit: limit.toString(), }); // Search notes via TriliumNext API const response = await triliumClient.get(`notes?${params}`); if (!response || typeof response !== 'object' || !Array.isArray(response.results)) { throw new TriliumAPIError('Invalid response from TriliumNext API - expected object with results array'); } const results = response.results; logger.info(`Found ${results.length} notes matching query "${query}"`); // Prepare structured response data const searchData = { query, limit, totalResults: results.length, hasMore: results.length === limit, // Might be more results if we hit the limit timestamp: new Date().toISOString(), notes: results.map(note => ({ noteId: note.noteId, title: note.title || 'Untitled', type: note.type || 'text', dateCreated: note.dateCreated, dateModified: note.dateModified, parentNoteIds: note.parentNoteIds || [], isProtected: note.isProtected || false, // Preserve additional fields that might be useful ...(note.mime && { mime: note.mime }), ...(note.attributes && { attributes: note.attributes }), ...(note.contentLength && { contentLength: note.contentLength }) })) }; if (results.length === 0) { return { content: [ { type: 'text', text: `No notes found for "${query}"` }, { type: 'application/json', text: JSON.stringify(searchData, null, 2) } ], }; } // Create concise summary const summary = `Found ${results.length} note${results.length === 1 ? '' : 's'} for "${query}"${searchData.hasMore ? ' (showing first ' + limit + ')' : ''}`; return { content: [ { type: 'text', text: summary }, { type: 'application/json', text: JSON.stringify(searchData, null, 2) } ], }; } catch (error) { logger.error(`Failed to search notes: ${error.message}`); // Create structured error response const errorData = { query: args.query, limit: args.limit, timestamp: new Date().toISOString(), error: { type: error.constructor.name, message: error.message, ...(error instanceof TriliumAPIError && { status: error.status }), ...(error instanceof TriliumAPIError && error.details && { details: error.details }) } }; if (error instanceof ValidationError) { return { content: [ { type: 'text', text: `Validation error: ${error.message}` }, { type: 'application/json', text: JSON.stringify(errorData, null, 2) } ], isError: true, }; } if (error instanceof TriliumAPIError) { return { content: [ { type: 'text', text: `TriliumNext API error: ${error.message}` }, { type: 'application/json', text: JSON.stringify(errorData, null, 2) } ], isError: true, }; } // Unknown error return { content: [ { type: 'text', text: `Search failed: ${error.message}` }, { type: 'application/json', text: JSON.stringify(errorData, null, 2) } ], isError: true, }; } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/RadonX/mcp-trilium'

If you have feedback or need assistance with the MCP directory API, please join our Discord server