Skip to content

Commit 79f0304

Browse files
authored
Fix TODOs now that new features are available (#107)
1 parent 8466ef2 commit 79f0304

8 files changed

Lines changed: 55 additions & 74 deletions

File tree

cli/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
### Patch
2424

25+
- Remove `rmcp::tool` work-around by using `local` attribute
2526
- Fix clippy lints
2627
- Update dependencies
2728
- Support the new internal message timestamp logic

cli/Cargo.lock

Lines changed: 26 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cli/Cargo.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ opener = "0.7.2"
3030
platform-info = "2.0.5"
3131
rand = "0.9.3"
3232
reqwest = { version = "0.12.15", features = ["json"] }
33-
rmcp = "0.8.2"
33+
rmcp = "1.4.0"
3434
schemars = "1.0.4"
3535
serde = { version = "1.0.219", features = ["derive"] }
3636
serde_json = { version = "1.0.140", features = ["preserve_order"] }
@@ -45,8 +45,6 @@ uuid = { version = "1.16.0", features = ["v4"] }
4545
inherits = "release"
4646

4747
[lints]
48-
# TODO(https://github.com/rust-lang/rust/issues/53667): Remove when stable.
49-
clippy.collapsible-if = "allow"
5048
clippy.mod-module-files = "warn"
5149
clippy.unit-arg = "allow"
5250
rust.elided-lifetimes-in-paths = "warn"

cli/src/cli/interact.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -323,12 +323,12 @@ fn display_json_object(
323323
) {
324324
for (key, val) in map {
325325
write!(out, "{}:", key.bold().color(color)).unwrap();
326-
if let Some(val) = val.as_str() {
327-
if val.find('\n').is_some_and(|i| i + 1 < val.len()) {
328-
write!(out, "\n{}", val.color(color)).unwrap();
329-
ensure_newline(val, out);
330-
continue;
331-
}
326+
if let Some(val) = val.as_str()
327+
&& val.find('\n').is_some_and(|i| i + 1 < val.len())
328+
{
329+
write!(out, "\n{}", val.color(color)).unwrap();
330+
ensure_newline(val, out);
331+
continue;
332332
}
333333
writeln!(out, " {}", serde_json::to_string(val).unwrap().color(color)).unwrap();
334334
}

cli/src/cli/interact/cmds.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -307,14 +307,13 @@ fn quote(mut word: &str) -> Cow<'_, str> {
307307
return word.into();
308308
};
309309
let mut quoted = String::new();
310-
if word.starts_with("--") {
311-
if let Some(eq) = word.find('=') {
312-
if eq < pos {
313-
let (prefix, suffix) = word.split_at(eq + 1);
314-
quoted = prefix.to_string();
315-
word = suffix;
316-
}
317-
}
310+
if word.starts_with("--")
311+
&& let Some(eq) = word.find('=')
312+
&& eq < pos
313+
{
314+
let (prefix, suffix) = word.split_at(eq + 1);
315+
quoted = prefix.to_string();
316+
word = suffix;
318317
}
319318
quoted.push('\'');
320319
for c in word.chars() {

cli/src/tool/exec.rs

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ use crate::config;
2626
use crate::tool::Tools;
2727

2828
pub fn list(tools: &mut Tools) {
29-
tools.push(_spawn_tool_attr(), spawn);
30-
tools.push(_interact_tool_attr(), interact);
31-
tools.push(_kill_tool_attr(), kill);
29+
tools.push(spawn_tool_attr(), spawn);
30+
tools.push(interact_tool_attr(), interact);
31+
tools.push(kill_tool_attr(), kill);
3232
}
3333

3434
#[derive(Serialize, Deserialize, JsonSchema)]
@@ -47,12 +47,7 @@ pub struct SpawnRequest {
4747
///
4848
/// This tool can be used together with `file_write` (setting `executable` to create an executable
4949
/// file) to execute a Python or shell script.
50-
#[rmcp::tool(name = "exec_spawn")]
51-
async fn _spawn(_: Parameters<SpawnRequest>) -> Result<Json<InteractResponse>, String> {
52-
// TODO(https://github.com/modelcontextprotocol/rust-sdk/issues/495): Remove when fixed.
53-
unreachable!()
54-
}
55-
50+
#[rmcp::tool(local, name = "exec_spawn")]
5651
async fn spawn(params: Parameters<SpawnRequest>) -> Result<Json<InteractResponse>, String> {
5752
let SpawnRequest { program, arguments, interact: request } = params.0;
5853
let mut child = Command::new(program)
@@ -103,13 +98,8 @@ pub struct InteractResponse {
10398
/// The tool will listen for output until some amount of inactivity or some fixed deadline,
10499
/// whichever happens first. The tool will fail if the process outputs binary data that is not
105100
/// UTF-8.
106-
#[rmcp::tool(name = "exec_interact")]
107-
async fn _interact(_: Parameters<InteractRequest>) -> Result<Json<InteractResponse>, String> {
108-
// TODO(https://github.com/modelcontextprotocol/rust-sdk/issues/495): Remove when fixed.
109-
unreachable!()
110-
}
111-
112101
#[allow(clippy::await_holding_lock)]
102+
#[rmcp::tool(local, name = "exec_interact")]
113103
async fn interact(params: Parameters<InteractRequest>) -> Result<Json<InteractResponse>, String> {
114104
let InteractRequest { stdin, close_stdin } = params.0;
115105
let mut state = STATE.lock().unwrap();
@@ -178,12 +168,8 @@ async fn interact(params: Parameters<InteractRequest>) -> Result<Json<InteractRe
178168
pub struct KillRequest {}
179169

180170
/// Kills an running process.
181-
#[rmcp::tool(name = "exec_kill", annotations(destructive_hint = false))]
182-
async fn _kill(_: Parameters<KillRequest>) -> Result<Json<String>, String> {
183-
unreachable!()
184-
}
185-
186171
#[allow(clippy::await_holding_lock)]
172+
#[rmcp::tool(name = "exec_kill", annotations(destructive_hint = false))]
187173
async fn kill(params: Parameters<KillRequest>) -> Result<Json<String>, String> {
188174
let KillRequest {} = params.0;
189175
let Some(mut running) = STATE.lock().unwrap().take() else {

cli/src/tool/file.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use tokio::io::{AsyncReadExt, AsyncWriteExt};
2727
use crate::tool::Tools;
2828

2929
pub fn list(tools: &mut Tools) {
30-
tools.push(_list_tool_attr(), _list);
30+
tools.push(flist_tool_attr(), flist);
3131
tools.push(read_tool_attr(), read);
3232
tools.push(write_tool_attr(), write);
3333
tools.push(sha256_tool_attr(), sha256);
@@ -47,7 +47,7 @@ pub struct ListResponse {
4747
///
4848
/// In the response, directories are suffixed with a slash like `bin/`.
4949
#[rmcp::tool(name = "file_list", annotations(read_only_hint = true))]
50-
async fn _list(params: Parameters<ListRequest>) -> Result<Json<ListResponse>, String> {
50+
async fn flist(params: Parameters<ListRequest>) -> Result<Json<ListResponse>, String> {
5151
let ListRequest { path } = params.0;
5252
let mut names = Vec::new();
5353
let mut entries = tokio::fs::read_dir(path).await.map_err(|e| e.to_string())?;

cli/src/tool/net.rs

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ use crate::config;
2525
use crate::tool::Tools;
2626

2727
pub fn list(tools: &mut Tools) {
28-
tools.push(_connect_tool_attr(), connect);
29-
tools.push(_interact_tool_attr(), interact);
30-
tools.push(_close_tool_attr(), close);
28+
tools.push(connect_tool_attr(), connect);
29+
tools.push(interact_tool_attr(), interact);
30+
tools.push(close_tool_attr(), close);
3131
}
3232

3333
#[derive(Serialize, Deserialize, JsonSchema)]
@@ -42,12 +42,7 @@ pub struct ConnectRequest {
4242
/// To interact with the connection, use the `net_tcp_interact` tool. To close the connection, use
4343
/// the `net_tcp_close` tool. The initial interaction is built-in by taking the same `input` field
4444
/// as `net_tcp_interact` and returning the same fields.
45-
#[rmcp::tool(name = "net_tcp_connect", annotations(destructive_hint = false))]
46-
async fn _connect(_: Parameters<ConnectRequest>) -> Result<Json<InteractResponse>, String> {
47-
// TODO(https://github.com/modelcontextprotocol/rust-sdk/issues/495): Remove when fixed.
48-
unreachable!()
49-
}
50-
45+
#[rmcp::tool(local, name = "net_tcp_connect", annotations(destructive_hint = false))]
5146
async fn connect(params: Parameters<ConnectRequest>) -> Result<Json<InteractResponse>, String> {
5247
let ConnectRequest { host, port, input } = params.0;
5348
let stream = TcpStream::connect((host, port)).await.map_err(|e| e.to_string())?;
@@ -73,13 +68,8 @@ pub struct InteractResponse {
7368
///
7469
/// The tool will listen until some amount of inactivity or some fixed deadline, whichever happens
7570
/// first. The tool will fail if the peer sends binary data that is not UTF-8.
76-
#[rmcp::tool(name = "net_tcp_interact", annotations(destructive_hint = false))]
77-
async fn _interact(_: Parameters<InteractRequest>) -> Result<Json<InteractResponse>, String> {
78-
// TODO(https://github.com/modelcontextprotocol/rust-sdk/issues/495): Remove when fixed.
79-
unreachable!()
80-
}
81-
8271
#[allow(clippy::await_holding_lock)]
72+
#[rmcp::tool(local, name = "net_tcp_interact", annotations(destructive_hint = false))]
8373
async fn interact(params: Parameters<InteractRequest>) -> Result<Json<InteractResponse>, String> {
8474
let InteractRequest { input } = params.0;
8575
let mut state = STATE.lock().unwrap();
@@ -119,12 +109,8 @@ async fn interact(params: Parameters<InteractRequest>) -> Result<Json<InteractRe
119109
pub struct CloseRequest {}
120110

121111
/// Closes an open TCP connection.
122-
#[rmcp::tool(name = "net_tcp_close", annotations(destructive_hint = false))]
123-
async fn _close(_: Parameters<CloseRequest>) -> Result<Json<String>, String> {
124-
unreachable!()
125-
}
126-
127112
#[allow(clippy::await_holding_lock)]
113+
#[rmcp::tool(name = "net_tcp_close", annotations(destructive_hint = false))]
128114
async fn close(params: Parameters<CloseRequest>) -> Result<Json<String>, String> {
129115
let CloseRequest {} = params.0;
130116
let Some(mut stream) = STATE.lock().unwrap().take() else {

0 commit comments

Comments
 (0)