mirror of
https://github.com/codewhale-hq/Codewhale.git
synced 2026-11-10 17:10:18 -10:00
Merge pull request #5336 from xiaoray-blip/fix/mcp-nextcursor-null
fix(mcp): omit nextCursor when there are no further pages
This commit is contained in:
2 files changed
+40
-3
No files matched your search
@@ -233,7 +233,10 @@ impl McpServer {
|
||||
}
|
||||
}
|
||||
}
|
||||
json!({ "tools": tools, "nextCursor": Value::Null })
|
||||
// MCP spec: `nextCursor` must be omitted (or be a string) when there
|
||||
// are no more results. Emitting `null` violates the spec and breaks
|
||||
// strict clients (e.g. Claude Code) that validate the response shape.
|
||||
json!({ "tools": tools })
|
||||
}
|
||||
|
||||
fn list_resources_response(&self) -> Value {
|
||||
@@ -258,7 +261,9 @@ impl McpServer {
|
||||
}
|
||||
}
|
||||
|
||||
json!({ "resources": resources, "nextCursor": Value::Null })
|
||||
// Same spec point as `list_tools_response`: omit `nextCursor` when
|
||||
// there are no further pages rather than emitting `null`.
|
||||
json!({ "resources": resources })
|
||||
}
|
||||
|
||||
fn call_tool(
|
||||
@@ -650,4 +655,36 @@ mod tests {
|
||||
);
|
||||
assert_eq!(map.get("shell").map(String::as_str), Some("exec_shell"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn list_responses_omit_null_next_cursor() {
|
||||
// MCP spec: `nextCursor` must be omitted (or be a string) when there
|
||||
// are no further pages. Emitting `null` breaks strict clients such as
|
||||
// Claude Code, which validate the response shape.
|
||||
let settings = McpServerSettings {
|
||||
expose_tools: vec!["deepseek".to_string(), "apply_patch".to_string()],
|
||||
require_approval: false,
|
||||
};
|
||||
let server = McpServer::new(PathBuf::from("."), settings).expect("build server");
|
||||
|
||||
let tools_value = server.list_tools_response();
|
||||
let tools = tools_value
|
||||
.as_object()
|
||||
.expect("tools/list response is an object");
|
||||
assert!(tools.contains_key("tools"));
|
||||
assert!(
|
||||
tools.get("nextCursor").is_none(),
|
||||
"tools/list must omit nextCursor when there are no more pages"
|
||||
);
|
||||
|
||||
let resources_value = server.list_resources_response();
|
||||
let resources = resources_value
|
||||
.as_object()
|
||||
.expect("resources/list response is an object");
|
||||
assert!(resources.contains_key("resources"));
|
||||
assert!(
|
||||
resources.get("nextCursor").is_none(),
|
||||
"resources/list must omit nextCursor when there are no more pages"
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -188,7 +188,7 @@
|
||||
"large_module_threshold_lines": 1000,
|
||||
"max_large_module_count": 178,
|
||||
"max_module_lines": 17739,
|
||||
"max_total_owned_rust_lines": 689659,
|
||||
"max_total_owned_rust_lines": 689696,
|
||||
"schema_version": 1,
|
||||
"workspace_packages": [
|
||||
"codewhale-agent",
|
||||
|
||||
Reference in new issue
Block a user