Searchable Discord index served over MCP: fetch -> SQLite FTS5 + embeddings -> MCP tools.
Four well-named, read-only tools with strong descriptions (avg 180 chars) and comprehensive parameter documentation. All tools have input schemas with types and descriptions. search_messages is particularly well-designed with context/mode enums and clear guidance on when to use each. Weaknesses: output schemas are not formally documented in the tool definitions (only visible in smoke test); no tool annotations (readOnlyHint); error handling guidance is minimal; parameter descriptions could be more prescriptive about format/constraints.
Fetch the messages immediately before and after a given message id, in chronological order. Use this after search_messages when a hit looks relevant but you need the surrounding conversation to interpret it.
List every indexed channel with its message count and last activity. Use to discover exact channel names for search_messages.
Search the indexed Discord server. Returns whole CONVERSATIONS, not isolated messages: each hit is assembled from reply chains, the surrounding thread, and neighbouring messages, with `matched: true` marking the messages that actually matched. Hits from the same discussion are merged into one result. Ranked by hybrid keyword + semantic relevance, with jump URLs. Use `context: "wide"` when asked for a whole discussion. Always check `freshness`: if `stale` is true, recent activity is missing.
Index totals, embedding coverage, freshness, and the last sync run (including its error, if it failed). Use when results look incomplete or out of date.
Output schemas not formally documented in tool definitions. Smoke test reveals JSON responses (search results with 'hits', 'freshness', 'mode_used'; context with 'messages', 'channel', 'is_anchor'; channels array; status object), but these are not declared in the tool registration. LLMs cannot plan downstream operations without knowing response structure.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). All four tools are read-only and idempotent, but this is not declared in the tool metadata. Agents cannot infer safety properties without explicit hints.
Error handling guidance is absent. No recovery hints in descriptions (e.g., 'If results are stale, call sync_status()' or 'If channel not found, call list_channels()'). Descriptions state WHAT the tool does but not what to do if it fails.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 62 | 2026-07-28+ | v2 |
Parameter descriptions lack format/constraint details. 'query' in search_messages says 'What to look for' but does not specify length limits, character restrictions, or whether special syntax (regex, operators) is supported. 'message_id' in get_context says 'Discord message id (the trailing number of a jump_url)' but does not specify format (numeric string, length).
list_channels and sync_status have empty input schemas ({}). While this is correct for discovery tools, the descriptions do not explain what structure they return or when to call them. 'List every indexed channel' is vague, does it return channel IDs, names, metadata, message counts? (Smoke test reveals it does, but this is not documented.)