refactor: Enforce strict typed JsonSchema for all MCP tools
This commit is contained in:
1 parent
686fea683d
commit
2d3aaed289
31 files changed
+2892
-308
No files matched your search
+97
@@ -0,0 +1,97 @@
|
||||
import re
|
||||
|
||||
with open("server/src/main.rs", "r", encoding="utf-8") as f:
|
||||
content = f.read()
|
||||
|
||||
cli_gate_block = re.search(r' if let Some\(command\) = cli\.command \{.*?(?= run_server\(state\))', content, re.DOTALL)
|
||||
if cli_gate_block:
|
||||
content = content.replace(cli_gate_block.group(0), "")
|
||||
|
||||
new_cli_logic = """
|
||||
if let Some(command) = cli.command {
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
rt.block_on(async {
|
||||
let client = reqwest::Client::new();
|
||||
match command {
|
||||
Commands::Gate { subcmd } => match subcmd {
|
||||
GateCommands::Set { action, target, namespace, params, authorize, block, reason } => {
|
||||
let mut param_map = HashMap::new();
|
||||
for p in params {
|
||||
if let Some((k, v)) = p.split_once('=') {
|
||||
param_map.insert(k.to_string(), v.to_string());
|
||||
}
|
||||
}
|
||||
let body = serde_json::json!({
|
||||
"action": action,
|
||||
"target": target,
|
||||
"namespace": namespace,
|
||||
"params": param_map,
|
||||
"authorize": authorize,
|
||||
"block": block,
|
||||
"reason": reason
|
||||
});
|
||||
match client.post("http://127.0.0.1:3000/gate/set").json(&body).send().await {
|
||||
Ok(res) if res.status().is_success() => {
|
||||
println!("Gate state updated via daemon.");
|
||||
std::process::exit(0);
|
||||
}
|
||||
Ok(res) => {
|
||||
eprintln!("Failed to update gate: {}", res.status());
|
||||
std::process::exit(1);
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Failed to connect to daemon: {}", e);
|
||||
std::process::exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
GateCommands::Verify { action, target, namespace, params, consume } => {
|
||||
let mut query = vec![
|
||||
("action".to_string(), action),
|
||||
("target".to_string(), target),
|
||||
("consume".to_string(), consume.to_string()),
|
||||
];
|
||||
if let Some(ns) = namespace {
|
||||
query.push(("namespace".to_string(), ns));
|
||||
}
|
||||
// Reqwest will serialize params correctly if we pass the right struct.
|
||||
// Actually, axum's Query extractor for HashMap requires flat keys or standard serialization.
|
||||
for p in params {
|
||||
if let Some((k, v)) = p.split_once('=') {
|
||||
query.push((k.to_string(), v.to_string()));
|
||||
}
|
||||
}
|
||||
match client.get("http://127.0.0.1:3000/gate/verify").query(&query).send().await {
|
||||
Ok(res) => {
|
||||
let status = res.status();
|
||||
let text = res.text().await.unwrap_or_default();
|
||||
if status.is_success() {
|
||||
std::process::exit(0);
|
||||
} else if status == reqwest::StatusCode::FORBIDDEN {
|
||||
eprintln!("❌ {}", text);
|
||||
std::process::exit(1);
|
||||
} else {
|
||||
eprintln!("❌ {}", text);
|
||||
std::process::exit(2);
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Failed to connect to daemon: {}", e);
|
||||
std::process::exit(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return Ok(());
|
||||
}
|
||||
"""
|
||||
|
||||
restart_block = re.search(r' if cli\.restart \{.*?return Ok\(\(\);\n \}', content, re.DOTALL)
|
||||
if restart_block:
|
||||
content = content.replace(restart_block.group(0), restart_block.group(0) + "\n" + new_cli_logic)
|
||||
|
||||
with open("server/src/main.rs", "w", encoding="utf-8") as f:
|
||||
f.write(content)
|
||||
|
||||
Reference in new issue
Block a user