/** * Properties Tools * User Story 2 (P2): Property discovery and querying */ import { ObsidianMCPServer, createToolHandler } from '../server.js'; import { executeObsidianCommand } from '../cli/executor.js'; import { formatForMCP, parseOutput } from '../cli/parser.js'; import { handleCLIResult } from '../utils/error-handler.js'; import { logger } from '../utils/logger.js'; import { sanitizeParameters } from '../validation/sanitizer.js'; /** * Register all property tools for discovery */ export async function registerPropertyDiscoveryTools(server: ObsidianMCPServer): Promise { logger.info('Registering property discovery tools'); // T057: List properties tool (vault-wide) server.registerTool( 'obsidian_list_properties', 'List all properties used in the vault. Shows property keys and optionally their types and usage counts.', { type: 'object', properties: {} }, createToolHandler( 'List all properties in vault', { type: 'object', properties: {} }, async (args) => { const sanitized = sanitizeParameters(args as any) as any; const cmdArgs: string[] = ['list-properties']; if (sanitized.counts) cmdArgs.push('--counts'); if (sanitized.types) cmdArgs.push('--types'); if (sanitized.format) cmdArgs.push('--format', sanitized.format as string); const result = await executeObsidianCommand('property', cmdArgs); handleCLIResult(result, { operation: 'list_properties' }); const format = sanitized.format || 'text'; const parsedData = parseOutput(result.stdout, format); return { content: [ { type: 'text', text: formatForMCP(parsedData, format), }, ], }; } ) ); // T058: Get property count tool server.registerTool( 'obsidian_get_property_count', 'Get the usage count for a specific property across the vault. Shows how many notes use this property.', { type: 'object', properties: {} }, createToolHandler( 'Get property usage count', { type: 'object', properties: {} }, async (args) => { const sanitized = sanitizeParameters(args as any) as any; if (!sanitized.property) { throw new Error('Property parameter is required'); } const cmdArgs: string[] = ['property-count', sanitized.property as string]; if (sanitized.format) cmdArgs.push('--format', sanitized.format as string); const result = await executeObsidianCommand('property', cmdArgs); handleCLIResult(result, { operation: 'property_count', property: sanitized.property }); const format = sanitized.format || 'text'; const parsedData = parseOutput(result.stdout, format); return { content: [ { type: 'text', text: formatForMCP(parsedData, format), }, ], }; } ) ); logger.info('Property discovery tools registered', { count: 2 }); }