soma_mcp_server/
error_result.rs1use rmcp::{
8 model::{CallToolResult, ContentBlock},
9 ErrorData,
10};
11use serde_json::{json, Value};
12
13pub fn tool_error_result(
18 value: Value,
19 max_response_bytes: usize,
20) -> Result<CallToolResult, ErrorData> {
21 let text = serde_json::to_string(&value)
22 .map_err(|e| ErrorData::internal_error(format!("serialization error: {e}"), None))?;
23 let (payload, text) = if text.len() <= max_response_bytes {
24 (value, text)
25 } else {
26 let payload = error_overflow_payload(&value, text.len(), max_response_bytes);
27 let text = serde_json::to_string(&payload)
28 .map_err(|e| ErrorData::internal_error(format!("serialization error: {e}"), None))?;
29 (payload, text)
30 };
31 let mut result = CallToolResult::structured_error(payload);
32 result.content = vec![ContentBlock::text(text)];
33 Ok(result)
34}
35
36fn error_overflow_payload(
37 value: &Value,
38 serialized_bytes: usize,
39 max_response_bytes: usize,
40) -> Value {
41 json!({
42 "kind": "mcp_tool_error",
43 "schema_version": 1,
44 "code": "error_payload_too_large",
45 "original_kind": value.get("kind").cloned().unwrap_or(Value::Null),
46 "original_code": value.get("code").cloned().unwrap_or(Value::Null),
47 "message": "Tool error payload exceeded the MCP response size limit. The original JSON was not returned to avoid invalid truncated JSON.",
48 "retryable": true,
49 "serialized_bytes": serialized_bytes,
50 "max_response_bytes": max_response_bytes,
51 "remediation": "Retry with narrower arguments. If this repeats, inspect server logs for the original error details.",
52 })
53}
54
55pub fn unknown_tool_error(tool_name: &str, available_tools: &[&str]) -> ErrorData {
59 let message = if available_tools.is_empty() {
60 format!("unknown tool: {tool_name}")
61 } else {
62 format!(
63 "unknown tool: {tool_name}; available tools: {}",
64 available_tools.join(", ")
65 )
66 };
67 ErrorData::invalid_params(
68 message,
69 Some(json!({
70 "kind": "mcp_protocol_error",
71 "schema_version": 1,
72 "code": "unknown_tool",
73 "tool": tool_name,
74 "available_tools": available_tools,
75 "retryable": true,
76 "remediation": "Call tools/list, then retry with one of the advertised tool names.",
77 })),
78 )
79}
80
81#[cfg(test)]
82#[path = "error_result_tests.rs"]
83mod tests;