The server defines a single tool 'discord_api' with a schema, but has critical definition gaps that prevent production use. The tool name lacks an action verb and is overly generic ('discord_api' instead of 'execute_discord_api' or 'send_discord_api_request'). The description is only 106 characters and lacks crucial context about when/why to use this tool, what it actually returns, and what side effects occur. The schema provides basic types (method enum, endpoint/payload strings) but critically omits descriptions for the 'endpoint' and 'payload' parameters, LLMs cannot determine valid endpoint formats or payload structures without descriptions. The tool implements a dangerous pattern: it accepts arbitrary HTTP methods and endpoints, acting as an unfiltered gateway to Discord's entire API surface without guardrails, validation, or error guidance. Error handling returns raw Discord API responses (e.g., 'Discord API error: 400 - Unknown Guild') without telling the LLM what corrective action to take. The implementation conflates two concerns (REST API calls + slash command parsing) in a single tool, violating single-responsibility design. No output schema is documented, the LLM cannot predict the response structure.
Execute raw Discord API commands. Supports both REST API calls and application commands.
Tool name 'discord_api' is not action-verb-based and is ambiguous. Does it send, get, execute, or list? LLMs will struggle to determine when to call this vs. other potential Discord tools.
Parameter 'endpoint' lacks a description. LLMs cannot infer valid Discord API endpoint formats (e.g., 'users/@me', 'guilds/{guild_id}/roles', 'channels/{channel_id}/messages') without explicit guidance. This violates the critical requirement that every parameter must have a description.
Parameter 'payload' lacks a description and type details. LLMs will not know what structure to pass, what fields are required, or how to construct Discord API request bodies. This forces guessing and causes API errors.
No output schema is documented. The tool returns JSON responses, but the LLM cannot predict the structure (fields, types, required vs. optional). This prevents downstream tool chaining and forces LLMs to parse unstructured output, which wastes tokens and increases errors.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 28 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 34 | - | v1 |
Tool description (106 chars) is too short and lacks critical context. It states WHAT (execute raw Discord API commands) but does NOT explain WHEN to use it, what side effects occur (create, delete, modify server state), what errors mean, or how to recover from them. A production tool description should be 150-300 chars with clear guidance on intent and error recovery.
Error responses provide no recovery guidance. Example: 'Discord API error: 400 - Invalid Guild'. The LLM does not learn what to do next, retry? Ask user for correct guild_id? Call a discovery tool? Raw error messages without actionable guidance violate the recovery-guide pattern.
Tool lacks idempotency guarantees. The description makes no statement about whether repeated calls with the same parameters are safe (idempotent) or will cause duplicate side effects. For destructive operations (DELETE, channel creation), this is a safety issue.
Tool mixes two concerns: REST API pass-through + slash command interpretation. The code attempts to parse /role create syntax and convert it to POST /guilds/{guild_id}/roles, but this logic is brittle, incomplete, and couples two distinct tool responsibilities. This violates the single-responsibility pattern and makes the tool unpredictable.
No permission or scope declaration. The tool accepts any Discord API endpoint and method, acting as an unfiltered gateway. There is no indication of what permissions the calling agent needs (e.g., 'requires: admin on target guild'). This violates scope-declaration and permission-gate patterns.
No rate limiting or timeout protection. An agent could invoke this tool in a loop, generating thousands of Discord API calls per minute. Without rate guards or timeouts, the tool can exhaust the bot token's rate limits and block legitimate Discord traffic.
DISCORD_TOKEN is exposed in the Dockerfile as a plaintext environment variable (ENV DISCORD_TOKEN=YOUR-BOT-TOKEN) and loaded via os.getenv(). While the placeholder suggests configuration, the pattern is vulnerable to token leakage in logs and container images. Use a vault/secret manager.