Skip to content

Commit d88ba5e

Browse files
author
Zehee
committed
refactor: remove recall_recent tool, merge capabilities into list
1 parent 433b68b commit d88ba5e

6 files changed

Lines changed: 29 additions & 72 deletions

File tree

‎README.en.md‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,9 +241,8 @@ You can override the storage root with the `MEMORY_STORE_ROOT` environment varia
241241
|------|---------|
242242
| `remember` | Write a Markdown memory |
243243
| `recall` | Read a memory by key |
244-
| `recall_recent` | List recently updated memories |
245244
| `search` | Keyword search across memories |
246-
| `list` | List memories |
245+
| `list` | List memories, with optional folder / tag filter and limit |
247246
| `list_tags` | List all tags |
248247
| `delete` | Delete a memory |
249248
| `move` | Move or rename a memory |

‎README.md‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -242,9 +242,8 @@ Agent:[调用 mcp__kimi-memory__tag_theme] theme=cache-design
242242
|------|------|
243243
| `remember` | 写入一条 Markdown 记忆 |
244244
| `recall` | 按 key 读取记忆 |
245-
| `recall_recent` | 列出最近更新的记忆 |
246245
| `search` | 在记忆中关键词搜索 |
247-
| `list` | 列出记忆 |
246+
| `list` | 列出记忆,支持按 folder / tag 过滤和 limit 限制 |
248247
| `list_tags` | 列出所有标签 |
249248
| `delete` | 删除记忆 |
250249
| `move` | 移动或重命名记忆 |

‎docs/ARCHITECTURE.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ This document explains how Kimi Code Memory MCP Server is structured, how data f
6767
| `src/server.ts` | MCP server entry, registers tools, starts stdio transport. |
6868
| `src/config.ts` | Default paths, environment variable handling (`MEMORY_STORE_ROOT`, `MEMORY_SESSIONS_ROOT`, `KIMI_CODE_HOME`). |
6969
| `src/tools/index.ts` | Tool schemas, validation, and dispatch. |
70-
| `src/tools/memory-tools.ts` | `remember`, `recall`, `recall_recent`, `search`, `list`, `list_tags`, `delete`, `move`. |
70+
| `src/tools/memory-tools.ts` | `remember`, `recall`, `search`, `list`, `list_tags`, `delete`, `move`. |
7171
| `src/tools/context-tools.ts` | `load_workspace_context`, `load_more_context`, `search_context`, `load_turn_context`. |
7272
| `src/tools/theme-tools.ts` | `tag_theme`, `trace_theme`, `list_themes`, `refine_session_turns`. |
7373
| `src/tools/system-tools.ts` | `organize_memories`, `sync_workspace_index`, `bootstrap_workspace`, `get_current_workspace`. |
@@ -115,7 +115,7 @@ This document explains how Kimi Code Memory MCP Server is structured, how data f
115115

116116
1. **Capture** — Agent writes a memory via `remember`.
117117
2. **Index** — `IndexDao` updates `index.json` and writes the `.md` file.
118-
3. **Recall** — Agent uses `search`, `recall`, or `recall_recent` to retrieve memories.
118+
3. **Recall** — Agent uses `search`, `recall`, or `list` to retrieve memories.
119119
4. **Distill** — `organize_memories` condenses `memory/` into `essence/essence.md` (≤15 KB).
120120
5. **Trace** — `tag_theme` and `trace_theme` connect memories and conversation turns into evolving themes.
121121
6. **Archive/Move** — `move` renames or relocates a memory; `delete` removes it.

