From 171c8a04909c8b0b0c79692196a40351bdddad27 Mon Sep 17 00:00:00 2001 From: Anthony Merlo Date: Thu, 20 Aug 2026 17:37:10 +0100 Subject: [PATCH] fix: get_goals inputSchema now {type: object} not {} MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Parameter-less tools in rmcp generated inputSchema: {} (empty dict with no type field), which the Hermes MCP client rejects — one bad tool fails the entire tools/list response. Fix: added NoParams struct (empty, derives JsonSchema) and changed get_goals to accept Parameters. schemars generates {"type": "object", ...} for empty structs, which is valid. --- .beads/interactions.jsonl | 1 + src/tools.rs | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.beads/interactions.jsonl b/.beads/interactions.jsonl index 4862436..a043909 100644 --- a/.beads/interactions.jsonl +++ b/.beads/interactions.jsonl @@ -11,3 +11,4 @@ {"id":"int-15bbd2d9f2c21ef8d1e7fe43d7790dd6","kind":"field_change","created_at":"2026-08-20T15:53:22.91492504Z","actor":"Anthony Merlo","issue_id":"nutrition-mcp-yd5","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"README.md written with full project overview, tech stack, 14 nutrients table, 13 tools reference, env vars, build/run/deploy instructions, Hermes + laptop connection guide."}} {"id":"int-3c1839f2748ae8a9fb303881ba9c3dda","kind":"field_change","created_at":"2026-08-20T15:56:03.881585777Z","actor":"Anthony Merlo","issue_id":"nutrition-mcp-foe","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"Deployed: systemd user service created at ~/.config/systemd/user/nutrition-mcp.service, enabled with linger. Server running on 0.0.0.0:9432. Health check passes. Registered with Hermes via mcp_servers config. API key: 333f09ce904e9cbbe3b578fda393be92869122c7222dbccd"}} {"id":"int-b0e97dffd303b9e4f164830ebcbe2085","kind":"field_change","created_at":"2026-08-20T15:56:04.581867751Z","actor":"Anthony Merlo","issue_id":"nutrition-mcp-aea","extra":{"field":"status","new_value":"closed","old_value":"open","reason":"Hermes skill created at ~/.hermes/skills/productivity/nutrition-tracker/SKILL.md with workflow guidance, meal auto-detection, portion handling, protein estimation guide, and gout/hypertension health context."}} +{"id":"int-c69e98d9ab404dbe46f1b088e3453677","kind":"field_change","created_at":"2026-08-20T16:25:47.847889101Z","actor":"Anthony Merlo","issue_id":"nutrition-mcp-45t","extra":{"field":"status","new_value":"closed","old_value":"in_progress","reason":"25 integration tests added, all passing. Covers: DB init, goals seeding, FTS5 cache search, upsert, portion scaling, sum_nutriments (with no-data handling), meal detection, date format, log entry round trips, goals update, weight log + upsert. Also fixed sum_nutriments display key bug (was using OFF field names instead of display names) and weight_log UNIQUE constraint."}} diff --git a/src/tools.rs b/src/tools.rs index c1733f2..b340c13 100644 --- a/src/tools.rs +++ b/src/tools.rs @@ -57,6 +57,12 @@ impl NutritionServer { // ── Tool parameter structs ────────────────────────────────────────── +/// Empty parameter struct for tools that take no arguments. +/// Ensures the inputSchema is {"type": "object", "properties": {}} +/// instead of {} (which some MCP clients reject). +#[derive(Debug, Deserialize, schemars::JsonSchema)] +pub struct NoParams {} + #[derive(Debug, Deserialize, schemars::JsonSchema)] pub struct SearchFoodParams { /// Food name to search for (e.g. "chicken breast", "coca cola") @@ -588,7 +594,10 @@ impl NutritionServer { #[tool( description = "Get current daily nutrition goals. Returns all 14 tracked nutrient targets." )] - async fn get_goals(&self) -> Result { + async fn get_goals( + &self, + Parameters(_params): Parameters, + ) -> Result { let pool = self.pool().await?; let row = sqlx::query("SELECT goals FROM daily_goal WHERE id = 1")