mcp-redmine
A Model Context Protocol server that connectsClaude (Desktop or Code) — or any other MCP client — to a Redmineinstance through its REST API.
It exposes 73 tools covering, in practice, the entire stable Redmine REST API:issues, relations, projects, memberships, versions, categories, users, groups,roles, wiki, time tracking, attachments, project files, news, and search. Pointyour agent at a Redmine project and let it read and manage issues, log time,edit wiki pages, and administer users — all through natural conversation.
Features
- Full read/write coverage of issues, including bulk updates, relations,watchers, and comments.
- Project administration: create/update/archive projects, manage members,versions, and categories.
- User and group administration, with deliberately no "delete user" or"delete project" tool — see Security.
- Wiki, including nested pages and file attachments.
- Time tracking, attachments, project files, news, and full-text search.
- Readable errors: every failure comes back as a clear sentence pulledfrom Redmine's own validation response, not a raw stack trace.
- Nothing to run: a single Python process talking stdio to your MCPclient — no database, no server to host, no Docker required.
Prerequisites
- Python 3.10+
- A Redmine instance with the REST API enabled:
- In Redmine, go to Administration → Settings → API and enable"Enable REST web service" (if not already on).
- Go to My account → API access key and copy the value.
Installation
The distribution is published as mcp-redmine-rest, and the command itinstalls is mcp-redmine-rest. The shorter mcp-redmine name on PyPI belongsto an unrelated project — don'tinstall that one expecting this server.
If you're pointing an AI agent at this repository to do the setup for you,llms-install.md is written for exactly that.
With uv (recommended)
uv tool install mcp-redmine-rest
With pip
pip install mcp-redmine-rest
From source
git clone https://github.com/alsimoes/mcp-redmine-rest.git
cd mcp-redmine-rest
python3 -m venv venv && source venv/bin/activate # Linux/Mac
pip install -e .
On Windows, use py and PowerShell rather than a Git Bash/WSL shell — creatingor recreating the venv from a Unix-style shell on Windows overwritesvenv\pyvenv.cfg with a Unix home path, and every subsequent launch ofvenv\Scripts\python.exe fails with No Python at '/usr/bin\python.exe' (orsimilar):
git clone https://github.com/alsimoes/mcp-redmine-rest.git
cd mcp-redmine-rest
py -3 -m venv venv
.\venv\Scripts\Activate.ps1
pip install -e .
Configuration
The server reads its configuration from environment variables:
| Variable | Required | Description |
|---|---|---|
REDMINE_URL |
Yes | Base URL of your Redmine instance (no trailing slash). |
REDMINE_API_KEY |
Yes | Your API access key, from My account → API access key. |
REDMINE_TIMEOUT |
No | Per-request timeout in seconds. Defaults to 15. |
REDMINE_UPLOAD_ROOTS |
No | Directories the file-upload tools may read from, separated by os.pathsep (; on Windows, : on Linux/macOS). Unset = uploads disabled. See Security. |
Keeping the key out of the client configuration
Values missing from the environment are read from a .env file, so the APIkey does not have to sit in plain text in your MCP client's configuration.Copy .env.example to .env in the repository root and fill it in — everyvariable in the table above is honoured, so the client's env block can bedropped entirely:
REDMINE_URL=https://redmine.example.com
REDMINE_API_KEY=your_api_key_here
REDMINE_TIMEOUT=15
The file is gitignored. Variables already present in the environment alwayswin, so an env block in your client's configuration still overrides it. Tokeep the file somewhere else, set REDMINE_ENV_FILE to its full path.
This matters on Claude Desktop in particular: it launches MCP servers with aminimal environment it builds itself, so variables you export in your shellor set with setx never reach the server. Use the env block or a .envfile.
Claude Desktop
Edit (or create) the Claude Desktop configuration file:
- Mac:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json - Linux:
~/.config/Claude/claude_desktop_config.json
{
"mcpServers": {
"redmine": {
"command": "mcp-redmine-rest",
"env": {
"REDMINE_URL": "https://redmine.example.com",
"REDMINE_API_KEY": "your_api_key_here"
}
}
}
}
If you installed from source instead of via uv tool install / pip install, point command at the interpreter in your virtual environment andpass the script as an argument:
{
"mcpServers": {
"redmine": {
"command": "/full/path/to/mcp-redmine/venv/bin/python",
"args": ["-m", "mcp_redmine"],
"env": {
"REDMINE_URL": "https://redmine.example.com",
"REDMINE_API_KEY": "your_api_key_here"
}
}
}
}
On Windows, point command at venv\Scripts\python.exe (with \\ escapedin JSON):
{
"mcpServers": {
"redmine": {
"command": "C:\\full\\path\\to\\mcp-redmine\\venv\\Scripts\\python.exe",
"args": ["-m", "mcp_redmine"],
"env": {
"REDMINE_URL": "https://redmine.example.com",
"REDMINE_API_KEY": "your_api_key_here"
}
}
}
}
Restart Claude Desktop afterwards. The tools icon (🔨) should show theRedmine tools as available.
Claude Code
claude mcp add redmine \
--env REDMINE_URL=https://redmine.example.com \
--env REDMINE_API_KEY=your_api_key_here \
-- mcp-redmine-rest
Confirm with:
claude mcp list
Cline (VS Code)
Open the MCP settings from the palette — Ctrl+Shift+P → Cline: Open MCPConfig File — or click the gear next to "MCP Servers" in the Cline sidebarand choose Configure MCP Servers. Either one openscline_mcp_settings.json; add the server there:
{
"mcpServers": {
"redmine": {
"command": "mcp-redmine-rest",
"env": {
"REDMINE_URL": "https://redmine.example.com",
"REDMINE_API_KEY": "your_api_key_here"
}
}
}
}
Use the palette command rather than editing the file by hand — it lives deepin VS Code's global storage(.../User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json),and the path differs per platform.
If mcp-redmine-rest is not on the PATH that VS Code sees, use the moduleform instead — "command" pointing at the interpreter that has the packageinstalled, with "args": ["-m", "mcp_redmine"], exactly like the ClaudeDesktop examples above.
Reload the window (Ctrl+Shift+P → Developer: Reload Window) and the servershould come up as connected under "MCP Servers". A longer walkthrough,covering the workspace .mcp.json and the Add-Server UI, is inCLINE_SETUP.md.
Other MCP clients
Any client that can launch a local process and speak MCP over stdio works thesame way: run mcp-redmine-rest (or python -m mcp_redmine) withREDMINE_URL and REDMINE_API_KEY set in its environment.
Run locally (optional)
Useful for a quick sanity check before wiring the server into a client:
cp .env.example .env # then edit .env with your values
export $(grep -v '^#' .env | xargs) # or use a tool like direnv
mcp-redmine-rest
If there's no connection error, the server is ready — it waits for MCPmessages on stdin/stdout, so seeing nothing happen in the terminal is normal.Press Ctrl+C to stop it.
Usage examples
Once configured, just talk to the agent:
- "List the open issues assigned to me in the Website project."
- "Create a bug in Website titled 'Login button unresponsive on mobile',priority high."
- "Move issues #101, #104, and #110 to In Progress and assign them to Alice."
- "Log 3.5 hours on issue #204 for today, activity Development."
- "What's on the wiki page 'Deployment' for the Infra project?"
- "Search for 'timeout' across all projects."
Available tools
73 tools, grouped by resource. The full reference — signatures, parameters,return shape, and the caveats that matter (like how precedes reschedulesissues, or that list_custom_fields requires an administrator) — lives indocs/TOOLS.md.
| Resource | Tools |
|---|---|
| Issues | list_issues, get_issue, create_issue, update_issue, bulk_update_issues, delete_issue, add_watcher, remove_watcher, update_journal_note |
| Issue relations | list_issue_relations, create_issue_relation, delete_issue_relation, chain_issues |
| Projects | list_projects, get_project, create_project, update_project, archive_project |
| Project members | list_project_members, add_project_member, update_project_member, remove_project_member |
| Versions | list_project_versions, create_project_version, update_version, delete_version |
| Categories | list_project_categories, create_project_category, update_project_category, delete_project_category |
| Users | get_current_user, list_users, get_user, create_user, update_user, update_my_account |
| Groups | list_groups, get_group, create_group, update_group, delete_group, add_user_to_group, remove_user_from_group |
| Roles | list_roles, get_role |
| Wiki | list_wiki_pages, get_wiki_page, create_or_update_wiki_page, attach_file_to_wiki_page, delete_wiki_page |
| Time tracking | list_time_entries, get_time_entry, log_time, update_time_entry, delete_time_entry, list_time_entry_activities |
| Attachments | attach_file_to_issue, get_attachment, update_attachment, delete_attachment |
| Project files | list_project_files, upload_project_file |
| News | list_news, get_news_item, create_news, update_news, delete_news |
| Search | search, list_saved_queries |
| Metadata | list_statuses_and_priorities, list_trackers, list_custom_fields, list_document_categories |
API coverage
| Redmine API resource | Status |
|---|---|
| Issues | Complete (list, read, create, update, bulk, delete, watchers) |
| Issue relations | Complete |
| Projects | Complete minus deletion |
| Project members | Complete |
| Versions | Complete |
| Issue categories | Complete |
| Users | Complete minus deletion |
| Groups | Complete |
| Roles | Complete (the API is read-only) |
| Wiki | Complete, including nesting and attachments |
| Attachments | Complete |
| Project files | Complete |
| News | Complete |
| Time tracking | Complete |
| Search and saved queries | Complete |
| Trackers, statuses, priorities, activities, custom fields | Complete (the API is read-only) |
| Document categories | Complete (the API is read-only) |
The two omissions are deliberate. delete_project and delete_user areirreversible and take other people's content down with them — issues, timeentries, wiki pages, authorship. archive_project and update_user withstatus=3 cover the real use case reversibly. Deleting for real remains a webUI operation, where confirmation is explicit and human. SeeSECURITY.md for the full reasoning.
Trackers, issue statuses, priorities, and roles have no write operations inthe Redmine API — they're configurable only in Administration. That's not agap in this server.
Outside the stable REST API, and therefore outside this server's scope:repositories and changesets, wiki page protection, and instance-wide settingsscreens.
Error messages
Errors are handled centrally: when Redmine rejects a call, the server readsthe response body — that's where the real explanation lives, in the errorsfield — and returns that sentence. Without a useful body, it falls back tothe HTTP status with a likely reason:
| Status | Message |
|---|---|
| 401 | invalid or missing API key |
| 403 | not allowed to perform this operation, or the module is disabled for this project |
| 404 | not found (check the ID, or this endpoint may not exist in this Redmine version) |
| 409 | conflict — the resource was changed by someone else |
| 422 | Redmine rejected the data during validation |
This applies to every tool, read and write alike.
Troubleshooting
- "REDMINE_URL and REDMINE_API_KEY must be set": the server checks itsconfiguration at startup and exits immediately with this message ratherthan starting up broken. Check the
envblock in your MCP client'sconfiguration. - Every call fails with a network error: confirm the server process canactually reach
REDMINE_URL— MCP clients run the server as a localprocess, so it needs the same network access as your machine, not thebrowser. - 401 on every call: the API key is wrong, or "Enable REST web service"is off in Redmine's settings.
- 403 on a specific tool: usually a missing permission on the role of theuser who owns the API key.
get_roleshows exactly which permissions arole has. - A tool responds 404 that you'd expect to work: a few endpoints(
update_journal_note,update_news/delete_news,update_attachment) were added in specific Redmine versions — seedocs/TOOLS.md for the minimum version of each.
Security
See SECURITY.md for the full model. In short: an API keygrants access equivalent to the user who owns it, so create a dedicatedRedmine user with a role scoped to what you want the agent to do, and usethat user's key — don't try to limit the agent by editing this server's code.
File uploads are disabled until you set REDMINE_UPLOAD_ROOTS. Thethree tools that upload a local file (attach_file_to_issue,attach_file_to_wiki_page, upload_project_file) refuse every path bydefault, precisely because an agent can be steered by injected content(an issue comment, a wiki page) into uploading a file it was never meant toread. See SECURITY.md.
Contributing
See CONTRIBUTING.md.
License
MIT