This Rust-based MCP server for Miniflux RSS reader has clear, action-verb naming and present but inconsistent descriptions. All 13 tools are explicitly defined with parameter schemas. However, there are significant gaps: most parameter descriptions are sparse (often just 'Feed ID' or 'Entry ID' with no context about valid ranges, formats, or error cases); output schemas are not documented (tools return debug-formatted structs via Content::text() rather than structured JSON objects); complex tools like miniflux_get_entries have 10 parameters but lack documentation on parameter relationships (e.g., which filters are mutually exclusive); and error handling is minimal (most errors just wrap the API error in rmcp::Error::internal_error() with no guidance on recovery). The server demonstrates solid engineering discipline, validation helpers (parse_status, parse_order, parse_direction) are present, but falls short of LLM-optimized design. Parameter descriptions average ~20 - 30 chars, well below the 72-char baseline. The read-only mode enforcement (check_write_allowed) is good security practice, but no rate limiting, audit logging, or permission scoping is visible.
Output schemas not documented. All tools return unstructured debug-formatted text (Content::text(format!("{:#?}", result))) instead of structured JSON objects. LLMs cannot reliably parse or chain results.
Convert all text output to structured JSON. Replace Content::text(format!("{:#?}", result)) with a proper JSON response that includes only the fields an LLM needs (e.g., for get_categories: [{id, title, unread_count}] instead of the full debug representation). Document the output schema in each tool's description.
Expand parameter descriptions to 50 - 100 characters. For status parameter: 'Filter entries by status. Valid values: read (already viewed), unread (new), removed (deleted). If omitted, returns all statuses.' For limit: 'Number of entries to return (default: 20, max: 100). Larger limits may increase response time.'
Add enum constraints in the schema for status, order, and direction parameters instead of relying only on parse functions. Define them as JSON Schema enums: {"enum": ["read", "unread", "removed"]}. This makes valid values machine-discoverable.
Document pagination behavior. For get_entries and get_feed_entries: 'Pagination: offset (default 0, max 10000) + limit (default 20, max 100). Returns total_count in response for calculating next page. No cursor; use offset + limit for sequential access.'
Improve error messages. Instead of wrapping raw API errors, categorize them: 'Feed not found (404)' → 'Feed ID 9999 not found. Retrieve valid feed IDs with miniflux_get_feeds.'; 'Permission denied (403)' → 'User is read-only. Contact admin to enable write access.'; 'Connection timeout' → 'Miniflux instance unreachable. Check health with miniflux_healthcheck, then retry.'
Add tool annotations to the MCP tool definition. Mark miniflux_import_opml with destructiveHint=true (modifies feed subscriptions); mark all read-only tools with readOnlyHint=true; mark idempotent tools (healthcheck, get_*) with idempotentHint=true.
Complex tools (miniflux_get_entries, miniflux_get_feed_entries) have 10 parameters with undocumented relationships. No guidance on mutually exclusive filters, default pagination limits, or how to chain multiple filter conditions. The description mentions valid values but only as inline text, not enums.
Pagination not explicit. Tools accept 'offset' and 'limit' but no documentation on page size limits, default values, or total count/next_cursor in response. Large result sets could exhaust context window.
Error handling is generic. All API errors wrapped in rmcp::Error::internal_error(format!("{e}")) with no recovery guidance. LLMs receive 'ApiError: Connection timeout' but no suggestion to retry or contact admin.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). Risk levels are documented in the assessment but not in the tool definitions where the MCP spec expects them.
Validation errors have some structure (parse_status, parse_order, parse_direction) but others are missing. URL validation is present in discover_subscription, but feed_id and entry_id accept any i64 with no range checks. Miniflux likely has constraints (e.g., max 10000 for page size) that are not enforced.
miniflux_get_entriesminiflux_get_feed_entries
Add numeric range validation. Enforce offset >= 0, limit >= 1 and <= 100, feed_id > 0, entry_id > 0 with explicit error messages: 'Invalid limit: 500 exceeds maximum of 100.'
Document tool chaining. For example: 'Call miniflux_get_feeds first to retrieve valid feed_id values, then pass a feed_id to miniflux_get_feed_entries.' Include downstream parameter names in responses (e.g., get_feeds returns feed_id not just id).
Add result limiting. Cap returned entries at 50 per call by default; document in the description: 'For large result sets, use pagination (offset + limit) rather than requesting all entries in a single call.'
Implement audit logging. Log which user/agent called which tool, with which parameters, at what time, and what the result was. Required for compliance if this server manages user authentication.
Add rate limiting to prevent runaway agents. Limit concurrent calls and implement backoff strategies for tools like miniflux_get_entries that could be called in tight loops.