Skip to content

Conversation

dylan-hurd-oai
Copy link
Collaborator

@dylan-hurd-oai dylan-hurd-oai commented Aug 25, 2025

Summary

Expose a simple fuzzy file search implementation for mcp clients to work with

Testing

  • Tested locally

@dylan-hurd-oai dylan-hurd-oai requested a review from gpeal August 25, 2025 16:13
@dylan-hurd-oai dylan-hurd-oai added the codex-rust-review Perform a detailed review of Rust changes. label Aug 25, 2025
@github-actions github-actions bot added codex-rust-review-in-progress and removed codex-rust-review Perform a detailed review of Rust changes. labels Aug 25, 2025
Copy link

Summary
Adds fuzzy file search to MCP: new protocol request/response types, TypeScript exports, and mcp-server implementation using codex-file-search, plus dependency wiring.

  • Protocol: ClientRequest::FuzzyFileSearch and corresponding params/response.
  • TS: exports for new types.
  • Server: implements fuzzy_file_search using codex-file-search across multiple roots.

Review
Nice, focused feature addition with clean protocol and TS integration. A few small polish items to consider for consistency and determinism:

  • codex-rs/mcp-server/src/codex_message_processor.rs (new fuzzy_file_search): Prefer Arc::new(AtomicBool::new(false)) since Arc is already imported; current code uses std::sync::Arc::new(...).
  • codex-rs/mcp-server/src/codex_message_processor.rs (files aggregation): Consider sorting files before responding for deterministic output across roots.
  • codex-rs/mcp-server/src/codex_message_processor.rs (config): The hardcoded limit_per_root = 50 and threads = 2 could be parameters or derived (e.g., CPU count) to tune behavior.
  • codex-rs/mcp-server/Cargo.toml: Ensure [dependencies] remain alphabetically sorted with the new codex-file-search entry.
  • codex-rs/protocol/src/mcp_protocol.rs: Looks consistent; good use of #[serde(rename = "id")] and TS derivations.

If not already in the PR body, suggest adding a brief motivation (e.g., expose server-side fuzzy search to power clients’ quick file navigation) and, if applicable, a short note on expected performance/limits.


View workflow run

Copy link
Contributor

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codex Review: Here are some suggestions.

Reply with @codex fix comments to fix any unresolved comments.

About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you open a pull request for review, mark a draft as ready, or comment "@codex review". If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex fix this CI failure" or "@codex address that feedback".

Comment on lines 644 to 1243
async fn fuzzy_file_search(&self, request_id: RequestId, params: FuzzyFileSearchParams) {
let FuzzyFileSearchParams { query, roots } = params;

// Execute fuzzy search across provided roots using codex-file-search.
use codex_file_search as file_search;
use std::collections::HashSet;
use std::num::NonZero;
use std::path::PathBuf;

let mut files: Vec<String> = Vec::new();
let mut seen: HashSet<String> = HashSet::new();
#[expect(clippy::expect_used)]
let limit_per_root = NonZero::new(50).expect("50 is a valid non-zero usize");
#[expect(clippy::expect_used)]
let threads = NonZero::new(2).expect("2 is a valid non-zero usize");
let compute_indices = false;

for root in roots {
let search_dir = PathBuf::from(&root);
// TODO: offer a way to cancel outdated requests in the interface
let cancel_flag = std::sync::Arc::new(AtomicBool::new(false));

// because message_processor runs each request in a separate thread, we don't need to spawn a new thread
match file_search::run(
&query,
limit_per_root,
&search_dir,
Vec::new(),
threads,
cancel_flag,
compute_indices,
) {
Ok(res) => {
for m in res.matches {
// Join root + relative match path for clarity across multiple roots.
let full_path = PathBuf::from(&root).join(m.path);
if let Some(s) = full_path.to_str()
&& seen.insert(s.to_string())
{
files.push(s.to_string());
}
}
}
Err(e) => {
tracing::warn!("fuzzy-file-search root '{}' failed: {}", root, e);
}
}
}

let response = FuzzyFileSearchResponse { files };
self.outgoing.send_response(request_id, response).await;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Avoid blocking processor during fuzzy search

In fuzzy_file_search (mcp-server/src/codex_message_processor.rs lines 644‑695) the code calls file_search::run directly with a comment claiming each request runs in its own thread. However MessageProcessor::process_request handles requests sequentially on one Tokio task, so this synchronous filesystem traversal can block the entire processor, preventing other JSON‑RPC messages from being serviced and making the server unresponsive during large searches.

Useful? React with 👍 / 👎.

.map(std::num::NonZero::get)
.unwrap_or(1);
let threads = cores.min(MAX_THREADS);
let threads_per_root = (threads / roots.len()).max(1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let threads_per_root = (threads / roots.len()).max(1);
let threads_per_root = (threads / roots.len()).min(1);

right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we want max here! It's primarily to catch the case where roots.len() > threads, and make sure threads_per_root != 0

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You want 5.min(1) -> 5 and 0.min(1) -> 1 right?

Isn't 5.max(1) -> 1 and 0.max(1) -> 0?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other way around! Here's a repl to make sure we're on the same page:

Screenshot 2025-09-26 at 5 31 43 PM

@dylan-hurd-oai dylan-hurd-oai merged commit 197f45a into main Sep 29, 2025
19 checks passed
@dylan-hurd-oai dylan-hurd-oai deleted the dh--mcp-file-search branch September 29, 2025 19:19
@github-actions github-actions bot locked and limited conversation to collaborators Sep 29, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants