Skip to content

Commit 27df5ba

Browse files
committed
fix: align header mismatch error code with draft spec
1 parent b18ddc0 commit 27df5ba

3 files changed

Lines changed: 16 additions & 16 deletions

File tree

crates/rmcp/src/model.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,7 +515,7 @@ pub struct JsonRpcNotification<N = Notification> {
515515
pub struct ErrorCode(pub i32);
516516

517517
impl ErrorCode {
518-
pub const HEADER_MISMATCH: Self = Self(-32001);
518+
pub const HEADER_MISMATCH: Self = Self(-32020);
519519
pub const RESOURCE_NOT_FOUND: Self = Self(-32002);
520520
pub const INVALID_REQUEST: Self = Self(-32600);
521521
pub const METHOD_NOT_FOUND: Self = Self(-32601);

crates/rmcp/src/transport/common/mcp_headers.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,7 @@ pub(crate) fn standard_request_headers(
252252
/// Validates incoming SEP-2243 headers against the request body.
253253
///
254254
/// Returns `Err(reason)` when a required header is missing or its value does not
255-
/// match the body; the caller maps this to a JSON-RPC `-32001` error (HTTP 400).
255+
/// match the body; the caller maps this to a JSON-RPC `-32020` error (HTTP 400).
256256
#[cfg(feature = "server-side-http")]
257257
pub(crate) fn validate_request_headers(
258258
headers: &http::HeaderMap,

crates/rmcp/tests/test_streamable_http_standard_headers.rs

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ async fn accepts_matching_standard_headers() -> anyhow::Result<()> {
102102
let (client, url, ct) = spawn_server().await;
103103

104104
// Matching headers pass validation and reach dispatch. (Stateless mode without a
105-
// prior initialize yields an unrelated -32601, which still proves -32001 was not raised.)
105+
// prior initialize yields an unrelated -32601, which still proves -32020 was not raised.)
106106
let response = post_tool_call(
107107
&client,
108108
&url,
@@ -116,7 +116,7 @@ async fn accepts_matching_standard_headers() -> anyhow::Result<()> {
116116
.await;
117117
let body: serde_json::Value = response.json().await?;
118118
assert_ne!(
119-
body["error"]["code"], -32001,
119+
body["error"]["code"], -32020,
120120
"matching headers must not be rejected as a header mismatch, got: {body}"
121121
);
122122

@@ -125,7 +125,7 @@ async fn accepts_matching_standard_headers() -> anyhow::Result<()> {
125125
}
126126

127127
#[tokio::test]
128-
async fn rejects_method_mismatch_with_32001() -> anyhow::Result<()> {
128+
async fn rejects_method_mismatch_with_32020() -> anyhow::Result<()> {
129129
let (client, url, ct) = spawn_server().await;
130130

131131
let response = post_tool_call(
@@ -141,14 +141,14 @@ async fn rejects_method_mismatch_with_32001() -> anyhow::Result<()> {
141141
.await;
142142
assert_eq!(response.status(), 400);
143143
let body: serde_json::Value = response.json().await?;
144-
assert_eq!(body["error"]["code"], -32001);
144+
assert_eq!(body["error"]["code"], -32020);
145145

146146
ct.cancel();
147147
Ok(())
148148
}
149149

150150
#[tokio::test]
151-
async fn rejects_missing_method_header_with_32001() -> anyhow::Result<()> {
151+
async fn rejects_missing_method_header_with_32020() -> anyhow::Result<()> {
152152
let (client, url, ct) = spawn_server().await;
153153

154154
let response = post_tool_call(
@@ -164,14 +164,14 @@ async fn rejects_missing_method_header_with_32001() -> anyhow::Result<()> {
164164
.await;
165165
assert_eq!(response.status(), 400);
166166
let body: serde_json::Value = response.json().await?;
167-
assert_eq!(body["error"]["code"], -32001);
167+
assert_eq!(body["error"]["code"], -32020);
168168

169169
ct.cancel();
170170
Ok(())
171171
}
172172

173173
#[tokio::test]
174-
async fn rejects_name_mismatch_with_32001() -> anyhow::Result<()> {
174+
async fn rejects_name_mismatch_with_32020() -> anyhow::Result<()> {
175175
let (client, url, ct) = spawn_server().await;
176176

177177
let response = post_tool_call(
@@ -187,7 +187,7 @@ async fn rejects_name_mismatch_with_32001() -> anyhow::Result<()> {
187187
.await;
188188
assert_eq!(response.status(), 400);
189189
let body: serde_json::Value = response.json().await?;
190-
assert_eq!(body["error"]["code"], -32001);
190+
assert_eq!(body["error"]["code"], -32020);
191191

192192
ct.cancel();
193193
Ok(())
@@ -211,7 +211,7 @@ async fn skips_validation_for_pre_sep_version() -> anyhow::Result<()> {
211211
.await;
212212
let body: serde_json::Value = response.json().await?;
213213
assert_ne!(
214-
body["error"]["code"], -32001,
214+
body["error"]["code"], -32020,
215215
"pre-SEP versions must skip header validation, got: {body}"
216216
);
217217

@@ -236,7 +236,7 @@ async fn accepts_matching_param_header() -> anyhow::Result<()> {
236236
.await;
237237
let body: serde_json::Value = response.json().await?;
238238
assert_ne!(
239-
body["error"]["code"], -32001,
239+
body["error"]["code"], -32020,
240240
"matching Mcp-Param-* must not be rejected, got: {body}"
241241
);
242242

@@ -245,7 +245,7 @@ async fn accepts_matching_param_header() -> anyhow::Result<()> {
245245
}
246246

247247
#[tokio::test]
248-
async fn rejects_param_mismatch_with_32001() -> anyhow::Result<()> {
248+
async fn rejects_param_mismatch_with_32020() -> anyhow::Result<()> {
249249
let (client, url, ct) = spawn_server().await;
250250

251251
let response = post_tool_call(
@@ -261,14 +261,14 @@ async fn rejects_param_mismatch_with_32001() -> anyhow::Result<()> {
261261
.await;
262262
assert_eq!(response.status(), 400);
263263
let body: serde_json::Value = response.json().await?;
264-
assert_eq!(body["error"]["code"], -32001);
264+
assert_eq!(body["error"]["code"], -32020);
265265

266266
ct.cancel();
267267
Ok(())
268268
}
269269

270270
#[tokio::test]
271-
async fn rejects_missing_param_header_with_32001() -> anyhow::Result<()> {
271+
async fn rejects_missing_param_header_with_32020() -> anyhow::Result<()> {
272272
let (client, url, ct) = spawn_server().await;
273273

274274
// `region` argument is present but the annotated `Mcp-Param-Region` header is absent.
@@ -285,7 +285,7 @@ async fn rejects_missing_param_header_with_32001() -> anyhow::Result<()> {
285285
.await;
286286
assert_eq!(response.status(), 400);
287287
let body: serde_json::Value = response.json().await?;
288-
assert_eq!(body["error"]["code"], -32001);
288+
assert_eq!(body["error"]["code"], -32020);
289289

290290
ct.cancel();
291291
Ok(())

0 commit comments

Comments
 (0)