42 static constexpr const char*
k_host =
"127.0.0.1";
56 auto
get_host() const -> const
char*;
72 ->
std::optional<
std::invoke_result_t<
std::decay_t<Fn>>>
74 using result_t = std::invoke_result_t<std::decay_t<Fn>>;
75 static_assert(!std::is_void_v<result_t>,
"invoke_on_main requires a non-void return type");
77 tpp::this_thread::register_this_thread();
78 auto future = tpp::async(tpp::main_thread::get_id(), std::forward<Fn>(fn));
79 if(future.wait_for(timeout) != std::future_status::ready)
81 error_count_.fetch_add(1);
82 log_activity(
"rpc",
"Timed out waiting for main thread",
true);
90 catch(
const std::exception&
ex)
92 error_count_.fetch_add(1);
93 log_activity(
"rpc", std::string(
"Exception on main thread: ") +
ex.what(),
true);
98 error_count_.fetch_add(1);
99 log_activity(
"rpc",
"Exception on main thread",
true);
105 using job_fn = std::function<std::string()>;
107 auto run_on_main_thread(job_fn job, std::chrono::milliseconds timeout = std::chrono::milliseconds(5000))
109 auto handle_http_request(
const std::string& body) -> std::string;
110 auto dispatch_json_rpc(
const std::string& body) -> std::string;
111 auto execute_tool_call(
const std::string& tool_name,
112 const std::string& args_json,
113 const std::optional<std::string>&
id) -> std::string;
114 void log_activity(std::string category, std::string message,
bool is_error =
false);
117 mcp::mcp_tool_registry registry_;
118 std::unique_ptr<httplib::Server> server_;
119 std::thread server_thread_;
120 std::atomic_bool running_{
false};
124 mutable std::mutex activity_mutex_;
125 std::deque<mcp_activity_entry> activity_;
126 std::atomic_uint64_t request_count_{0};
127 std::atomic_uint64_t tool_call_count_{0};
128 std::atomic_uint64_t error_count_{0};
std::chrono::system_clock::time_point timestamp