Skip to main content
Glama

analyze_text

Analyzes story page text to generate insights and reports, helping users understand narrative content through structured analysis.

Instructions

Analyzes a story page and generates a report with insights

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
textYesThe story page text to analyze or enhance

Implementation Reference

  • The primary handler function for the 'analyze_text' tool. It performs detailed text analysis including statistics, scene type detection, mood analysis, repetition detection, and generates a comprehensive markdown-formatted report.
    function analyzeText(text) { const wordCount = text.split(/\s+/).filter(Boolean).length; const charCount = text.length; // Basic analysis calculations const averageSentenceLength = wordCount / (text.match(/[.!?]+/g)?.length || 1); // Simple repetition detection (counts words that appear more than once) const words = text.toLowerCase().match(/\b\w+\b/g) || []; const wordFreq = {}; words.forEach(word => { wordFreq[word] = (wordFreq[word] || 0) + 1; }); const repeatedWords = Object.entries(wordFreq) .filter(([_, count]) => count > 1) .sort((a, b) => b[1] - a[1]) .slice(0, 5) .map(([word, count]) => `"${word}" (${count} times)`); // Detect scene type let sceneType = 'exposition'; if (text.includes('!') || text.match(/run|jump|fight|chase|grab|throw|dash|leap|slam/gi)) { sceneType = 'action'; } else if ((text.match(/"|'|said|asked|replied|whispered|shouted/g) || []).length > wordCount/20) { sceneType = 'dialogue'; } // Detect mood let mood = 'neutral'; const positiveWords = text.match(/happy|joy|smile|laugh|wonderful|beautiful|success|love|hope/gi) || []; const negativeWords = text.match(/sad|fear|angry|hate|despair|pain|suffer|terrible|awful/gi) || []; if (positiveWords.length > negativeWords.length) { mood = 'positive'; } else if (negativeWords.length > positiveWords.length) { mood = 'negative'; } // Create an analysis report in markdown format return `UNO Analysis Report ## Text Statistics - **Original Word Count**: ${wordCount} - **Original Character Count**: ${charCount} - **Target Word Count (200%)**: ${wordCount * 2} - **Target Character Count (200%)**: ${charCount * 2} ## Contextual Assessment ### Narrative Position - **Position**: ${text.length < 200 ? 'beginning' : (text.length > 1000 ? 'climax/turning point' : 'middle')} - **Introduction Markers**: ${text.length < 300 ? 'Present' : 'Absent'} - **Climax Markers**: ${text.match(/suddenly|realized|moment|revelation|truth/gi) ? 'Present' : 'Absent'} - **Resolution Markers**: ${text.match(/finally|end|last|resolution|conclusion/gi) ? 'Present' : 'Absent'} ### Character Focus - **Point of View**: ${text.match(/\bI\b|\bme\b|\bmy\b/gi) ? 'first-person' : 'third-person'} - **Potential Characters**: ${Array.from(new Set(text.match(/[A-Z][a-z]+/g) || [])).slice(0, 7).join(' ')} - **Pronoun Distribution**: - First Person: ${(text.match(/\bI\b|\bme\b|\bmy\b|\bmine\b|\bmyself\b/gi) || []).length} - Second Person: ${(text.match(/\byou\b|\byour\b|\byours\b|\byourself\b/gi) || []).length} - Third Person: ${(text.match(/\bhe\b|\bshe\b|\bit\b|\bhim\b|\bher\b|\bhis\b|\bits\b|\bthey\b|\bthem\b|\btheir\b/gi) || []).length} ### Scene Type - **Dominant Type**: ${sceneType} - **Action Elements**: ${sceneType === 'action' ? 'Strong' : 'Weak'} - **Dialogue Elements**: ${sceneType === 'dialogue' ? 'Strong' : 'Weak'} - **Exposition Elements**: ${sceneType === 'exposition' ? 'Strong' : 'Weak'} ### Mood and Tone - **Dominant Mood**: ${mood} - **Positive Elements**: ${positiveWords.length > 0 ? 'Present' : 'Absent'} - **Negative Elements**: ${negativeWords.length > 0 ? 'Present' : 'Absent'} - **Suspense Elements**: ${text.match(/mystery|unknown|wonder|question|curious|suspense/gi) ? 'Present' : 'Absent'} ## Enhancement Recommendations ### Golden Shadow Enhancement - **Need Level**: ${wordCount < 100 ? 'high' : (wordCount < 300 ? 'medium' : 'low')} - **Underdeveloped Characters**: ${Array.from(new Set(text.match(/[A-Z][a-z]+/g) || [])).slice(0, 4).join(' ')} - **Underdeveloped Plot Elements**: ${text.length < 500 ? 'Present' : 'Absent'} ### Environmental Expansion - **Need Level**: ${(text.match(/saw|looked|appeared|seemed|felt|heard|smelled|tasted/gi) || []).length < wordCount/20 ? 'high' : 'low'} - **Sensory Richness (0-4)**: ${Math.min(4, Math.floor((text.match(/saw|looked|appeared|seemed|felt|heard|smelled|tasted/gi) || []).length / (wordCount/100)))} - **Setting Description**: ${text.match(/room|house|building|street|city|forest|mountain|ocean|sky/gi) ? 'Present' : 'Absent'} - **Areas to Enhance**: - Visual: ${text.match(/saw|looked|appeared|seemed|watched|observed/gi) ? 'Sufficient' : 'Needs improvement'} - Auditory: ${text.match(/heard|sound|noise|voice|whisper|shout|bang|crash/gi) ? 'Sufficient' : 'Needs improvement'} - Tactile: ${text.match(/felt|touch|rough|smooth|hot|cold|soft|hard/gi) ? 'Sufficient' : 'Needs improvement'} - Olfactory: ${text.match(/smell|scent|odor|fragrance|stench/gi) ? 'Sufficient' : 'Needs improvement'} ### Action Scene Enhancement - **Applicability**: ${sceneType === 'action' ? 'Applicable' : 'Not applicable'} ${sceneType === 'action' ? ` - **Current Intensity (0-4)**: ${Math.min(4, (text.match(/run|jump|fight|chase|grab|throw|dash|leap|slam/gi) || []).length)} - **Sensory Detail in Action**: ${(text.match(/saw|looked|appeared|seemed|felt|heard|smelled|tasted/gi) || []).length > (text.match(/run|jump|fight|chase|grab|throw|dash|leap|slam/gi) || []).length ? 'Sufficient' : 'Needs improvement'} - **Time Manipulation**: ${text.match(/suddenly|instant|moment|second|minute|time slowed|froze/gi) ? 'Present' : 'Absent'} - **Environmental Interaction**: ${text.match(/against|through|over|under|between|around/gi) ? 'Present' : 'Absent'}` : ''} ### Prose Smoothing - **Need Level**: ${averageSentenceLength > 20 || averageSentenceLength < 8 ? 'high' : 'low'} - **Average Sentence Length**: ${averageSentenceLength.toFixed(1)} words - **Sentence Length Variety**: ${(100 * (text.match(/\b\w{7,}\b/g)?.length || 0) / (text.match(/\b\w+\b/g)?.length || 1)).toFixed(1)}% - **Transition Words**: ${text.match(/however|therefore|meanwhile|subsequently|conversely|furthermore/gi) ? 'Present' : 'Absent'} - **Paragraph Length Variety**: ${text.split('\n\n').length > 1 ? 'Present' : 'Absent'} ### Repetition Elimination - **Severity**: ${repeatedWords.length > 10 ? 'high' : (repeatedWords.length > 5 ? 'medium' : 'low')} - **Repeated Word Count**: ${repeatedWords.length} - **Top Repeated Words**: - ${repeatedWords[0] || 'None'} ${repeatedWords[1] ? ` - ${repeatedWords[1]}` : ''} ## Repetition Patterns ### Repeated Words ${repeatedWords.slice(0, 4).map(word => `- ${word}`).join('\n') || '- No significant word repetition detected'} ### Repeated Phrases - No significant phrase repetition detected ### Repeated Sentence Structures - ${text.match(/[A-Z][^.!?]*\b(he|she|it|they)\b[^.!?]*/gi) ? 'pronoun-start pattern detected' : 'No significant structure repetition detected'} - ${text.match(/[A-Z][^.!?]*\b(was|were|had been)\b[^.!?]*/gi) ? 'passive-voice pattern detected' : ''} `; }
  • Input schema definition for the 'analyze_text' tool, specifying the required 'text' parameter.
    const analyzeTextInputSchema = { type: 'object', properties: { text: { type: 'string', description: 'The story page text to analyze or enhance' } }, required: ['text'] };
  • src/index.js:375-378 (registration)
    Registration of the 'analyze_text' tool in the list of available tools returned by ListToolsRequest.
    name: 'analyze_text', description: 'Analyzes text and generates a comprehensive report', inputSchema: analyzeTextInputSchema, },
  • TypeScript handler for 'analyze_text' tool that validates input and delegates to TextAnalyzer.analyzeText.
    private async handleAnalyzeText(args: any) { if (!args.text || typeof args.text !== 'string') { throw new McpError(ErrorCode.InvalidParams, 'Missing or invalid text parameter'); } const report = await this.analyzer.analyzeText(args.text); return { content: [ { type: 'text', text: report } ] }; }
  • Input schema used for the 'analyze_text' tool in the TypeScript implementation.
    const textInputSchema = { type: 'object', properties: { text: { type: 'string', description: 'The story page text to analyze or enhance', } }, required: ['text'] };
Install Server

Other Tools

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/MushroomFleet/UNO-MCP'

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