summaryrefslogtreecommitdiff
path: root/src/mcp/tools/get_system_health.c
blob: 4189db3c19890ac707f319ed195ca1a161cc4e0a (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
#include "mcp/tools/common/registry.h"

#include "mcp/tools/common/common.h"
#include "mcp/tools/common/context.h"

static void
call_get_system_health(const mcpc_tool_t *tool, mcpc_ucbr_t *result)
{
  tiny_mcp_tools_context_t *context = tiny_mcp_tools_context_current();
  tiny_store_health_t health;
  tiny_json_buffer_t json;
  (void)tool;
  if (!context)
    {
      tiny_mcp_tool_add_error(result, "INTERNAL_ERROR", "tool context is unavailable");
      return;
    }
  if (!tiny_mcp_tools_ensure_history_index(context) || !context->history_index)
    {
      tiny_mcp_tool_add_error(result, "INTERNAL_ERROR", "history index allocation failed");
      return;
    }
  tiny_store_health(context->store, &health);
  tiny_json_init(&json);
  tiny_json_raw(&json, "{\"status\":");
  tiny_json_string(&json, health.last_error[0] ? "DEGRADED" : "OK");
  tiny_json_raw(&json, ",\"format_version\":");
  tiny_json_u64(&json, health.format_version);
  tiny_json_raw(&json, ",\"log_size\":");
  tiny_json_u64(&json, health.log_size);
  tiny_json_raw(&json, ",\"snapshot_size\":");
  tiny_json_u64(&json, health.snapshot_size);
  tiny_json_raw(&json, ",\"active_messages\":");
  tiny_json_u64(&json, health.active_messages);
  tiny_json_raw(&json, ",\"session_count\":");
  tiny_json_u64(&json, tiny_history_index_session_count(context->history_index));
  tiny_json_raw(&json, ",\"deleted_messages\":");
  tiny_json_u64(&json, health.deleted_messages);
  tiny_json_raw(&json, ",\"last_sequence\":");
  tiny_json_u64(&json, health.last_sequence);
  tiny_json_raw(&json, ",\"update_records\":");
  tiny_json_u64(&json, health.update_records);
  tiny_json_raw(&json, ",\"dead_bytes\":");
  tiny_json_u64(&json, health.dead_bytes);
  tiny_json_raw(&json, ",\"memory_estimate\":{\"total_bytes\":");
  tiny_json_u64(&json,
                health.memory_entry_bytes + health.memory_body_bytes + health.memory_metadata_bytes
                    + tiny_search_index_memory_estimate(context->search_index)
                    + tiny_history_index_memory_estimate(context->history_index)
                    + tiny_memory_index_memory_estimate(context->memory_index));
  tiny_json_raw(&json, ",\"store_entries_bytes\":");
  tiny_json_u64(&json, health.memory_entry_bytes);
  tiny_json_raw(&json, ",\"body_bytes\":");
  tiny_json_u64(&json, health.memory_body_bytes);
  tiny_json_raw(&json, ",\"metadata_bytes\":");
  tiny_json_u64(&json, health.memory_metadata_bytes);
  tiny_json_raw(&json, ",\"search_index_bytes\":");
  tiny_json_u64(&json, tiny_search_index_memory_estimate(context->search_index));
  tiny_json_raw(&json, ",\"history_index_bytes\":");
  tiny_json_u64(&json, tiny_history_index_memory_estimate(context->history_index));
  tiny_json_raw(&json, ",\"relation_index_bytes\":");
  tiny_json_u64(&json, tiny_memory_index_memory_estimate(context->memory_index));
  tiny_json_raw(&json, "}");
  tiny_json_raw(&json, ",\"io\":{\"write_bytes\":");
  tiny_json_u64(&json, health.write_bytes);
  tiny_json_raw(&json, ",\"write_calls\":");
  tiny_json_u64(&json, health.write_calls);
  tiny_json_raw(&json, ",\"flush_calls\":");
  tiny_json_u64(&json, health.flush_calls);
  tiny_json_raw(&json, ",\"truncate_calls\":");
  tiny_json_u64(&json, health.truncate_calls);
  tiny_json_raw(&json, ",\"replace_calls\":");
  tiny_json_u64(&json, health.replace_calls);
  tiny_json_raw(&json, "}");
  tiny_json_raw(&json, ",\"recovered_tail\":");
  tiny_json_raw(&json, health.recovered_tail ? "true" : "false");
  tiny_json_raw(&json, ",\"snapshot_valid\":");
  tiny_json_raw(&json, health.snapshot_valid ? "true" : "false");
  tiny_json_raw(&json, ",\"last_error\":");
  tiny_json_string(&json, health.last_error);
  tiny_json_raw(&json, "}");
  tiny_mcp_tool_add_json(result, &json);
  tiny_json_free(&json);
}

bool
tiny_mcp_register_get_system_health(mcpc_server_t *server)
{
  mcpc_tool_t *tool = tiny_mcp_tool_new(
      "get_system_health",
      "Inspect storage health, recovery state, message counts, and file sizes. Use "
      "it to diagnose persistence or recovery problems.",
      call_get_system_health);
  return tool && mcpc_server_add_tool(server, tool) == MCPC_EC_0;
}