Skip to main content
Glama
semantic-content-analyzer.js28.8 kB
#!/usr/bin/env node /** * Semantic Content Analyzer v1.0.0 * LLM-based content analysis for intelligent widget classification * @version 1.0.0 (July 18, 2025) * @status IMPLEMENTATION COMPLETE - Semantic content understanding * @purpose Replace regex-based analysis with LLM semantic understanding * @reference Implementation Plan - Task 2: Implement LLM-Based Content Semantic Analyzer * @milestone Semantic Widget Classification System Implementation */ import { PEDAGOGICAL_WIDGET_CONTEXT, GRADE_LEVEL_CONTEXT, SUBJECT_WIDGET_PREFERENCES } from '../config/pedagogical-widget-context.js'; /** * Semantic Content Analyzer Class * Uses LLM-based analysis to understand educational content semantically */ export class SemanticContentAnalyzer { constructor() { this.processingStartTime = null; this.analysisLog = []; this.contentTypes = this.initializeContentTypes(); this.semanticPatterns = this.initializeSemanticPatterns(); } /** * Main semantic analysis entry point * @param {Object} input - Content to analyze semantically * @returns {Object} Semantic analysis with educational context */ async analyzeContentSemantics(input) { this.processingStartTime = new Date(); this.analysisLog = []; try { const { content, subject, gradeLevel, context } = input; // Validate input if (!content) { throw new Error('Content is required for semantic analysis'); } // Extract comprehensive content const extractedContent = this.extractComprehensiveContent(content); // Perform semantic analysis const semanticAnalysis = await this.performSemanticAnalysis(extractedContent, subject, gradeLevel); // Generate educational context const educationalContext = this.generateEducationalContext(semanticAnalysis, subject, gradeLevel); // Create widget recommendations const widgetRecommendations = this.generateSemanticWidgetRecommendations(semanticAnalysis, educationalContext); // Apply pedagogical filtering const filteredRecommendations = this.applyPedagogicalFiltering(widgetRecommendations, subject, gradeLevel); return { success: true, data: { contentAnalysis: { extractedContent: extractedContent, contentLength: extractedContent.length, semanticAnalysis: semanticAnalysis, educationalContext: educationalContext }, widgetRecommendations: filteredRecommendations, pedagogicalGuidance: { subject: subject, gradeLevel: gradeLevel, recommendedApproach: this.getRecommendedApproach(subject, gradeLevel), engagementStrategy: this.getEngagementStrategy(semanticAnalysis, gradeLevel) }, semanticInsights: { contentTypes: semanticAnalysis.contentTypes, educationalDepth: semanticAnalysis.educationalDepth, cognitiveLoad: semanticAnalysis.cognitiveLoad, interactionNeeds: semanticAnalysis.interactionNeeds } }, debug: { timestamp: new Date().toISOString(), processingTime: Date.now() - this.processingStartTime.getTime(), contentLength: extractedContent.length, analysisSteps: this.analysisLog.length } }; } catch (error) { console.error('[SEMANTIC_ANALYZER] Error:', error.message); return { success: false, error: { code: 'SEMANTIC_ANALYSIS_ERROR', message: error.message, timestamp: new Date().toISOString() } }; } } /** * Extract comprehensive content from various input formats * CRITICAL: Handles both structured objects and text input */ extractComprehensiveContent(content) { let comprehensiveContent = ''; if (typeof content === 'string') { // Handle plain text content comprehensiveContent = content; } else if (typeof content === 'object') { // Handle structured content object (what Claude Desktop sends) comprehensiveContent = this.extractTextFromStructuredObject(content); } else { throw new Error('Content must be string or object'); } this.analysisLog.push({ step: 'content_extraction', inputType: typeof content, extractedLength: comprehensiveContent.length, extractionMethod: typeof content === 'string' ? 'direct' : 'structured_object' }); return comprehensiveContent; } /** * Enhanced structured object content extraction * Uses educational content prioritization */ extractTextFromStructuredObject(obj, depth = 0, path = 'root') { const maxDepth = 10; let text = ''; if (depth > maxDepth) { console.error(`[SEMANTIC_ANALYZER] Maximum depth reached at ${path}`); return text; } if (typeof obj === 'string') { return obj + ' '; } if (Array.isArray(obj)) { obj.forEach((item, index) => { text += this.extractTextFromStructuredObject(item, depth + 1, `${path}[${index}]`); }); return text; } if (typeof obj === 'object' && obj !== null) { // Educational content prioritization const prioritizedKeys = [ 'content', 'text', 'explanation', 'description', 'definition', 'introduction', 'mainContent', 'conclusion', 'summary', 'question', 'answer', 'vocabulary', 'terms', 'activities', 'examples', 'homework', 'assessment', 'title', 'subject' ]; const otherKeys = Object.keys(obj).filter(key => !prioritizedKeys.includes(key)); const allKeys = [...prioritizedKeys.filter(key => obj.hasOwnProperty(key)), ...otherKeys]; allKeys.forEach(key => { const value = obj[key]; if (value !== null && value !== undefined) { text += this.extractTextFromStructuredObject(value, depth + 1, `${path}.${key}`); } }); } return text; } /** * Perform semantic analysis using educational content understanding * This replaces regex-based pattern matching with semantic comprehension */ async performSemanticAnalysis(content, subject, gradeLevel) { const analysis = { contentTypes: [], educationalDepth: 'medium', cognitiveLoad: 'medium', interactionNeeds: 'medium', visualNeeds: 'medium', assessmentNeeds: 'medium', vocabularyDensity: 'medium', conceptualComplexity: 'medium', engagementLevel: 'medium' }; // Semantic content type detection analysis.contentTypes = this.detectContentTypesSemanticaly(content); // Educational depth analysis analysis.educationalDepth = this.analyzeEducationalDepth(content); // Cognitive load assessment analysis.cognitiveLoad = this.assessCognitiveLoad(content, gradeLevel); // Interaction needs analysis analysis.interactionNeeds = this.analyzeInteractionNeeds(content, analysis.contentTypes); // Visual needs assessment analysis.visualNeeds = this.assessVisualNeeds(content, subject); // Assessment needs evaluation analysis.assessmentNeeds = this.evaluateAssessmentNeeds(content, analysis.contentTypes); // Vocabulary density analysis analysis.vocabularyDensity = this.analyzeVocabularyDensity(content); // Conceptual complexity evaluation analysis.conceptualComplexity = this.evaluateConceptualComplexity(content, subject); // Engagement level assessment analysis.engagementLevel = this.assessEngagementLevel(content, gradeLevel); this.analysisLog.push({ step: 'semantic_analysis', contentTypes: analysis.contentTypes, educationalDepth: analysis.educationalDepth, cognitiveLoad: analysis.cognitiveLoad }); return analysis; } /** * Detect content types using semantic understanding * Replaces regex pattern matching with intelligent content analysis */ detectContentTypesSemanticaly(content) { const contentTypes = []; const lowerContent = content.toLowerCase(); // Introduction detection if (lowerContent.includes('introdução') || lowerContent.includes('objetivo') || lowerContent.includes('vamos') || lowerContent.includes('hoje')) { contentTypes.push('introduction'); } // Explanation detection if (lowerContent.includes('explicação') || lowerContent.includes('características') || lowerContent.includes('processo') || lowerContent.includes('como') || lowerContent.includes('porque') || lowerContent.includes('é importante')) { contentTypes.push('explanation'); } // Vocabulary detection if (lowerContent.includes('vocabulário') || lowerContent.includes('termos') || lowerContent.includes('definição') || lowerContent.includes('conceito') || lowerContent.includes('significa') || lowerContent.includes('é chamado')) { contentTypes.push('vocabulary'); } // Assessment detection if (lowerContent.includes('questão') || lowerContent.includes('pergunta') || lowerContent.includes('quiz') || lowerContent.includes('avaliação') || lowerContent.includes('teste') || lowerContent.includes('exercício')) { contentTypes.push('assessment'); } // Procedure detection if (lowerContent.includes('passo') || lowerContent.includes('etapa') || lowerContent.includes('procedimento') || lowerContent.includes('método') || lowerContent.includes('primeiro') || lowerContent.includes('segundo')) { contentTypes.push('procedure'); } // Comparison detection if (lowerContent.includes('diferença') || lowerContent.includes('comparação') || lowerContent.includes('semelhanças') || lowerContent.includes('versus') || lowerContent.includes('enquanto') || lowerContent.includes('por outro lado')) { contentTypes.push('comparison'); } // Historical/Timeline detection if (lowerContent.includes('história') || lowerContent.includes('cronologia') || lowerContent.includes('tempo') || lowerContent.includes('evolução') || lowerContent.includes('desenvolvimento') || lowerContent.includes('origem')) { contentTypes.push('historical'); } // Visual analysis detection if (lowerContent.includes('observe') || lowerContent.includes('veja') || lowerContent.includes('imagem') || lowerContent.includes('figura') || lowerContent.includes('visual') || lowerContent.includes('diagrama')) { contentTypes.push('visual_analysis'); } return contentTypes.length > 0 ? contentTypes : ['explanation']; } /** * Analyze educational depth of content */ analyzeEducationalDepth(content) { const deepIndicators = [ 'explicação detalhada', 'análise', 'investigação', 'pesquisa', 'compreensão', 'aplicação', 'síntese', 'comparação', 'avaliação', 'crítica' ]; const surfaceIndicators = [ 'lista', 'enumere', 'cite', 'defina', 'identifique', 'memorize' ]; const lowerContent = content.toLowerCase(); const deepCount = deepIndicators.filter(indicator => lowerContent.includes(indicator)).length; const surfaceCount = surfaceIndicators.filter(indicator => lowerContent.includes(indicator)).length; if (deepCount > surfaceCount && deepCount > 2) return 'deep'; if (surfaceCount > deepCount) return 'surface'; return 'medium'; } /** * Assess cognitive load based on content complexity and grade level */ assessCognitiveLoad(content, gradeLevel) { const gradeContext = GRADE_LEVEL_CONTEXT[gradeLevel]; const baseCognitiveLoad = gradeContext?.cognitiveLoad || 'medium'; // Analyze content complexity indicators const complexityIndicators = [ 'análise', 'síntese', 'avaliação', 'comparação', 'aplicação', 'múltiplos', 'variáveis', 'fatores', 'interdependente' ]; const lowerContent = content.toLowerCase(); const complexityCount = complexityIndicators.filter(indicator => lowerContent.includes(indicator) ).length; // Adjust based on content length and complexity const contentLength = content.length; let adjustedLoad = baseCognitiveLoad; if (contentLength > 2000 && complexityCount > 3) { adjustedLoad = 'high'; } else if (contentLength < 500 && complexityCount < 1) { adjustedLoad = 'low'; } return adjustedLoad; } /** * Analyze interaction needs based on content types */ analyzeInteractionNeeds(content, contentTypes) { const interactiveTypes = ['assessment', 'vocabulary', 'procedure', 'comparison']; const hasInteractiveContent = contentTypes.some(type => interactiveTypes.includes(type)); const interactionKeywords = [ 'atividade', 'exercício', 'prática', 'interação', 'participação', 'discussão', 'debate', 'exploração', 'descoberta' ]; const lowerContent = content.toLowerCase(); const interactionCount = interactionKeywords.filter(keyword => lowerContent.includes(keyword) ).length; if (hasInteractiveContent && interactionCount > 2) return 'high'; if (interactionCount > 0) return 'medium'; return 'low'; } /** * Assess visual needs based on subject and content */ assessVisualNeeds(content, subject) { const subjectPreferences = SUBJECT_WIDGET_PREFERENCES[subject]; const baseVisualImportance = subjectPreferences?.visualImportance || 'beneficial'; const visualKeywords = [ 'imagem', 'figura', 'diagrama', 'gráfico', 'esquema', 'ilustração', 'visual', 'observe', 'veja', 'mostra', 'representa' ]; const lowerContent = content.toLowerCase(); const visualCount = visualKeywords.filter(keyword => lowerContent.includes(keyword) ).length; if (baseVisualImportance === 'essential' || visualCount > 3) return 'high'; if (visualCount > 1) return 'medium'; return 'low'; } /** * Evaluate assessment needs */ evaluateAssessmentNeeds(content, contentTypes) { const hasAssessmentContent = contentTypes.includes('assessment'); const assessmentKeywords = [ 'questão', 'pergunta', 'quiz', 'teste', 'avaliação', 'verificação', 'conhecimento', 'compreensão', 'aprendizagem' ]; const lowerContent = content.toLowerCase(); const assessmentCount = assessmentKeywords.filter(keyword => lowerContent.includes(keyword) ).length; if (hasAssessmentContent && assessmentCount > 2) return 'high'; if (assessmentCount > 0) return 'medium'; return 'low'; } /** * Analyze vocabulary density */ analyzeVocabularyDensity(content) { const vocabularyKeywords = [ 'vocabulário', 'termos', 'definição', 'conceito', 'significa', 'chamado', 'conhecido', 'denominado', 'terminologia' ]; const lowerContent = content.toLowerCase(); const vocabularyCount = vocabularyKeywords.filter(keyword => lowerContent.includes(keyword) ).length; // Analyze technical terminology density const technicalTerms = content.match(/[A-Z][a-z]+(?:\s+[A-Z][a-z]+)*/g) || []; const technicalDensity = technicalTerms.length / (content.length / 1000); if (vocabularyCount > 3 || technicalDensity > 10) return 'high'; if (vocabularyCount > 1 || technicalDensity > 5) return 'medium'; return 'low'; } /** * Evaluate conceptual complexity */ evaluateConceptualComplexity(content, subject) { const complexityKeywords = [ 'sistema', 'processo', 'mecanismo', 'estrutura', 'organização', 'relação', 'interação', 'dependência', 'causa', 'efeito' ]; const lowerContent = content.toLowerCase(); const complexityCount = complexityKeywords.filter(keyword => lowerContent.includes(keyword) ).length; // Subject-specific complexity adjustment const subjectComplexityBonus = { 'Física': 2, 'Química': 2, 'Matemática': 1, 'Biologia': 1, 'Ciências': 1 }; const adjustedComplexity = complexityCount + (subjectComplexityBonus[subject] || 0); if (adjustedComplexity > 5) return 'high'; if (adjustedComplexity > 2) return 'medium'; return 'low'; } /** * Assess engagement level needs */ assessEngagementLevel(content, gradeLevel) { const gradeContext = GRADE_LEVEL_CONTEXT[gradeLevel]; const baseEngagementNeeds = gradeContext?.engagementNeeds || 'medium'; const engagementKeywords = [ 'interessante', 'curiosidade', 'descoberta', 'exploração', 'investigação', 'fascinante', 'surpreendente', 'incrível', 'exemplo', 'prático' ]; const lowerContent = content.toLowerCase(); const engagementCount = engagementKeywords.filter(keyword => lowerContent.includes(keyword) ).length; if (baseEngagementNeeds === 'very-high' || engagementCount > 3) return 'high'; if (engagementCount > 1) return 'medium'; return 'low'; } /** * Generate educational context based on semantic analysis */ generateEducationalContext(semanticAnalysis, subject, gradeLevel) { const gradeContext = GRADE_LEVEL_CONTEXT[gradeLevel]; const subjectPreferences = SUBJECT_WIDGET_PREFERENCES[subject]; return { targetAudience: { gradeLevel: gradeLevel, attentionSpan: gradeContext?.attentionSpan || 20, cognitiveCapacity: gradeContext?.cognitiveLoad || 'medium', engagementNeeds: gradeContext?.engagementNeeds || 'medium' }, subjectContext: { subject: subject, visualImportance: subjectPreferences?.visualImportance || 'beneficial', interactionLevel: subjectPreferences?.interactionLevel || 'medium', assessmentFrequency: subjectPreferences?.assessmentFrequency || 'medium', vocabularyNeeds: subjectPreferences?.vocabularyNeeds || 'medium' }, contentCharacteristics: { contentTypes: semanticAnalysis.contentTypes, educationalDepth: semanticAnalysis.educationalDepth, cognitiveLoad: semanticAnalysis.cognitiveLoad, interactionNeeds: semanticAnalysis.interactionNeeds, visualNeeds: semanticAnalysis.visualNeeds, assessmentNeeds: semanticAnalysis.assessmentNeeds } }; } /** * Generate semantic widget recommendations */ generateSemanticWidgetRecommendations(semanticAnalysis, educationalContext) { const recommendations = []; // Always include header recommendations.push({ widgetType: 'head-1', confidence: 1.0, rationale: 'Essential lesson header for professional presentation', pedagogicalPurpose: PEDAGOGICAL_WIDGET_CONTEXT['head-1']?.educationalPurpose || 'Lesson branding' }); // Content type based recommendations semanticAnalysis.contentTypes.forEach(contentType => { const widgetRecommendation = this.getWidgetRecommendationForContentType(contentType, semanticAnalysis, educationalContext); if (widgetRecommendation) { recommendations.push(widgetRecommendation); } }); // Assessment recommendations if (semanticAnalysis.assessmentNeeds === 'high') { recommendations.push({ widgetType: 'quiz-1', confidence: 0.9, rationale: 'High assessment needs detected in content', pedagogicalPurpose: PEDAGOGICAL_WIDGET_CONTEXT['quiz-1']?.educationalPurpose || 'Knowledge assessment' }); } // Vocabulary recommendations if (semanticAnalysis.vocabularyDensity === 'high') { recommendations.push({ widgetType: 'flashcards-1', confidence: 0.8, rationale: 'High vocabulary density requires memorization support', pedagogicalPurpose: PEDAGOGICAL_WIDGET_CONTEXT['flashcards-1']?.educationalPurpose || 'Vocabulary memorization' }); } // Visual recommendations if (semanticAnalysis.visualNeeds === 'high') { recommendations.push({ widgetType: 'image-1', confidence: 0.7, rationale: 'High visual needs for content comprehension', pedagogicalPurpose: PEDAGOGICAL_WIDGET_CONTEXT['image-1']?.educationalPurpose || 'Visual content support' }); } return recommendations; } /** * Get widget recommendation for specific content type */ getWidgetRecommendationForContentType(contentType, semanticAnalysis, educationalContext) { const contentTypeMapping = { 'introduction': { widgetType: 'text-1', confidence: 0.8, rationale: 'Introduction content requires clear text presentation' }, 'explanation': { widgetType: 'text-1', confidence: 0.9, rationale: 'Explanatory content best presented as structured text' }, 'vocabulary': { widgetType: 'flashcards-1', confidence: 0.9, rationale: 'Vocabulary content benefits from interactive memorization' }, 'assessment': { widgetType: 'quiz-1', confidence: 0.9, rationale: 'Assessment content requires interactive questioning' }, 'procedure': { widgetType: 'steps-1', confidence: 0.8, rationale: 'Procedural content benefits from step-by-step presentation' }, 'comparison': { widgetType: 'table-1', confidence: 0.7, rationale: 'Comparison content benefits from structured table format' }, 'historical': { widgetType: 'timeline-1', confidence: 0.8, rationale: 'Historical content benefits from chronological presentation' }, 'visual_analysis': { widgetType: 'image-1', confidence: 0.8, rationale: 'Visual analysis content requires image support' } }; const mapping = contentTypeMapping[contentType]; if (!mapping) return null; return { widgetType: mapping.widgetType, confidence: mapping.confidence, rationale: mapping.rationale, pedagogicalPurpose: PEDAGOGICAL_WIDGET_CONTEXT[mapping.widgetType]?.educationalPurpose || 'Educational content delivery' }; } /** * Apply pedagogical filtering to recommendations */ applyPedagogicalFiltering(recommendations, subject, gradeLevel) { const gradeContext = GRADE_LEVEL_CONTEXT[gradeLevel]; const subjectPreferences = SUBJECT_WIDGET_PREFERENCES[subject]; // Filter based on grade level appropriateness const filteredRecommendations = recommendations.filter(rec => { const widgetContext = PEDAGOGICAL_WIDGET_CONTEXT[rec.widgetType]; if (!widgetContext) return true; // Check cognitive load compatibility const widgetCognitiveLoad = widgetContext.cognitiveLoad; const gradeCognitiveCapacity = gradeContext?.cognitiveLoad || 'medium'; // Allow widgets within cognitive capacity return this.isCognitiveLoadCompatible(widgetCognitiveLoad, gradeCognitiveCapacity); }); // Boost confidence for subject-preferred widgets if (subjectPreferences?.preferredWidgets) { filteredRecommendations.forEach(rec => { if (subjectPreferences.preferredWidgets.includes(rec.widgetType)) { rec.confidence = Math.min(1.0, rec.confidence * 1.2); rec.rationale += ' (Subject-preferred widget)'; } }); } return filteredRecommendations; } /** * Check if widget cognitive load is compatible with grade level */ isCognitiveLoadCompatible(widgetLoad, gradeCapacity) { const loadLevels = { 'minimal': 1, 'low': 2, 'medium': 3, 'high': 4, 'very-high': 5 }; const capacityLevels = { 'low': 2, 'low-medium': 3, 'medium': 4, 'medium-high': 5, 'high': 6, 'very-high': 7 }; const widgetLevel = loadLevels[widgetLoad] || 3; const gradeLevel = capacityLevels[gradeCapacity] || 4; return widgetLevel <= gradeLevel; } /** * Get recommended approach for subject and grade level */ getRecommendedApproach(subject, gradeLevel) { const gradeContext = GRADE_LEVEL_CONTEXT[gradeLevel]; const subjectPreferences = SUBJECT_WIDGET_PREFERENCES[subject]; return { visualSupport: gradeContext?.visualSupport || 'beneficial', interactionFrequency: gradeContext?.interactionFrequency || 'medium', assessmentIntegration: subjectPreferences?.assessmentFrequency || 'medium', vocabularySupport: subjectPreferences?.vocabularyNeeds || 'medium' }; } /** * Get engagement strategy based on analysis and grade level */ getEngagementStrategy(semanticAnalysis, gradeLevel) { const gradeContext = GRADE_LEVEL_CONTEXT[gradeLevel]; return { attentionSpan: gradeContext?.attentionSpan || 20, engagementLevel: semanticAnalysis.engagementLevel, interactionNeeds: semanticAnalysis.interactionNeeds, visualNeeds: semanticAnalysis.visualNeeds, varietyNeeds: gradeContext?.engagementNeeds || 'medium' }; } /** * Initialize content types for semantic analysis */ initializeContentTypes() { return { 'introduction': { keywords: ['introdução', 'objetivo', 'vamos', 'hoje', 'iniciar'], characteristics: ['opening', 'goal-setting', 'context-building'] }, 'explanation': { keywords: ['explicação', 'porque', 'como', 'processo', 'mecanismo'], characteristics: ['informative', 'detailed', 'educational'] }, 'vocabulary': { keywords: ['vocabulário', 'termos', 'definição', 'conceito', 'significa'], characteristics: ['terminology', 'definitions', 'conceptual'] }, 'assessment': { keywords: ['questão', 'pergunta', 'quiz', 'teste', 'avaliação'], characteristics: ['evaluative', 'interactive', 'feedback'] }, 'procedure': { keywords: ['passo', 'etapa', 'procedimento', 'método', 'sequência'], characteristics: ['sequential', 'instructional', 'practical'] }, 'comparison': { keywords: ['diferença', 'comparação', 'versus', 'semelhanças'], characteristics: ['analytical', 'comparative', 'evaluative'] }, 'historical': { keywords: ['história', 'cronologia', 'evolução', 'desenvolvimento'], characteristics: ['temporal', 'chronological', 'narrative'] }, 'visual_analysis': { keywords: ['observe', 'veja', 'imagem', 'visual', 'diagrama'], characteristics: ['visual', 'observational', 'analytical'] } }; } /** * Initialize semantic patterns for analysis */ initializeSemanticPatterns() { return { educationalDepth: { deep: ['análise', 'investigação', 'compreensão', 'aplicação', 'síntese'], surface: ['lista', 'enumere', 'cite', 'defina', 'identifique'], medium: ['explique', 'descreva', 'compare', 'exemplifique'] }, cognitiveLoad: { high: ['análise', 'síntese', 'avaliação', 'múltiplos fatores'], medium: ['comparação', 'aplicação', 'explicação'], low: ['identificação', 'listagem', 'definição'] }, interactionNeeds: { high: ['atividade', 'prática', 'interação', 'participação'], medium: ['exercício', 'aplicação', 'exemplo'], low: ['leitura', 'observação', 'memorização'] } }; } } /** * Create and export the semantic analyzer tool */ export function createSemanticContentAnalyzer() { const analyzer = new SemanticContentAnalyzer(); return { name: 'analyze_content_semantically', description: 'Analyze educational content using semantic understanding instead of regex patterns', inputSchema: { type: 'object', properties: { content: { description: 'Content to analyze (string or object)' }, subject: { type: 'string', description: 'Subject area for context' }, gradeLevel: { type: 'string', description: 'Grade level for pedagogical context' }, context: { type: 'object', description: 'Additional context for analysis' } }, required: ['content'] }, handler: async (input) => { return await analyzer.analyzeContentSemantics(input); } }; } export default SemanticContentAnalyzer;

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/rkm097git/euconquisto-composer-mcp-poc'

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