Skip to main content
Glama

Social Media MCP Server

by tayler-id
mcp-client.ts9.08 kB
import { createComponentLogger } from '../../utils/logger.js'; import rateLimitManager from '../../rate-limit/manager.js'; const logger = createComponentLogger('PerplexityMcpClient'); /** * Perplexity MCP client for in-depth research using the Perplexity MCP server */ class PerplexityMcpClient { private readonly serverName = 'github.com/pashpashpash/perplexity-mcp'; constructor() { logger.info('Perplexity MCP client initialized'); } /** * Research a topic using the Perplexity MCP */ async research(query: string, options: { depth?: 'basic' | 'detailed' | 'comprehensive' } = {}): Promise<any> { const depth = options.depth || 'detailed'; logger.info('Researching topic using Perplexity MCP', { query, depth }); try { // Use rate limit manager to handle API rate limits const result = await rateLimitManager.executeRequest({ api: 'perplexity', endpoint: 'research', method: 'GET', priority: 'high', retryCount: 0, maxRetries: 3, execute: async () => { // Use the MCP tool to research try { // Map depth to detail_level for the search tool const detail_level = depth === 'basic' ? 'brief' : depth === 'comprehensive' ? 'detailed' : 'normal'; // Use the search tool from the Perplexity MCP const response = await this.useMcpTool('search', { query, detail_level }); // Transform the response to match our expected format return this.transformSearchResponse(response, query); } catch (error) { // If the MCP tool is not available, return a mock response logger.warn('Perplexity MCP tool not available, using mock response', { error: error instanceof Error ? error.message : String(error) }); return this.generateMockResponse(query, depth); } } }); logger.info('Research results retrieved successfully', { query, resultCount: result.facts?.length || 0 }); return this.formatResearchResults(result, query); } catch (error) { logger.error('Error researching topic', { query, error: error instanceof Error ? error.message : String(error) }); throw error; } } /** * Transform the response from the Perplexity MCP search tool * to match our expected format */ private transformSearchResponse(response: any, query: string): any { logger.info('Transforming Perplexity search response', { query }); try { // Extract the text content from the response const text = response?.text || ''; // Extract sources if available const sources = response?.sources || []; // Extract facts from the text content // Split the text into paragraphs and use them as facts const facts = text .split('\n\n') .filter((paragraph: string) => paragraph.trim().length > 0) .map((paragraph: string) => paragraph.trim()); // Generate a summary from the first paragraph const summary = facts.length > 0 ? facts[0] : ''; // Format sources const formattedSources = sources.map((source: any) => ({ title: source.title || 'Unknown Source', url: source.url || 'https://example.com', description: source.description || '', source: source.url ? new URL(source.url).hostname : 'unknown', })); return { facts, sources: formattedSources, summary, query, }; } catch (error) { logger.error('Error transforming Perplexity search response', { error: error instanceof Error ? error.message : String(error) }); // Return a minimal valid response return { facts: [], sources: [], summary: '', query, }; } } /** * Format research results from the Perplexity MCP */ private formatResearchResults(data: any, query: string): any { // Extract facts const facts = data.facts || []; // Extract sources const sources = data.sources || []; // Format sources const formattedSources = sources.map((source: any) => ({ title: source.title, url: source.url, description: source.description || '', source: new URL(source.url).hostname, })); return { query: query, facts: facts, sources: formattedSources, summary: data.summary || '', source: { name: 'Perplexity MCP', type: 'research', timestamp: new Date().toISOString(), }, }; } /** * Generate a mock response for testing */ private generateMockResponse(query: string, depth: string): any { // Generate a mock response based on the query and depth const mockFacts = [ `${query} is a rapidly evolving field with significant implications for various industries.`, `Recent research in ${query} has shown promising results in improving efficiency and accuracy.`, `Experts in ${query} predict substantial growth in the coming years.`, `The history of ${query} dates back to early developments in related technologies.`, `Current challenges in ${query} include scalability, security, and ethical considerations.` ]; // Add more facts for detailed and comprehensive research if (depth === 'detailed' || depth === 'comprehensive') { mockFacts.push( `Implementation of ${query} requires careful planning and consideration of various factors.`, `Case studies have demonstrated the effectiveness of ${query} in real-world scenarios.` ); } // Add even more facts for comprehensive research if (depth === 'comprehensive') { mockFacts.push( `The economic impact of ${query} is estimated to be significant in the next decade.`, `Regulatory frameworks for ${query} are still being developed in many jurisdictions.`, `Comparative analysis shows that ${query} outperforms traditional approaches in several metrics.` ); } // Generate mock sources const mockSources = [ { title: `The Future of ${query}`, url: `https://example.com/future-of-${query.replace(/\s+/g, '-')}`, description: `A comprehensive analysis of ${query} and its future implications.` }, { title: `${query} Research Paper`, url: `https://research.example.com/${query.replace(/\s+/g, '-')}-paper`, description: `Academic research on ${query} with empirical evidence.` }, { title: `${query} Industry Report`, url: `https://industry.example.com/${query.replace(/\s+/g, '-')}-report`, description: `Industry analysis of ${query} trends and developments.` } ]; // Generate a mock summary const mockSummary = `${query} represents a significant area of interest with various applications and implications. Recent developments have shown promising results, though challenges remain in terms of implementation, scalability, and regulatory frameworks. Experts predict continued growth and evolution in this field, with potential for substantial impact across multiple industries.`; return { facts: mockFacts, sources: mockSources, summary: mockSummary, isMock: true }; } /** * Extract insights from research results */ async extractInsights(query: string, count: number = 5): Promise<string[]> { logger.info('Extracting insights using Perplexity MCP', { query, count }); try { // Research the topic const researchResults = await this.research(query, { depth: 'detailed' }); // Extract insights from facts const insights = researchResults.facts.slice(0, count); logger.info('Insights extracted successfully', { count: insights.length }); return insights; } catch (error) { logger.error('Error extracting insights', { query, error: error instanceof Error ? error.message : String(error) }); throw error; } } /** * Use the MCP tool to communicate with the Perplexity MCP server */ private async useMcpTool(toolName: string, args: any): Promise<any> { try { // @ts-ignore - This is a special function provided by the MCP environment const result = await use_mcp_tool({ server_name: this.serverName, tool_name: toolName, arguments: args }); return result; } catch (error) { logger.error('Error using MCP tool', { toolName, args, error: error instanceof Error ? error.message : String(error) }); throw error; } } } // Export singleton instance export default new PerplexityMcpClient();

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/tayler-id/social-media-mcp'

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