Model Context Protocol server for Redmine integration - project management, issue tracking, and time tracking
The Redmine MCP server has solid structural foundations with 10 well-named tools covering core Redmine workflows (issues, projects, time tracking). Tool names consistently follow verb_noun convention (get_issues, create_issue, update_issue, log_time). Input schemas are fully visible with proper JSON Schema typing across all parameters. However, there are significant gaps in parameter descriptions, many parameters lack descriptions or have minimal ones (e.g., 'Activity ID to get activities for' vs. contextual guidance on when to use), and output schemas are undocumented, making it difficult for LLMs to plan downstream calls. Error handling is not evident in the source code provided. Descriptions are present but many are generic and lack the specificity recommended for LLM-optimal guidance (e.g., 'Get issues from Redmine with optional filtering' could specify what filtering options are most common or when to use each). The server correctly avoids exposing secrets as parameters (apiKey is environment-injected). Overall, this is a competent implementation that covers the core domain but lacks the refinement in descriptions and error handling expected of production-grade agent tooling.
Create a new issue in Redmine
Get information about the current user (based on API token)
Get a specific issue by its ID from Redmine
Get issues from Redmine with optional filtering
Get users and groups assigned to a specific project with their roles. Supports pagination for projects with many members.
Get mapping of project names to their IDs from Redmine. Automatically fetches all projects using internal pagination. Supports optional case-insensitive name filtering.
Output schemas are undocumented across all 10 tools. LLMs cannot plan downstream calls or extract the right fields without knowing what the response contains. This violates the critical pattern: 'Document the output schema.'
Parameter descriptions are often terse and lack context for LLM selection. Examples: 'Status ID to filter by' doesn't explain what 'open' vs 'closed' mean; 'Priority ID' doesn't explain valid range; 'Textile markup' assumes LLM knowledge of markup formats. Descriptions should include format constraints and use cases.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 57 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 0 | - | v1 |
Get available time tracking activities for a project or globally.
Get time entries from Redmine
Log time spent on an issue or project.
Update an existing issue in Redmine. Description should be provided in Textile markup.
Pagination is inconsistently implemented. get_issues and get_time_entries support limit but no offset/cursor. get_project_memberships has both limit and offset. This inconsistency complicates agent reasoning. Either: (1) add offset to all paginated tools, or (2) document why some omit it.
Error handling and recovery guidance are absent from the source code. Tools do not appear to return actionable error messages (e.g., 'Invalid priority: must be 1-5' vs bare 404). No dry-run or confirmation step for destructive operations (create_issue, update_issue, log_time). This blocks agent self-correction and confidence in state changes.
Tool descriptions lack dependency hints and precedence guidance. For example, log_time requires activity_id, but the description doesn't say 'Call get_time_activities first.' create_issue needs project_id, but description doesn't suggest get_projects as a discovery step. This forces unnecessary lookup calls.
Some parameters accept both IDs and names (project_id in get_project_memberships is string|number), but others are ID-only (priority_id, tracker_id, etc.). This inconsistency forces agents to discover IDs via lookup tools. Best practice: accept human-readable identifiers (project names, priority names) directly, or provide dual parameters (project_id, project_name) with clear documentation of precedence.
Mutually exclusive parameters are not consistently documented. log_time says issue_id and project_id are partially mutually exclusive ('required if issue_id not provided') but the phrasing is unclear. Best practice: 'Either issue_id or project_id is required; both cannot be omitted.' Similar issue in get_issues with multiple optional filters.