# Redmine MCP Server (oci · ghcr.io/igorolv/redmine-mcp-server)

Redmine for AI agents: issues, projects, wiki, attachments, time entries and release analytics

- Trust score: 51/100 (low)
- Change this week: +41
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-10-18

## Components

- oci · `ghcr.io/igorolv/redmine-mcp-server`: 51/100 (this document), [markdown](https://verifymcp.io/servers/igorolv-redmine-mcp-server/ghcr-io-igorolv-redmine-mcp-server.md), [page](https://verifymcp.io/servers/igorolv-redmine-mcp-server/ghcr-io-igorolv-redmine-mcp-server)

## Channel facts

- Registry: `oci`
- Package: `ghcr.io/igorolv/redmine-mcp-server`
- Version: `0.1.1`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-10-18.

- **Supply Chain Security**: 0/100
  - No malware scan is available for this kind of package: the supply-chain vendors we use do not cover it. This is a permanent gap in our coverage, not a finding about the package.
  - Known CVEs could not be checked: this artifact ships no SBOM or dependency manifest, so there is no dependency list to read.
  - Install-script risk not yet assessed.
  - Dependency health could not be checked: this artifact ships no SBOM or dependency manifest, so there is no dependency list to read.
- **Provenance & Transparency**: 48/100
  - Source repository is publicly reachable at the declared URL.
  - Provenance check failed: no build-provenance attestation is published.
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 19 days ago).
  - Publishes a security disclosure policy (SECURITY.md).
- **Schema Quality & AI Usability**: 85/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (good).
  - Tool/resource definitions use about 2592 tokens (~81/item across 32 items; 32 tools + 0 resources), lean.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 67/100
  - Stability observed for 20 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 87/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 56% of tool parameters carry a description.
  - Structured output schemas are declared (100% of tools); any adoption earns full credit.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - We read all 32 captured tool definition(s), and no name or description among them implies an irreversible operation.
  - An AI judge read all 32 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

**Unverified: 1 category.** A category scored 0 because we could not verify it: a data source with nothing on this package, evidence we could not reach, or a check we could not run. We only credit what we can confirm.

## Install

### How do I install the Redmine MCP Server server?

Redmine MCP Server runs locally as a container image, launched with docker run --rm -i -e REDMINE_URL -e REDMINE_API_KEY -e REDMINE_MCP_WRITE_ENABLED ghcr.io/igorolv/redmine-mcp-server:0.1.1. Ready-made configuration for Claude, Cursor, VS Code, Codex and 3 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add igorolv-redmine-mcp-server -- docker run --rm -i -e REDMINE_URL -e REDMINE_API_KEY -e REDMINE_MCP_WRITE_ENABLED ghcr.io/igorolv/redmine-mcp-server:0.1.1
```

This image reads REDMINE_URL, REDMINE_API_KEY and REDMINE_MCP_WRITE_ENABLED. Set them in your client's env block for this server; docker run -e passes each one through to the container.

### Cursor

```json
{
  "mcpServers": {
    "igorolv-redmine-mcp-server": {
      "command": "docker",
      "args": [
        "run",
        "--rm",
        "-i",
        "-e",
        "REDMINE_URL",
        "-e",
        "REDMINE_API_KEY",
        "-e",
        "REDMINE_MCP_WRITE_ENABLED",
        "ghcr.io/igorolv/redmine-mcp-server:0.1.1"
      ]
    }
  }
}
```

This image reads REDMINE_URL, REDMINE_API_KEY and REDMINE_MCP_WRITE_ENABLED. Set them in your client's env block for this server; docker run -e passes each one through to the container.

### VS Code

```json
{
  "servers": {
    "igorolv-redmine-mcp-server": {
      "command": "docker",
      "args": [
        "run",
        "--rm",
        "-i",
        "-e",
        "REDMINE_URL",
        "-e",
        "REDMINE_API_KEY",
        "-e",
        "REDMINE_MCP_WRITE_ENABLED",
        "ghcr.io/igorolv/redmine-mcp-server:0.1.1"
      ]
    }
  }
}
```

This image reads REDMINE_URL, REDMINE_API_KEY and REDMINE_MCP_WRITE_ENABLED. Set them in your client's env block for this server; docker run -e passes each one through to the container.

### Codex

```bash
codex mcp add igorolv-redmine-mcp-server -- docker run --rm -i -e REDMINE_URL -e REDMINE_API_KEY -e REDMINE_MCP_WRITE_ENABLED ghcr.io/igorolv/redmine-mcp-server:0.1.1
```

This image reads REDMINE_URL, REDMINE_API_KEY and REDMINE_MCP_WRITE_ENABLED. Set them in your client's env block for this server; docker run -e passes each one through to the container.

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "igorolv-redmine-mcp-server": {
      "type": "local",
      "command": [
        "docker",
        "run",
        "--rm",
        "-i",
        "-e",
        "REDMINE_URL",
        "-e",
        "REDMINE_API_KEY",
        "-e",
        "REDMINE_MCP_WRITE_ENABLED",
        "ghcr.io/igorolv/redmine-mcp-server:0.1.1"
      ],
      "enabled": true
    }
  }
}
```

