mcp-redmine
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| REDMINE_URL | Yes | Base URL of your Redmine instance (no trailing slash). | |
| REDMINE_API_KEY | Yes | Your API access key, from My account → API access key. | |
| REDMINE_TIMEOUT | No | Per-request timeout in seconds. Defaults to 15. | 15 |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| attach_file_to_issueA | Attach a local file to an issue. Uploads the file and links it to the issue right after — the two steps Redmine's API requires, in a single call. The path is resolved on the machine running this MCP server. Args: issue_id: issue ID. file_path: full path of the file on the server's machine. description: attachment description, shown next to its name. comment: note to add to the history along with the attachment. file_name: display name in Redmine (empty = use the file's own name). |
| get_attachmentA | Show an attachment's details: name, size, type, author, and download URL. Args: attachment_id: attachment ID (shown in get_issue, in the 'attachments' list). |
| update_attachmentA | Rename an attachment or change its description, without re-uploading it. Available since Redmine 5.0; older versions respond with 404. Args: attachment_id: attachment ID. file_name: new display name (empty = leave alone). description: new description (empty = leave alone). |
| delete_attachmentA | Permanently delete an attachment. The file is removed from the server's disk. Args: attachment_id: attachment ID. |
| list_project_categoriesA | List a project's issue categories, with their IDs. Args: project_identifier: project identifier (e.g. 'my-project'). |
| create_project_categoryA | Create an issue category in a project. Args: project_identifier: project identifier. name: category name (e.g. 'Infrastructure'). assigned_to_id: user assigned by default to issues in this category (0 = none). |
| update_project_categoryA | Update an issue category. Args: category_id: category ID (use list_project_categories). name: new name (empty = leave alone). assigned_to_id: new default assignee (0 = leave alone). |
| delete_project_categoryA | Delete an issue category. Issues that used the category are left without one, unless you give another category to receive them. Args: category_id: ID of the category to delete. reassign_to_id: ID of the category that receives the orphaned issues (0 = leave them without a category). |
| list_groupsA | List the instance's user groups. Requires administrator privileges. |
| get_groupA | Show a group's details: its members and the projects it belongs to. Args: group_id: group ID. |
| create_groupA | Create a user group. A group grants permissions to several people at once: add it as a project member and every member inherits the roles. Args: name: group name. user_ids: initial members' IDs (optional). |
| update_groupA | Update a group. Args: group_id: group ID. name: new name (empty = leave alone). user_ids: new, COMPLETE list of members — anyone not in it is removed from the group. To add one person without touching the rest, use add_user_to_group. |
| delete_groupA | Delete a group. The users themselves keep existing; they only lose the permissions that came from it. Args: group_id: group ID. |
| add_user_to_groupA | Add a user to a group, without touching the other members. Args: group_id: group ID. user_id: user ID. |
| remove_user_from_groupC | Remove a user from a group. Args: group_id: group ID. user_id: user ID. |
| list_issue_relationsB | List an issue's relations (precedes, blocks, related to, and so on). Args: issue_id: issue ID. |
| create_issue_relationA | Create a relation between two issues. Args: issue_id: source issue ID. target_issue_id: target issue ID. relation_type: relates, precedes, follows, blocks, blocked, duplicates, duplicated, copied_to, copied_from. delay: gap in days; only applies to 'precedes' and 'follows'. Warning: 'precedes' and 'follows' are date-driven — creating the relation makes Redmine reschedule the following issue, pushing its start date forward. Use 'relates' when you only want to link the issues without touching dates. |
| delete_issue_relationA | Delete a relation between issues by the relation's ID. Args: relation_id: relation ID (from the 'id' field in list_issue_relations). |
| chain_issuesA | Chain a list of issues in sequence. The first relates to the second, the second to the third, and so on. Useful for enforcing the execution order of a set of tasks without opening the relations form once per pair. Args: issue_ids: IDs in the desired order (e.g. [22, 25, 49, 51]). relation_type: same set as create_issue_relation. Defaults to 'precedes'. delay: gap in days; only applies to 'precedes' and 'follows'. Does not abort on the first error: it tries every pair and reports each result. Safe to re-run — Redmine rejects a duplicate relation with 422, which shows up as an error for that pair without affecting the others. |
| list_issuesA | List Redmine issues, with filters. Args: project_identifier: project identifier. Empty = all projects. status: 'open', 'closed', '*' (all), or the ID of a specific status. limit: maximum issues per page. Redmine caps this at 100. tracker_id: filter by tracker (use list_trackers). category_id: filter by category (use list_project_categories). fixed_version_id: filter by target version (use list_project_versions). assigned_to_id: filter by assignee. author_id: filter by who created the issue. parent_issue_id: return the subtasks of an issue. subject_contains: text contained in the subject (partial match). created_after: YYYY-MM-DD, issues created on or after this date. created_before: YYYY-MM-DD, issues created on or before this date. updated_after: YYYY-MM-DD, issues updated on or after this date. custom_fields: map of {field_id: value}, e.g. {"1": "8"}. sort_by: field and direction, e.g. 'priority:desc', 'updated_on:desc', 'id:asc'. Several can be comma-separated. offset: how many issues to skip — use together with 'limit' to paginate. query_id: run a saved query (use list_saved_queries). When given, the other filters are ignored by Redmine. Returns: JSON with the total number of matching issues (not just this page), so it's possible to tell whether pagination is needed without guessing. |
| get_issueA | Return every detail of an issue. Includes the description, attachments, relations, watchers, and subtasks. Args: issue_id: issue ID. include_history: also fetch the comments and change log. Turn this off for long issues when only the current field values matter. |
| bulk_update_issuesA | Apply the same change to several issues at once. Useful when the change is identical across issues — moving a batch of cards to a new status, fixing the category for a whole set, assigning a version. There is no equivalent for creation: each issue has its own content, so batching creation would not save anything. This does not abort on the first error: it tries every issue and reports each individual result. Every field besides issue_ids uses the same "leave alone" sentinels as update_issue: 0 for IDs, empty string for text and dates, -1 for percentage and hours. Args: issue_ids: IDs of the issues to change. status_id: new status ID (0 = leave alone). notes: comment appended to each issue's history. priority_id: new priority (0 = leave alone). tracker_id: new tracker (0 = leave alone). category_id: new category (0 = leave alone). fixed_version_id: new target version (0 = leave alone). assigned_to_id: new assignee (0 = leave alone). start_date: new start date, YYYY-MM-DD (empty = leave alone). due_date: new due date, YYYY-MM-DD (empty = leave alone). done_ratio: 0 to 100 (-1 = leave alone). estimated_hours: estimated effort in hours (-1 = leave alone). custom_fields: map of {field_id: value}, e.g. {"1": "5"}. |
| create_issueA | Create a new issue in Redmine. Args: project_identifier: project identifier (e.g. 'my-project'). subject: issue title. description: detailed description. tracker_id: tracker ID (varies per instance; use list_trackers). priority_id: priority ID (use list_statuses_and_priorities). status_id: status ID (0 = use the workflow's initial status). category_id: category ID (use list_project_categories). fixed_version_id: target version ID (use list_project_versions). assigned_to_id: assignee's user ID. parent_issue_id: parent issue ID, to create this as a subtask. start_date: start date, YYYY-MM-DD format. due_date: due date, YYYY-MM-DD format. estimated_hours: estimated effort in hours (-1 = not provided). custom_fields: map of {field_id: value}, e.g. {"1": "5"}. Use list_custom_fields to discover the IDs. Every field besides project and subject is optional; anything not provided is left to the project's defaults. |
| update_issueA | Update an existing issue. Only changes the fields that are provided. Args: issue_id: ID of the issue to update. status_id: new status ID (0 = leave alone). notes: comment to add to the history (does not replace the description). subject: new title (empty = leave alone). description: new description — REPLACES the existing one entirely. priority_id: new priority (0 = leave alone). tracker_id: new tracker (0 = leave alone). category_id: new category (0 = leave alone). fixed_version_id: new target version (0 = leave alone). assigned_to_id: new assignee (0 = leave alone). parent_issue_id: new parent issue (0 = leave alone). start_date: new start date, YYYY-MM-DD (empty = leave alone). due_date: new due date, YYYY-MM-DD (empty = leave alone). done_ratio: 0 to 100 (-1 = leave alone). estimated_hours: estimated effort in hours (-1 = leave alone). custom_fields: map of {field_id: value}, e.g. {"1": "5"}. "Leave alone" sentinels: 0 for IDs, empty string for text and dates, -1 for percentage and hours. There is no way to clear a field through this tool — to blank out a date or remove an assignee, use the Redmine web UI. |
| delete_issueA | Permanently delete an issue. WARNING: this is irreversible and takes the issue's subtasks, time entries, and history with it. Redmine has no trash can. Prefer moving to a closed status (e.g. Cancelled) when the goal is only to take it off the board. Args: issue_id: ID of the issue to delete. |
| add_watcherA | Add a watcher to an issue. Args: issue_id: issue ID. user_id: ID of the user to add as a watcher (use list_users). |
| remove_watcherA | Remove a watcher from an issue. Args: issue_id: issue ID. user_id: ID of the user to remove. |
| update_journal_noteA | Edit the text of a comment already posted to an issue's history. The journal ID is the 'id' field of each entry in 'journals', visible via get_issue — not to be confused with the issue ID. This endpoint is marked alpha in the Redmine documentation and may not exist in older versions; a 404 usually means that. Args: journal_id: ID of the history entry (journal). text: new text for the comment. |
| list_project_membersA | List a project's members and each one's roles. Args: project_identifier: project identifier. |
| add_project_memberB | Add a user as a project member, with one or more roles. Args: project_identifier: project identifier. user_id: user ID (use list_users). role_ids: list of role IDs (use list_roles). |
| update_project_memberA | Replace a member's roles. The given list becomes the complete list — any role not in it is removed. Args: membership_id: membership ID (the 'membership_id' field in list_project_members), not the user's ID. role_ids: new, complete list of role IDs. |
| remove_project_memberA | Remove a member from a project. The user loses access, but what they created remains — issues, comments, and time entries stay recorded under their name. Args: membership_id: membership ID (the 'membership_id' field in list_project_members), not the user's ID. |
| list_statuses_and_prioritiesA | List the issue statuses and priority levels available on this instance. |
| list_trackersA | List the instance's trackers (issue types), with their IDs. IDs vary per instance — use this tool before create_issue instead of assuming Redmine's default values. |
| list_custom_fieldsA | List the custom fields visible through the API. Each entry has an ID, format, and what it applies to. Needed to fill in 'custom_fields' in create_issue and update_issue. Requires the API key's user to be an administrator. |
| list_document_categoriesA | List the instance's document categories, with their IDs. These belong to the Documents module; if it's disabled for a project, the list still exists but has no practical use there. |
| list_newsA | List news items. Args: project_identifier: restrict to a project (empty = all). limit: maximum number of news items. |
| get_news_itemA | Show a news item's full text and comments. Args: news_id: news item ID (use list_news). |
| create_newsA | Publish a news item in a project. News is visible to every project member and triggers an email notification according to the instance's configuration — not a silent draft. Args: project_identifier: project identifier. title: news title. description: news body. summary: summary line shown in the listing. |
| update_newsA | Update a published news item. Available since Redmine 5.1; older versions respond with 404. Args: news_id: news item ID. title: new title (empty = leave alone). description: new body (empty = leave alone). summary: new summary (empty = leave alone). |
| delete_newsB | Delete a news item. Available since Redmine 5.1. Args: news_id: news item ID. |
| list_project_filesA | List the files published under a project's Files tab. Not to be confused with issue attachments: these are project-level artifacts — builds, installers, documents — optionally tied to a version. Args: project_identifier: project identifier. |
| upload_project_fileA | Publish a file under a project's Files tab. The path is resolved on the machine running this MCP server. Args: project_identifier: project identifier. file_path: full path of the file on the server's machine. description: description shown in the listing. version_id: ties the file to a version (0 = none). file_name: display name (empty = use the file's own name). |
| list_projectsA | List every project available in Redmine. |
| get_projectA | Show a project's details: description, enabled modules, trackers, and categories. Args: project_identifier: project identifier. |
| create_projectA | Create a project. Args: name: display name. identifier: URL identifier — lowercase letters, digits, and hyphens, immutable after creation. description: project description. parent_project_id: parent project ID, to create this as a subproject. is_public: whether it's visible to non-member users. The default here is private, more conservative than Redmine's own default. |
| update_projectA | Update a project. Only changes the fields that are provided. The 'identifier' cannot be changed after creation — that's a Redmine limitation, not one of this server. Args: project_identifier: project identifier. name: new display name (empty = leave alone). description: new description (empty = leave alone). homepage: project URL (empty = leave alone). |
| archive_projectA | Archive or unarchive a project. An archived project becomes read-only and disappears from listings, without losing anything. It's the reversible alternative to deletion, which this server deliberately does not expose — deletion is irreversible and takes issues, time entries, and wiki content with it. Deleting a project for real is a web UI operation. Args: project_identifier: project identifier. archive: True archives, False unarchives. |
| list_rolesA | List the instance's roles, with their IDs. |
| get_roleA | Show a role's details, including the full list of granted permissions. Useful for understanding why an operation is being refused, before trying again. Args: role_id: role ID (use list_roles). |
| searchA | Search for text across issues, wiki pages, news, and other Redmine objects. Args: query: text to search for. project_identifier: restrict to a project (empty = the whole instance). titles_only: search titles only, not the body. open_issues_only: restrict to open issues. all_words: require every word in the query; False = match any of them. limit: maximum number of results. |
| list_saved_queriesA | List the saved queries (filters) visible to the API key's user. Args: project_identifier: restrict to a project's queries (empty = all). |
| list_time_entriesA | List time entries, with optional filters. Args: project_identifier: filter by project (identifier or id). issue_id: filter by a specific issue (0 = ignore this filter). user_id: filter by user; use 'me' for the API key's own user. start_date: minimum date, YYYY-MM-DD format. end_date: maximum date, YYYY-MM-DD format. limit: maximum number of entries returned. |
| get_time_entryA | Show a time entry's details. Args: time_entry_id: time entry ID (use list_time_entries). |
| log_timeA | Log time spent, tied to either an issue or a project. Args: hours: amount of time worked (e.g. 2.5). date: date the work was done, YYYY-MM-DD format. issue_id: issue ID (use this OR project_identifier, not both). project_identifier: project identifier (if not tying this to a specific issue). activity_id: activity type ID (varies per instance; use list_time_entry_activities to see the options). comment: description of what was done. |
| update_time_entryA | Update an existing time entry. Args: time_entry_id: ID of the time entry to update. hours: new hours value (0 = leave alone). comment: new comment (empty = leave alone). activity_id: new activity ID (0 = leave alone). |
| delete_time_entryB | Delete a time entry by ID. |
| list_time_entry_activitiesA | List the activity types available for logging time. For example: Development, Design, Support. |
| get_current_userA | Return the user that owns the API key configured on this server. Useful for confirming which identity issues are being created under, and whether that user is an administrator. |
| list_usersA | List Redmine users. Requires administrator privileges. Args: status: 1 = active, 2 = registered awaiting activation, 3 = locked. name: filter by login, first name, last name, or email (partial match). limit: maximum number of users returned. |
| get_userB | Show a user's details. Includes which projects they belong to and with which role. Args: user_id: user ID. |
| create_userA | Create a user. Requires administrator privileges. The password is generated by Redmine itself and emailed to the person — this tool deliberately does not accept a password as a parameter, so no credential ever passes through the conversation. To set the password manually instead, use the Redmine web UI. Args: login: username for authentication. firstname: first name. lastname: last name. email: email address, also used to send the credentials. admin: grants administrator privileges. send_information: sends the email with the generated password. Only turn this off if you'll set the password another way — without it, the person cannot log in. |
| update_userA | Update a user. Requires administrator privileges. Locking is the reversible alternative to deletion: the user loses access but everything they created stays attributed to them. This server does not expose user deletion for that reason — deleting for real is still a web UI operation. Args: user_id: user ID. login: new login (empty = leave alone). firstname: new first name (empty = leave alone). lastname: new last name (empty = leave alone). email: new email (empty = leave alone). status: 1 = active, 3 = locked (0 = leave alone). admin: 1 grants, 0 revokes, -1 leaves alone. |
| update_my_accountA | Update the account of the user that owns the API key. Args: firstname: new first name (empty = leave alone). lastname: new last name (empty = leave alone). email: new email (empty = leave alone). |
| list_project_versionsC | List a project's versions (milestones), with their IDs. Args: project_identifier: project identifier. |
| create_project_versionA | Create a version (milestone) in a project. Args: project_identifier: project identifier. name: version name (e.g. 'v0.1 - Identity'). description: free-text description. status: 'open', 'locked', or 'closed'. due_date: version date, YYYY-MM-DD format. |
| update_versionA | Update an existing version. Only changes the fields that are provided. Args: version_id: version ID (use list_project_versions). name: new name (empty = leave alone). description: new description (empty = leave alone). status: 'open', 'locked', or 'closed' (empty = leave alone). Closing a version removes it from the choices offered to new issues, without affecting the ones that already reference it. due_date: new date, YYYY-MM-DD (empty = leave alone). |
| delete_versionA | Delete a version. Issues that reference it are left without a target version. To take a version out of circulation without losing the historical link, prefer update_version with status='closed'. Args: version_id: ID of the version to delete. |
| list_wiki_pagesA | List every wiki page of a project. Args: project_identifier: project identifier (e.g. 'my-project'). |
| get_wiki_pageA | Read the content of a specific wiki page. Args: project_identifier: project identifier. title: page title (e.g. 'Home'). Case-sensitive, as in Redmine. version: version number to read (0 = most recent). |
| create_or_update_wiki_pageA | Create a new wiki page, or update an existing one. Redmine uses the same PUT endpoint for both cases. Args: project_identifier: project identifier. title: page title (e.g. 'Home'). text: content in Markdown or Textile, depending on the instance's configuration (Administration -> Settings -> General -> Text formatting). comment: comment about the edit (shows up in the page's history). parent_page: title of the page that should become this one's parent, to nest it in the wiki index. Empty = leave the current nesting alone; on a new page, leaves it at the root. |
| attach_file_to_wiki_pageA | Attach a file to an existing wiki page. The page's text is preserved: this tool reads the current content and rewrites it together with the attachment, because Redmine's endpoint replaces the whole page. The path is resolved on the machine running this MCP server. Args: project_identifier: project identifier. title: title of the page that will receive the attachment. file_path: full path of the file on the server's machine. comment: edit comment, shown in the page's history. file_name: display name (empty = use the file's own name). |
| delete_wiki_pageA | Delete a wiki page (and its sub-pages, per Redmine's default behavior). Args: project_identifier: project identifier. title: title of the page to delete. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/alsimoes/mcp-redmine'
If you have feedback or need assistance with the MCP directory API, please join our Discord server