Skip to main content
Glama

Memory File Statistics

memory_stats
Read-onlyIdempotent

Get detailed statistics and optimization status of a memory file to monitor memory usage and efficiency.

Instructions

Get detailed statistics and optimization status for a memory file.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
memory_fileNo

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The 'memory_stats' tool is registered as a FastMCP tool at line 96-97 with the @app.tool decorator. The handler function 'memory_stats' (line 113) formats and returns detailed statistics about a memory file by calling optimizer.get_memory_stats().
    @app.tool(
        name="memory_stats",
        description="Get detailed statistics and optimization status for a memory file.",
        tags={"public", "memory"},
        annotations={
            "idempotentHint": True,
            "readOnlyHint": True,
            "title": "Memory File Statistics",
            "parameters": {
                "memory_file": "Optional path to specific memory file. If not provided, will show stats for the user's main memory file.",
            },
            "returns": "Returns comprehensive statistics including file size, entry count, optimization eligibility, and configuration settings.",
        },
        meta={
            "category": "memory",
        },
    )
    def memory_stats(
        memory_file: Annotated[Optional[str], "Path to memory file to analyze"] = None,
    ) -> str:
        """Get detailed statistics about a memory file."""
        try:
            # Determine which file to analyze
            if memory_file:
                file_path = Path(memory_file)
                if not file_path.exists():
                    return f"Error: Memory file not found: {memory_file}"
            else:
                # Use default user memory file
                user_memory_path = instruction_manager.get_memory_file_path()
                if not user_memory_path.exists():
                    return "No user memory file found"
                file_path = user_memory_path
    
            # Get stats
            optimizer = MemoryOptimizer(instruction_manager)
            stats = optimizer.get_memory_stats(file_path)
    
            if "error" in stats:
                return str(stats["error"])
    
            # Format stats message
            message = "📊 **Memory File Statistics**\n\n"
            message += f"📁 **File**: `{stats['file_path']}`\n"
            message += f"📏 **Size**: {stats['file_size_bytes']:,} bytes\n"
            message += f"🎯 **Tokens**: {stats['current_tokens']:,} (Last optimized: {stats['last_optimized_tokens']:,})\n"
            message += f"📈 **Growth**: {stats['token_growth_percent']}% since last optimization\n"
            message += f"📝 **Entries**: {stats['current_entries']}\n"
            message += f"🔄 **Last Optimized**: {stats['last_optimized'] or 'Never'}\n"
            message += f"⚡ **Optimization Version**: {stats['optimization_version']}\n\n"
    
            message += "⚙️ **Configuration**:\n"
            message += f"• Auto-optimize: {'✅ Enabled' if stats['auto_optimize_enabled'] else '❌ Disabled'}\n"
            threshold_percent = int((stats["token_growth_threshold"] - 1.0) * 100)
            message += f"• Token growth threshold: {threshold_percent}% ({stats['token_growth_threshold']})\n\n"
    
            message += "🎯 **Optimization Status**:\n"
            message += f"• Eligible: {'✅ Yes' if stats['optimization_eligible'] else '❌ No'}\n"
            message += f"• Reason: {stats['optimization_reason']}\n"
            message += f"• New entries since last optimization: {stats['entries_since_last_optimization']}"
    
            return message
    
        except Exception as e:
            return f"Error getting memory stats: {str(e)}"
  • The handler function 'memory_stats' determines the file path, creates a MemoryOptimizer instance, calls get_memory_stats() on it, and formats the returned stats into a human-readable string message.
    def memory_stats(
        memory_file: Annotated[Optional[str], "Path to memory file to analyze"] = None,
    ) -> str:
        """Get detailed statistics about a memory file."""
        try:
            # Determine which file to analyze
            if memory_file:
                file_path = Path(memory_file)
                if not file_path.exists():
                    return f"Error: Memory file not found: {memory_file}"
            else:
                # Use default user memory file
                user_memory_path = instruction_manager.get_memory_file_path()
                if not user_memory_path.exists():
                    return "No user memory file found"
                file_path = user_memory_path
    
            # Get stats
            optimizer = MemoryOptimizer(instruction_manager)
            stats = optimizer.get_memory_stats(file_path)
    
            if "error" in stats:
                return str(stats["error"])
    
            # Format stats message
            message = "📊 **Memory File Statistics**\n\n"
            message += f"📁 **File**: `{stats['file_path']}`\n"
            message += f"📏 **Size**: {stats['file_size_bytes']:,} bytes\n"
            message += f"🎯 **Tokens**: {stats['current_tokens']:,} (Last optimized: {stats['last_optimized_tokens']:,})\n"
            message += f"📈 **Growth**: {stats['token_growth_percent']}% since last optimization\n"
            message += f"📝 **Entries**: {stats['current_entries']}\n"
            message += f"🔄 **Last Optimized**: {stats['last_optimized'] or 'Never'}\n"
            message += f"⚡ **Optimization Version**: {stats['optimization_version']}\n\n"
    
            message += "⚙️ **Configuration**:\n"
            message += f"• Auto-optimize: {'✅ Enabled' if stats['auto_optimize_enabled'] else '❌ Disabled'}\n"
            threshold_percent = int((stats["token_growth_threshold"] - 1.0) * 100)
            message += f"• Token growth threshold: {threshold_percent}% ({stats['token_growth_threshold']})\n\n"
    
            message += "🎯 **Optimization Status**:\n"
            message += f"• Eligible: {'✅ Yes' if stats['optimization_eligible'] else '❌ No'}\n"
            message += f"• Reason: {stats['optimization_reason']}\n"
            message += f"• New entries since last optimization: {stats['entries_since_last_optimization']}"
    
            return message
    
        except Exception as e:
            return f"Error getting memory stats: {str(e)}"
  • The 'get_memory_stats' method on MemoryOptimizer class that collects all statistics about a memory file: file size, entry count, token count, last optimized info, token growth, optimization eligibility, and configuration settings.
    def get_memory_stats(self, file_path: Path) -> Dict[str, Any]:
        """
        Get statistics about a memory file.
    
        Returns metadata and file information for user inspection.
        """
        try:
            metadata = self._get_memory_metadata(file_path)
            frontmatter, content = parse_frontmatter_file(file_path)
    
            current_entries = self._count_memory_entries(content)
            file_size = file_path.stat().st_size
    
            # Count current tokens
            full_content = "---\n"
            for key, value in frontmatter.items():
                if isinstance(value, str) and ('"' in value or "'" in value):
                    full_content += f'{key}: "{value}"\n'
                else:
                    full_content += f"{key}: {value}\n"
            full_content += f"---\n{content}"
            current_tokens = self._count_tokens(full_content)
    
            # Calculate optimization eligibility
            should_optimize, reason = self._should_optimize_memory(file_path, metadata)
    
            # Calculate token growth
            last_optimized_tokens = metadata.get("lastOptimizedTokenCount", 0)
            token_growth = 0.0
            if last_optimized_tokens > 0:
                token_growth = ((current_tokens - last_optimized_tokens) / last_optimized_tokens) * 100
    
            return {
                "file_path": str(file_path),
                "file_size_bytes": file_size,
                "current_entries": current_entries,
                "current_tokens": current_tokens,
                "last_optimized": metadata.get("lastOptimized"),
                "last_optimized_tokens": last_optimized_tokens,
                "token_growth_percent": round(token_growth, 1),
                "optimization_version": metadata.get("optimizationVersion", 0),
                "auto_optimize_enabled": metadata.get("autoOptimize", True),
                "token_growth_threshold": metadata.get("tokenGrowthThreshold", 1.20),
                "optimization_eligible": should_optimize,
                "optimization_reason": reason,
                "entries_since_last_optimization": current_entries - metadata.get("entryCount", 0),
            }
    
        except Exception as e:
            return {"error": f"Could not read memory file stats: {e}"}
  • The tool annotation/configuration block defining the memory_stats tool's name, description, tags, parameters schema, and return type information.
    @app.tool(
        name="memory_stats",
        description="Get detailed statistics and optimization status for a memory file.",
        tags={"public", "memory"},
        annotations={
            "idempotentHint": True,
            "readOnlyHint": True,
            "title": "Memory File Statistics",
            "parameters": {
                "memory_file": "Optional path to specific memory file. If not provided, will show stats for the user's main memory file.",
            },
            "returns": "Returns comprehensive statistics including file size, entry count, optimization eligibility, and configuration settings.",
        },
        meta={
            "category": "memory",
        },
    )
Behavior3/5

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

Annotations already declare readOnlyHint=true and idempotentHint=true, so the description's claim of 'Get' is consistent but not additive. The description adds that it provides 'statistics and optimization status,' which is useful but superficial; it does not disclose any behavioral traits beyond what annotations imply.

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

Conciseness5/5

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

The description is extremely concise at one sentence and 12 words. It is front-loaded with the verb 'Get' and contains no extraneous information.

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

Completeness2/5

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

Despite the tool being simple with one optional parameter and an output schema, the description lacks details about what statistics are returned, what optimization status means, and how the input should be specified. It leaves significant gaps.

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

Parameters1/5

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

With 0% schema description coverage and no explanation of the 'memory_file' parameter in the description, the agent has no semantic understanding of this optional parameter. The description does not compensate for the schema gap.

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 what the tool does: 'Get detailed statistics and optimization status for a memory file.' It uses a specific verb and resource, and its purpose is distinct from sibling tools like 'optimize_memory' and 'configure_memory_optimization'. However, it does not explicitly differentiate from these siblings.

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 such as 'optimize_memory' or 'configure_memory_optimization'. It simply describes the action without 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/NiclasOlofsson/mode-manager-mcp'

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