summaryrefslogtreecommitdiff
path: root/src/mcp/tools/update_message.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mcp/tools/update_message.c')
-rw-r--r--src/mcp/tools/update_message.c97
1 files changed, 97 insertions, 0 deletions
diff --git a/src/mcp/tools/update_message.c b/src/mcp/tools/update_message.c
new file mode 100644
index 0000000..aca1bed
--- /dev/null
+++ b/src/mcp/tools/update_message.c
@@ -0,0 +1,97 @@
+#include "mcp/tools/common/registry.h"
+
+#include "mcp/tools/common/common.h"
+#include "mcp/tools/common/context.h"
+
+#include <stdint.h>
+#include <stdlib.h>
+
+static void
+call_update_message(const mcpc_tool_t *tool, mcpc_ucbr_t *result)
+{
+ tiny_mcp_tools_context_t *context = tiny_mcp_tools_context_current();
+ char *message_id = tiny_mcp_tool_get_string(tool, "message_id", TINY_MESSAGE_ID_LENGTH);
+ char *content = tiny_mcp_tool_get_string(tool, "content", TINY_CONTENT_MAX);
+ char *metadata_json = tiny_mcp_tool_get_string(tool, "metadata_json", TINY_CONTENT_MAX);
+ int32_t expected = 0;
+ mcpc_errcode_t expected_status
+ = mcpc_tool_get_tpropval_i32(tool, (const char8_t *)"expected_revision", &expected);
+ tiny_message_t parsed, updated;
+ tiny_message_patch_t patch;
+ tiny_store_status_t status;
+ tiny_json_buffer_t json;
+ bool changed = false;
+ tiny_metadata_mask_t metadata_mask = 0;
+ tiny_message_init(&parsed);
+ tiny_message_init(&updated);
+ patch.content = content;
+ patch.metadata = metadata_json ? &parsed.metadata : NULL;
+ patch.metadata_mask = 0;
+ patch.expected_revision = (uint64_t)expected;
+ patch.has_expected_revision = expected_status == MCPC_EC_0;
+ if (!context || !message_id || (!content && !metadata_json)
+ || (metadata_json && !tiny_mcp_parse_metadata(metadata_json, &parsed, &metadata_mask))
+ || (expected_status != MCPC_EC_0 && expected_status != MCPC_EC_ANYDATA_NOTFOUND)
+ || (patch.has_expected_revision && expected < 1))
+ {
+ tiny_mcp_tool_add_error(result, "VALIDATION_ERROR", "invalid update_message arguments");
+ }
+ else
+ {
+ patch.metadata_mask = metadata_mask;
+ status = tiny_store_update(context->store, message_id, &patch, &updated, &changed);
+ if (status != TINY_STORE_OK)
+ {
+ tiny_mcp_tool_add_error(
+ result, tiny_store_status_name(status), "message was not updated");
+ }
+ else
+ {
+ if (changed)
+ {
+ tiny_mcp_tools_invalidate_indexes(context);
+ }
+ tiny_json_init(&json);
+ tiny_json_raw(&json, "{\"status\":\"OK\",\"changed\":");
+ tiny_json_raw(&json, changed ? "true" : "false");
+ tiny_json_raw(&json, ",\"message\":");
+ tiny_mcp_tool_append_message(&json, &updated);
+ tiny_json_raw(&json, "}");
+ tiny_mcp_tool_add_json(result, &json);
+ tiny_json_free(&json);
+ }
+ }
+ free(message_id);
+ free(content);
+ free(metadata_json);
+ tiny_message_free(&parsed);
+ tiny_message_free(&updated);
+}
+
+bool
+tiny_mcp_register_update_message(mcpc_server_t *server)
+{
+ mcpc_tool_t *tool = tiny_mcp_tool_new("update_message",
+ "Update message content or metadata while preserving "
+ "identity, session, role, and creation time.",
+ call_update_message);
+ return tool
+ && tiny_mcp_tool_add_property(
+ tool, "message_id", "ULID of the live message to update.", MCPC_U8STR, true)
+ && tiny_mcp_tool_add_property(tool,
+ "content",
+ "Replacement UTF-8 content; omit to retain content.",
+ MCPC_U8STR,
+ false)
+ && tiny_mcp_tool_add_property(tool,
+ "metadata_json",
+ "Replacement metadata JSON; omit to retain metadata.",
+ MCPC_U8STR,
+ false)
+ && tiny_mcp_tool_add_property(tool,
+ "expected_revision",
+ "Optional positive revision for optimistic concurrency.",
+ MCPC_I32,
+ false)
+ && mcpc_server_add_tool(server, tool) == MCPC_EC_0;
+}