‎src/tools/index.ts‎

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ export function createTools(ctx: Ctx) {
1717
const handlers = {
1818
remember: memory.handleRemember,
1919
recall: memory.handleRecall,
20-
recall_recent: memory.handleRecallRecent,
2120
search: memory.handleSearch,
2221
list_tags: memory.handleListTags,
2322
list: memory.handleList,
@@ -86,18 +85,6 @@ export function createTools(ctx: Ctx) {
8685
required: ['key'],
8786
},
8887
},
89-
{
90-
name: 'recall_recent',
91-
description: 'Return the most recently updated memory entries, optionally filtered.',
92-
inputSchema: {
93-
type: 'object',
94-
properties: {
95-
n: { type: 'number', description: 'Maximum number of entries to return (default: 10)' },
96-
folder: { type: 'string', description: 'Filter to a specific subfolder' },
97-
tag: { type: 'string', description: 'Filter to entries containing this tag' },
98-
},
99-
},
100-
},
10188
{
10289
name: 'search',
10390
description: 'Case-insensitive keyword search across memory titles and contents.',
@@ -219,11 +206,13 @@ export function createTools(ctx: Ctx) {
219206
},
220207
{
221208
name: 'list',
222-
description: 'List all memory entries in the workspace, optionally filtered by folder.',
209+
description: 'List memory entries in the workspace, sorted by most recently updated.',
223210
inputSchema: {
224211
type: 'object',
225212
properties: {
226213
folder: { type: 'string', description: 'Filter to a specific subfolder' },
214+
limit: { type: 'number', description: 'Maximum number of entries to return (default: all)' },
215+
tag: { type: 'string', description: 'Filter to entries containing this tag' },
227216
},
228217
},
229218
},

‎src/tools/memory-tools.ts‎

Lines changed: 20 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/**
2-
* Memory CRUD tools: remember, recall, recall_recent, search, list, list_tags, delete, move.
2+
* Memory CRUD tools: remember, recall, search, list, list_tags, delete, move.
33
*/
44

55
import fs from 'fs';
@@ -8,7 +8,7 @@ import type {
88
Ctx,
99
RememberArgs,
1010
RecallArgs,
11-
RecallRecentArgs,
11+
ListArgs,
1212
SearchArgs,
1313
DeleteArgs,
1414
MoveArgs,
@@ -111,52 +111,6 @@ export function createMemoryTools(ctx: Ctx) {
111111
});
112112
}
113113

114-
function handleRecallRecent(args: RecallRecentArgs) {
115-
const n = typeof args.n === 'number' ? Math.max(1, Math.floor(args.n)) : 10;
116-
const folderFilterRaw = typeof args.folder === 'string' ? args.folder : null;
117-
const folderFilter = folderFilterRaw ? sanitizeFolder(folderFilterRaw) : null;
118-
if (folderFilterRaw && !folderFilter) {
119-
return toolResult({ items: [], error: 'Invalid folder path' }, true);
120-
}
121-
const tagFilter = typeof args.tag === 'string' ? args.tag : null;
122-
123-
const index = indexDao.getIndex();
124-
const items = [];
125-
for (const key of Object.keys(index.index)) {
126-
if (!key.endsWith('.md')) continue;
127-
const value = index.index[key];
128-
const folder = path.dirname(key);
129-
const entryKey = path.basename(key, '.md');
130-
131-
if (folderFilter && folder !== folderFilter) continue;
132-
if (tagFilter && (!Array.isArray(value.tags) || !value.tags.includes(tagFilter))) continue;
133-
134-
const filePath = path.join(storeRoot, key);
135-
const stats = fileStats(filePath);
136-
items.push({
137-
key: entryKey,
138-
folder,
139-
title: value.title || toTitle(entryKey),
140-
tags: Array.isArray(value.tags) ? value.tags : [],
141-
updatedAt: stats ? stats.mtime.toISOString() : new Date().toISOString(),
142-
preview: '',
143-
});
144-
}
145-
146-
items.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
147-
148-
return toolResult({
149-
items: items.slice(0, n).map((item) => {
150-
const filePath = resolveFilePath(item.folder, item.key);
151-
const parsed = safeParseFile(filePath);
152-
return {
153-
...item,
154-
preview: (parsed?.body || '').slice(0, 400),
155-
};
156-
}),
157-
});
158-
}
159-
160114
function handleSearch(args: SearchArgs) {
161115
const query = args.query;
162116
if (!query || typeof query !== 'string') {
@@ -219,12 +173,14 @@ export function createMemoryTools(ctx: Ctx) {
219173
return toolResult({ tags: Array.from(tagSet).sort() });
220174
}
221175

222-
function handleList(args: RecallRecentArgs) {
176+
function handleList(args: ListArgs) {
223177
const folderFilterRaw = typeof args.folder === 'string' ? args.folder : null;
224178
const folderFilter = folderFilterRaw ? sanitizeFolder(folderFilterRaw) : null;
225179
if (folderFilterRaw && !folderFilter) {
226180
return toolResult({ items: [], error: 'Invalid folder path' }, true);
227181
}
182+
const tagFilter = typeof args.tag === 'string' ? args.tag : null;
183+
const limit = typeof args.limit === 'number' ? Math.max(1, Math.floor(args.limit)) : null;
228184
const index = indexDao.getIndex();
229185

230186
const items = [];
@@ -233,6 +189,7 @@ export function createMemoryTools(ctx: Ctx) {
233189
const value = index.index[key];
234190
const folder = path.dirname(key);
235191
if (folderFilter && folder !== folderFilter) continue;
192+
if (tagFilter && (!Array.isArray(value.tags) || !value.tags.includes(tagFilter))) continue;
236193

237194
const filePath = path.join(storeRoot, key);
238195
const stats = fileStats(filePath);
@@ -247,6 +204,20 @@ export function createMemoryTools(ctx: Ctx) {
247204
}
248205

249206
items.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
207+
208+
if (limit !== null) {
209+
return toolResult({
210+
items: items.slice(0, limit).map((item) => {
211+
const filePath = resolveFilePath(item.folder, item.key);
212+
const parsed = safeParseFile(filePath);
213+
return {
214+
...item,
215+
preview: (parsed?.body || '').slice(0, 400),
216+
};
217+
}),
218+
});
219+
}
220+
250221
return toolResult({ items });
251222
}
252223

@@ -332,7 +303,6 @@ export function createMemoryTools(ctx: Ctx) {
332303
return {
333304
handleRemember,
334305
handleRecall,
335-
handleRecallRecent,
336306
handleSearch,
337307
handleListTags,
338308
handleList,

‎src/types.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ export interface RecallArgs {
3030
folder?: string;
3131
}
3232

33-
export interface RecallRecentArgs {
34-
n?: number;
33+
export interface ListArgs {
3534
folder?: string;
35+
limit?: number;
3636
tag?: string;
3737
}
3838

0 commit comments

Comments
 (0)