This image reads REDMINE_URL, REDMINE_API_KEY and REDMINE_MCP_WRITE_ENABLED. Set them in your client's env block for this server; docker run -e passes each one through to the container.

### Hermes

```yaml
mcp_servers:
  igorolv-redmine-mcp-server:
    command: "docker"
    args: ["run", "--rm", "-i", "-e", "REDMINE_URL", "-e", "REDMINE_API_KEY", "-e", "REDMINE_MCP_WRITE_ENABLED", "ghcr.io/igorolv/redmine-mcp-server:0.1.1"]
```

This image reads REDMINE_URL, REDMINE_API_KEY and REDMINE_MCP_WRITE_ENABLED. Set them in your client's env block for this server; docker run -e passes each one through to the container.

### Netclaw

```json
{
  "McpServers": {
    "igorolv-redmine-mcp-server": {
      "Transport": "stdio",
      "Command": "docker",
      "Arguments": [
        "run",
        "--rm",
        "-i",
        "-e",
        "REDMINE_URL",
        "-e",
        "REDMINE_API_KEY",
        "-e",
        "REDMINE_MCP_WRITE_ENABLED",
        "ghcr.io/igorolv/redmine-mcp-server:0.1.1"
      ]
    }
  }
}
```

This image reads REDMINE_URL, REDMINE_API_KEY and REDMINE_MCP_WRITE_ENABLED. Set them in your client's env block for this server; docker run -e passes each one through to the container.

### Other

```json
{
  "mcpServers": {
    "igorolv-redmine-mcp-server": {
      "command": "docker",
      "args": [
        "run",
        "--rm",
        "-i",
        "-e",
        "REDMINE_URL",
        "-e",
        "REDMINE_API_KEY",
        "-e",
        "REDMINE_MCP_WRITE_ENABLED",
        "ghcr.io/igorolv/redmine-mcp-server:0.1.1"
      ]
    }
  }
}
```

This image reads REDMINE_URL, REDMINE_API_KEY and REDMINE_MCP_WRITE_ENABLED. Set them in your client's env block for this server; docker run -e passes each one through to the container.

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-10-17 (score 51, +41)

- [security improvement] Injection markers: unverified → pass
- [functional improvement] Stability: unverified → 0.63
- [functional improvement] Tool coverage: unverified → 100
- [functional improvement] MCP protocol: unverified → pass
- [functional improvement] Schema quality: unverified → 100

### 2026-10-09 (score 10, −32)

- [security regression] Tool safety: pass → unverified
- [security] Stability: Stability not yet verified: this server's registry entry declares environment variables (an API key or similar), and its server did not start in our sandbox, so we have no schema to compare.
- [functional regression] Tool coverage: 100 → unverified
- [functional regression] Capabilities: pass → unverified
- [functional regression] Schema quality: 100 → unverified

### 2026-09-28 (score 42)

First indexed and scored.

## MCP tools (32)

### `getAttachment` (~129 tokens)

Retrieve and inspect one known issue attachment by downloading it to the server's local snapshot and extracting text from supported documents or archives. Use getIssue to discover attachment IDs; images and unsupported binaries return metadata and a local path without extracted text. Text cut by the limits stays readable at each part's localPath.

Input parameters:

