Skip to main content
Glama

search_memories

Search stored memories using advanced filters including keywords, date ranges, and relevance scores to retrieve specific conversation data from the Memory MCP Server.

Instructions

使用高級過濾條件搜索記憶。支持關鍵詞、時間範圍、分數過濾等。

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
conversation_idYes對話 ID
queryNo搜索查詢文本(將提取關鍵詞)
keywordsNo直接指定關鍵詞列表
date_fromNo起始日期(ISO 格式)
date_toNo結束日期(ISO 格式)
min_scoreNo最低分數
max_scoreNo最高分數
limitNo返回結果數量限制
sort_byNo排序方式relevance
orderNo排序順序desc
memory_typeNo搜索的記憶類型short_term

Implementation Reference

  • The async handler function implementing the core logic of the 'search_memories' tool. It retrieves memories from short-term and/or long-term managers, applies filters using helper functions, sorts results, limits them, and returns formatted results.
      async handler(args) {
        const {
          conversation_id,
          query,
          keywords: providedKeywords,
          date_from,
          date_to,
          min_score,
          max_score,
          limit,
          sort_by,
          order,
          memory_type
        } = args;
    
        try {
          const results = [];
    
          // 搜索短期記憶
          if (memory_type === 'short_term' || memory_type === 'both') {
            const manager = await getShortTermManager(conversation_id);
            const memories = manager.getMemories();
    
            const filtered = await filterMemories(memories, {
              query,
              providedKeywords,
              date_from,
              date_to,
              min_score,
              max_score
            });
    
            results.push(...filtered.map(m => ({ ...m, memory_type: 'short_term' })));
          }
    
          // 搜索長期記憶
          if (memory_type === 'long_term' || memory_type === 'both') {
            const manager = await getLongTermManager(conversation_id);
            const memories = manager.getMemories();
    
            const filtered = await filterMemories(memories, {
              query,
              providedKeywords,
              date_from: date_from,
              date_to: date_to,
              min_score,
              max_score,
              isLongTerm: true
            });
    
            results.push(...filtered.map(m => ({ ...m, memory_type: 'long_term' })));
          }
    
          // 排序
          sortResults(results, sort_by, order);
    
          // 限制結果數量
          const limitedResults = results.slice(0, limit);
    
          return {
            success: true,
            total_found: results.length,
            returned: limitedResults.length,
            results: limitedResults.map(formatSearchResult)
          };
        } catch (error) {
          return {
            success: false,
            error: error.message
          };
        }
      }
    });
  • Zod input schema defining parameters for the 'search_memories' tool, including conversation_id, query options, filters, limits, and sorting.
    inputSchema: z.object({
      conversation_id: z.string().describe('對話 ID'),
      query: z.string().optional().describe('搜索查詢文本(將提取關鍵詞)'),
      keywords: z.array(z.string()).optional().describe('直接指定關鍵詞列表'),
      date_from: z.string().optional().describe('起始日期(ISO 格式)'),
      date_to: z.string().optional().describe('結束日期(ISO 格式)'),
      min_score: z.number().optional().describe('最低分數'),
      max_score: z.number().optional().describe('最高分數'),
      limit: z.number().default(20).describe('返回結果數量限制'),
      sort_by: z.enum(['relevance', 'score', 'timestamp']).default('relevance').describe('排序方式'),
      order: z.enum(['asc', 'desc']).default('desc').describe('排序順序'),
      memory_type: z.enum(['short_term', 'long_term', 'both']).default('short_term').describe('搜索的記憶類型')
    }),
  • src/index.js:164-166 (registration)
    Registration of search tools, including 'search_memories', by invoking createSearchTools and registering each tool in the toolRegistry.
    // 註冊高級搜索工具
    const searchTools = createSearchTools(getShortTermManager, getLongTermManager);
    searchTools.forEach(tool => registerTool(tool, 'search'));
  • Key helper function called by the handler to filter memories based on keyword matching, date ranges, and score thresholds.
    async function filterMemories(memories, filters) {
      const {
        query,
        providedKeywords,
        date_from,
        date_to,
        min_score,
        max_score,
        isLongTerm
      } = filters;
    
      let filtered = [...memories];
    
      // 關鍵詞過濾
      if (query || providedKeywords) {
        let searchKeywords = [];
    
        if (query) {
          const extracted = extractKeywords(query, 10);
          searchKeywords = extracted.map(kw => kw.word.toLowerCase());
        }
    
        if (providedKeywords) {
          searchKeywords = [...searchKeywords, ...providedKeywords.map(k => k.toLowerCase())];
        }
    
        filtered = filtered.filter(mem => {
          const memoryKeywords = (mem.keywords || []).map(kw =>
            (kw.word || kw).toLowerCase()
          );
    
          return searchKeywords.some(sk => memoryKeywords.includes(sk));
        });
      }
    
      // 日期範圍過濾
      if (date_from || date_to) {
        const fromTimestamp = date_from ? new Date(date_from).getTime() : 0;
        const toTimestamp = date_to ? new Date(date_to).getTime() : Infinity;
    
        filtered = filtered.filter(mem => {
          let timestamp;
    
          if (isLongTerm) {
            timestamp = mem.createdAt ? new Date(mem.createdAt).getTime() : 0;
          } else {
            timestamp = mem.time_stamp ? new Date(mem.time_stamp).getTime() : 0;
          }
    
          return timestamp >= fromTimestamp && timestamp <= toTimestamp;
        });
      }
    
      // 分數範圍過濾
      if (min_score !== undefined || max_score !== undefined) {
        const minScoreVal = min_score !== undefined ? min_score : -Infinity;
        const maxScoreVal = max_score !== undefined ? max_score : Infinity;
    
        filtered = filtered.filter(mem => {
          const score = mem.score || 0;
          return score >= minScoreVal && score <= maxScoreVal;
        });
      }
    
      return filtered;
    }
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 filtering capabilities but doesn't describe important behavioral aspects like whether this is a read-only operation, what permissions are required, how results are returned (format, pagination), or any rate limits. The phrase '高级过滤条件' (advanced filtering conditions) is vague and doesn't provide concrete behavioral information.

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 a single, efficient sentence that states the core purpose and mentions key filtering capabilities. It's appropriately concise and front-loaded with the main function. However, it could be slightly more structured by explicitly listing the main filter types rather than using '等' (etc.).

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?

Given the complexity (11 parameters, no annotations, no output schema) and the presence of similar sibling tools, the description is insufficient. It doesn't explain how this tool differs from search_long_term_memories and search_short_term_memories, doesn't describe the return format or behavior, and provides minimal guidance for a tool with many filtering options. For a search tool with this many parameters, more context is needed.

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 mentions '关键词、时间范围、分数过滤等' (keywords, time range, score filtering, etc.), which maps to some parameters (query/keywords, date_from/date_to, min_score/max_score). However, with 100% schema description coverage, the schema already documents all 11 parameters thoroughly. The description adds minimal value beyond what's already in the schema, meeting the baseline for high schema coverage.

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: '搜索记忆' (search memories) with '高级过滤条件' (advanced filtering conditions). It specifies the action (search) and resource (memories) but doesn't explicitly differentiate from sibling tools like search_long_term_memories or search_short_term_memories, which appear to be more specific versions.

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 mentions '支持关键词、时间范围、分数过滤等' (supports keywords, time range, score filtering, etc.), which implies some usage context but doesn't provide explicit guidance on when to use this tool versus the more specific sibling tools (search_long_term_memories, search_short_term_memories). No alternatives or exclusions are mentioned.

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/win10ogod/memory-mcp-server'

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