1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
#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;
const char *metadata_error = NULL;
tiny_metadata_parse_status_t metadata_status = TINY_METADATA_PARSE_OK;
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 (metadata_json)
{
metadata_status
= tiny_mcp_parse_metadata(metadata_json, &parsed, &metadata_mask, &metadata_error);
}
if (metadata_status == TINY_METADATA_PARSE_NO_MEMORY)
{
tiny_mcp_tool_add_error(result, "INTERNAL_ERROR", metadata_error);
}
else if (metadata_status == TINY_METADATA_PARSE_INVALID)
{
tiny_mcp_tool_add_error(result, "VALIDATION_ERROR", metadata_error);
}
else if (!context || !message_id || (!content && !metadata_json)
|| (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;
}
|