# feat\(server\): add bounded thread content search · PR \#8721 · pingdotgg/t3code

[View on GitCafe](https://git.cafe/pingdotgg/t3code/pull/8721)

Repository: [pingdotgg/t3code](https://git.cafe/pingdotgg/t3code)

Visibility: public

State: closed

Source repository: pingdotgg/t3code

Source branch: agents/mcp-thread-search/search

Target branch: t3code/codex-turn-mapping

Head commit: 298b869dc63809571f15ec9f92eaf1740c7b53f7

[Discussion and reviews](https://git.cafe/pingdotgg/t3code/pull/8721)

[Commits](https://git.cafe/pingdotgg/t3code/pull/8721/commits?format=markdown)

[Files changed](https://git.cafe/pingdotgg/t3code/pull/8721/diffs?format=markdown)

## Description

---

## Problem

The existing thread search RPC is global, active-only, and cannot return stable anchors into the visible V2 timeline. MCP callers need project-scoped search without changing that established client wire behavior.

## Change

Add an opt-in, bounded `ProjectionSnapshotQuery.searchThreadContent` path that searches durable titles plus visible user and assistant messages. The query:

- scopes every result to one project and an optional thread
- defaults to active threads with an explicit archived opt-in
- excludes deleted projects and threads, streaming output, rolled-back runs, cancelled queued messages, and inherited-only fork content
- treats V2 metadata as authoritative while retaining legacy-only threads
- bounds title and message fragments in SQL before decoding
- escapes literal `%`, `_`, and `!`, rejects NUL, and preserves valid Unicode and internal whitespace
- returns live offset pagination and real source identities when available

The existing `searchThreads` RPC and cache shape are unchanged.

## Behavior

Results are deterministic within each live query page. Legacy hits keep nullable anchors instead of inventing V2 identifiers. V2 title, archive, and deletion state cannot be shadowed by stale legacy rows.

## Validation

- `vp test run apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.search.test.ts` (3/3)
- real in-memory SQLite coverage for V2 and legacy metadata authority, archived/deleted scope, literal wildcard and whitespace matching, Unicode bounds, queued visibility, and pagination
- scoped `t3`, `@t3tools/contracts`, and `@t3tools/shared` typechecks
- targeted lint, format, and `git diff --check`

## Dependency

Bottom of native stack #8785. Based on `t3code/codex-turn-mapping` at `415ed0f73b97f1655b6282492f81d0b2bba3a9cc`. The dependent MCP tool is [#8722](https://github.com/pingdotgg/t3code/pull/8722).

Implemented by GPT-5.6-Sol via Codex in T3 Code.