- `attachmentId` (integer, required)
- `issueId` (integer, required)
- `maxChars` (integer): Total character budget for extracted text across all parts
- `partLimit` (integer): Per-part character cap, mainly for ZIP entries; defaults to maxChars when maxChars is set

Output parameters:

- `attachment`
- `compressionNotes` (array|null): Human-readable notes describing how this response was compressed to fit the response size budget. Null/empty when no compression was applied.
- `extractionType` (string|null): Detected document kind used for extraction (`image`, `pdf`, `docx`, `xlsx`, `pptx`, `text`, `zip`, ...).
- `fileUri` (string|null): RFC 3986 `file://` URI pointing at the downloaded file.
- `limits`
- `localPath` (string|null): Absolute filesystem path of the downloaded file.
- `localSize` (integer): Size of the downloaded file on disk, in bytes (-1 if the size could not be determined).
- `note` (string|null): Free-text note explaining the result, typically present when text extraction was skipped.
- `parts` (array|null): Extracted parser output. Text parts carry content; images and unsupported binaries carry localPath/fileUri and an explanatory note.
- `textExtracted` (boolean): True when at least one part contains successfully extracted text.
- `truncated` (boolean): True when at least one part's text was cut to fit response size limits.

### `getBlockerChain` (~55 tokens)

Trace only blocks/blocked_by relations recursively in both directions, returning the full upstream and downstream blocking dependency chains. Use getIssueTree for parent/subtask hierarchy and other direct relation types.

Input parameters:

- `issueId` (integer, required)

Output parameters:

- `blockedBy` (array|null): Issues that block the root (recursively), each annotated with its depth from the root.
- `blocks` (array|null): Issues that depend on the root (recursively), each annotated with its depth from the root.
- `chainDepth` (integer): End-to-end depth of the chain (upstream + 1 + downstream).
- `root` (object|null): The issue the chain is centred on.
- `totalIssues` (integer): Total number of distinct issues in the chain (including the root).

### `getStaleIssues` (~79 tokens)

Identify neglected open issues in one project by last-update age, ordered most stale first. Use listIssues for general field or status filters; this tool is for inactivity triage.

Input parameters:

- `daysSinceUpdate` (integer): Minimum days since last update
- `limit` (integer)
- `projectId` (string, required): Project identifier or numeric ID

Output parameters:

- `daysSinceUpdate` (integer): Inactivity threshold in days that was applied.
- `issues` (array|null): Stale issues that crossed the threshold.
- `limit` (integer): Maximum number of results the search was capped at.
- `oldestDaysSinceUpdated` (integer): How many days the oldest returned issue has been untouched. 0 when the result set is empty.
- `projectId` (string|null): Project identifier the search was scoped to.

### `getIssueHistory` (~66 tokens)

Read an issue's chronological journal events and status intervals. Long text is shortened; use journalId with getIssueJournal for full text, and nextOffset to read any remaining events.

Input parameters:

- `issueId` (integer, required)
- `offset` (integer): Next page index from nextOffset

Output parameters:

- `compressionNotes` (array|null): What text was shortened and how to retrieve it in full.
- `nextOffset` (integer|null): Pass this as offset to getIssueHistory for the next page; absent when complete.
- `offset` (integer): Index of this page's first event.
- `sourceUpdatedOn` (string|null): Issue update timestamp; compare across pages to detect intervening edits.
- `statusDurations` (array|null): Status intervals beginning in this page's events.
- `timeline` (array|null): Chronological timeline of creation and update events.
- `totalEvents` (integer): Total creation and journal events available.

### `getIssueTree` (~66 tokens)

Explore one issue's parent chain and subtasks down to the requested depth. Root and ancestors are compact; use getIssue for full details or relations and getBlockerChain for blockers.

Input parameters:

- `depth` (integer): How deep to traverse children
- `issueId` (integer, required)

Output parameters:

- `ancestors` (array|null): Compact parent chain in order parent → grandparent → ... up to the root-most ancestor.
- `fetchedCount` (integer): Total issues fetched while building the tree (visibility into rate-limited traversal).
- `limitReached` (boolean): True when traversal stopped at the safety limit and additional branches/depths exist.
- `root`: Compact context for the target issue; call getIssue for full details and relations.
- `subtree` (object|null): The root issue plus its descendant subtree, expanded up to the requested depth.

