diff --git a/headroom/ccr/mcp_server.py b/headroom/ccr/mcp_server.py index 650e375bc..5cdfc37dd 100644 --- a/headroom/ccr/mcp_server.py +++ b/headroom/ccr/mcp_server.py @@ -424,6 +424,23 @@ class HeadroomMCPServer: "results": results, "count": len(results), } + # The query matched no items above the relevance floor, but the + # entry itself may still be present and unexpired. An empty search + # is not the same as a missing/expired hash, so fall back to the + # full content rather than reporting it as not found. + entry = store.retrieve(hash_key) + if entry: + self._stats.record_retrieval(hash_key) + return { + "hash": hash_key, + "source": "local", + "query": query, + "results": [], + "count": 0, + "original_content": entry.original_content, + "note": "Entry exists but no item matched the query above " + "the relevance threshold; returning the full content.", + } else: entry = store.retrieve(hash_key) if entry: diff --git a/tests/test_ccr_mcp_server.py b/tests/test_ccr_mcp_server.py index d217593e2..7ecb983d0 100644 --- a/tests/test_ccr_mcp_server.py +++ b/tests/test_ccr_mcp_server.py @@ -65,3 +65,30 @@ def test_mcp_retrieves_proxy_stored_content(fresh_store) -> None: assert result.get("source") == "local" assert result["original_content"] == original + + +def test_mcp_retrieve_with_nonmatching_query_returns_full_content(fresh_store) -> None: + """A query that matches no item above the relevance floor must still return + the stored entry (it exists and is unexpired) rather than the "Content not + found" error, which is reserved for genuine misses.""" + pytest.importorskip("mcp", reason="MCP SDK required") + original = "the the the the the the the the the the\n" * 5 + hash_key = get_compression_store().store(original, "<>") + # Precondition: the query genuinely matches nothing above the BM25 floor. + assert get_compression_store().search(hash_key, "zzqx_nonmatching_token") == [] + + server = mcp_server.HeadroomMCPServer(check_proxy=False) + result = asyncio.run(server._retrieve_content(hash_key, query="zzqx_nonmatching_token")) + + assert "error" not in result + assert result.get("source") == "local" + assert result["original_content"] == original + assert result["count"] == 0 + + +def test_mcp_retrieve_missing_hash_still_errors(fresh_store) -> None: + """A genuinely missing hash must still report "Content not found".""" + pytest.importorskip("mcp", reason="MCP SDK required") + server = mcp_server.HeadroomMCPServer(check_proxy=False) + result = asyncio.run(server._retrieve_content("nonexistent_hash", query="anything")) + assert "Content not found" in result.get("error", "")