Skip to main content
Glama

analyze_document

Analyze Markdown document structure and provide validation insights to identify issues and improve content quality.

Instructions

        Analyze document structure and provide insights.
        
        Args:
            document_path: Path to the Markdown file
            validation_level: Validation strictness - "STRICT", "NORMAL", or "PERMISSIVE"
        

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
document_pathYes
validation_levelNoNORMAL

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • Primary MCP tool handler for 'analyze_document'. Decorated with @self.mcp.tool() for automatic registration and schema inference. Loads document, analyzes structure (sections, heading levels), computes content statistics (lines, words, characters), and returns detailed analysis.
    @self.mcp.tool()
    def analyze_document(document_path: str, validation_level: str = "NORMAL") -> Dict[str, Any]:
        """
        Analyze document structure and provide insights.
        
        Args:
            document_path: Path to the Markdown file
            validation_level: Validation strictness - "STRICT", "NORMAL", or "PERMISSIVE"
        """
        try:
            validation_map = {"STRICT": ValidationLevel.STRICT, "NORMAL": ValidationLevel.NORMAL, "PERMISSIVE": ValidationLevel.PERMISSIVE}
            validation_enum = validation_map.get(validation_level.upper(), ValidationLevel.NORMAL)
            
            editor = self.processor.load_document(document_path, validation_enum)
            sections = editor.get_sections()
            content = editor.to_markdown()
            
            # Analyze heading levels
            heading_levels = {}
            for section in sections:
                level = section.level
                heading_levels[level] = heading_levels.get(level, 0) + 1
            
            # Content statistics
            lines = content.split('\n')
            words = len(content.split())
            
            return {
                "success": True,
                "document_path": document_path,
                "analysis": {
                    "structure": {
                        "total_sections": len(sections),
                        "heading_levels": heading_levels,
                        "max_depth": max(heading_levels.keys()) if heading_levels else 0,
                        "min_depth": min(heading_levels.keys()) if heading_levels else 0
                    },
                    "content": {
                        "total_lines": len(lines),
                        "non_empty_lines": len([line for line in lines if line.strip()]),
                        "total_words": words,
                        "total_characters": len(content),
                        "average_section_length": words // len(sections) if sections else 0
                    },
                    "validation": {
                        "level": validation_level,
                        "is_valid": True  # If we got here, it loaded successfully
                    }
                }
            }
            
        except Exception as e:
            return self.processor.create_error_response(str(e), type(e).__name__)
  • Explicit registration of 'analyze_document' tool (mapped to _analyze_document_impl) in the internal call_tool_sync method for synchronous testing.
        "load_document": self._load_document_impl,
        "list_sections": self._list_sections_impl,
        "get_section": self._get_section_impl,
        "insert_section": self._insert_section_impl,
        "update_section": self._update_section_impl,
        "delete_section": self._delete_section_impl,
        "move_section": self._move_section_impl,
        "get_document": self._get_document_impl,
        "save_document": self._save_document_impl,
        "analyze_document": self._analyze_document_impl,
    }
  • Helper implementation for analyze_document used in synchronous tool calls. Performs similar document analysis using the processor.execute_operation pattern, returning EditResult with analysis metadata.
    def _analyze_document_impl(self, document_path: str) -> Dict[str, Any]:
        """Implementation for analyze_document tool."""
        def operation(editor):
            from .safe_editor_types import EditResult, EditOperation
            
            content = editor.to_markdown()
            sections = editor.get_sections()
            
            # Basic document analysis
            lines = content.split('\n')
            word_count = len(content.split())
            char_count = len(content)
            
            # Section analysis
            section_levels = {}
            for section in sections:
                level = section.level
                section_levels[level] = section_levels.get(level, 0) + 1
            
            analysis_data = {
                "analysis": {
                    "total_sections": len(sections),
                    "section_levels": section_levels,
                    "word_count": word_count,
                    "character_count": char_count,
                    "line_count": len(lines),
                    "heading_structure": [
                        {
                            "id": section.id,
                            "title": section.title,
                            "level": section.level
                        }
                        for section in sections
                    ]
                }
            }
            
            return EditResult(
                success=True,
                operation=EditOperation.BATCH_OPERATIONS,
                modified_sections=[],
                errors=[],
                warnings=[],
                metadata=analysis_data
            )
        
        return self.processor.execute_operation(document_path, operation, auto_save=False)
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions 'analyze document structure and provide insights' but doesn't specify what kind of insights, whether this is a read-only operation, if it modifies the document, what permissions are required, or any rate limits. For an analysis tool with zero annotation coverage, this leaves significant behavioral gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is appropriately sized with a clear purpose statement followed by parameter documentation. The two-sentence structure is efficient with zero wasted words. The parameter documentation uses a clean Args: format that's easy to parse. It could be slightly more front-loaded by moving the parameter details to a separate section.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given that an output schema exists, the description doesn't need to explain return values. However, for a 2-parameter analysis tool with no annotations, the description should provide more context about what 'analyze' means in practice, what kind of insights are provided, and how this differs from simply retrieving the document. The parameter documentation helps, but the overall context remains somewhat incomplete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description explicitly documents both parameters with their purposes: 'document_path: Path to the Markdown file' and 'validation_level: Validation strictness - "STRICT", "NORMAL", or "PERMISSIVE"'. This adds substantial value beyond the input schema which has 0% description coverage. However, it doesn't explain the practical implications of different validation levels or provide examples of valid document paths.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose as 'Analyze document structure and provide insights' with a specific verb ('analyze') and resource ('document'). It distinguishes itself from siblings like 'get_document' (retrieval) or 'update_section' (modification) by focusing on analysis rather than basic CRUD operations. However, it doesn't explicitly differentiate from potential analysis-related siblings if they existed.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. With siblings like 'get_document' (retrieval), 'load_document' (loading), and 'list_sections' (listing), there's no indication whether this tool should be used instead of or in conjunction with them. The description lacks any 'when-to-use' or 'when-not-to-use' context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

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/quantalogic/quantalogic_markdown_mcp'

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