Create main.rs
Browse files- src/main.rs +77 -0
src/main.rs
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
mod indexer;
|
| 2 |
+
mod mcp;
|
| 3 |
+
mod parser;
|
| 4 |
+
|
| 5 |
+
use clap::Parser;
|
| 6 |
+
use indexer::TantivyEngine;
|
| 7 |
+
use mcp::McpServer;
|
| 8 |
+
use std::path::PathBuf;
|
| 9 |
+
use std::sync::Arc;
|
| 10 |
+
use tracing::info;
|
| 11 |
+
|
| 12 |
+
#[derive(Parser, Debug)]
|
| 13 |
+
#[command(name = "rust-mcp-search")]
|
| 14 |
+
#[command(about = "Ultra-high-performance Tantivy-backed Model Context Protocol server", long_about = None)]
|
| 15 |
+
struct Args {
|
| 16 |
+
/// Transport mode: 'stdio' or 'http'
|
| 17 |
+
#[arg(short, long, env = "MCP_TRANSPORT", default_value = "stdio")]
|
| 18 |
+
transport: String,
|
| 19 |
+
|
| 20 |
+
/// HTTP host binding
|
| 21 |
+
#[arg(long, env = "HOST", default_value = "0.0.0.0")]
|
| 22 |
+
host: String,
|
| 23 |
+
|
| 24 |
+
/// HTTP port binding (defaults to HF Spaces standard 7860)
|
| 25 |
+
#[arg(short, long, env = "PORT", default_value = "7860")]
|
| 26 |
+
port: u16,
|
| 27 |
+
|
| 28 |
+
/// Tantivy index directory path
|
| 29 |
+
#[arg(short, long, env = "DATA_DIR", default_value = "./data/index")]
|
| 30 |
+
index_dir: PathBuf,
|
| 31 |
+
|
| 32 |
+
/// Rayon thread pool concurrency limit (0 = auto-detect hardware concurrency)
|
| 33 |
+
#[arg(long, env = "RAYON_NUM_THREADS", default_value = "0")]
|
| 34 |
+
threads: usize,
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
#[tokio::main]
|
| 38 |
+
async fn main() -> anyhow::Result<()> {
|
| 39 |
+
let args = Args::parse();
|
| 40 |
+
|
| 41 |
+
// Direct all logs strictly to stderr to prevent breaking the MCP STDIO JSON protocol
|
| 42 |
+
tracing_subscriber::fmt()
|
| 43 |
+
.with_writer(std::io::stderr)
|
| 44 |
+
.with_env_filter(
|
| 45 |
+
tracing_subscriber::EnvFilter::from_default_env()
|
| 46 |
+
.add_directive(tracing::Level::INFO.into()),
|
| 47 |
+
)
|
| 48 |
+
.init();
|
| 49 |
+
|
| 50 |
+
if args.threads > 0 {
|
| 51 |
+
rayon::ThreadPoolBuilder::new()
|
| 52 |
+
.num_threads(args.threads)
|
| 53 |
+
.build_global()?;
|
| 54 |
+
info!("Configured Rayon thread pool with {} threads", args.threads);
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
info!("Initializing Tantivy index engine at: {:?}", args.index_dir);
|
| 58 |
+
let engine = Arc::new(TantivyEngine::new(&args.index_dir)?);
|
| 59 |
+
let server = Arc::new(McpServer::new(engine));
|
| 60 |
+
|
| 61 |
+
match args.transport.to_lowercase().as_str() {
|
| 62 |
+
"http" | "sse" => {
|
| 63 |
+
info!("Starting MCP HTTP/SSE transport...");
|
| 64 |
+
server.run_http(&args.host, args.port).await?;
|
| 65 |
+
}
|
| 66 |
+
"stdio" => {
|
| 67 |
+
info!("Starting MCP STDIO transport...");
|
| 68 |
+
server.run_stdio().await?;
|
| 69 |
+
}
|
| 70 |
+
other => {
|
| 71 |
+
eprintln!("Unknown transport '{}'. Expected 'stdio' or 'http'.", other);
|
| 72 |
+
std::process::exit(1);
|
| 73 |
+
}
|
| 74 |
+
}
|
| 75 |
+
|
| 76 |
+
Ok(())
|
| 77 |
+
}
|