fix: index_create updates tracked project for search_text
index_create and index_update now update the MCP server's tracked project path so subsequent calls like search_text use the same project. search_text also gains an optional 'project' parameter to explicitly override the default. Closes #9.
This commit is contained in:
1 parent
4b55a41ece
commit
2cd801558d
1 file changed
+25
-10
+25
-10
@@ -1,7 +1,7 @@
|
||||
//! Minimal MCP server: JSON-RPC over stdio, dispatching to the same ops as the CLI.
|
||||
|
||||
use std::io::{BufRead, Write};
|
||||
use std::path::Path;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use anyhow::Result;
|
||||
use serde_json::{Value, json};
|
||||
@@ -10,6 +10,7 @@ const PROTOCOL_VERSION: &str = "2024-11-05";
|
||||
|
||||
pub fn serve(project: &Path) -> Result<()> {
|
||||
eprintln!("rustytokens MCP server listening on stdio");
|
||||
let mut project = project.to_path_buf();
|
||||
let stdin = std::io::stdin();
|
||||
let stdout = std::io::stdout();
|
||||
for line in stdin.lock().lines() {
|
||||
@@ -39,7 +40,7 @@ pub fn serve(project: &Path) -> Result<()> {
|
||||
continue;
|
||||
}
|
||||
};
|
||||
if let Some(resp) = handle(&msg, project) {
|
||||
if let Some(resp) = handle(&msg, &mut project) {
|
||||
let mut out = stdout.lock();
|
||||
serde_json::to_writer(&mut out, &resp)?;
|
||||
out.write_all(b"\n")?;
|
||||
@@ -49,7 +50,7 @@ pub fn serve(project: &Path) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn handle(msg: &Value, project: &Path) -> Option<Value> {
|
||||
fn handle(msg: &Value, project: &mut PathBuf) -> Option<Value> {
|
||||
let id = msg.get("id").cloned();
|
||||
|
||||
// Notifications have no id -> no response.
|
||||
@@ -101,7 +102,7 @@ fn handle(msg: &Value, project: &Path) -> Option<Value> {
|
||||
}
|
||||
}
|
||||
|
||||
fn call_tool(name: &str, args: &Value, project: &Path) -> Value {
|
||||
fn call_tool(name: &str, args: &Value, project: &mut PathBuf) -> Value {
|
||||
let result: Result<Value> = dispatch(name, args, project);
|
||||
match result {
|
||||
Ok(v) => json!({
|
||||
@@ -114,7 +115,7 @@ fn call_tool(name: &str, args: &Value, project: &Path) -> Value {
|
||||
}
|
||||
}
|
||||
|
||||
fn dispatch(name: &str, args: &Value, project: &Path) -> Result<Value> {
|
||||
fn dispatch(name: &str, args: &Value, project: &mut PathBuf) -> Result<Value> {
|
||||
use crate::ops;
|
||||
|
||||
fn req_str<'a>(args: &'a Value, key: &str, tool: &str) -> Result<&'a str> {
|
||||
@@ -128,8 +129,16 @@ fn dispatch(name: &str, args: &Value, project: &Path) -> Result<Value> {
|
||||
let excludes = crate::config::ExcludeSet::new(&exclude_list(args));
|
||||
|
||||
match name {
|
||||
"index_create" => ops::index_create(Path::new(req_str(args, "path", name)?)),
|
||||
"index_update" => ops::index_update(Path::new(req_str(args, "path", name)?)),
|
||||
"index_create" => {
|
||||
let path = PathBuf::from(req_str(args, "path", name)?);
|
||||
project.clone_from(&path);
|
||||
ops::index_create(&path)
|
||||
}
|
||||
"index_update" => {
|
||||
let path = PathBuf::from(req_str(args, "path", name)?);
|
||||
project.clone_from(&path);
|
||||
ops::index_update(&path)
|
||||
}
|
||||
"index_file" => ops::index_file(project, req_str(args, "path", name)?),
|
||||
"search_symbols" => ops::search_symbols(
|
||||
project,
|
||||
@@ -143,15 +152,20 @@ fn dispatch(name: &str, args: &Value, project: &Path) -> Result<Value> {
|
||||
.unwrap_or(200),
|
||||
&excludes,
|
||||
),
|
||||
"search_text" => ops::search_text(
|
||||
project,
|
||||
"search_text" => {
|
||||
let search_project = opt_str("project")
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or_else(|| project.clone());
|
||||
ops::search_text(
|
||||
&search_project,
|
||||
req_str(args, "query", name)?,
|
||||
args.get("limit")
|
||||
.and_then(|v| v.as_u64())
|
||||
.map(|n| n as usize)
|
||||
.unwrap_or(100),
|
||||
&excludes,
|
||||
),
|
||||
)
|
||||
}
|
||||
"inspect_symbol" => {
|
||||
if let Some(id) = args.get("id").and_then(|v| v.as_i64()) {
|
||||
ops::inspect_symbol(project, &id.to_string())
|
||||
@@ -272,6 +286,7 @@ fn tools() -> Value {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"query": { "type": "string", "description": "Text or phrase to search for" },
|
||||
"project": { "type": "string", "description": "Project directory to search (defaults to the last indexed project)" },
|
||||
"limit": { "type": "integer", "description": "Maximum matching files (default 100)" },
|
||||
"exclude": {
|
||||
"type": "array",
|
||||
|
||||
Reference in new issue
Block a user