MCP: search_chats finds content across every chat - #640
Open
katulevskiy wants to merge 1 commit into
Open
katulevskiy wants to merge 1 commit into
katulevskiy wants to merge 1 commit into
Conversation
Agents could list chats and read one transcript at a time, but had no way to find "the chat where we talked about X" short of reading them all. Titles were the only searchable field. search_chats scans transcript content (messages, tool lines, titles): - words mode (default) is forgiving: per-word exact/substring/typo scoring, rare words weigh more, and a chat only has to cover min_match of the query, with words allowed to land in different messages. - regex mode is ripgrep-style, case-insensitive unless case_sensitive. - Hits carry a snippet and offsetFromNewest, which drops straight into read_chat's offset. - Filters: project, device, parent, role, archived, tools, reasoning. The calling chat is skipped unless include_self. There is no engine-side index: transcripts are read 8 at a time, newest activity first, capped by max_chats (default 200), and the reply reports truncated/unreadableChats so a partial scan is never mistaken for a full one.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
An agent can
list_chatsandread_chatone transcript at a time, but it cannot find "the chat where we talked about X" without reading every chat. Titles were the only searchable field, and only by exact match.Change
New MCP tool
search_chatssearches the content of every chat: messages, the one-line tool ledger, and titles.wordsmode (default) is forgiving. Each query word scores per message: exact 1.0, substring 0.8, typo within a length-scaled edit budget 0.6/0.5. Rare words weigh more than ones present in most chats. A chat is listed when it coversmin_match(default 0.5) of the query, and the words may land in different messages, so a loose description finds the chat.regexmode is ripgrep-style, case-insensitive unlesscase_sensitive.offsetFromNewest, which is theread_chatoffset that lands on that message.project,device,parent,role,include_archived,include_tools,include_reasoning. The calling chat is skipped unlessinclude_self.Showcase
Real output of the tool on five fictional chats (highlighting added for the image). Top: a typo'd query finds a chat whose title never mentions throttling. Middle: "race condition" never appears in the chat, yet it is found via
races,flaky,test. Bottom: a case-sensitive regex.The image lives on a separate
pr-assets-mcp-searchbranch of my fork, so it isn't part of this diff.Design notes
read_chatdoes (8 at a time, newest activity first, capped bymax_chats, default 200, max 1000) and scores it in the MCP process. The reply reportscandidateChats,scannedChats,unreadableChatsandtruncated, so a partial scan is never mistaken for a full one. If this gets slow on large histories, the next step is an engine-side index (SQLite FTS5;rusqliteis already in the tree).list_chatsandsearch_chatsnow share onefiltered_chatshelper (project/device/archived/parent filters); behaviour oflist_chatsis unchanged.regexas a workspace dependency; it was already in the build tree indirectly.Tests
cargo test -p zeron-mcp: 27 pass. New: unit tests for tokenising, match weights, ranking (rare terms,min_match, terms spanning messages, title-only), regex case handling and UTF-8-safe snippets; two tool tests through the in-memory engine stub (typo/fragment search, the offset feeding straight intoread_chat, regex, role filter, invalid input, self-skip, truncation reporting).cargo clippy -p zeron-mcp --all-targetsandcargo fmt --checkare clean.zeron mcpagainst a live engine (scanned all chats, ranked the relevant ones first).Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.