Multi-tenant Discord MCP bot — one bot, unlimited AI identities via webhooks
This server presents 7 tools with mixed quality. Tool definitions are present in dashboard files (ToolPicker.tsx, Tools.tsx), but CRITICAL ISSUE: the actual MCP server implementation source code is NOT provided, only Dockerfile, package.json files, and React dashboard components are visible. The server appears to be HTTP-based (Express), but the core MCP tool registration, schema definitions, and error handling logic cannot be verified from the provided code. For the 7 tools documented in the dashboard: 1. NAMING (average 75): All tools use clear verb_noun format (read_messages, send_message, add_reaction, etc.), which is excellent. Names are self-documenting and follow arcade.dev patterns. No compound 'and' names. ✓ 2. DESCRIPTIONS (average 55): Descriptions exist for all 7 tools and range from 50-170 characters. However, most lack depth. For example, 'read_messages' has a solid description explaining the 15-minute queue and filtering behavior. But 'list_channels' is bare ('List Discord channels this entity can access'), 42 chars, minimal guidance on when to call vs get_channel_history. 'introduce' description (58 chars) omits whether it requires special permissions or how formatting works. Most descriptions are under 100 chars and lack WHEN/WHY/HOW context that LLMs need for robust selection. Baseline is 194 chars for A+ tools. 3. PARAMETERS (average 45): Critical gap. Tool definitions list parameter names, types, and brief descriptions, BUT: - Parameters are documented in the React components (ToolPicker.tsx, Tools.tsx), NOT in the actual MCP server code visible here. - No input schemas are visible in the provided source code. - Parameter validation rules are not documented (e.g., channel_id format, message_id constraints, emoji format beyond '👍'). - Many parameters lack format guidance: 'channel_id' is a string, but is it a numeric Discord ID or a slug? The description just says 'Channel ID'. - 'read_messages' has good param descriptions for limit (default 50) and boolean flags, but 'get_entity_info' has ZERO parameters, no schema shown. - No documented dependencies between parameters (e.g., 'emoji' param says 'custom emoji name', what format? How does the bot resolve custom emoji?). 4. OUTPUT SCHEMAS (average 35): MAJOR GAP. No output schemas are documented in the provided code. For example: - What does 'read_messages' return? Assume a list of message objects, but what fields? {id, content, author, timestamp}? Are timestamps ISO 8601 or Unix? Are attachments included? - 'send_message', does it return the sent message? Just a success bool? Missing message_id needed for reactions/edits? - 'list_channels', what fields? channel_id, name, topic, type? Pagination? - 'get_entity_info', what identity fields? Missing: would force LLM to guess structure. - This violates the output schema requirement (100% of A+ tools have documented return types). All 7 tools score ~0 on output documentation. 5. ERROR HANDLING (average 20): No error guidance visible. No recovery hints, no retryable/fatal classification. The MCP server source code (where error handling would be) is not provided. 6. SECURITY (average 30): - No visible mention of permission gates or scope declarations. - Tool descriptions mention 'this entity' (Discord bot identity) but no indication of RBAC or per-tool permission checks. - No audit trail guidance. - 'send_message' and 'send_dm' (in ToolPicker hint) could be high-risk, no dry-run or confirmation pattern mentioned. 7. COMPOSITION (average 35): - read_messages → send_message chain seems sound (get channel context, then reply). - 'introduce' reads 'get_entity_info', so multi-step is possible. - However, many tools overlap or have unclear sequencing (list_channels vs get_channel_history vs search_messages, when use each?). - No documented tool chains or prerequisites. PER-TOOL BREAKDOWN (7 tools evaluated from React dashboard; actual MCP registration NOT visible):
Add a reaction emoji to a message.
Get information about this entity — identity, description, platform, partner, servers, and channels. Call this at the start of a session to understand who you are.
Post a rich namecard embed in a channel introducing this entity. Shows name, description, platform, and partner. Use this when joining a new channel or when someone asks who you are.
List Discord channels this entity can access.
Read recent messages from the queue for subscribed channels. Messages are held for 15 minutes after they arrive. Use addressed_only to filter for messages directed at you (trigger words or @mentions). Use unread_only to get only messages you haven't seen yet.
Remove the bot's reaction from a message.
NO OUTPUT SCHEMAS DOCUMENTED. All 7 tools lack return type documentation. LLMs cannot plan downstream calls, extract fields, or handle responses. This is a HARD REQUIREMENT for any production tool.
ACTUAL MCP SERVER CODE NOT PROVIDED. Dockerfile, package.json, and React dashboard components are shown, but the core src/index.ts (MCP tool registration, schema definition, error handling) is absent. Cannot verify actual tool schemas, error handling, or protocol compliance. Evaluation is limited to inferred intent from dashboard UI.
PARAMETER CONSTRAINTS UNDERDOCUMENTED. 'channel_id' appears in 4 tools but no format guidance (numeric Discord ID? slug?). 'emoji' param in add_reaction/remove_reaction lacks format spec (custom emoji resolution?). 'limit' in read_messages has default (50) but no stated range or max. LLMs will hallucinate invalid values.
Inferred effective spec: 2026-07-28+.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 40 | 2026-07-28+ | v2 |
| 2026-03-09 | D | 52 | - | v1 |
Send a message to a Discord channel as this entity (with your name and avatar). To mention users use <@USER_ID>, roles use <@&ROLE_ID>, channels use <#CHANNEL_ID>.
DESCRIPTIONS LACK CONTEXT. Most descriptions are 35 - 75 characters and omit WHEN/WHY/HOW guidance. E.g., 'list_channels' is 43 chars with no hint to distinguish it from get_channel_history or search_messages. Baseline A+ is 194 chars. LLMs struggle to select tools when descriptions are thin.
NO ERROR RECOVERY GUIDANCE. No visible error handling in code, no retryable/fatal classification, no recovery hints like 'Channel not found, try list_channels()'. Agents cannot self-correct on failure.
NO PERMISSION GATES OR SCOPE DECLARATIONS. Tools like send_message and introduce perform writes but no visible permission checks, scope hints, or audit trail. LLMs cannot reason about which tools are safe.
PARAMETER DEPENDENCIES UNDOCUMENTED. 'read_messages' has 'addressed_only' and 'unread_only' flags but no guidance on combining them. 'emoji' format varies by context (native emoji vs custom name) but not documented. Agents will misuse.
NO PAGINATION OR RESULT LIMITS. 'read_messages' defaults to 50 but no explicit max. 'list_channels' has no limit/offset or pagination hint. Large result sets will exhaust LLM context.
IDEMPOTENCY NOT ADDRESSED. send_message, add_reaction are writes, no indication of idempotency or deduplication. Agents retrying on timeout could send duplicate messages.