Local stdio MCP server for the Simple Support System REST API of Concrete CMS: read tickets, reply to them, change their state, and manage projects, comments and attachments.
Strong foundation with 20 well-named tools, comprehensive schemas, and clear descriptions. All tools have verb-noun naming (list_, get_, create_, update_, delete_, reply_, set_, approve_). Input schemas are complete with Zod types and descriptions for all parameters. Tool annotations (readOnlyHint, destructiveHint) are present. However, output schemas are not formally documented, responses are JSON-stringified but the structure is not declared in tool definitions. Error handling returns raw exception messages rather than actionable recovery guidance. Some descriptions could be more concise (list_tickets is 280+ chars, exceeds optimal 200-char range). Parameter descriptions are generally good but lack explicit format/constraint details in some cases (e.g., ticketState accepts any string, not an enum of valid workflow states).
Approve a comment that is pending moderation. Requires an API key.
Approve a ticket that is pending moderation. Requires an API key.
Create a new project. Requires an API key.
Create a new ticket in a project. Requires a project id or handle. Without an API key the email field is required, and the ticket may be held back for moderation.
Delete an attachment from a ticket. Requires an API key and confirm: true. Tickets in the states closed or invalid are locked by the API and reject edits.
Delete a comment. Requires an API key and confirm: true. Tickets in the states closed or invalid are locked by the API and reject edits.
Output schemas not formally documented. Tools return JSON-stringified responses but the structure (fields, types, required properties) is not declared in tool definitions. LLMs cannot reliably extract data for downstream tool calls.
set_ticket_state accepts ticketState as free-form string, not enum. Should constrain to valid workflow states (TICKET_WORKFLOW_STATES constant exists but not used in schema). Allows LLM to pass invalid states.
Error handling returns raw exception messages (failure() function). Does not categorize errors as retryable/user-fixable/fatal or provide recovery guidance. LLM receives 'Error: 404' with no actionable next step.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 63 | 2026-07-28+ | v2 |
Delete a project and all its tickets. Requires an API key and confirm: true.
Download an attachment by its file id. Returns the binary content.
Read a single comment.
Read a single project.
Read a single ticket with its attachments and, unless switched off, all comments in one call. Use this before replying or changing a state so the current content and state are known.
List all attachments of a ticket.
List all comments of a ticket.
List all projects the API key has access to, or all public projects without an API key.
List tickets, optionally filtered by project, state, type, priority, assignee or a text search. The API itself only filters by project, every other filter is applied by this server on the returned list. Returns a compact summary per ticket by default, set format to "full" for the complete records including attachments. This is the default way to find a ticket id.
Post a reply as a comment on a ticket. This is the normal way to answer a ticket. The reply triggers the notification mails of the package. Without an API key and without a logged in session the email field is required, and moderation may hold the comment back until it is approved.
Move a ticket to another workflow state and notify the people involved. Requires an API key. The state "new" is only set when a ticket is created and is rejected here. Tickets in the states closed or invalid are locked by the API and reject edits.
Update a project. Requires an API key.
Update the title, content, type or priority of a ticket. Requires an API key. Tickets in the states closed or invalid are locked by the API and reject edits.
Upload a file to use as an attachment. Returns a file id that can be used when creating or updating a ticket. The file is stored temporarily until it is attached to a ticket.
Destructive operations (delete_project, delete_comment, delete_attachment) require confirm: true but lack dry-run or preview capability. No way for agent to preview what will be deleted before confirming.
list_tickets description is 280+ characters, exceeds optimal 200-char range. Verbose explanation of filtering behavior dilutes key intent. Should be concise: 'List tickets with optional filters by project, state, type, priority, assignee, or search term.'