Skip to main content
Glama

MCP-RSS-Crawler

by mshk
db.ts4.68 kB
import Database from 'better-sqlite3'; import path from 'path'; import os from 'os'; // Database file path - using the same path as the main application const DB_DIR = process.env.DB_DIR || path.join(os.homedir(), '.mcp-rss-crawler'); const DB_FILE = process.env.DB_FILE || path.join(DB_DIR, 'feeds.db'); // Create singleton database connections let readOnlyDb: Database.Database | null = null; let writeDb: Database.Database | null = null; export function getDb(): Database.Database { if (!readOnlyDb) { try { readOnlyDb = new Database(DB_FILE, { readonly: true }); console.log(`Connected to database at ${DB_FILE}`); } catch (error) { console.error('Error connecting to database:', error); throw new Error('Failed to connect to the database'); } } return readOnlyDb; } export function getWriteDb(): Database.Database { if (!writeDb) { try { writeDb = new Database(DB_FILE); console.log(`Connected to database for writing at ${DB_FILE}`); } catch (error) { console.error('Error connecting to database for writing:', error); throw new Error('Failed to connect to the database for writing'); } } return writeDb; } // Feed types export interface Feed { id: string; url: string; name: string; category: string | null; last_updated: number; } // Item types export interface FeedItem { id: string; feed_id: string; title: string; link: string; summary: string | null; content: string | null; published: number; author: string | null; feed_title?: string; feed_url?: string; categories?: string[]; } // Get all feeds export function getAllFeeds(): Feed[] { const db = getDb(); return db.prepare('SELECT * FROM feeds ORDER BY category, name').all() as Feed[]; } // Get feeds by category export function getFeedsByCategory(category: string): Feed[] { const db = getDb(); return db.prepare('SELECT * FROM feeds WHERE category = ? ORDER BY name').all(category) as Feed[]; } // Get all categories export function getAllCategories(): string[] { const db = getDb(); const categories = db.prepare('SELECT DISTINCT category FROM feeds WHERE category IS NOT NULL').all() as { category: string }[]; return categories.map(c => c.category); } // Get items from a specific feed export function getItemsByFeed(feedId: string, limit: number = 50): FeedItem[] { const db = getDb(); return db.prepare(` SELECT i.*, f.name as feed_title, f.url as feed_url FROM items i JOIN feeds f ON i.feed_id = f.id WHERE i.feed_id = ? ORDER BY i.published DESC LIMIT ? `).all(feedId, limit) as FeedItem[]; } // Get recent items export function getRecentItems(limit: number = 50): FeedItem[] { const db = getDb(); return db.prepare(` SELECT i.*, f.name as feed_title, f.url as feed_url FROM items i JOIN feeds f ON i.feed_id = f.id ORDER BY i.published DESC LIMIT ? `).all(limit) as FeedItem[]; } // Get items by category export function getItemsByCategory(category: string, limit: number = 50): FeedItem[] { const db = getDb(); return db.prepare(` SELECT i.*, f.name as feed_title, f.url as feed_url FROM items i JOIN feeds f ON i.feed_id = f.id WHERE f.category = ? ORDER BY i.published DESC LIMIT ? `).all(category, limit) as FeedItem[]; } // Search items export function searchItems(query: string, limit: number = 50): FeedItem[] { const db = getDb(); const searchPattern = `%${query}%`; return db.prepare(` SELECT i.*, f.name as feed_title, f.url as feed_url FROM items i JOIN feeds f ON i.feed_id = f.id WHERE i.title LIKE ? OR i.summary LIKE ? OR i.content LIKE ? ORDER BY i.published DESC LIMIT ? `).all(searchPattern, searchPattern, searchPattern, limit) as FeedItem[]; } // Get categories for an item export function getItemCategories(itemId: string): string[] { const db = getDb(); const rows = db.prepare('SELECT category FROM categories WHERE item_id = ?').all(itemId) as { category: string }[]; return rows.map(row => row.category); } // Get a single item by ID export function getItemById(itemId: string): FeedItem | null { const db = getDb(); const item = db.prepare(` SELECT i.*, f.name as feed_title, f.url as feed_url FROM items i JOIN feeds f ON i.feed_id = f.id WHERE i.id = ? `).get(itemId) as FeedItem | null; if (item) { item.categories = getItemCategories(itemId); } return item; } // Close the database connections export function closeDb(): void { if (readOnlyDb) { readOnlyDb.close(); readOnlyDb = null; } if (writeDb) { writeDb.close(); writeDb = null; } }

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/mshk/mcp-rss-crawler'

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