Skip to main content
Glama

stats

Get memory statistics for a session, broken down by role and tier (working, long-term, archived), plus graph counts.

Instructions

Memory statistics for a session — total, by role, by tier (working/long_term/archived), graph counts.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
sessionIdYesSession identifier

Implementation Reference

  • The core implementation of the `stats` method on the Engram class. It queries the SQLite database for: total memory count, count by role, oldest/newest timestamps, and count of entries with embeddings.
    async stats(sessionId: string): Promise<{
      total: number;
      byRole: Record<string, number>;
      oldest: Date | null;
      newest: Date | null;
      withEmbeddings: number;
    }> {
      await this.init();
    
      const totalRow = await this.db.get(
        'SELECT COUNT(*) as count FROM memories WHERE session_id = ?',
        [sessionId]
      );
      const total = totalRow?.count || 0;
    
      const roleRows = await this.db.all(
        'SELECT role, COUNT(*) as count FROM memories WHERE session_id = ? GROUP BY role',
        [sessionId]
      );
      const byRole: Record<string, number> = {};
      roleRows.forEach((row: any) => { byRole[row.role] = row.count; });
    
      const range = await this.db.get(
        'SELECT MIN(timestamp) as oldest, MAX(timestamp) as newest FROM memories WHERE session_id = ?',
        [sessionId]
      );
    
      const embRow = await this.db.get(
        'SELECT COUNT(*) as count FROM memories WHERE session_id = ? AND embedding IS NOT NULL',
        [sessionId]
      );
    
      return {
        total,
        byRole,
        oldest: range?.oldest ? new Date(range.oldest) : null,
        newest: range?.newest ? new Date(range.newest) : null,
        withEmbeddings: embRow?.count || 0
      };
    }
  • The input schema definition for the 'stats' tool, declaring required 'sessionId' (string) input property.
    {
      name: 'stats',
      description: 'Memory statistics for a session — total, by role, by tier (working/long_term/archived), graph counts.',
      inputSchema: {
        type: 'object',
        properties: {
          sessionId:  { type: 'string', description: 'Session identifier' },
        },
        required: ['sessionId'],
      },
  • src/index.ts:35-256 (registration)
    The tool is registered via ListToolsRequestSchema handler, which lists all tools including 'stats' at line 93.
    server.setRequestHandler(ListToolsRequestSchema, async () => ({
      tools: [
        // ── Session memory ──────────────────────────────────────────────────
        {
          name: 'remember',
          description: 'Store a memory entry for a session. Embeddings and graph extraction happen automatically.',
          inputSchema: {
            type: 'object',
            properties: {
              sessionId:  { type: 'string', description: 'Session identifier' },
              content:    { type: 'string', description: 'Memory content to store' },
              role:       { type: 'string', enum: ['user', 'assistant', 'system'], default: 'user' },
              metadata:   { type: 'object', description: 'Optional key-value metadata' },
            },
            required: ['sessionId', 'content'],
          },
        },
        {
          name: 'recall',
          description: 'Retrieve relevant memories via semantic search (falls back to keyword). Searches working + long_term tiers. Pass userId to blend in cross-session user facts.',
          inputSchema: {
            type: 'object',
            properties: {
              sessionId:  { type: 'string', description: 'Session identifier' },
              query:      { type: 'string', description: 'Search query' },
              limit:      { type: 'number', description: 'Max results (default 10)', default: 10 },
              userId:     { type: 'string', description: 'Optional: also blend in this user\'s cross-session memories' },
              tiers:      { type: 'string', description: 'Comma-separated tiers to search: working,long_term,archived (default: working,long_term)' },
            },
            required: ['sessionId', 'query'],
          },
        },
        {
          name: 'history',
          description: 'Get recent conversation history for a session in chronological order.',
          inputSchema: {
            type: 'object',
            properties: {
              sessionId:  { type: 'string', description: 'Session identifier' },
              limit:      { type: 'number', description: 'Max entries (default 20)', default: 20 },
            },
            required: ['sessionId'],
          },
        },
        {
          name: 'forget',
          description: 'Delete session memories. Delete all, one by ID, or entries before a date.',
          inputSchema: {
            type: 'object',
            properties: {
              sessionId:  { type: 'string', description: 'Session identifier' },
              id:         { type: 'string', description: 'Specific memory ID to delete (optional)' },
              before:     { type: 'string', description: 'ISO date — delete entries before this date (optional)' },
            },
            required: ['sessionId'],
          },
        },
        {
          name: 'stats',
          description: 'Memory statistics for a session — total, by role, by tier (working/long_term/archived), graph counts.',
          inputSchema: {
            type: 'object',
            properties: {
              sessionId:  { type: 'string', description: 'Session identifier' },
            },
            required: ['sessionId'],
          },
        },
        {
          name: 'consolidate',
          description: 'Consolidate old working memories into dense long-term summaries via LLM. Archives originals.',
          inputSchema: {
            type: 'object',
            properties: {
              sessionId:  { type: 'string', description: 'Session identifier' },
              batch:      { type: 'number', description: 'Number of memories to consolidate (default 50)' },
              keep:       { type: 'number', description: 'Most recent N to leave untouched (default 20)' },
              dryRun:     { type: 'boolean', description: 'Preview summaries without writing (default false)' },
            },
            required: ['sessionId'],
          },
        },
        {
          name: 'graph',
          description: 'Query the knowledge graph for an entity — returns relationships and source memories. Requires ENGRAM_GRAPH=1.',
          inputSchema: {
            type: 'object',
            properties: {
              sessionId:  { type: 'string', description: 'Session identifier' },
              entity:     { type: 'string', description: 'Entity name to look up (case-insensitive)' },
            },
            required: ['sessionId', 'entity'],
          },
        },
        // ── User-scoped (cross-session) memory ──────────────────────────────
        {
          name: 'remember_user',
          description: 'Store a user-scoped memory that persists across all sessions. Use for preferences, identity, long-term facts.',
          inputSchema: {
            type: 'object',
            properties: {
              userId:     { type: 'string', description: 'User identifier' },
              content:    { type: 'string', description: 'Memory content to store' },
              role:       { type: 'string', enum: ['user', 'assistant', 'system'], default: 'user' },
              metadata:   { type: 'object', description: 'Optional key-value metadata' },
            },
            required: ['userId', 'content'],
          },
        },
        {
          name: 'recall_user',
          description: 'Recall user-scoped memories — works from any session context.',
          inputSchema: {
            type: 'object',
            properties: {
              userId:     { type: 'string', description: 'User identifier' },
              query:      { type: 'string', description: 'Search query (optional — returns all if omitted)' },
              limit:      { type: 'number', description: 'Max results (default 10)', default: 10 },
            },
            required: ['userId'],
          },
        },
        {
          name: 'forget_user',
          description: 'Delete user-scoped memories.',
          inputSchema: {
            type: 'object',
            properties: {
              userId:     { type: 'string', description: 'User identifier' },
              id:         { type: 'string', description: 'Specific memory ID (optional)' },
              before:     { type: 'string', description: 'ISO date — delete entries before this date (optional)' },
            },
            required: ['userId'],
          },
        },
        {
          name: 'consolidate_user',
          description: 'Consolidate user-scoped working memories into long-term summaries.',
          inputSchema: {
            type: 'object',
            properties: {
              userId:     { type: 'string', description: 'User identifier' },
              batch:      { type: 'number', description: 'Number of memories to consolidate (default 50)' },
              keep:       { type: 'number', description: 'Most recent N to leave untouched (default 20)' },
              dryRun:     { type: 'boolean', description: 'Preview without writing (default false)' },
            },
            required: ['userId'],
          },
        },
        {
          name: 'user_stats',
          description: 'Memory statistics for a user — total, by role, by tier.',
          inputSchema: {
            type: 'object',
            properties: {
              userId:     { type: 'string', description: 'User identifier' },
            },
            required: ['userId'],
          },
        },
        // ── Temporal & export tools ────────────────────────────────────────
        {
          name: 'recall_by_time',
          description: 'Query memories using natural language time expressions like "yesterday", "last week", "this morning", "before 3pm".',
          inputSchema: {
            type: 'object',
            properties: {
              sessionId:  { type: 'string', description: 'Session identifier' },
              expression: { type: 'string', description: 'Natural language time expression like "yesterday", "last week", "before Monday"' },
              limit:      { type: 'number', description: 'Max results (default 10)', default: 10 },
            },
            required: ['sessionId', 'expression'],
          },
        },
        {
          name: 'recall_recent',
          description: 'Get the N most recent memories for a session — no query needed.',
          inputSchema: {
            type: 'object',
            properties: {
              sessionId:  { type: 'string', description: 'Session identifier' },
              limit:      { type: 'number', description: 'Number of recent memories to return (default 20)', default: 20 },
            },
            required: ['sessionId'],
          },
        },
        {
          name: 'daily_summary',
          description: 'Returns a summary of memories for a given date (YYYY-MM-DD), or today if omitted.',
          inputSchema: {
            type: 'object',
            properties: {
              sessionId:  { type: 'string', description: 'Session identifier' },
              date:       { type: 'string', description: 'ISO date string YYYY-MM-DD (optional, defaults to today)' },
            },
            required: ['sessionId'],
          },
        },
        {
          name: 'temporal_stats',
          description: 'Returns temporal statistics about when memories were created — frequency over time, most active periods.',
          inputSchema: {
            type: 'object',
            properties: {
              sessionId:  { type: 'string', description: 'Session identifier' },
            },
            required: ['sessionId'],
          },
        },
        {
          name: 'export_memories',
          description: 'Export all session memories as markdown or JSON.',
          inputSchema: {
            type: 'object',
            properties: {
              sessionId:  { type: 'string', description: 'Session identifier' },
              format:     { type: 'string', enum: ['markdown', 'json'], description: 'Export format (default "markdown")', default: 'markdown' },
            },
            required: ['sessionId'],
          },
        },
      ],
  • The MCP request handler for the 'stats' tool — calls memory.stats() and returns the result as JSON text.
    case 'stats': {
      const stats = await memory.stats(args.sessionId as string);
      return { content: [{ type: 'text', text: JSON.stringify(stats, null, 2) }] };
    }
Behavior2/5

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

With no annotations, the description carries the burden of disclosing behavioral traits. It only lists output categories but does not confirm the operation is read-only or non-destructive. For a stats tool, the lack of explicit safety information is a gap.

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 a single sentence, front-loaded with the main purpose, and every word contributes meaning. No filler or redundancy.

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?

The description lists output categories but omits any detail on return format, pagination, or behavior. While adequate for a simple tool, it lacks completeness given the lack of output schema and annotations.

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?

Schema coverage is 100% with a basic description for sessionId ('Session identifier'). The tool description adds no further context about the parameter, so the agent gains no extra understanding beyond the schema.

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

Purpose5/5

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

The description explicitly states 'Memory statistics for a session' and lists specific breakdowns (total, by role, by tier, graph counts). It clearly distinguishes from sibling stats tools like temporal_stats and user_stats by focusing on a single session.

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?

No guidance is provided on when to use this tool versus alternatives such as temporal_stats or recall. There are no when-to-use or when-not-to-use instructions, leaving the agent without decision criteria.

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/Cartisien/engram-mcp'

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