UNPKG

marketing-post-generator-mcp

Version:

A powerful MCP server for AI-powered marketing blog post generation with Claude integration

301 lines 11.3 kB
import { VersionManager } from './VersionManager.js'; /** * Service for discovering and exploring available tools and prompts */ export class DiscoveryService { versionManager; constructor(versionManager) { this.versionManager = versionManager || new VersionManager(); } /** * Discover tools and prompts based on query criteria */ discover(toolEntries, promptEntries, query = {}) { // Collect all entries based on type filter const allEntries = []; if (query.type === 'tool' || query.type === undefined || query.type === 'all') { allEntries.push(...Array.from(toolEntries.values())); } if (query.type === 'prompt' || query.type === undefined || query.type === 'all') { allEntries.push(...Array.from(promptEntries.values())); } // Apply filters let filteredEntries = this.applyFilters(allEntries, query); // Apply sorting filteredEntries = this.applySorting(filteredEntries, query); // Calculate pagination const total = filteredEntries.length; const limit = query.limit || 50; const offset = query.offset || 0; const hasMore = offset + limit < total; // Apply pagination const paginatedEntries = filteredEntries.slice(offset, offset + limit); // Convert to discovery entries const discoveryEntries = this.convertToDiscoveryEntries(paginatedEntries); // Generate metadata const metadata = this.generateDiscoveryMetadata(toolEntries, promptEntries, query); return { entries: discoveryEntries, metadata, pagination: { total, limit, offset, hasMore, }, }; } /** * Search for tools and prompts by text */ search(toolEntries, promptEntries, searchText, options = {}) { return this.discover(toolEntries, promptEntries, { ...options, searchText: searchText.toLowerCase(), }); } /** * Get tools and prompts by specific tags */ getByTags(toolEntries, promptEntries, tags, options = {}) { return this.discover(toolEntries, promptEntries, { ...options, tags, }); } /** * Get tools and prompts by author */ getByAuthor(toolEntries, promptEntries, author, options = {}) { return this.discover(toolEntries, promptEntries, { ...options, author, }); } /** * Get compatible tools and prompts for a specific version */ getCompatibleEntries(toolEntries, promptEntries, targetVersion, options = {}) { const versionString = this.versionManager.formatVersion(targetVersion); return this.discover(toolEntries, promptEntries, { ...options, versionRange: `^${versionString}`, }); } /** * Get recently created or updated entries */ getRecent(toolEntries, promptEntries, days = 30, options = {}) { const cutoffDate = new Date(); cutoffDate.setDate(cutoffDate.getDate() - days); const allEntries = [ ...Array.from(toolEntries.values()), ...Array.from(promptEntries.values()), ]; const recentEntries = allEntries.filter((entry) => entry.createdAt >= cutoffDate || entry.updatedAt >= cutoffDate); // Convert to map format for discovery method const recentToolEntries = new Map(); const recentPromptEntries = new Map(); recentEntries.forEach((entry) => { if (entry.type === 'tool') { recentToolEntries.set(entry.name, entry); } else { recentPromptEntries.set(entry.name, entry); } }); return this.discover(recentToolEntries, recentPromptEntries, { ...options, sortBy: 'updated', sortOrder: 'desc', }); } /** * Get deprecated entries */ getDeprecated(toolEntries, promptEntries, options = {}) { return this.discover(toolEntries, promptEntries, { ...options, deprecated: true, }); } /** * Get available categories (tags) */ getCategories(toolEntries, promptEntries) { const categories = new Set(); // Collect tags from tools toolEntries.forEach((tool) => { tool.tags?.forEach((tag) => categories.add(tag)); }); // Collect tags from prompts promptEntries.forEach((prompt) => { prompt.tags?.forEach((tag) => categories.add(tag)); }); return Array.from(categories).sort(); } /** * Get statistics about available entries */ getStatistics(toolEntries, promptEntries) { const allEntries = [ ...Array.from(toolEntries.values()), ...Array.from(promptEntries.values()), ]; const authors = new Set(); const categories = new Set(); let deprecatedCount = 0; const totalVersion = { major: 0, minor: 0, patch: 0 }; let latestVersion = { major: 0, minor: 0, patch: 0 }; allEntries.forEach((entry) => { if (entry.author) authors.add(entry.author); entry.tags?.forEach((tag) => categories.add(tag)); if (entry.deprecated) deprecatedCount++; totalVersion.major += entry.version.major; totalVersion.minor += entry.version.minor; totalVersion.patch += entry.version.patch; if (this.versionManager.compareVersions(entry.version, latestVersion) > 0) { latestVersion = entry.version; } }); const count = allEntries.length || 1; const averageVersion = { major: Math.round(totalVersion.major / count), minor: Math.round(totalVersion.minor / count), patch: Math.round(totalVersion.patch / count), }; return { tools: toolEntries.size, prompts: promptEntries.size, total: allEntries.length, deprecated: deprecatedCount, categories: categories.size, authors: authors.size, averageVersion: this.versionManager.formatVersion(averageVersion), latestVersion: this.versionManager.formatVersion(latestVersion), }; } // Private helper methods applyFilters(entries, query) { return entries.filter((entry) => { // Type filter if (query.type && query.type !== 'all' && entry.type !== query.type) { return false; } // Tags filter if (query.tags && query.tags.length > 0) { const entryTags = entry.tags || []; const hasMatchingTag = query.tags.some((tag) => entryTags.includes(tag)); if (!hasMatchingTag) { return false; } } // Author filter if (query.author && entry.author !== query.author) { return false; } // Deprecated filter if (query.deprecated !== undefined && entry.deprecated !== query.deprecated) { return false; } // Version range filter if (query.versionRange) { try { if (!this.versionManager.satisfiesRange(entry.version, query.versionRange)) { return false; } } catch (error) { // If version range is invalid, skip this filter } } // Search text filter if (query.searchText) { const searchText = query.searchText.toLowerCase(); const matchesName = entry.name.toLowerCase().includes(searchText); const matchesDescription = entry.description.toLowerCase().includes(searchText); const matchesTags = entry.tags?.some((tag) => tag.toLowerCase().includes(searchText)) || false; if (!matchesName && !matchesDescription && !matchesTags) { return false; } } return true; }); } applySorting(entries, query) { const sortBy = query.sortBy || 'name'; const sortOrder = query.sortOrder || 'asc'; return entries.sort((a, b) => { let comparison = 0; switch (sortBy) { case 'name': comparison = a.name.localeCompare(b.name); break; case 'version': comparison = this.versionManager.compareVersions(a.version, b.version); break; case 'created': comparison = a.createdAt.getTime() - b.createdAt.getTime(); break; case 'updated': comparison = a.updatedAt.getTime() - b.updatedAt.getTime(); break; default: comparison = a.name.localeCompare(b.name); } return sortOrder === 'desc' ? -comparison : comparison; }); } convertToDiscoveryEntries(entries) { return entries.map((entry) => { const discoveryEntry = { name: entry.name, type: entry.type, description: entry.description, version: this.versionManager.formatVersion(entry.version), deprecated: entry.deprecated || false, tags: entry.tags || [], }; if (entry.type === 'tool') { discoveryEntry.inputSchema = entry.toolDefinition.inputSchema; } else { discoveryEntry.parameters = entry.promptDefinition.parameters; } return discoveryEntry; }); } generateDiscoveryMetadata(toolEntries, promptEntries, query) { const allEntries = [ ...Array.from(toolEntries.values()), ...Array.from(promptEntries.values()), ]; const categories = new Set(); let latestVersion = { major: 0, minor: 0, patch: 0 }; allEntries.forEach((entry) => { entry.tags?.forEach((tag) => categories.add(tag)); if (this.versionManager.compareVersions(entry.version, latestVersion) > 0) { latestVersion = entry.version; } }); return { totalTools: toolEntries.size, totalPrompts: promptEntries.size, categories: Array.from(categories), latestVersion: this.versionManager.formatVersion(latestVersion), serverCapabilities: [ 'tools', 'prompts', 'versioning', 'discovery', 'search', 'filtering', 'pagination', 'sorting', ], }; } } //# sourceMappingURL=DiscoveryService.js.map