memory_query
Access and filter stored observations using keywords, dates, tags, or agents. Retrieve relevant data efficiently for enhanced decision-making and problem-solving in AI-driven workflows.
Instructions
Query the memory store with advanced filters
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| after | No | ISO date to filter observations after | |
| agent | No | Agent that created the observations | |
| before | No | ISO date to filter observations before | |
| keyword | No | Text to search for in observations | |
| limit | No | Maximum number of results to return | |
| tag | No | Tag to filter observations by |
Implementation Reference
- src/memory/tools.ts:538-567 (registration)Registers the MCP tool 'memory_query' with the FastMCP server, including description, Zod parameter schema, and execute handler.server.addTool({ name: 'memory_query', description: 'Query the memory store with advanced filters', parameters: z.object({ keyword: z.string().optional().describe("Text to search for in observations"), before: z.string().optional().describe("ISO date to filter observations before"), after: z.string().optional().describe("ISO date to filter observations after"), tag: z.string().optional().describe("Tag to filter observations by"), agent: z.string().optional().describe("Agent that created the observations"), limit: z.number().optional().describe("Maximum number of results to return") }), execute: async (args) => { const results = await memoryStore.query({ keyword: args.keyword, time: { before: args.before, after: args.after }, tag: args.tag, agent: args.agent, limit: args.limit }); return JSON.stringify({ observations: results, count: results.length, message: `Found ${results.length} matching observations.` }); } });
- Defines the MemoryQuery TypeScript interface used for querying observations, matching the tool's parameter structure.export interface MemoryQuery { keyword?: string; time?: { before?: string; after?: string; }; tag?: string; agent?: string; limit?: number; }
- src/memory/tools.ts:549-566 (handler)The execute handler for the memory_query tool, which maps arguments to MemoryQuery and calls memoryStore.query, returning JSON results.execute: async (args) => { const results = await memoryStore.query({ keyword: args.keyword, time: { before: args.before, after: args.after }, tag: args.tag, agent: args.agent, limit: args.limit }); return JSON.stringify({ observations: results, count: results.length, message: `Found ${results.length} matching observations.` }); }
- Core implementation of the query method in JsonlMemoryStore, which iterates over all entities and observations, applies filters for keyword, time, tag, and limit, returning matching results.async query(query: MemoryQuery): Promise<{ entityName: string; observation: Observation; }[]> { await this.getLoadingPromise(); const results: { entityName: string; observation: Observation }[] = []; const keyword = query.keyword?.toLowerCase(); for (const [entityName, entity] of this.enhancedEntities.entries()) { for (const observation of entity.observations) { let matches = true; // Filter by keyword if (keyword && !observation.text.toLowerCase().includes(keyword)) { matches = false; } // Filter by time range if (query.time) { const obsTime = new Date(observation.timestamp).getTime(); if (query.time.after && obsTime < new Date(query.time.after).getTime()) { matches = false; } if (query.time.before && obsTime > new Date(query.time.before).getTime()) { matches = false; } } // Filter by tag (would require additional metadata tracking) // This is a placeholder for future implementation if (query.tag) { // Not implemented yet // For now, we'll just check if the tag appears in the text if (!observation.text.toLowerCase().includes(query.tag.toLowerCase())) { matches = false; } } // Filter by agent (would require additional metadata tracking) // This is a placeholder for future implementation if (query.agent) { // Not implemented yet matches = false; } if (matches) { results.push({ entityName, observation }); } } } // Apply limit if specified if (query.limit && query.limit > 0) { return results.slice(0, query.limit); } return results; }