feat: integrate MCP server and screen override into system firmware
- Add McpSettings (load/save mcpEnabled, mcpOverrideEnabled to /data/service/mcp/settings.properties) - Add McpSystem: global state, canvas drawing (RGB565, BMP, PBM, text), I2S audio (WAV, MP3 via minimp3, tone, record) - Add McpHandler: unauthenticated POST /api/mcp (JSON-RPC 2.0, 13 tools) and POST /api/screen/raw endpoints - Route MCP endpoints before Basic Auth check in WebServerService::handleApiPost - Start HTTP server at boot if either webServerEnabled OR mcpEnabled is set - Fix setEnabled: start unconditionally when called with true; only stop if both WS and MCP are disabled - Add McpSettingsApp (Settings category): toggle MCP service + screen override, show live endpoint URL - Add McpOverrideApp (appId one.tactility.mcpscreen): full-screen LVGL canvas for LLM-driven display override - Register both new apps in Tactility.cpp
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
#include <Tactility/settings/McpSettings.h>
|
||||
#include <Tactility/file/PropertiesFile.h>
|
||||
#include <Tactility/file/File.h>
|
||||
#include <Tactility/Logger.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
namespace tt::settings::mcp {
|
||||
|
||||
static const auto LOGGER = Logger("McpSettings");
|
||||
constexpr auto* SETTINGS_FILE = "/data/service/mcp/settings.properties";
|
||||
|
||||
constexpr auto* KEY_MCP_ENABLED = "mcpEnabled";
|
||||
constexpr auto* KEY_MCP_OVERRIDE_ENABLED = "mcpOverrideEnabled";
|
||||
|
||||
bool load(McpSettings& settings) {
|
||||
std::map<std::string, std::string> map;
|
||||
if (!file::loadPropertiesFile(SETTINGS_FILE, map)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto mcp_enabled = map.find(KEY_MCP_ENABLED);
|
||||
auto mcp_override = map.find(KEY_MCP_OVERRIDE_ENABLED);
|
||||
|
||||
settings.mcpEnabled = (mcp_enabled != map.end())
|
||||
? (mcp_enabled->second == "1" || mcp_enabled->second == "true")
|
||||
: false;
|
||||
|
||||
settings.mcpOverrideEnabled = (mcp_override != map.end())
|
||||
? (mcp_override->second == "1" || mcp_override->second == "true")
|
||||
: true; // Default true
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
McpSettings getDefault() {
|
||||
return McpSettings{
|
||||
.mcpEnabled = false,
|
||||
.mcpOverrideEnabled = true
|
||||
};
|
||||
}
|
||||
|
||||
McpSettings loadOrGetDefault() {
|
||||
McpSettings settings;
|
||||
if (!load(settings)) {
|
||||
settings = getDefault();
|
||||
file::findOrCreateDirectory("/data/service/mcp", 0755);
|
||||
save(settings);
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
|
||||
bool save(const McpSettings& settings) {
|
||||
file::findOrCreateDirectory("/data/service/mcp", 0755);
|
||||
|
||||
std::map<std::string, std::string> map;
|
||||
map[KEY_MCP_ENABLED] = settings.mcpEnabled ? "true" : "false";
|
||||
map[KEY_MCP_OVERRIDE_ENABLED] = settings.mcpOverrideEnabled ? "true" : "false";
|
||||
|
||||
if (!file::savePropertiesFile(SETTINGS_FILE, map)) {
|
||||
LOGGER.error("Failed to save MCP settings to {}", SETTINGS_FILE);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
Reference in New Issue
Block a user