diff --git a/CHANGELOG.md b/CHANGELOG.md index deaf154..bf3374d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -61,3 +61,4 @@ - Bound MCP attachment downloads before writing them to disk. - Ignore symlinked and other non-regular entries when reading MCP history or pending files. - Filter pending MCP history by its saved Discord channel name or ID. +- Filter pending MCP history by the saved message timestamp when a date is requested. diff --git a/src/mcp/server.ts b/src/mcp/server.ts index 43f4ef9..f1952eb 100644 --- a/src/mcp/server.ts +++ b/src/mcp/server.ts @@ -47,9 +47,10 @@ function isWithinDiscordMessageLimit(message: string): boolean { return true; } -function readPendingChannel(filePath: string): { +function readPendingMetadata(filePath: string): { channelId: string | undefined; channelName: string | undefined; + date: string | undefined; } { const lines = fs.readFileSync(filePath, "utf-8").split("\n"); const separatorIndex = lines.indexOf("---"); @@ -58,12 +59,22 @@ function readPendingChannel(filePath: string): { const channelIdLine = headerLines.find((line) => line.startsWith("Channel ID: "), ); + const timestampLine = headerLines.find((line) => + line.startsWith("Timestamp: "), + ); + const timestamp = timestampLine + ? new Date(timestampLine.slice("Timestamp: ".length)) + : undefined; return { channelId: channelIdLine?.slice("Channel ID: ".length), channelName: channelLine ?.slice("Channel: #".length) .replace(/[^a-zA-Z0-9-_]/g, "_"), + date: + timestamp && !Number.isNaN(timestamp.getTime()) + ? timestamp.toISOString().slice(0, 10) + : undefined, }; } @@ -384,18 +395,19 @@ export function createMcpServer(): Server { ) .map((entry) => { const filePath = path.join(dir, entry.name); - const pendingChannel = + const pendingMetadata = type === "pending" - ? readPendingChannel(filePath) + ? readPendingMetadata(filePath) : undefined; return { displayName: entry.name, filePath, - channelId: pendingChannel?.channelId, + channelId: pendingMetadata?.channelId, channelName: type === "history" ? getLegacyHistoryChannel(entry.name) - : pendingChannel?.channelName, + : pendingMetadata?.channelName, + date: pendingMetadata?.date, }; }); @@ -419,6 +431,7 @@ export function createMcpServer(): Server { ), channelId: parsed?.channelId, channelName: parsed?.channelName, + date: undefined, }; }); files.push(...channelFiles); @@ -442,8 +455,10 @@ export function createMcpServer(): Server { ); } if (date) { - files = files.filter((f) => - f.displayName.endsWith(`_${date}.txt`), + files = files.filter((file) => + type === "pending" + ? file.date === date + : file.displayName.endsWith(`_${date}.txt`), ); } diff --git a/tests/mcpHistory.test.mjs b/tests/mcpHistory.test.mjs index 1a3308f..cacb191 100644 --- a/tests/mcpHistory.test.mjs +++ b/tests/mcpHistory.test.mjs @@ -145,6 +145,14 @@ test("MCP history filters matching regular files and preserves pending indentati createdAt: new Date("2026-08-01T12:45:00.000Z"), content: "other-channel pending entry", }); + savePending({ + id: "555555555555555555", + author: { tag: "user#0003" }, + channel: { name: "general" }, + channelId: "111111111111111111", + createdAt: new Date("2026-08-02T00:15:00.000Z"), + content: "next-day pending entry", + }); fs.writeFileSync( path.join(messagesDir, "pending", "333333333333333333.txt"), [ @@ -158,6 +166,22 @@ test("MCP history filters matching regular files and preserves pending indentati "utf8", ); + const pendingDateResult = await client.callTool({ + name: "read-message-history", + arguments: { type: "pending", date: "2026-08-01" }, + }); + const pendingDateText = pendingDateResult.content.find( + (item) => item.type === "text", + )?.text; + + assert.equal(typeof pendingDateText, "string"); + assert.match(pendingDateText, /222222222222222222\.txt/); + assert.match(pendingDateText, /333333333333333333\.txt/); + assert.match(pendingDateText, /444444444444444444\.txt/); + assert.doesNotMatch(pendingDateText, /regular\.txt/); + assert.doesNotMatch(pendingDateText, /555555555555555555\.txt/); + assert.doesNotMatch(pendingDateText, /next-day pending entry/); + for (const channel of ["general", "111111111111111111"]) { const pendingResult = await client.callTool({ name: "read-message-history",