redmine-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@redmine-mcp show my assigned issues"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Redmine local MCP POC
This server exposes thirty-five MCP tools over stdio:
list_projectslists projects visible to the configured Redmine API user, with pagination and documented project associations.list_querieslists visible saved issue queries with collection pagination.searchsearches visible global Redmine content with documented search filters and pagination.list_issue_statuseslists all issue statuses in Redmine's configured order.list_issue_prioritieslists all issue priorities in Redmine's configured order.list_time_entry_activitieslists all shared time-entry activities in Redmine's configured order.list_document_categorieslists all shared document categories in Redmine's configured order.list_trackerslists all trackers in Redmine's configured order.list_roleslists non-built-in project-member roles in Redmine's configured order.get_rolereads one Redmine role by positive numeric role ID.get_projectreads one visible project by numeric ID or project identifier, with optional documented project associations.list_project_issue_categorieslists one project's issue categories by numeric ID or project identifier.get_issue_categoryreads one visible issue category by positive numeric ID.list_project_membershipslists a project's user and group memberships, roles, and pagination metadata by numeric project ID or project identifier.get_project_membershipreads one project membership by positive membership ID, including its user or group principal and roles.list_project_versionslists a project's visible and shared versions by numeric project ID or project identifier.list_project_fileslists a project's files by numeric project ID or project identifier.list_project_wiki_pageslists a project's wiki page index by numeric project ID or project identifier.get_project_wiki_pagereads one current project wiki page by numeric project ID or project identifier and title.get_project_wiki_page_versionreads one historic project wiki page revision by numeric project ID or project identifier, title, and version.get_attachmentreads one visible attachment by positive numeric attachment ID.get_versionreads one visible Redmine version by positive numeric version ID.get_userreads one visible Redmine user by positive numeric ID, with optional visible project memberships.get_current_userreads the Redmine user represented by the configured API token, with optional visible project memberships.get_my_accountreads the configured API user's own account from Redmine's/my/account.jsonendpoint.get_issuereads one visible Redmine issue and optionally includes documented issue associations and journal history.list_issue_relationslists the visible relations for one Redmine issue.get_issue_relationreads one visible Redmine issue relation by positive numeric relation ID.list_issueslists visible Redmine issues with pagination, sorting, documented filters, custom-field filters, attachments, and relations.list_newslists visible global Redmine news with collection pagination.get_newsreads one visible Redmine news item by positive numeric ID, with optional documented associations.list_project_newslists visible news for one project by numeric ID or project identifier, with collection pagination.list_time_entrieslists visible Redmine time entries with documented pagination, ID, project, activity, and date filters.get_time_entryreads one visible Redmine time entry by positive numeric ID.list_my_assigned_issuesreturns issues assigned to the Redmine user represented byREDMINE_API_TOKEN.
The server is read-only. It sends the token to Redmine in the X-Redmine-API-Key header. The token is not an MCP tool argument and is not included in tool results.
Run it
You need Node.js 20 or newer and pnpm.
Copy-Item .env.example .envEdit .env:
REDMINE_BASE_URL=https://redmine.example.com
REDMINE_API_TOKEN=your-redmine-api-tokenIf Redmine lives under a path, include it in the URL, for example https://example.com/redmine.
Enable the REST API in Redmine under Administration > Settings > API, then install and build:
pnpm install
pnpm buildRelated MCP server: Redmine MCP Server
Connect VS Code over stdio
The repository includes .vscode/mcp.json. VS Code starts dist/stdio.js itself, loads .env, and communicates over stdin and stdout.
After building, open this folder in VS Code and start redmine-test-mcp-server from the MCP server list. Rebuild after changing the TypeScript source.
To run the stdio process manually for troubleshooting:
pnpm startDo not use pnpm start as the VS Code command. Package manager output can interfere with the stdio protocol. The included configuration starts Node directly.
Tool input
list_projects accepts the documented offset, limit, and page pagination controls. All are omitted by default, so Redmine applies its own defaults. limit is capped at 100. The include list is empty by default and accepts trackers, issue_categories, enabled_modules, time_entry_activities, and issue_custom_fields.
{
"page": 2,
"limit": 25,
"include": ["trackers", "enabled_modules"]
}list_queries reads the visible saved issue queries from /queries.json. It accepts only Redmine's documented collection pagination controls: offset, limit, and page. Redmine defaults to an offset of 0 and a limit of 25, caps the limit at 100, and gives offset precedence over page. The endpoint has no documented project, resource-type, or include filters; internal and administrator-only query selectors are not exposed. Results preserve Redmine's name order and map the API fields id, name, is_public, and project_id to id, name, isPublic, and projectId. Explicit null and omitted projectId values are preserved. Each url points to the corresponding filtered issue list (/issues?query_id=:id), which is Redmine's documented way to use a saved query because /queries/:id is not a show route.
Redmine's QueriesController#index accepts ordinary API authentication, uses IssueQuery by default, and obtains visibility through IssueQuery.visible. Public queries are visible to logged-in users, role-visible queries require a matching project membership role, and private queries are visible only to their owner (subject to the query's view permission and project visibility). The client sends an authenticated GET, allowlists only the documented response fields, and returns sealed 401, 403, or 404 errors without upstream response bodies. See Redmine's Queries REST API documentation, REST API pagination documentation, current queries controller, queries API view, routes, query model, issue query model, and application authorization source.
{
"page": 2,
"limit": 25
}search reads the global /search.json endpoint for the configured Redmine API user. Its optional query input maps to Redmine's q parameter, which Redmine strips at both ends; omitting query is valid and returns an empty result collection on current Redmine. The tool accepts only the documented search controls: offset (nonnegative), limit (1 through 100), scope, all_words, titles_only, issues, news, documents, changesets, wiki_pages, messages, projects, open_issues, and attachments. It does not expose page, project_id, format, include, nometa, internal selectors, or administrator-only controls. Unknown, duplicated, malformed, and unsafe query inputs are rejected before the request is sent.
scope accepts all, subprojects, the current controller's my_projects and bookmarks, and the REST wiki's older my_project spelling. The client sends my_project as the current my_projects value. Because this tool intentionally calls the global route, subprojects has no project anchor and therefore behaves as the global scope. all_words defaults to Redmine's true; the client sends all_words=1 for true and an empty all_words value for false, matching Redmine's presence-based controller logic. The other boolean filters are sent as 1 only when true. attachments accepts exactly 0 for descriptions only, 1 for descriptions and attachments, or only for attachment-only search. Redmine applies its own default offset of 0, default limit of 25, and maximum limit of 100 when the pagination controls are omitted.
The output wrapper is results plus paging metadata and an echoed camelCase filters object. Each result allowlists id, title, type, url, description, and datetime; description and datetime preserve Redmine's explicit null or omission. Result type remains an opaque nonempty string so current core values and plugin-provided search types are preserved. The result array is returned in the exact order Redmine supplies. Current Redmine emits absolute result URLs. The client keeps a URL only when it is HTTP(S), same-origin, rooted under REDMINE_BASE_URL, and free of user info, fragments, path traversal, and credential-like query parameter names; an unsafe upstream URL becomes null and is never emitted verbatim.
This is an ordinary authenticated read. Redmine authorizes the global search action, then applies each searchable model's ordinary visibility and project-permission scopes, so results are limited to content visible to the configured API user. Search does not accept a project path in this tool; Redmine's route supports an optional project path, but the REST search contract does not require a project_id query input. The REST search API was added in Redmine 3.3.0. The current controller's plural my_projects and bookmarks scopes are documented in the later scope change. See Redmine's Search REST API documentation, REST API pagination documentation, search controller, search API view, routes, search engine, searchable model support, API authorization source, REST search feature, and search scope change.
{
"query": "release notes",
"offset": 0,
"limit": 25,
"scope": "all",
"all_words": true,
"titles_only": false,
"issues": true,
"wiki_pages": true,
"attachments": "0"
}list_issue_statuses reads all issue statuses from /issue_statuses.json. It accepts no query, include, or pagination controls because Redmine documents none for this collection and the controller loads every status in position order. The current API view returns id, name, is_closed, and description; the tool maps them to id, name, isClosed, and description, preserving the order Redmine sends and preserving an explicit null or an omitted description. It adds no browser links because Redmine's HTML index is admin-or-API-only and the routes define no status show page. Redmine accepts ordinary API authentication for this read and may return HTTP 401, 403, or 404 without exposing the upstream response body. See Redmine's Issue Statuses REST API documentation, current issue statuses controller, issue statuses API view, routes, and issue status model.
list_trackers reads all trackers from /trackers.json. It accepts no query, include, or pagination controls because Redmine documents none for this collection. The current API view returns id, name, default_status, description, and enabled_standard_fields; the tool maps them to id, name, defaultStatus, description, and enabledStandardFields, preserves Redmine's position order, and strips all other data. Redmine added description in 4.2.0 and enabled_standard_fields in 5.0.0, so those fields remain optional for older servers. Explicit null values remain null, and omitted fields remain omitted. The nested default status contains only its documented id and name. The result has no browser links because the HTML tracker index requires an administrator or API request and the routes define no tracker show page or ordinary status show page. Redmine accepts ordinary API authentication for this read and may return HTTP 401, 403, or 404 without exposing the upstream response body. See Redmine's Trackers REST API documentation, current trackers controller, trackers API view, routes, tracker model, and API authorization source.
list_roles reads /roles.json. It accepts no query, include, or pagination controls. Redmine's current controller returns Role.givable, which includes only non-built-in project-member roles and orders them by position. The current list API view returns only id and name; the tool preserves Redmine's response order, strips detail-only fields such as assignable, visibility settings, and permissions, and returns no browser links. Missing or null required fields are malformed responses, not optional values. Redmine accepts ordinary API authentication for this index, while the HTML roles page is restricted for non-admin users. Redmine may return HTTP 401, 403, or 404 without exposing the upstream response body. See Redmine's Roles REST API documentation, current roles controller, roles index API view, Role model, routes, API authorization source, and permission mapping.
get_role reads one role from /roles/:id.json. It accepts exactly one positive safe-integer role_id and sends no query string, include, pagination, or undocumented controls. The detail response is wrapped as role and maps the current API fields id, name, assignable, issues_visibility, time_entries_visibility, users_visibility, and permissions to id, name, assignable, issuesVisibility, timeEntriesVisibility, usersVisibility, and permissions. The visibility values are validated against Redmine's closed model domains: all, default, and own for issue visibility; all and own for time-entry visibility; and all and members_of_visible_projects for user visibility. Permissions remain opaque strings and retain Redmine's exact array order. The four assignability/visibility fields were added to the roles API in Redmine 4.0.0, so the client preserves their omission on older servers and preserves explicit null values when a server returns them. Unlike /roles.json, the detail route loads a role by ID and can return the built-in Non member and Anonymous roles when their IDs are known. The API route is available to ordinary API users, but the HTML role page is restricted to administrators for browser requests, so the result has no browser link. Redmine may return HTTP 401, 403, or 404 without exposing the upstream response body. See Redmine's Roles REST API documentation, the original role-detail API change, the Redmine 4.0 field change, current roles controller, role-detail API view, Role model, routes, and API authorization source.
get_project accepts a positive numeric project ID or a valid Redmine project identifier. Its include list is empty by default and accepts trackers, issue_categories, enabled_modules, time_entry_activities, and issue_custom_fields.
{
"project_id": "redmine",
"include": ["trackers", "enabled_modules"]
}list_project_issue_categories reads /projects/:project_id/issue_categories.json. It accepts only the required project_id, using the same positive numeric ID or valid Redmine project identifier rules as the other project tools. The request is an authenticated GET with no query string because Redmine documents no pagination, filter, include, or other query controls for this collection. Redmine's current controller loads @project.issue_categories.to_a, so the result preserves the API response order. The issue_categories wrapper maps to issueCategories, and total_count maps to totalCount only when Redmine returns it, preserving an explicit null or omission. Each category allowlists id, project, name, and optional assigned_to, mapping the last field to assignedTo; unknown upstream fields are removed. A returned project reference gets a safe base-path browser URL. Categories do not get URLs because their HTML index and show routes redirect to project settings, and assignees do not get URLs because Redmine models assigned_to as a Principal, which may be a user or group. The tool returns HTTP 401, 403, or 404 as sealed errors without upstream response bodies.
This is a non-admin read. Redmine authorizes it through the project's view_issues permission with the issue_tracking module enabled, while project visibility and the normal application authorization checks still apply. See Redmine's Issue Categories REST API documentation, current issue categories controller, issue categories API view, issue category model, routes, issue-tracking permission map, and application authorization source.
{
"project_id": "redmine"
}get_issue_category reads /issue_categories/:id.json for one visible issue category. It accepts exactly one positive safe-integer issue_category_id and sends no query string, include, or undocumented controls. Redmine's detail response is wrapped as issue_category; the current serializer emits id, optional project { id, name }, name, and optional assigned_to { id, name }. The result maps these fields to camelCase, preserves explicit null values and omitted associations, and strips unknown upstream fields. Only a returned project reference gets a safe browser URL: the category HTML show action redirects to member-only project settings, while assigned_to is a Principal that may be a user or group, so category and assignee URLs are omitted. No version-dependent detail fields are documented. Redmine may return HTTP 401, 403, or 404, and the tool does not expose upstream error bodies.
{
"issue_category_id": 2
}See Redmine's Issue Categories REST API documentation, current issue categories controller, issue category detail API view, issue category model, routes, issue-tracking and category permission map, and application authorization source.
list_project_memberships accepts a positive numeric project ID or valid Redmine project identifier, plus the documented collection pagination controls offset, limit, and page. These controls are omitted by default so Redmine applies its defaults. Redmine uses a limit of 25 by default, caps it at 100, and gives offset precedence over page. Each result identifies its principal as a user or group and preserves inherited roles. This endpoint is not admin-only, but Redmine still enforces project visibility and permissions, so a user without the relevant project permission may receive HTTP 403.
{
"project_id": "redmine",
"page": 2,
"limit": 25
}get_project_membership accepts only a positive safe-integer membership_id and sends no query parameters. It reads one membership from /memberships/:id.json, distinguishes user and group principals, preserves inherited roles, and returns null for a group principal URL because Redmine's group endpoint is administrative. This endpoint is not admin-only, but Redmine still enforces the membership's project visibility and permissions, so a user without the relevant project permission may receive HTTP 403.
{
"membership_id": 1
}list_project_versions accepts only a positive numeric project ID or valid Redmine project identifier. It reads /projects/:project_id/versions.json and sends no pagination, filter, or include parameters because Redmine's documented versions collection does not define them. Redmine may include shared versions from other projects, adds total_count, and the current API controller preserves the response order rather than applying the HTML roadmap sort. Visible custom fields are returned when Redmine's API view includes them. Redmine handles API authentication, project authorization, and version visibility, so the tool may return HTTP 401, 403, or 404 without exposing upstream error bodies. See Redmine's Versions REST API documentation, current versions controller, versions API view, custom-field API renderer, application authorization source, project shared-version source, and version model.
{
"project_id": "redmine"
}list_project_files accepts only a positive numeric project ID or valid Redmine project identifier and reads /projects/:project_id/files.json. Redmine documents no pagination, filters, include, or other query controls for this collection, so the request sends no query string. The files array is returned in the exact order Redmine supplies it; the current controller assembles project attachments and version attachments without this client reordering them. The tool returns the documented id, filename, filesize, content_type, description, content_url, optional thumbnail_url, optional author { id, name }, created_on, optional version { id, name }, digest, and downloads fields with camelCase names. Optional fields remain omitted when Redmine omits them, and explicit nulls remain null. The result also includes filters.projectId, safe attachment url and downloadUrl links, and safe browser links for returned authors and versions. Upstream content and thumbnail URLs are kept only when they use the configured Redmine origin and subpath, have no credentials or fragments, contain no path traversal, and have no credential-like query parameter names. No pagination metadata is added.
This is an ordinary authenticated, non-admin read. FilesController#index accepts API authentication and authorizes the project with the view_files permission. Project and version attachments use the same project-level attachment visibility rules, and Redmine may return HTTP 401, 403, or 404 without the tool exposing the upstream response body. See Redmine's Files REST API documentation, current FilesController#index, files API view, routes, attachment model, version model, file permission map, and application authorization source.
{
"project_id": "redmine"
}list_project_wiki_pages accepts only a positive numeric project ID or valid Redmine project identifier and reads /projects/:project_id/wiki/index.json. Redmine's documented wiki-page index defines no pagination, filters, include, or nometa controls, so the tool sends no query parameters. The current API view returns wiki_pages in Redmine's title-and-parent order with title, optional parent.title, version, optional project { id, name }, created_on, and updated_on; the tool maps these fields to camelCase, preserves explicit null values and omitted optional fields, and adds safe base-path browser URLs for the page and returned project. This is an ordinary authenticated API read authorized by the project's view_wiki_pages permission; Redmine may return HTTP 401, 403, or 404 without exposing upstream error bodies. See Redmine's Wiki Pages REST API documentation, current wiki controller, wiki index API view, routes, and application authorization source.
{
"project_id": "redmine"
}get_project_wiki_page reads /projects/:project_id/wiki/:title.json for the configured Redmine API user. project_id accepts a positive numeric project ID or valid Redmine project identifier. title must be a safe, nonempty string. The client rejects path separators and control characters, applies Redmine's title lookup normalization, and percent-encodes the resulting path segment. The only documented include is attachments.
The result unwraps Redmine's wiki_page response and includes title, parent, text, version, author, comments, project, createdOn, updatedOn, and url. attachments is returned only when Redmine includes it. The mapper keeps explicit null values and does not create fields that Redmine omitted. It removes credentials, fragments, and credential-like query parameters from attachment URLs, and adds browser links rooted under REDMINE_BASE_URL.
This is an ordinary authenticated read authorized by the project's view_wiki_pages permission. It does not read historic versions or change Redmine data. Redmine may return HTTP 401, 403, or 404, and the server does not expose those response bodies. See Redmine's Wiki Pages REST API documentation, current wiki controller, wiki detail API view, wiki index API view, routes, application authorization source, and attachment API renderer.
{
"project_id": "redmine",
"title": "UsersGuide",
"include": ["attachments"]
}get_project_wiki_page_version reads /projects/:project_id/wiki/:title/:version.json for one historic project wiki page revision. It accepts the same project selector, title, and attachments include as get_project_wiki_page, plus a positive safe-integer version. The client sends the exact versioned path after applying the shared Redmine title normalization and percent-encoding. The response uses the same wiki_page wrapper and allowlisted fields as the current-page detail response, but its url includes the returned historic version. Explicit null values remain null, omitted fields remain omitted, and attachment URLs are sanitized before they reach the tool result.
Redmine's WikiController#show authorizes the project normally with view_wiki_pages, then requires view_wiki_edits whenever a version is requested. A missing revision returns 404. This tool does not read the history listing and never writes to Redmine. Redmine may return HTTP 401, 403, or 404 without exposing upstream error bodies. See Redmine's Wiki Pages REST API documentation, the current wiki controller, wiki detail API view, routes, application authorization source, and attachment API renderer.
{
"project_id": "redmine",
"title": "UsersGuide",
"version": 23,
"include": ["attachments"]
}get_attachment reads /attachments/:id.json for the configured Redmine API user. attachment_id must be one positive safe integer. Redmine documents no query or include controls for this GET, so the client sends the exact path and no query string.
The response unwraps Redmine's attachment wrapper and allowlists id, filename, filesize, content_type, description, content_url, optional thumbnail_url, optional author { id, name }, and created_on. The result uses camelCase field names, preserves explicit null values and omitted optional fields, sanitizes the returned content and thumbnail URLs, and adds safe base-path url and downloadUrl links for Redmine's browser and named-download routes. It does not download file bytes or implement PATCH or DELETE.
Redmine accepts ordinary API authentication for this read and checks Attachment#visible?, which delegates to the owning object's attachment visibility rules or limits unattached files to their author. Redmine may return HTTP 401, 403, or 404; the client does not expose those response bodies. See Redmine's Attachments REST API documentation, current attachments controller, attachment API view, attachment helper, routes, attachment model, and application authentication source.
{
"attachment_id": 6243
}get_version accepts only a positive safe-integer version_id and reads /versions/:id.json with no query parameters because Redmine's documented version detail GET defines no pagination, filters, or include controls. The response wrapper is version; the result reuses the documented version fields and visible custom fields from the versions API, and adds estimatedHours and spentHours only when the detail API view returns them for an API user allowed to view time entries. Explicit Redmine null values remain null, while omitted fields remain omitted. The tool adds safe browser links rooted under REDMINE_BASE_URL, and Redmine enforces ordinary API authentication plus version/project visibility, so it may return HTTP 401, 403, or 404 without exposing upstream error bodies. See Redmine's Versions REST API documentation, current versions controller, version detail API view, custom-field API renderer, application authorization source, and version model.
{
"version_id": 2
}get_user accepts only a positive safe-integer user_id. Its only optional include is memberships, which Redmine documents and permits for non-admin callers; the result contains only memberships in projects visible to the requesting user. The server rejects administrator-only groups and auth_source includes and omits administrator-only or private fields such as admin, status, API keys, two-factor settings, password metadata, and authentication-source details. Redmine may omit email when the user's profile hides it, and it may omit version-dependent profile fields or custom values when Redmine does not return them. A visible user can be read by an ordinary authenticated API user, while an invisible or locked user may produce HTTP 404 and insufficient visibility may produce HTTP 403. See Redmine's Users REST API documentation and the current users API view for the upstream visibility and include rules.
{
"user_id": 3,
"include": ["memberships"]
}get_current_user reads the user represented by the configured API token from /users/current.json; it does not accept a user_id. Its only optional include is memberships, which Redmine also permits for ordinary authenticated callers and filters to projects visible to the requesting user. The result shares get_user's safe public profile contract, so it omits self-only fields such as the API key, administrator status, two-factor settings, password metadata, authentication-source details, and groups. Redmine may return HTTP 401 or 403 when the token is rejected or the endpoint is not permitted. See Redmine's Users REST API documentation and users API view.
{
"include": ["memberships"]
}get_my_account reads the configured API user's own account from /my/account.json. It accepts an empty object only and sends no query, include, pagination, or administrator controls. The result maps the official account view's safe profile fields and visible custom fields to camelCase, preserves explicit nulls and omitted fields, strips the API key and administrator flag, and adds the ordinary-user /my/account browser URL. The account controller accepts ordinary API authentication for this GET action. Preferences are not returned because the official API view does not serialize them. Redmine may return HTTP 401 or 403 without exposing the upstream response body. See Redmine's MyAccount REST API documentation, current routes, MyController, account API view, User model, UserPreference model, and custom-field API renderer.
{}get_issue requires one positive Redmine issue ID. Its include list is empty by default and accepts children, attachments, relations, changesets, journals, watchers, allowed_statuses, and reactions. Use journals to retrieve the issue journal history; reactions also adds reactions to returned journals when both associations are requested.
{
"issue_id": 42,
"include": ["children", "journals", "reactions"]
}list_issue_relations reads /issues/:issue_id/relations.json for one issue. It accepts exactly one positive safe numeric issue_id and sends no query parameters because Redmine's issue-relations route documents no filters or pagination. The result preserves Redmine's relation order, which the current source sorts by relation type order and then relation ID. It supports the documented relates, duplicates, duplicated, blocks, blocked, precedes, follows, copied_to, and copied_from relation types, preserves explicit delay nulls and omitted delays, and adds url, issueUrl, and issueToUrl only for valid IDs. These links are rooted under REDMINE_BASE_URL; the tool does not follow them or implement relation detail or write operations. Redmine authenticates the ordinary API user, enforces requested-issue and related-project visibility, and may return HTTP 401, 403, or 404 without exposing the upstream response body. See Redmine's Issue Relations REST API documentation, current issue-relations controller, issue-relations API view, issue model, issue-relation model, and routes.
{
"issue_id": 42
}get_issue_relation reads /relations/:id.json for one relation. It accepts exactly one positive safe numeric relation_id and sends no query parameters. The result preserves Redmine's documented relation fields, including all nine directional relation types and the explicit delay value or omission returned by Redmine, and adds url, issueUrl, and issueToUrl only for valid IDs. These links are rooted under REDMINE_BASE_URL. Redmine's current controller accepts API authentication for this GET action and checks that both linked issues are visible to the authenticated user; it does not require an administrator-only action. The tool does not implement relation creation or deletion and does not expose upstream response bodies on HTTP 401, 403, or 404. See Redmine's Issue Relations REST API documentation, REST API authentication documentation, current issue-relations controller, detail API view, issue-relation model, and routes.
{
"relation_id": 1819
}All list_issues fields are optional. The defaults are an open-issue page of 25 items, sorted by updated_on:desc, with no associations included.
{
"status_id": "open",
"project_id": 12,
"assigned_to_id": "me",
"created_on": ">=2026-01-01",
"custom_fields": [
{ "id": 4, "value": "~customer" }
],
"sort": "updated_on:desc,priority:desc",
"include": ["attachments", "relations"],
"limit": 25,
"offset": 0
}Supported filters are issue_id, project_id, subproject_id, tracker_id, status_id, assigned_to_id, parent_id, query_id, created_on, and updated_on. Single-ID filters accept one positive numeric ID. issue_id also accepts comma-separated IDs. subproject_id also accepts !*. status_id accepts open, closed, *, or one status ID. assigned_to_id accepts me or one user ID. Date filters accept Redmine operators such as >=2026-01-01 and ranges such as ><2026-01-01|2026-01-31.
Custom-field filters use { "id": number, "value": string | number | boolean } entries. The server turns each entry into the Redmine cf_<id> query parameter and rejects non-numeric field IDs. include is empty by default and accepts attachments and relations when requested; limit is capped at 100. list_my_assigned_issues keeps its existing status, limit, and offset input.
list_news reads the global /news.json collection for the configured API user. It accepts only the documented offset, limit, and page pagination controls. Redmine uses a default limit of 25, caps it at 100, and gives offset precedence over page. The result contains only the documented news fields, maps visible project and author references to base-path-safe browser URLs, and preserves fields Redmine omits or returns as null. Redmine applies its ordinary project and news visibility rules. See Redmine's News REST API documentation, the current news API view, news controller, and news model.
{
"page": 2,
"limit": 25
}list_project_news reads /projects/:project_id/news.json for one project. project_id accepts a positive numeric project ID or valid Redmine project identifier. It accepts only the documented offset, limit, and page collection pagination controls. Redmine uses a default limit of 25, caps it at 100, and gives offset precedence over page. The result uses the same news fields, mapping, null and omission behavior, and base-path-safe browser URLs as list_news. Redmine enforces the configured API user's project and news visibility and may return HTTP 401, 403, or 404. See Redmine's News REST API documentation, current news controller, and news model.
{
"project_id": "redmine",
"page": 2,
"limit": 25
}get_news reads /news/:id.json for one news item. news_id must be a positive safe numeric ID. Its include list is empty by default and accepts attachments, comments, and reactions. Reactions on comments are returned only when both comments and reactions are requested. The tool sends no other query controls. It reuses the list-news fields and mappings, preserves fields Redmine omits or returns as null, and adds only the association fields returned by Redmine's detail serializer. Attachment URLs are sanitized before they reach the tool result. Redmine enforces the item's news and project visibility and may return HTTP 401, 403, or 404. See Redmine's News REST API documentation, news detail API view, news controller, news model, and the official reactions REST API change.
{
"news_id": 54,
"include": ["attachments", "comments", "reactions"]
}list_time_entries reads /time_entries.json for the configured API user. It accepts the collection pagination controls offset, limit, and page, plus user_id, project_id, issue_id, activity_id, spent_on, from, and to. user_id accepts one positive numeric ID or me; the other ID filters accept one positive numeric ID. project_id also accepts a Redmine project identifier. spent_on accepts only a bare YYYY-MM-DD date, =, >=, or <= followed by one date, or the exact ><YYYY-MM-DD|YYYY-MM-DD range form with the dates in chronological order. from and to accept only real YYYY-MM-DD calendar dates. Surrounding whitespace is trimmed, but timestamps, impossible dates, operators on from/to, internal whitespace, malformed ranges, and unknown or admin-only query controls are rejected. Redmine still enforces the API user's view time entries permission and time-entry visibility rules.
The result contains allowlisted time-entry fields, visible custom fields when Redmine returns them, browser URLs rooted under REDMINE_BASE_URL, and paging metadata with the upstream offset, limit, and total_count. The server sends only GET /time_entries.json with the shared API-key transport and does not expose upstream error bodies. See Redmine's Time Entries REST API documentation, the current time-entry list API view, and the current time-entry query source.
get_time_entry reads /time_entries/:id.json for the configured API user. It accepts exactly one time_entry_id, which must be a positive safe numeric ID, and sends no query parameters. Its result uses the same allowlisted time-entry fields and browser-link rules as list_time_entries, preserves fields that Redmine omits or returns as null, and includes visible custom fields when Redmine returns them. Redmine enforces the API user's view_time_entries permission and time-entry visibility; 401, 403, and 404 responses are returned as safe status errors without upstream response bodies. See Redmine's time-entry REST API documentation, detail API view, time-entry controller, and time-entry visibility source.
{
"project_id": "redmine",
"user_id": 3,
"activity_id": 9,
"from": "2026-01-01",
"to": "2026-01-31",
"page": 2,
"limit": 25
}list_issue_priorities reads all issue priorities from /enumerations/issue_priorities.json. It accepts no query, include, or pagination controls. Redmine's current controller selects shared global IssuePriority records and returns them in the model's position order, which the Redmine guide describes as lower priority to higher priority. The API view returns id, name, is_default, active, and visible custom_fields when present; the tool maps them to id, name, isDefault, active, and customFields, strips every other field, preserves the upstream order, and keeps custom-field null values and omitted version-dependent fields. Redmine added active to the enumeration API in 4.1.0 and enumeration custom-field values in 3.4.0, so older servers may omit those fields. The API index has no ordinary priority show route, and its HTML view is restricted to administrators or API requests, so results have no browser links. Redmine may return HTTP 401, 403, or 404 without exposing the upstream response body. See Redmine's Enumerations REST API documentation, enumerations controller, enumerations API view, IssuePriority model, Enumeration model and ordering scopes, custom-field API renderer, routes, API authorization source, active-field change, and enumeration custom-field change.
list_time_entry_activities reads all shared time-entry activities from /enumerations/time_entry_activities.json. It accepts no query, include, or pagination controls. Redmine's current controller selects shared TimeEntryActivity records and returns them in the enumeration position order. That global collection includes inactive activities and does not return project-specific activity overrides; use the documented project include=time_entry_activities response when project-specific activity availability is needed. The API view returns id, name, is_default, active, and visible custom_fields when present; the tool maps them to id, name, isDefault, active, and customFields, strips every other field, preserves the upstream order, explicit custom-field null values, and omitted version-dependent fields. Redmine added active to the enumeration API in 4.1.0 and enumeration custom-field values in 3.4.0, so older servers may omit those fields. Ordinary API authentication can read this index, while the HTML index is restricted to administrators or API requests. Redmine defines no time-entry-activity show route, so results have no browser links. Redmine may return HTTP 401, 403, or 404 without exposing the upstream response body. See Redmine's Enumerations REST API documentation, Projects REST API documentation, enumerations controller, enumerations API view, TimeEntryActivity model, Enumeration model and ordering scopes, custom-field API renderer, routes, API authorization source, project time-entry activity source, active-field change, and enumeration custom-field change.
list_document_categories reads all shared document categories from /enumerations/document_categories.json. It accepts no query, include, or pagination controls because Redmine's documented endpoint defines none. The current controller selects DocumentCategory.shared.sorted, so the result contains global/shared categories in Redmine's position order and excludes project-specific enumeration overrides. The collection includes inactive categories; current Redmine returns active, while servers older than 4.1.0 may omit it. The current API view returns id, name, is_default, active, and visible custom_fields; enumeration custom-field values were added in Redmine 3.4.0, so older servers may omit custom_fields. The tool maps these fields to id, name, isDefault, active, and customFields, preserves order, explicit custom-field null values, and omitted version-dependent fields, and strips all other upstream data. Redmine accepts ordinary API authentication for this read. Its HTML index is admin-or-API-only for non-admin users and the routes define no document-category show page, so results have no browser links. Redmine may return HTTP 401, 403, or 404 without exposing the upstream response body. See Redmine's Enumerations REST API documentation, enumerations controller, enumerations API view, DocumentCategory model, Enumeration model and ordering scopes, DocumentCategory custom-field model, custom-field API renderer, routes, API authorization source, active-field change, and enumeration custom-field change.
Quick checks
$env:NODE_EXTRA_CA_CERTS = (Resolve-Path .cert\localhost-cert.pem)
node -e 'fetch("https://127.0.0.1:3000/health").then(async response => console.log(await response.text()))'
pnpm testFor HTTP clients, point the MCP client at https://127.0.0.1:3000/mcp. Configure that client to trust the local certificate, or supply a certificate signed by a CA it already trusts. The server supports current MCP HTTP requests and the stateless legacy fallback supplied by the official SDK.
POC boundaries
This cut intentionally has no issue updates, time-entry writes, token rotation, MCP-side authentication, caching, or retries. Anyone who can access the local HTTPS endpoint can read whatever the configured Redmine token can read, which is why the HTTPS process only listens on loopback. Stdio does not open a network port.
Available Tools
35 toolsget_attachmentGet a Redmine attachmentARead-onlyIdempotent
Read one visible Redmine attachment from GET /attachments/:id.json for the configured API user. The required attachment_id is a positive safe integer. This endpoint has no documented query or include controls. Results contain the documented attachment metadata, sanitized content and thumbnail URLs, and safe base-path browser and download links. Redmine enforces attachment visibility and may return HTTP 401, 403, or 404. This tool never downloads files, changes attachment metadata, or deletes attachments.
Inputs: attachment_id (required). Returns: id, url, author, filename, +7 more
get_current_userGet the current Redmine userARead-onlyIdempotent
Read the Redmine user represented by the configured API credentials from GET /users/current.json. This non-admin read requires no user_id and accepts only the documented memberships include, which Redmine filters to projects visible to the requesting user. The result uses the same safe public profile contract as get_user and never exposes self-only API keys, administrator status, two-factor settings, password metadata, authentication-source data, or groups. Redmine may return HTTP 401 or 403 when credentials are rejected or the endpoint is not permitted. This tool never changes Redmine data.
Inputs: include. Returns: id, url, email, login, +8 more
get_issueGet a Redmine issueARead-onlyIdempotent
Read one visible Redmine issue from GET /issues/:id.json for the configured API user. The required issue_id is a positive issue ID. Optionally include children, attachments, relations, changesets, journals, watchers, allowed_statuses, and reactions. This tool never changes Redmine data; include=journals also returns the issue's journal history.
Inputs: issue_id (required), include. Returns: id, url, author, parent, +29 more
get_issue_categoryGet a Redmine issue categoryARead-onlyIdempotent
Read one visible Redmine issue category from GET /issue_categories/:id.json for the configured Redmine API user. The required issue_category_id is a positive safe integer. This endpoint accepts no query, include, or undocumented controls, and results contain only the current issue-category serializer fields with camelCase names, preserving explicit nulls and omitted associations. A safe browser URL is added only to the returned project reference. The category HTML show route redirects to member-only project settings, and assigned_to is a Principal that may be a user or group, so categories and assignees receive no browser URLs. This is a non-admin read authorized by the category project's view_issues permission with the issue_tracking module enabled, subject to Redmine's project visibility and ordinary permission checks. Redmine may return HTTP 401, 403, or 404. This tool never changes Redmine data.
Inputs: issue_category_id (required). Returns: id, name, project, assignedTo
get_issue_relationGet a Redmine issue relationARead-onlyIdempotent
Read one visible Redmine issue relation from GET /relations/:id.json for the configured API user. The required relation_id is one positive safe numeric ID. This route has no query controls. The result contains only documented relation fields and safe base-path browser links for valid issue and relation IDs, preserving Redmine's explicit null or omitted delay. Redmine accepts ordinary API authentication, enforces visibility for both linked issues, and may return HTTP 401, 403, or 404. This tool never changes Redmine data.
Inputs: relation_id (required). Returns: id, url, delay, issueId, +4 more
get_my_accountGet my Redmine accountARead-onlyIdempotent
Read the current user's own Redmine account from GET /my/account.json for the configured API credentials. This endpoint accepts an empty object only and sends no query, include, pagination, or administrator controls. The result allowlists the official account view's safe profile fields and visible custom fields, strips the API key and administrator flag, preserves explicit nulls and omitted version-dependent fields, and adds the ordinary-user /my/account browser URL. Redmine may return HTTP 401 or 403 when credentials are rejected or the endpoint is not permitted. This tool never changes Redmine data.
Inputs: no named parameters. Returns: id, url, email, login, +5 more
get_newsGet a Redmine news itemARead-onlyIdempotent
Read one visible Redmine news item from GET /news/:id.json for the configured API user. The required news_id is one positive safe numeric ID. Optionally include the documented attachments, comments, and reactions associations. Redmine enforces news and project visibility and may return HTTP 401, 403, or 404. This tool never changes Redmine data.
Inputs: news_id (required), include. Returns: id, url, title, author, +7 more
get_projectGet a Redmine projectARead-onlyIdempotent
Read one visible Redmine project from GET /projects/:id.json for the configured API user. The required project_id is a positive numeric project ID or valid project identifier. Optionally include trackers, issue_categories, enabled_modules, time_entry_activities, and issue_custom_fields. This tool never changes Redmine data.
Inputs: project_id (required), include. Returns: id, url, name, parent, +16 more
get_project_membershipGet a Redmine project membershipARead-onlyIdempotent
Read one project membership from GET /memberships/:id.json for the configured Redmine API user. The required membership_id is a positive safe integer, and this endpoint has no query parameters. Results distinguish user and group principals, preserve roles including inherited flags, and never expose administrative group links. This is a non-admin read, but Redmine still enforces the membership's project visibility and permissions and may return HTTP 403 when the user lacks the relevant project permission. This tool never changes Redmine data.
Inputs: membership_id (required). Returns: id, roles, project, principal
get_project_wiki_pageGet a Redmine project wiki pageARead-onlyIdempotent
Read one current project wiki page from GET /projects/:project_id/wiki/:title.json for the configured Redmine API user. The required project_id is a positive numeric project ID or valid Redmine project identifier, and title must be a safe nonempty wiki page title. The only documented include is attachments. Results contain the current page fields and safe base-path browser links. Redmine enforces the ordinary view_wiki_pages permission and may return HTTP 401, 403, or 404. This tool does not read historic versions or change Redmine data.
Inputs: title (required), project_id (required), include. Returns: url, text, title, author, +7 more
get_project_wiki_page_versionGet a historic Redmine project wiki page revisionARead-onlyIdempotent
Read one historic project wiki page revision from GET /projects/:project_id/wiki/:title/:version.json for the configured Redmine API user. The required project_id is a positive numeric project ID or valid Redmine project identifier, title must be a safe nonempty wiki page title, and version must be a positive safe integer. The only documented include is attachments. Results use the historic revision fields and a safe browser link that includes the revision number. Redmine authorizes the ordinary view_wiki_pages permission and separately requires view_wiki_edits for versioned reads; it may return HTTP 401, 403, or 404. This tool never reads the history listing or changes Redmine data.
Inputs: title (required), version (required), project_id (required), include. Returns: url, text, title, author, +7 more
get_roleGet a Redmine roleARead-onlyIdempotent
Read one Redmine role from GET /roles/:id.json for the configured Redmine API user. The required role_id is a positive safe integer. This detail endpoint accepts ordinary API authentication, sends no query, include, pagination, or undocumented controls, and can return a built-in Non member or Anonymous role when its ID is known; unlike GET /roles.json, it is not limited to givable project-member roles. Results map the current serializer fields id, name, assignable, issues_visibility, time_entries_visibility, users_visibility, and ordered permissions to camelCase, validate the closed visibility enum domains, preserve permission order, preserve explicit nulls, and preserve omission of the Redmine 4.0+ assignable and visibility fields on older servers. The HTML roles page is admin-only for ordinary browser requests, so results have no browser links. Redmine may return HTTP 401, 403, or 404 without exposing the upstream response body. This tool never changes Redmine data.
Inputs: role_id (required). Returns: id, name, assignable, permissions, +3 more
get_time_entryGet a Redmine time entryARead-onlyIdempotent
Read one visible Redmine time entry from GET /time_entries/:id.json for the configured API user. The required time_entry_id is one positive safe numeric ID. The result contains only the documented time-entry fields, visible custom fields when returned, and base-path-safe browser URLs. Redmine enforces the user's view_time_entries permission and time-entry visibility and may return 401, 403, or 404. This tool never changes Redmine data.
Inputs: time_entry_id (required). Returns: id, url, user, hours, +8 more
get_userGet a Redmine userARead-onlyIdempotent
Read one visible Redmine user from GET /users/:id.json for the configured API user. The required user_id is a positive safe integer. Optionally include memberships, which Redmine documents for non-admin callers and filters to projects visible to the requesting user. Redmine omits private or administrator-only fields such as email when hidden, status, API keys, two-factor settings, authentication sources, groups, and password metadata. This is a non-admin read, but Redmine still enforces user visibility and may return HTTP 403 or 404. This tool never changes Redmine data.
Inputs: user_id (required), include. Returns: id, url, email, login, +8 more
get_versionGet a Redmine versionARead-onlyIdempotent
Read one visible Redmine version from GET /versions/:id.json for the configured Redmine API user. The required version_id is a positive safe integer, and this route has no query parameters or documented include controls. Results include the documented version fields and visible custom fields, plus estimatedHours and spentHours only when Redmine returns them. Redmine enforces version and project visibility and may return HTTP 401, 403, or 404. This tool never changes Redmine data.
Inputs: version_id (required). Returns: id, url, name, status, +10 more
list_document_categoriesList Redmine document categoriesARead-onlyIdempotent
Read all shared Redmine document categories from GET /enumerations/document_categories.json for the configured Redmine API user. This endpoint accepts no query, include, or pagination controls and preserves Redmine's shared position order. Results map id, name, is_default, active, and visible custom_fields to id, name, isDefault, active, and customFields, preserving upstream order, explicit custom-field null values, and omitted version-dependent fields. The active field is available since Redmine 4.1.0 and enumeration custom-field values since 3.4.0. The shared collection includes inactive categories when Redmine returns them and does not include project-specific enumeration overrides. The HTML index is admin-or-API-only for non-admin users and Redmine has no document-category show route, so results have no browser links. Redmine may return HTTP 401, 403, or 404 without exposing the upstream response body. This tool never changes Redmine data.
Inputs: no named parameters. Returns: documentCategories
list_issue_prioritiesList Redmine issue prioritiesARead-onlyIdempotent
Read all Redmine issue priorities from GET /enumerations/issue_priorities.json for the configured Redmine API user. This endpoint accepts no query, include, or pagination controls and returns shared global priorities in Redmine's lower-to-higher position order. Results map id, name, is_default, active, and visible custom_fields to id, name, isDefault, active, and customFields, preserving upstream order, explicit custom-field null values, and omitted version-dependent fields. The active field is available since Redmine 4.1.0 and enumeration custom-field values since 3.4.0. The HTML index is admin-or-API-only for non-admin users and Redmine has no priority show route, so results have no browser links. Redmine may return HTTP 401, 403, or 404 without exposing the upstream response body. This tool never changes Redmine data.
Inputs: no named parameters. Returns: issuePriorities
list_issue_relationsList Redmine issue relationsARead-onlyIdempotent
Read the visible relations for one Redmine issue from GET /issues/:issue_id/relations.json for the configured API user. The required issue_id is one positive safe numeric ID. This Redmine route has no query controls or pagination. Results contain only relation fields and safe base-path browser links for valid issue and relation IDs. Redmine enforces issue and related-project visibility and may return HTTP 401, 403, or 404. This tool never changes Redmine data.
Inputs: issue_id (required). Returns: relations
list_issuesList Redmine issuesARead-onlyIdempotent
Read visible Redmine issues from GET /issues.json for the configured API user. Supports offset and limit up to 100, sorting, attachments and relations, issue_id, project_id, subproject_id, tracker_id, status_id, assigned_to_id, parent_id, query_id, created_on, updated_on, and numeric-ID custom-field filters. This tool never changes Redmine data.
Inputs: sort, limit, offset, include, +11 more. Returns: issues, paging, filters
list_issue_statusesList Redmine issue statusesARead-onlyIdempotent
Read all Redmine issue statuses from GET /issue_statuses.json for the configured Redmine API user. This endpoint accepts no query, include, or pagination controls. Results preserve Redmine's position order and map the current API fields id, name, is_closed, and description to id, name, isClosed, and description, preserving an explicit null or an omitted description. Redmine accepts ordinary API authentication for this index, but its HTML index is admin-or-API-only and there is no status show route, so the result has no browser links. Redmine may return HTTP 401, 403, or 404 without exposing the upstream response body. This tool never changes Redmine data.
Inputs: no named parameters. Returns: issueStatuses
list_my_assigned_issuesList my assigned Redmine issuesARead-onlyIdempotent
List Redmine issues assigned to the user represented by the server's configured API token. Results are ordered by most recently updated.
Inputs: limit, offset, status. Returns: user, issues, paging, filters
list_newsList Redmine newsARead-onlyIdempotent
Read visible global Redmine news from GET /news.json for the configured API user. Supports the documented offset, limit, and page collection pagination controls. Redmine applies its ordinary news and project visibility rules; this tool never changes Redmine data.
Inputs: page, limit, offset. Returns: news, paging, filters
list_project_filesList Redmine project filesARead-onlyIdempotent
Read a project's files from GET /projects/:project_id/files.json for the configured Redmine API user. The required project_id is a positive numeric project ID or valid project identifier. This endpoint has no documented pagination, filter, include, or other query controls, so the request sends no query string and preserves Redmine's response order. Results allowlist the file metadata fields, preserve optional and null values, sanitize upstream content and thumbnail URLs against the configured Redmine origin and subpath, and add safe browser and download links for the attachment plus ordinary version and author pages. Redmine authorizes this ordinary non-admin read with the project's view_files permission and project visibility and may return HTTP 401, 403, or 404 without exposing the upstream response body. This tool never downloads files or changes Redmine data.
Inputs: project_id (required). Returns: files, filters
list_project_issue_categoriesList Redmine project issue categoriesARead-onlyIdempotent
Read one project's issue categories from GET /projects/:project_id/issue_categories.json for the configured Redmine API user. The required project_id is a positive numeric project ID or valid Redmine project identifier. This collection has no documented pagination, filters, include, or other query controls, so the request sends no query string and preserves Redmine's response order. Results map id, project, name, and optional assigned_to to camelCase, preserve total_count when Redmine returns it, and add a safe browser URL only to a returned project reference. Category HTML routes redirect to project settings, and assigned_to is a Principal that may be a user or group, so categories and assignees receive no browser URLs. This is a non-admin read authorized by the project's view_issues permission with the issue_tracking module enabled, subject to Redmine's project visibility and ordinary permission checks. Redmine may return HTTP 401, 403, or 404. This tool never changes Redmine data.
Inputs: project_id (required). Returns: filters, totalCount, issueCategories
list_project_membershipsList Redmine project membershipsARead-onlyIdempotent
Read the paginated memberships from GET /projects/:project_id/memberships.json for the configured Redmine API user. The required project_id is a positive numeric project ID or valid project identifier. Optional offset, limit, and page parameters use Redmine's collection pagination rules, including a default limit of 25 and a maximum limit of 100. Results distinguish user and group principals and preserve roles, including inherited roles. This is a non-admin read, but Redmine still enforces project visibility and permissions and may return HTTP 403 when the user lacks the relevant project permission. This tool never changes Redmine data.
Inputs: project_id (required), page, limit, offset. Returns: paging, filters, memberships
list_project_newsList Redmine project newsARead-onlyIdempotent
Read visible news for one Redmine project from GET /projects/:project_id/news.json for the configured API user. The required project_id is a positive numeric project ID or valid project identifier. Supports the documented offset, limit, and page collection pagination controls. Redmine applies its ordinary project and news visibility rules; this tool never changes Redmine data.
Inputs: project_id (required), page, limit, offset. Returns: news, paging, filters
list_projectsList Redmine projectsARead-onlyIdempotent
Read projects visible to the configured Redmine API user from GET /projects.json. Supports the documented offset, limit, and page pagination controls, plus trackers, issue_categories, enabled_modules, time_entry_activities, and issue_custom_fields associations. This tool never changes Redmine data.
Inputs: page, limit, offset, include. Returns: paging, filters, projects
list_project_versionsList Redmine project versionsARead-onlyIdempotent
Read the visible/shared versions from GET /projects/:project_id/versions.json for the configured Redmine API user. The required project_id is a positive numeric project ID or valid Redmine project identifier. This route has no pagination, filters, or documented include controls, and Redmine preserves its response order. This tool never changes Redmine data.
Inputs: project_id (required). Returns: filters, versions, totalCount
list_project_wiki_pagesList Redmine project wiki pagesARead-onlyIdempotent
Read the wiki page index from GET /projects/:project_id/wiki/index.json for the configured Redmine API user. The required project_id is a positive numeric project ID or valid Redmine project identifier. This route has no pagination, filters, or documented include controls; results preserve Redmine's title-and-parent order, include only the current index fields, and add safe browser links. Redmine enforces the ordinary view_wiki_pages permission and may return HTTP 401, 403, or 404. This tool never changes Redmine data.
Inputs: project_id (required). Returns: filters, wikiPages
list_queriesList Redmine saved queriesARead-onlyIdempotent
Read visible saved issue queries from GET /queries.json for the configured Redmine API user. Supports the documented offset, limit, and page collection pagination controls; Redmine defaults to 25 items, caps the limit at 100, orders by query name, and applies ordinary public/private/role visibility. This tool does not expose project, resource-type, or include filters and never changes Redmine data.
Inputs: page, limit, offset. Returns: paging, filters, queries
list_rolesList Redmine rolesARead-onlyIdempotent
Read Redmine's non-built-in project-member roles from GET /roles.json for the configured Redmine API user. This endpoint accepts no query, include, or pagination controls and preserves Redmine's position order. The list response contains only id and name; it does not expose permissions, visibility settings, or other fields from the separate role-detail response. Redmine accepts ordinary API authentication for this index, but the HTML roles page is restricted for non-admin users, so results have no browser links. Redmine may return HTTP 401, 403, or 404 without exposing the upstream response body. This tool never changes Redmine data.
Inputs: no named parameters. Returns: roles
list_time_entriesList Redmine time entriesARead-onlyIdempotent
Read visible Redmine time entries from GET /time_entries.json for the configured API user. Supports offset, limit, and page pagination, a positive numeric user_id or me, project_id, issue_id, activity_id, exact Redmine spent_on date/range forms, and real YYYY-MM-DD from/to filters. Redmine enforces the user's view-time-entry permissions and visibility. This tool never changes Redmine data.
Inputs: to, from, page, limit, +6 more. Returns: paging, filters, timeEntries
list_time_entry_activitiesList Redmine time-entry activitiesARead-onlyIdempotent
Read all shared Redmine time-entry activities from GET /enumerations/time_entry_activities.json for the configured Redmine API user. This endpoint accepts no query, include, or pagination controls and preserves Redmine's shared position order. Results map id, name, is_default, active, and visible custom_fields to id, name, isDefault, active, and customFields, preserving upstream order, explicit custom-field null values, and omitted version-dependent fields. The active field is available since Redmine 4.1.0 and enumeration custom-field values since 3.4.0. Project-specific activity overrides are not returned by this global collection. The HTML index is admin-or-API-only for non-admin users and Redmine has no time-entry-activity show route, so results have no browser links. Redmine may return HTTP 401, 403, or 404 without exposing the upstream response body. This tool never changes Redmine data.
Inputs: no named parameters. Returns: timeEntryActivities
list_trackersList Redmine trackersARead-onlyIdempotent
Read all Redmine trackers from GET /trackers.json for the configured Redmine API user. This endpoint accepts ordinary API authentication and has no documented query, include, or pagination controls. Results preserve Redmine's configured position order and map id, name, default_status, description, and enabled_standard_fields to id, name, defaultStatus, description, and enabledStandardFields. Description is available since Redmine 4.2.0 and enabledStandardFields since Redmine 5.0.0. The HTML index is admin-or-API-only and Redmine has no tracker show route, so results have no browser links. Redmine may return HTTP 401, 403, or 404 without exposing the upstream response body. This tool never changes Redmine data.
Inputs: no named parameters. Returns: trackers
searchSearch RedmineARead-onlyIdempotent
Search visible global Redmine content through GET /search.json for the configured API user. The optional query maps to Redmine's q parameter. Supports only Redmine's documented offset, limit, scope, all_words, titles_only, result-type flags, open_issues, and attachments controls; project_id, page, include, and internal or administrator-only controls are rejected. Redmine defaults to 25 results and caps the limit at 100. Results preserve Redmine's upstream order and expose only id, title, type, url, description, and datetime. Unsafe result URLs are omitted, and this read never changes Redmine data.
Inputs: news, limit, query, scope, +11 more. Returns: paging, filters, results
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 35 tools
Every tool is clearly distinct: list_* for collections, get_* for single resources, and each maps to a specific Redmine API endpoint. Even similar tools like get_project and list_projects differ obviously by cardinality. Semantic overlaps (e.g., get_version vs get_project_wiki_page_version) are unambiguous from context.
The naming pattern is overwhelmingly consistent: list_* for index endpoints, get_* for show endpoints, with clear resource nouns. Minor deviations like get_my_account instead of get_current_user and list_my_assigned_issues being slightly longer than other list_* names are easy to predict but not perfectly uniform.
With 35 tools, this is above the 15-25 range considered 'heavy' and closer to the chaotic end. While Redmine has many resource types, the count feels bloated—several read-only variants (e.g., list_project_issues vs list_all_issues) could be consolidated. Users face a steep CLI surface.
The tool set is exclusively read-only. While it covers a broad set of GET endpoints (projects, issues, wiki, memberships, etc.), there are no create, update, or delete operations. A complete Redmine integration would at least allow issue mutations, leaving major dead ends for agents that need to take actions.
Maintenance
Related MCP Connectors
Read-only MCP access to a documented IT fleet: state, changes, posture. 15 tools.
Read-only developer, date, finance, and text utilities. Authless remote MCP server by Clean.tools.
Reddit API as 61 MCP tools: search, subreddits, posts, comments, users, monitors, writes, feedback.
Read and write Mission Control state via MCP — projects, tasks, subtasks, templates, status updates.
Related MCP Servers
- AlicenseBqualityBmaintenanceExposes 30 tools to manage Redmine resources (issues, projects, users, time entries, wiki pages, news, files, roles) via the REST API using stdio transport.33264 npm6MIT
- AlicenseNot gradedqualityCmaintenanceProvides MCP tools for interacting with Redmine, including issues, projects, wiki pages, time entries, and more.15 npm1MIT
- AlicenseAqualityDmaintenanceA local STDIO server that exposes Redmine REST API as MCP tools, allowing MCP clients to browse Redmine projects and tickets.6MIT
- AlicenseNot gradedqualityDmaintenanceA read-only MCP server for querying Redmine issue data via the Redmine REST API, designed for seamless integration with AI assistants.15 npmMIT