|
|
@@ -46,6 +46,100 @@ namespace Mcp.Core {
|
|
|
in_message = false;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Checks if a JSON string contains an "id" field.
|
|
|
+ *
|
|
|
+ * @param json_str The JSON string to check
|
|
|
+ * @return true if the JSON contains an "id" field, false otherwise
|
|
|
+ */
|
|
|
+ private bool json_has_id (string json_str) {
|
|
|
+ // Simple check for "id" field in JSON
|
|
|
+ // Look for "id": pattern (accounting for whitespace)
|
|
|
+ try {
|
|
|
+ // Use regex to find "id": pattern
|
|
|
+ Regex id_regex = new Regex ("\"id\"\\s*:");
|
|
|
+ return id_regex.match (json_str);
|
|
|
+ } catch (Error e) {
|
|
|
+ // If regex fails, fall back to simple string search
|
|
|
+ return json_str.contains ("\"id\":");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Injects ,"id":null" before the last closing brace in a JSON string.
|
|
|
+ *
|
|
|
+ * @param json_str The JSON string to modify
|
|
|
+ * @return The modified JSON string with ,"id":null" injected
|
|
|
+ */
|
|
|
+ private string inject_id_null (string json_str) {
|
|
|
+ // Find the position of the last closing brace
|
|
|
+ int last_brace_pos = json_str.last_index_of ("}");
|
|
|
+
|
|
|
+ if (last_brace_pos == -1) {
|
|
|
+ // No closing brace found, return original string
|
|
|
+ return json_str;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Check if there's any content before the last brace (not an empty object)
|
|
|
+ string before_brace = json_str.substring (0, last_brace_pos);
|
|
|
+ before_brace = before_brace.strip ();
|
|
|
+
|
|
|
+ if (before_brace.length == 0 || before_brace == "{") {
|
|
|
+ // Empty object, just add id:null
|
|
|
+ return json_str.substring (0, last_brace_pos) + "\"id\":0" + json_str.substring (last_brace_pos);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Non-empty object, add ,"id":null" before the last brace
|
|
|
+ return json_str.substring (0, last_brace_pos) + ",\"id\":0" + json_str.substring (last_brace_pos);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Checks if a JSON string contains a "method" field but no "params" field.
|
|
|
+ *
|
|
|
+ * @param json_str The JSON string to check
|
|
|
+ * @return true if the JSON contains "method" but not "params", false otherwise
|
|
|
+ */
|
|
|
+ private bool json_has_method_without_params (string json_str) {
|
|
|
+ try {
|
|
|
+ // Use regex to find "method": and "params": patterns
|
|
|
+ Regex method_regex = new Regex ("\"method\"\\s*:");
|
|
|
+ Regex params_regex = new Regex ("\"params\"\\s*:");
|
|
|
+
|
|
|
+ return method_regex.match (json_str) && !params_regex.match (json_str);
|
|
|
+ } catch (Error e) {
|
|
|
+ // If regex fails, fall back to simple string search
|
|
|
+ return json_str.contains ("\"method\":") && !json_str.contains ("\"params\":");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Injects "params": {} before the last closing brace in a JSON string.
|
|
|
+ *
|
|
|
+ * @param json_str The JSON string to modify
|
|
|
+ * @return The modified JSON string with "params": {} injected
|
|
|
+ */
|
|
|
+ private string inject_params_empty (string json_str) {
|
|
|
+ // Find the position of the last closing brace
|
|
|
+ int last_brace_pos = json_str.last_index_of ("}");
|
|
|
+
|
|
|
+ if (last_brace_pos == -1) {
|
|
|
+ // No closing brace found, return original string
|
|
|
+ return json_str;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Check if there's any content before the last brace (not an empty object)
|
|
|
+ string before_brace = json_str.substring (0, last_brace_pos);
|
|
|
+ before_brace = before_brace.strip ();
|
|
|
+
|
|
|
+ if (before_brace.length == 0 || before_brace == "{") {
|
|
|
+ // Empty object, just add params:{}
|
|
|
+ return json_str.substring (0, last_brace_pos) + "\"params\":{}" + json_str.substring (last_brace_pos);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Non-empty object, add ,"params":{}" before the last brace
|
|
|
+ return json_str.substring (0, last_brace_pos) + ",\"params\":{}" + json_str.substring (last_brace_pos);
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Converts input data by injecting Content-Length headers.
|
|
|
*
|
|
|
@@ -75,9 +169,22 @@ namespace Mcp.Core {
|
|
|
|
|
|
// Skip empty lines
|
|
|
if (json_str.length > 0) {
|
|
|
+ // Process JSON to inject missing fields
|
|
|
+ string processed_json = json_str;
|
|
|
+
|
|
|
+ // Check if JSON has an ID field and inject one if needed
|
|
|
+ if (!json_has_id (processed_json)) {
|
|
|
+ processed_json = inject_id_null (processed_json);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Check if JSON has method but no params and inject params if needed
|
|
|
+ if (json_has_method_without_params (processed_json)) {
|
|
|
+ processed_json = inject_params_empty (processed_json);
|
|
|
+ }
|
|
|
+
|
|
|
// Create the message with Content-Length header
|
|
|
string message_with_header = "Content-Length: %d\r\n\r\n%s".printf (
|
|
|
- json_str.length, json_str);
|
|
|
+ processed_json.length, processed_json);
|
|
|
|
|
|
// Check if we have enough space in output buffer
|
|
|
if (bytes_written + message_with_header.length > outbuf.length) {
|
|
|
@@ -101,9 +208,22 @@ namespace Mcp.Core {
|
|
|
string json_str = buffer.str.strip ();
|
|
|
|
|
|
if (json_str.length > 0) {
|
|
|
+ // Process JSON to inject missing fields
|
|
|
+ string processed_json = json_str;
|
|
|
+
|
|
|
+ // Check if JSON has an ID field and inject one if needed
|
|
|
+ if (!json_has_id (processed_json)) {
|
|
|
+ processed_json = inject_id_null (processed_json);
|
|
|
+ }
|
|
|
+
|
|
|
+ // Check if JSON has method but no params and inject params if needed
|
|
|
+ if (json_has_method_without_params (processed_json)) {
|
|
|
+ processed_json = inject_params_empty (processed_json);
|
|
|
+ }
|
|
|
+
|
|
|
// Create the message with Content-Length header
|
|
|
string message_with_header = "Content-Length: %d\r\n\r\n%s".printf (
|
|
|
- json_str.length, json_str);
|
|
|
+ processed_json.length, processed_json);
|
|
|
|
|
|
// Check if we have enough space in output buffer
|
|
|
if (bytes_written + message_with_header.length > outbuf.length) {
|