summaryrefslogtreecommitdiff
path: root/src/mcp/tools/update_message.c
blob: aca1bed3705abace3ad35b20fbf91636322a404e (plain)
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
#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;
}