Skip to content

Commit 92f77dc

Browse files
committed
[worker] fase C: upgrade rmcp 1.8.0 -> 3.3.0 (Aikido 34247111, 5 advisories)
Behavior-identical migration: legacy initialize/session paths preserved, 2026-07-28 stateless lifecycle NOT enabled. The tool macros absorb the MRTR response-enum changes, so code impact is contained to: - Content/RawContent -> ContentBlock (renamed/merged in 3.x) - #[tool_router(allow_empty)] on the ctors-only impl (3.3 rejects toolless routers; the real router is merged_tool_router()) - proxy call_tool returns CallToolResponse (manual ServerHandler impl) - test assertions drop the removed .raw projection Validation: cargo fmt, clippy -D warnings, 1384 lib+bin tests green.
1 parent a4aef75 commit 92f77dc

16 files changed

Lines changed: 143 additions & 169 deletions

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ finalized in place with a date — no renaming/migration step needed.
2020

2121
- **Dependency refresh: h2, rustls, quinn-proto, zerovec-derive, moka.** A semver-safe `cargo update` lifts 126 packages within their existing requirements, clearing five open advisories without code changes: h2 0.4.15→0.4.19 (Aikido 41883526), rustls 0.23.42→0.23.45 (RUSTSEC-2026-0285), quinn-proto 0.11.16→0.11.18 (Aikido 41883527), zerovec-derive 0.11.3→0.11.6 (Aikido 41883531) and moka 0.12.15→0.12.16 (Aikido 41297220). fastembed/ort are deliberately kept at 5.17.3/rc.12 — 5.17.4 hard-requires the unstable ort rc.13 API break, which moves in its own PR.
2222

23+
- **rmcp 1.8.0 → 3.3.0 — clears the five Aikido advisories on the MCP SDK (34247111).** Behavior-identical upgrade: the legacy `initialize` handshake and session semantics stay the default (`ProtocolVersion::LATEST` remains 2025-11-25); the 2026-07-28 stateless lifecycle is opt-in upstream and deliberately not enabled here. Code impact stayed small because the `#[tool_router]`/`#[tool_handler]` macros absorb the new MRTR response enums: `Content`/`RawContent` are now `ContentBlock`, the constructors-only impl takes `#[tool_router(allow_empty)]`, the stdio proxy's manual `call_tool` returns `CallToolResponse`, and content assertions drop the removed `.raw` projection.
24+
2325
## [1.3.19]
2426

2527
### Changed

Cargo.lock

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

Cargo.toml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,10 @@ bincode = "1.3"
104104
scip = "0.9"
105105
protobuf = "3.7"
106106
rand = "0.8"
107-
# Bumped floor from 1.5.0 to 1.8.0 for CVE patches (Aikido group: rmcp priority 82, 3 CVEs).
108-
# v2.x is available but is a breaking major bump — deferred.
109-
rmcp = { version = "1.8.0", features = ["server", "client", "transport-io", "transport-streamable-http-server", "transport-streamable-http-client-reqwest", "macros"] }
107+
# Aikido 34247111: 1.8.0 carries 5 advisories (CVE-2026-64684/317735/617985 + 2 more).
108+
# 3.x keeps legacy initialize/session behavior by default (ProtocolVersion::LATEST stays
109+
# V_2025_11_25); the 2026-07-28 stateless lifecycle is opt-in and NOT enabled here.
110+
rmcp = { version = "3.3.0", features = ["server", "client", "transport-io", "transport-streamable-http-server", "transport-streamable-http-client-reqwest", "macros"] }
110111
schemars = { version = "1.1.0", features = ["derive"] }
111112
reqwest = { version = "0.13", default-features = false, features = ["json", "rustls"] }
112113
sysinfo = { version = "0.38.4", default-features = true }

src/mcp/explore.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
use super::*;
77
use rmcp::{
88
handler::server::wrapper::Parameters,
9-
model::{CallToolResult, Content},
9+
model::{CallToolResult, ContentBlock},
1010
tool, tool_router, ErrorData as McpError,
1111
};
1212

@@ -40,7 +40,7 @@ impl CodesearchService {
4040
let chunk_id = match request.target.parse::<u32>() {
4141
Ok(id) => id,
4242
Err(_) => {
43-
return Ok(CallToolResult::success(vec![Content::text(format!(
43+
return Ok(CallToolResult::success(vec![ContentBlock::text(format!(
4444
"For similar mode, `target` must be a numeric chunk_id, got: '{}'",
4545
request.target
4646
))]));
@@ -54,7 +54,7 @@ impl CodesearchService {
5454
};
5555
self.similar_chunks(Parameters(similar_req)).await
5656
}
57-
_ => Ok(CallToolResult::success(vec![Content::text(format!(
57+
_ => Ok(CallToolResult::success(vec![ContentBlock::text(format!(
5858
"Unknown explore kind '{}'. Use `outline` or `similar`.",
5959
kind
6060
))])),
@@ -138,20 +138,20 @@ impl CodesearchService {
138138
.await
139139
{
140140
Ok(c) => c,
141-
Err(e) => return Ok(CallToolResult::success(vec![Content::text(e)])),
141+
Err(e) => return Ok(CallToolResult::success(vec![ContentBlock::text(e)])),
142142
};
143143

144144
// Outline operates on a single repo — reject group fan-out
145145
if ctx.is_multi {
146-
return Ok(CallToolResult::success(vec![Content::text(
146+
return Ok(CallToolResult::success(vec![ContentBlock::text(
147147
"Tool 'explore' operates on a single repo. Use 'project' instead of 'group'."
148148
.to_string(),
149149
)]));
150150
}
151151

152152
if ctx.needs_local_db {
153153
if let Err(e) = self.ensure_database_exists() {
154-
return Ok(CallToolResult::success(vec![Content::text(e)]));
154+
return Ok(CallToolResult::success(vec![ContentBlock::text(e)]));
155155
}
156156
}
157157

@@ -177,7 +177,7 @@ impl CodesearchService {
177177
{
178178
Ok(v) => v,
179179
Err(e) => {
180-
return Ok(CallToolResult::success(vec![Content::text(format!(
180+
return Ok(CallToolResult::success(vec![ContentBlock::text(format!(
181181
"Error reading outline: {e:#}"
182182
))]));
183183
}

src/mcp/federation_helpers_tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use super::{convert_remote_item, merge_ranked_lists, parse_search_items_from_call_result};
55
use crate::federation::RemoteSearchItem;
66
use crate::mcp::types::SearchResultItem;
7-
use rmcp::model::{CallToolResult, Content};
7+
use rmcp::model::{CallToolResult, ContentBlock};
88

99
fn local_item(chunk_id: u32, score: f32) -> SearchResultItem {
1010
SearchResultItem {
@@ -146,7 +146,7 @@ fn parse_federated_chunk_ref_rejects_garbage() {
146146
// === parse_search_items_from_call_result (serve-delegation re-parse) ===
147147

148148
fn call_result_with_json(json: &str) -> CallToolResult {
149-
CallToolResult::success(vec![Content::text(json.to_string())])
149+
CallToolResult::success(vec![ContentBlock::text(json.to_string())])
150150
}
151151

152152
#[test]

0 commit comments

Comments
 (0)