Model Context Protocol server for OTRS (Open Ticket Request System) integration
This server has significant definition quality issues. Both tools have descriptions, but the descriptions are very generic (10-25 characters, below the 50-200 char LLM-optimized range). Parameter schemas are present and typed, but descriptions for several parameters are either missing, trivial, or actively misleading (e.g., customer_user marked as 'IGNORED' in description while present in signature). The create_ticket tool has a hardcoded behavior that contradicts its parameter definition, which is a composition and clarity violation. Input validation is weak, the code shows fallback logic (trying multiple priority formats) that should be exposed as parameter constraints instead. Output schemas are not documented anywhere. Error handling is absent, no guidance on what to do if the API fails. The server exposes hardcoded credentials in the source code, a critical security violation.
Create a new ticket in OTRS
Get ticket details from OTRS
Hardcoded credentials exposed in source code (OTRS_USERNAME, OTRS_PASSWORD in server.py). Credentials must never be embedded or logged.
Tool descriptions far below LLM-optimized range. 'Create a new ticket in OTRS' (27 chars) and 'Get ticket details from OTRS' (29 chars) lack context on WHEN to use, WHAT gets returned, and prerequisites. LLM-optimized descriptions are 50-200 chars with explicit outcome/state-change messaging.
Parameter description contradicts behavior: create_ticket has 'customer_user' parameter documented as 'IGNORED - always uses Internal', but the parameter is still exposed in the signature. This violates the single-responsibility principle, either remove the parameter or implement it properly. The code shows hardcoded behavior that overrides user input without clear validation or messaging.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | F | 44 | 2026-07-28+ | v2 |
No output schemas documented for either tool. Callers cannot know what fields create_ticket returns (ticket_id? ticket_number? url?) or what structure get_ticket returns. This forces LLMs to guess and makes tool composition impossible.
No error handling or recovery guidance. If the API fails, returns a 401, or the queue doesn't exist, the tool will crash. Error responses should indicate: is this retryable? What should the agent try next? Instead, there are only unhandled exceptions.
Priority parameter marked optional but includes fallback logic trying 'multiple formats' (3 normal, 1 Low, 2 normal, 4 high). This validation logic should be exposed as an enum constraint, not hidden in implementation. Parameters accepting one of a known set of values MUST declare enums.
Queue parameter has optional valid values (Raw, Junk, Misc noted in code comment) but no enum in schema. Code silently falls back to default if an invalid queue is provided, this hides errors from the LLM. If 'queue' is optional with known values, declare them as an enum.
get_ticket parameters 'include_dynamic_fields' and 'include_extended_data' lack descriptions. These booleans are cryptic, what does 'extended data' mean? When should an LLM set them to true? Parameter names are not self-documenting.
Tool composition is blocked. Code shows helper functions get_ticket_web_url(), get_ticket_history_web_url(), get_ticket_search_web_url() exist but are never returned in tool output. If these URLs are useful for agents, they should be part of the response schema.