### `getIssue` (~128 tokens)

Retrieve complete context for one known issue ID: core and custom fields, subtasks, direct relations, journals, attachments and linked changesets, with focus modes controlling compression. Use getIssueTree for recursive structure, getIssueJournal for a journal omitted or shortened by compression, or getAttachment for file content.

Input parameters:

- `focus` (string): Response focus: default, implementation (implementation-relevant text and all changeset revisions), timeline (who-did-what-and-when), changesets (issue identity fields and changesets only), or full (…
- `issueId` (integer, required)

Output parameters:

- `assignedTo`: User currently assigned to the issue; null when unassigned.
- `attachments` (array|null): Files attached to the issue.
- `author`: Author who created the issue.
- `category`: Issue category within the project.
- `changesets` (array|null): Linked VCS changesets/commits, when the Redmine repository integration exposes them.
- `compressionNotes` (array|null): Human-readable notes describing how this response was compressed to fit the response size budget. Null/empty when no compression was applied.
- `createdOn` (string|null): Creation timestamp in ISO-8601.
- `customFields` (array|null): Project-defined custom field values, in display form.
- `description` (string|null): Long-form description of the issue, may contain Textile or Markdown markup depending on the Redmine instance.
- `doneRatio` (integer): Completion percentage from 0 to 100.
- `dueDate` (string|null): Planned due date in ISO-8601 (yyyy-MM-dd).
- `estimatedHours` (number|null): Estimated effort in hours.
- `fixedVersion`: Target version / milestone this issue is planned for.
- `focusNotes` (array|null): Human-readable notes describing semantic focus shaping applied before response-size compression. Null/empty when no focus shaping was applied.
- `id` (integer): Issue identifier (the # shown in Redmine).
- `journals` (array|null): Chronological history entries — notes, status changes, field edits.
- `priority`: Priority (e.g. Normal, High, Urgent).
- `project`: Project the issue belongs to.
- `related` (array|null): Enriched references to related issues (parent, siblings, children, relations) — id + subject/tracker/status + roles. Populated when the issue is loaded with related-issue enrichment; null otherwise.…
- `spentHours` (number|null): Aggregated time already logged against the issue, in hours.
- `startDate` (string|null): Planned start date in ISO-8601 (yyyy-MM-dd).
- `status`: Current workflow status (e.g. New, In Progress, Closed).
- `subject` (string|null): Short title of the issue.
- `tracker`: Tracker type (Bug, Feature, Task, ...).
- `updatedOn` (string|null): Timestamp of the most recent change in ISO-8601.

### `getIssueJournal` (~65 tokens)

Retrieve one known issue journal entry in full, without response compression. Use a journal ID from getIssue or getIssueHistory when exact text is needed.

Input parameters:

- `issueId` (integer, required)
- `journalId` (integer, required): Journal entry ID from getIssue or getIssueHistory

Output parameters:

- `createdOn` (string|null): Timestamp the entry was recorded, ISO-8601.
- `details` (array|null): Field-level changes recorded in this entry. Raw form — use issue history endpoints for resolved values.
- `id` (integer)
- `notes` (string|null): Free-text note. Empty when the entry only carries field changes.
- `user`

### `getMyIssues` (~119 tokens)

Browse issues assigned to the currently authenticated API-key user without first resolving their user ID. Use getUserWorkload for aggregated workload metrics or listIssues for another assignee.

Input parameters:

- `limit` (integer)
- `offset` (integer)
- `projectId` (string): Project identifier or numeric ID
- `sort` (string): Sort field and direction, e.g. 'updated_on:desc'
- `statusId` (string): Status filter: open (default), closed, * (all), or a numeric status ID from listStatuses

Output parameters:

- `page`
- `user`

### `listIssues` (~234 tokens)

Browse issue summaries with structured Redmine filters, saved queries, custom-field filters, sorting and pagination. Use searchIssues when only free text is known, or getIssue for one known issue's complete context.

Input parameters:

- `assignedToUserId` (integer)
- `customFieldFilters` (string): Custom field filters in query-string form, e.g. 'cf_10=rtk&cf_3=502167'
- `limit` (integer)
- `offset` (integer)
- `priorityId` (integer): Priority ID; from listPriorities
- `projectId` (string): Project identifier or numeric ID
- `queryId` (integer): Saved query ID; from listQueries
- `sort` (string): Sort field and direction, e.g. 'updated_on:desc'
- `statusId` (string): Status filter: open (default), closed, * (all), or a numeric status ID from listStatuses
- `trackerId` (integer): Tracker ID (issue type); from listTrackers
- `versionId` (integer): Version/milestone ID; from listVersions

Output parameters:

- `issues` (array|null): Issues on this page.
- `limit` (integer): Maximum number of issues that may appear on this page.
- `offset` (integer): Zero-based offset of the first issue on this page.
- `totalCount` (integer): Total number of issues matching the query across all pages.

### `searchIssues` (~79 tokens)

Find issue summaries by full-text query, optionally within one project. Use listIssues for exact field, saved-query or custom-field filtering, then getIssue to inspect a selected result.

Input parameters:

- `limit` (integer)
- `offset` (integer)
- `projectId` (string): Project identifier or numeric ID
- `searchQuery` (string, required)

Output parameters:

- `issues` (array|null): Issues on this page.
- `limit` (integer): Maximum number of issues that may appear on this page.
- `offset` (integer): Zero-based offset of the first issue on this page.
- `totalCount` (integer): Total number of issues matching the query across all pages.

### `getProject` (~57 tokens)

Inspect one known project's configuration and metadata, including description, trackers and enabled modules. Use getProjectSummary for aggregated issue metrics, listProjectMembers for people or listVersions for milestones.

Input parameters:

- `projectId` (string, required): Project identifier or numeric ID

Output parameters:

- `description` (string|null): Project description (Textile/Markdown markup).
- `enabledModules` (array|null): Names of enabled Redmine modules (e.g. issue_tracking, wiki, repository).
- `homepage` (string|null): Optional homepage URL configured for the project.
- `id` (integer)
- `identifier` (string|null): URL-safe project slug. Either this or the numeric id can be used as projectId for other tools.
- `isPublic` (boolean): True when the project is visible to anonymous users.
- `name` (string|null): Display name shown in the UI.
- `parent`: Parent project reference, null for top-level projects.
- `trackers` (array|null): Trackers enabled for this project (Bug, Feature, ...).

### `listProjectMembers` (~74 tokens)

Discover the users and groups that belong to one project, their IDs and assigned roles. Use when choosing or interpreting assignees; getUserWorkload analyzes a user's issues rather than membership.

Input parameters:

- `limit` (integer)
- `offset` (integer)
- `projectId` (string, required): Project identifier or numeric ID

Output parameters:

- `limit` (integer): Maximum number of memberships that may appear on this page.
- `members` (array|null): Memberships on this page.
- `offset` (integer): Zero-based offset of the first membership on this page.
- `totalCount` (integer): Total number of memberships across all pages.

### `listProjects` (~55 tokens)

Discover accessible Redmine projects and their valid identifiers before project-scoped operations when the target project is unknown. Returns project summaries; use getProject for one project's details.

Input parameters:

- `limit` (integer)
- `offset` (integer)

Output parameters:

- `limit` (integer): Maximum number of projects that may appear on this page.
- `offset` (integer): Zero-based offset of the first project on this page.
- `projects` (array|null): Projects on this page.
- `totalCount` (integer): Total number of projects across all pages.

### `listVersions` (~63 tokens)

Discover versions/milestones of one project and the IDs used by issue filters and release analytics. Returns milestone metadata, not issue scope or risk; use getVersionChangelog or getReleaseRisks for those.

Input parameters:

- `projectId` (string, required): Project identifier or numeric ID

Output parameters:

- `versions` (array|null): Project versions.

### `listIssueCategories` (~48 tokens)

Discover issue category IDs and names configured for one known project. Reuse the IDs as categoryId in createIssue or updateIssue.

Input parameters:

- `projectId` (string, required): Project identifier or numeric ID

Output parameters:

- `items` (array|null): Entity references.

### `listPriorities` (~41 tokens)

Discover valid issue priority IDs and names before filtering, creating or updating issues. Reuse the IDs as priorityId in listIssues, createIssue or updateIssue.

Output parameters:

- `items` (array|null): Entity references.

### `listQueries` (~57 tokens)

Discover saved Redmine issue queries (stored filters), especially filters involving custom fields. Returns query IDs and names rather than issue results; pass a selected queryId to listIssues.

Input parameters:

- `limit` (integer)
- `offset` (integer)

Output parameters:

- `limit` (integer): Maximum number of queries that may appear on this page.
- `offset` (integer): Zero-based offset of the first query on this page.
- `queries` (array|null): Queries on this page.
- `totalCount` (integer): Total number of queries across all pages.

### `listStatuses` (~41 tokens)

Discover valid Redmine issue status IDs and names for structured issue filtering or mutation. Reuse the IDs as statusId in listIssues, createIssue or updateIssue.

Output parameters:

- `items` (array|null): Entity references.

### `listTimeEntryActivities` (~46 tokens)

Discover valid time-entry activity IDs and names for interpreting logged hours or creating a time entry. Reuse an ID as activityId in createTimeEntry when the default activity is unsuitable.

Output parameters:

- `items` (array|null): Entity references.

### `listTrackers` (~44 tokens)

Discover valid tracker (issue type) IDs and names before filtering, creating or updating issues. Reuse the IDs as trackerId in listIssues, createIssue or updateIssue.

Output parameters:

- `items` (array|null): Entity references.

### `compareVersions` (~95 tokens)

Compare the issue scope and completion of two known versions/milestones in one project. Returns issues unique to each, shared issues and closure percentages; use listVersions to discover IDs.

Input parameters:

- `projectId` (string, required): Project identifier or numeric ID
- `versionId1` (integer, required): First version/milestone ID; from listVersions
- `versionId2` (integer, required): Second version/milestone ID; from listVersions

Output parameters:

- `first`: Scope statistics for the first version.
- `inBoth` (array|null): Issues present in both versions.
- `onlyInFirst` (array|null): Issues present only in the first version.
- `onlyInSecond` (array|null): Issues present only in the second version.
- `projectId` (string|null): Project identifier the versions belong to.
- `second`: Scope statistics for the second version.

### `getProjectSummary` (~96 tokens)

Summarize one project's issue health, optionally scoped to a milestone: complete open/closed totals plus status, tracker, priority and assignee distributions, overdue work and estimated versus spent hours for the analyzed open-issue set. Use listIssues when issue records are needed instead of aggregates.

Input parameters:

- `projectId` (string, required): Project identifier or numeric ID
- `versionId` (integer): Version/milestone ID; from listVersions

Output parameters:

- `analyzedOpenIssues` (integer): Number of open issues actually analyzed for the distributions below.
- `byAssignee` (array|null): Per-assignee workload — total and overdue counts.
- `byPriority`: Open-issue counts grouped by priority name.
- `byStatus`: Open-issue counts grouped by status name.
- `byTracker`: Open-issue counts grouped by tracker name.
- `counts`
- `hours`
- `overdue` (integer): Number of open issues whose due date is in the past.
- `projectId` (string|null): Project identifier the summary was computed for.
- `truncated` (boolean): True when the analyzed open issue set is a truncated slice of the full open set (analysis cap reached).
- `versionId` (integer|null): Version/milestone the summary was scoped to, null when unscoped.

### `getReleaseRisks` (~88 tokens)

Assess readiness risks for one known version/milestone: open blockers, overdue work, high-priority unresolved issues and unassigned tasks, with a risk score. Use getVersionChangelog for the milestone issue breakdown rather than risk triage.

Input parameters:

- `projectId` (string, required): Project identifier or numeric ID
- `versionId` (integer, required): Version/milestone ID; from listVersions

Output parameters:

- `analyzedIssues` (integer): Number of issues actually analyzed for risks.
- `categories` (array|null): Risk categories that contain at least one issue.
- `highPriorityNames` (array|null): Priority names treated as 'high' by the heuristic (top third of the priority ladder, or just the highest one).
- `projectId` (string|null): Project identifier the version belongs to.
- `score` (object|null): Aggregate risk score.
- `totalOpenIssues` (integer): Total open issues for the version across all pages.
- `truncated` (boolean): True when the analyzed set is a truncated slice of the full open set.
- `version`
- `versionId` (integer): Version/milestone identifier.

### `getUserWorkload` (~89 tokens)

Analyze one user's open-issue workload by project and priority, including overdue count, estimated versus spent hours and top issues; omitting userId selects the API-key user. This returns aggregates, not issue records; use getMyIssues for the current user or listIssues for a specified user.

Input parameters:

- `projectId` (string): Project identifier or numeric ID
- `userId` (integer)

Output parameters:

- `analyzedIssues` (integer): Number of issues actually analyzed (may be smaller than totalOpenIssues when analysis was truncated).
- `byProject` (array|null): Per-project breakdown of the user's workload.
- `hours`
- `overdue` (integer): Number of analyzed issues whose due date is in the past.
- `projectId` (string|null): Project the workload was scoped to, null when scope is all projects.
- `topIssues` (array|null): Up to 10 most important open issues for the user, sorted by priority then by due date.
- `totalOpenIssues` (integer): Total number of open issues assigned to the user across all pages.
- `truncated` (boolean): True when the analyzed set is a truncated slice of the full open set.
- `userId` (integer): User identifier the analysis is for.
- `userName` (string|null): Display name of the user. May be a placeholder like 'User #42' when only an id was provided.

### `getVersionChangelog` (~81 tokens)

Summarize the issue scope of one known version/milestone as open and closed counts with issues grouped by tracker. Use getReleaseRisks for readiness risks or listVersions to discover the version ID.

Input parameters:

- `projectId` (string, required): Project identifier or numeric ID
- `versionId` (integer, required): Version/milestone ID; from listVersions

Output parameters:

- `analyzedIssues` (integer): Number of issues actually analyzed for this changelog.
- `byTracker` (object|null): Issues grouped by tracker name (Bug, Feature, ...).
- `counts`
- `hours`
- `projectId` (string|null): Project identifier the version belongs to.
- `totalIssues` (integer): Total number of issues tied to this version across all pages.
- `truncated` (boolean): True when the analyzed set is a truncated slice of the full issue set.
- `version`
- `versionId` (integer): Version/milestone identifier.

### `searchAll` (~117 tokens)

Search by free text across mixed Redmine content such as issues, wiki pages, news, documents, changesets, messages and projects. Use searchIssues for richer issue-only results or searchWikiPages for wiki-only discovery.

Input parameters:

- `limit` (integer)
- `offset` (integer)
- `projectId` (string): Project identifier or numeric ID
- `searchQuery` (string, required)
- `types` (string): Comma-separated content types to include: issues, wiki_pages, news, documents, changesets, messages, projects

Output parameters:

- `limit` (integer): Maximum number of hits that may appear on this page.
- `offset` (integer): Zero-based offset of the first hit on this page.
- `results` (array|null): Hits on this page.
- `totalCount` (integer): Total number of hits across all pages.

### `getMyTimeEntries` (~97 tokens)

Browse actual time-entry records logged by the currently authenticated API-key user without first resolving their user ID. Use listTimeEntries for another user or broader administrative filtering.

Input parameters:

- `from` (string): YYYY-MM-DD
- `issueId` (integer)
- `limit` (integer)
- `offset` (integer)
- `projectId` (string): Project identifier or numeric ID
- `to` (string): YYYY-MM-DD

Output parameters:

- `page`
- `user`

### `listTimeEntries` (~114 tokens)

Browse actual Redmine time-entry records using project, issue, user and date-range filters. Use getMyTimeEntries for the API-key user without looking up an ID; getUserWorkload returns aggregates instead.

Input parameters:

- `from` (string): YYYY-MM-DD
- `issueId` (integer)
- `limit` (integer)
- `offset` (integer)
- `projectId` (string): Project identifier or numeric ID
- `to` (string): YYYY-MM-DD
- `userId` (integer)

Output parameters:

- `limit` (integer): Maximum number of entries that may appear on this page.
- `offset` (integer): Zero-based offset of the first entry on this page.
- `timeEntries` (array|null): Time entries on this page.
- `totalCount` (integer): Total number of time entries across all pages.

### `getCurrentUser` (~52 tokens)

Retrieve the identity and user ID of the currently authenticated API-key user. Use the ID in assignee/user filters; getMyIssues, getMyTimeEntries and the default getUserWorkload do not require it.

Output parameters:

- `id` (integer)
- `login` (string|null): Login name.
- `mail` (string|null): Email address, may be absent if not visible to the API caller.
- `name` (string|null): Display name (firstname + lastname).

### `getWikiPage` (~80 tokens)

Read the complete markup content and current version of one known project wiki page. Use listWikiPages or searchWikiPages to discover its title; the returned version is required by updateWikiPage.

Input parameters:

- `pageTitle` (string, required): Wiki page title (use 'Wiki' for the start page)
- `projectId` (string, required): Project identifier or numeric ID

Output parameters:

- `attachments` (array|null): Files attached to the page. Empty in index listings.
- `author`: Author of the most recent revision.
- `comments` (string|null): Comment attached to the most recent revision.
- `createdOn` (string|null): When the page was first created, ISO-8601.
- `text` (string|null): Page body in Textile or Markdown markup depending on the Redmine instance. Null in index listings.
- `title` (string|null): Page title (URL-escaped form used as the path).
- `updatedOn` (string|null): When the page was last edited, ISO-8601.
- `version` (integer|null): Monotonic revision number of the page. Null for a content-less page in index listings.

### `listWikiPages` (~56 tokens)

Discover wiki page titles in one known project without loading every page body. Use getWikiPage to read a selected title or searchWikiPages when only content terms are known.

Input parameters:

- `projectId` (string, required): Project identifier or numeric ID

Output parameters:

- `pages` (array|null): Wiki pages.

### `searchWikiPages` (~81 tokens)

Find project wiki pages by full-text content query, optionally across all accessible projects. Use getWikiPage to read a selected result or searchAll when non-wiki content should also match.

Input parameters:

- `limit` (integer)
- `offset` (integer)
- `projectId` (string): Project identifier or numeric ID
- `searchQuery` (string, required)

Output parameters:

- `limit` (integer): Maximum number of hits that may appear on this page.
- `offset` (integer): Zero-based offset of the first hit on this page.
- `results` (array|null): Hits on this page.
- `totalCount` (integer): Total number of hits across all pages.

## Diagnostics

Captured diagnostic sections: Provenance. The full working is on the page: https://verifymcp.io/servers/igorolv-redmine-mcp-server/ghcr-io-igorolv-redmine-mcp-server#diagnostics

## Score history

- 2026-10-18: 51
- 2026-10-17: 51
- 2026-10-16: 10
- 2026-10-15: 10
- 2026-10-14: 10
- 2026-10-13: 10
- 2026-10-12: 10
- 2026-10-10: 10
- 2026-10-09: 10
- 2026-10-07: 42
- 2026-10-05: 42
- 2026-10-04: 42
- 2026-10-03: 42
- 2026-10-02: 42
- 2026-10-01: 42
- 2026-09-30: 42
- 2026-09-29: 42
- 2026-09-28: 42

## Common questions

### What is the Redmine MCP Server server?

Redmine MCP Server is listed in the public MCP registry as io.github.igorolv/redmine-mcp-server. Redmine for AI agents: issues, projects, wiki, attachments, time entries and release analytics. This page covers its container image (ghcr.io/igorolv/redmine-mcp-server).

### Is the Redmine MCP Server server safe to use?

Redmine MCP Server scores 51 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the Redmine MCP Server server expose?

Redmine MCP Server exposes 32 tools: getAttachment, getBlockerChain, getStaleIssues, getIssueHistory, getIssueTree, and 27 more. Their descriptions and schemas cost roughly 2,592 tokens of context every time the server is loaded.

### Is the Redmine MCP Server server still maintained?

Redmine MCP Server is still listed as active in the MCP registry. We last reached this channel on 18 October 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

### What licence is the Redmine MCP Server server under?

Redmine MCP Server declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

## Links

- GitHub Container Registry: https://ghcr.io/igorolv/redmine-mcp-server
- Repository: https://github.com/igorolv/redmine-mcp-server
- Changelog RSS feed: https://verifymcp.io/servers/igorolv-redmine-mcp-server/ghcr-io-igorolv-redmine-mcp-server.xml
- Changelog JSON feed: https://verifymcp.io/servers/igorolv-redmine-mcp-server/ghcr-io-igorolv-redmine-mcp-server.json
- HTML version of this page: https://verifymcp.io/servers/igorolv-redmine-mcp-server/ghcr-io-igorolv-redmine-mcp-server
