Skip to main content
Glama
joelmnz

Article Manager MCP Server

by joelmnz
vectorIndex.ts3.46 kB
import { databaseEmbeddingService } from './databaseEmbedding.js'; import { Chunk } from './chunking.js'; // Maintain backward compatibility with existing interfaces export interface ChunkWithVector extends Chunk { vector: number[]; contentHash: string; } export interface SearchResult { chunk: Chunk; score: number; snippet: string; } // Helper function to convert filename to slug for database operations function filenameToSlug(filename: string): string { return filename.replace(/\.md$/, ''); } // Add or update chunks for a specific article export async function upsertArticleChunks( filename: string, chunks: Chunk[] ): Promise<void> { const slug = filenameToSlug(filename); await databaseEmbeddingService.upsertArticleEmbeddingsBySlug(slug, chunks); console.log(`Indexed ${chunks.length} chunks for ${filename}`); } // Remove all chunks for a specific article export async function deleteArticleChunks(filename: string): Promise<void> { const slug = filenameToSlug(filename); await databaseEmbeddingService.deleteArticleEmbeddingsBySlug(slug); console.log(`Deleted chunks for ${filename}`); } // Perform semantic search export async function semanticSearch(query: string, k: number = 5, folder?: string): Promise<SearchResult[]> { const dbResults = await databaseEmbeddingService.semanticSearch(query, k, folder); // Convert database results to legacy format (remove articleMetadata) return dbResults.map(result => ({ chunk: result.chunk, score: result.score, snippet: result.snippet })); } // Hybrid search combining title and semantic search export async function hybridSearch(query: string, k: number = 5, folder?: string): Promise<SearchResult[]> { const dbResults = await databaseEmbeddingService.hybridSearch(query, k, folder); // Convert database results to legacy format (remove articleMetadata) return dbResults.map(result => ({ chunk: result.chunk, score: result.score, snippet: result.snippet })); } // Rebuild the entire index from scratch export async function rebuildIndex(): Promise<void> { await databaseEmbeddingService.rebuildIndex(); } // Get index statistics export async function getIndexStats(): Promise<{ totalChunks: number; totalArticles: number }> { const stats = await databaseEmbeddingService.getIndexStats(); return { totalChunks: stats.totalChunks, totalArticles: stats.indexedArticles, // Use indexed articles for backward compatibility }; } // Get detailed index status including unindexed files export async function getDetailedIndexStats(): Promise<{ totalChunks: number; indexedArticles: number; totalArticles: number; unindexedFiles: string[]; }> { const stats = await databaseEmbeddingService.getIndexStats(); const detailed = await databaseEmbeddingService.getDetailedStats(); return { totalChunks: stats.totalChunks, indexedArticles: stats.indexedArticles, totalArticles: stats.totalArticles, unindexedFiles: detailed.unindexedSlugs.map(slug => `${slug}.md`), }; } // Index only unindexed articles export async function indexUnindexedArticles(): Promise<{ indexed: number; failed: string[] }> { const result = await databaseEmbeddingService.indexUnindexedArticles(); // Convert slugs back to filenames for backward compatibility const failedFilenames = result.failed.map(slug => `${slug}.md`); return { indexed: result.indexed, failed: failedFilenames }; }

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/joelmnz/mcp-markdown-manager'

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