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']
    };

Tool Definition Quality

Score is being calculated. Check back soon.

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