A Model Context Protocol (MCP) server that provides AI assistants with access to Redmine project management software via its REST API.
- Full Redmine API Access: Interact with projects, issues, users, time entries, and more
- MCP Protocol: Standard protocol for AI-to-tool communication
- Standalone Server: Independent deployment, connects to any Redmine instance
- Secure: API key-based authentication with Redmine
- Flexible: Configurable via environment variables
- Ruby 3.1 or higher
- Access to a Redmine instance (5.0+) with REST API enabled
- Redmine API key (obtain from /my/account page in Redmine)
Some MCP tools require the Redmine Extended API plugin for advanced functionality:
- Custom Fields CRUD:
create_custom_field,update_custom_field,delete_custom_field - Queries CRUD:
create_query,update_query,delete_query - Bulk Time Entries:
bulk_create_time_entries
Installation:
cd /path/to/redmine/plugins
git clone https://github.com/zh/redmine_extended_api.git
cd /path/to/redmine
bundle install
bundle exec rake redmine:plugins:migrate RAILS_ENV=production
systemctl restart redmineSee redmine_extended_api for details.
Note: All other MCP tools work with standard Redmine REST API (no plugins required).
-
Clone or download this repository
-
Install dependencies:
bundle install
-
Copy the example environment file and configure:
cp .env.example .env
-
Edit
.envand set your Redmine credentials:REDMINE_URL=https://your-redmine-instance.com REDMINE_API_KEY=your_api_key_here
All configuration is done via environment variables in the .env file:
| Variable | Description | Default | Required |
|---|---|---|---|
REDMINE_URL |
Base URL of your Redmine instance | - | Yes |
REDMINE_API_KEY |
Your Redmine API key | - | Yes |
| Variable | Description | Default | Required |
|---|---|---|---|
MCP_PORT |
Port for the MCP server | 3100 | No |
MCP_HOST |
Host to bind to | localhost | No |
RACK_ENV |
Environment (development/production) | development | No |
LOG_LEVEL |
Logging level (debug/info/warn/error) | info | No |
| Variable | Description | Default | Required |
|---|---|---|---|
HTTP_TIMEOUT |
HTTP request timeout in seconds | 30 | No |
HTTP_READ_TIMEOUT |
HTTP read timeout in seconds | 60 | No |
FALCON_PROCESSES |
Number of server worker processes | 1 | No |
METRICS_SLOW_THRESHOLD |
Slow request threshold in seconds | 1.0 | No |
Note: Connection pooling and compression (gzip/deflate) are handled automatically by the async HTTP client.
- Log into your Redmine instance
- Navigate to "My Account" (/my/account)
- Look for "API access key" on the right sidebar
- Click "Show" to reveal your key, or "Reset" to generate a new one
- Copy the key to your
.envfile
The server uses Falcon, a high-performance async web server.
Development mode (with auto-reload):
bundle exec rerun -- falcon serve --bind http://localhost:3100Production mode:
bundle exec falcon serve --bind http://localhost:3100The server will start with multiple worker processes (8 by default) for optimal performance. You can control the number of workers by setting FALCON_PROCESSES in your .env file.
Add the server to your MCP client configuration (e.g., Claude Desktop):
{
"mcpServers": {
"redmine": {
"command": "bundle",
"args": ["exec", "falcon", "serve", "--bind", "http://localhost:3100"],
"cwd": "/path/to/redmine_mcp_server"
}
}
}Or connect to the running server:
{
"mcpServers": {
"redmine": {
"url": "http://localhost:3100/mcp"
}
}
}- 53 Fully Implemented Tools (Projects, Memberships, Versions, Issues, Users, Groups, Time Entries, Custom Fields, Queries, Batch Operations)
- 21 Skeleton Tools (structure defined, ready for implementation)
- 74 Total Tools across 14 resource categories
list_projects- List all accessible projects with pagination and filteringget_project- Get detailed information about a specific projectcreate_project- Create a new projectupdate_project- Update an existing projectdelete_project- Delete a project
list_memberships- List all members of a projectget_membership- Get details of a specific membershipcreate_membership- Add a user/group to a project with rolesupdate_membership- Update roles for a project memberdelete_membership- Remove a user/group from a project
list_versions- List versions/milestones for a projectget_version- Get details of a specific versioncreate_version- Create a new version/milestoneupdate_version- Update an existing versiondelete_version- Delete a version
list_issues- List issues with filtering, sorting, and pagination (supports query_id for saved queries)get_issue- Get detailed information about a specific issuecreate_issue- Create a new issue in a projectupdate_issue- Update an existing issuedelete_issue- Delete an issueadd_issue_watcher- Add a watcher to an issueremove_issue_watcher- Remove a watcher from an issueget_issue_relations- Get all relations for an issue (blocks, relates to, etc.)create_issue_relation- Create a relation between two issuesdelete_issue_relation- Delete an issue relationget_issue_journals- Get the change history (journals) for an issuecopy_issue- Copy an issue to another project or within the same projectmove_issue- Move an issue to a different project
list_users- List all users with filtering and paginationget_user- Get detailed information about a specific usercreate_user- Create a new user account (requires admin)update_user- Update an existing user accountdelete_user- Delete a user account
list_groups- List all groups (requires admin)get_group- Get details of a specific group including memberscreate_group- Create a new group with optional initial membersupdate_group- Update group details and membershipdelete_group- Delete a group
list_time_entries- List time entries with filtering by user, project, issue, or date rangeget_time_entry- Get detailed information about a specific time entrycreate_time_entry- Log time on an issue or projectupdate_time_entry- Update an existing time entrydelete_time_entry- Delete a time entrybulk_create_time_entries- Create multiple time entries in a single request (requires Extended API plugin)
list_custom_fields- List all custom fields with their configurationcreate_custom_field- Create a new custom field (requires admin, Extended API plugin)update_custom_field- Update an existing custom field (requires admin, Extended API plugin)delete_custom_field- Delete a custom field (requires admin, Extended API plugin)
Note: Custom field values can be set in issues, projects, users, and other entities using the custom_field_values or custom_fields parameter in their respective create/update tools.
list_queries- List all accessible queries (saved filters) with paginationcreate_query- Create a new query with filters, visibility, and columns (requires Extended API plugin)update_query- Update an existing query (requires Extended API plugin)delete_query- Delete a query (requires Extended API plugin)
Query Features:
- Saved Filters: Queries are saved filters for issues, time entries, projects, etc.
- Filter Operators: Supports all Redmine operators (
=,!=,>=,<=,~,!~,o(open),c(closed),t(today),w(week),m(month),<t+N,>t-N) - Visibility Levels: Private (0), Roles (1), Public (2)
- Query Types: IssueQuery, ProjectQuery, TimeEntryQuery
- Execution: Use
list_issueswithquery_idparameter to execute saved queries - Permissions: Users manage own private queries;
manage_public_queriesfor project queries; admin for global queries
Example - Create and execute a query:
// 1. Create a query for late issues
{
"name": "create_query",
"params": {
"name": "Late Issues Before May",
"type": "IssueQuery",
"visibility": 0,
"filters": {
"due_date": {"operator": "<=", "values": ["2025-05-01"]},
"status_id": {"operator": "o"}
},
"column_names": ["id", "subject", "status", "due_date"],
"sort_criteria": [["due_date", "asc"]]
}
}
// Returns: {"id": 10, "name": "Late Issues Before May", ...}
// 2. Execute the saved query
{
"name": "list_issues",
"params": {
"query_id": 10
}
}
// Returns filtered and sorted issues based on the saved querybatch_execute- Execute multiple MCP tools concurrently for improved performance
All skeleton tools are defined with complete schemas but raise NotImplementedError:
- Wiki Pages (6 tools): list, get, create, update, delete, versions
- Attachments (3 tools): upload, get, delete
- News (2 tools): list, get
- Reference Data (7 tools): trackers, statuses, priorities, activities, roles, search
See TOOLS.md for complete tool documentation.
The MCP server includes built-in performance optimizations and monitoring capabilities.
- Automatic Connection Pooling: Async HTTP client manages connections automatically
- HTTP Keep-Alive: Efficient connection reuse with automatic management
- Response Compression: Automatic gzip/deflate compression (70-80% bandwidth reduction)
- Fiber-Based Concurrency: Lightweight concurrent operations using Ruby fibers
- Configurable Timeouts: Separate settings for connection and read operations
- Multi-Process Server: Falcon runs multiple worker processes (configurable) for true parallelism
Use the batch_execute tool to run multiple operations concurrently:
{
"name": "batch_execute",
"params": {
"calls": [
{ "name": "get_issue", "params": { "id": 123 } },
{ "name": "get_issue", "params": { "id": 456 } },
{ "name": "list_time_entries", "params": { "issue_id": 123 } }
],
"max_concurrency": 5
}
}Performance gain: Up to 20x faster for independent operations compared to sequential execution.
Monitor server performance in real-time:
Prometheus Format (for monitoring tools like Grafana):
curl http://localhost:3100/metricsTool Metrics (JSON):
curl http://localhost:3100/metrics/toolsReturns:
{
"tools": [
{
"tool": "list_issues",
"total_calls": 42,
"success_count": 40,
"error_count": 2,
"total_duration_ms": 1250.5,
"avg_duration_ms": 29.77,
"errors_by_type": { "NotFoundError": 2 }
}
]
}API Metrics (JSON):
curl http://localhost:3100/metrics/apiSlow Requests (JSON):
curl http://localhost:3100/metrics/slowLists requests exceeding the slow threshold (default: 1.0 second).
Configure performance settings in .env:
# HTTP timeouts in seconds
HTTP_TIMEOUT=30 # Request timeout
HTTP_READ_TIMEOUT=60 # Read timeout
# Server configuration
FALCON_PROCESSES=1 # Number of worker processes (increase for production)
# Metrics
METRICS_SLOW_THRESHOLD=1.0 # Slow request threshold in secondsNote: The async HTTP client handles connection pooling and compression automatically. No manual configuration needed for these features.
See docs/PERFORMANCE.md for detailed performance tuning guide.
All implemented tools have comprehensive RSpec test coverage (330+ tests).
Run all tests:
bundle exec rspecRun specific tool category:
bundle exec rspec spec/tools/time_entries/
bundle exec rspec spec/tools/custom_fields/
bundle exec rspec spec/tools/queries/Test coverage includes:
- Tool metadata validation
- Success cases with minimum and optional parameters
- Required parameter validation
- Error handling (auth, validation, not found)
See TOOLS.md for detailed testing guide.
bundle exec rubocop
bundle exec rubocop --autocorrectredmine_mcp_server/
├── lib/
│ ├── redmine_mcp_server.rb # Main application
│ ├── async_redmine_client.rb # Async Redmine API client
│ ├── tools/ # MCP tools (operations)
│ │ ├── base_tool.rb
│ │ ├── projects/ # Project CRUD
│ │ ├── issues/ # Issue operations
│ │ └── ...
│ └── resources/ # MCP resources (data sources)
├── spec/ # RSpec tests
├── Gemfile # Ruby dependencies
├── config.ru # Rack configuration
└── .env # Environment configuration
┌─────────────┐ ┌──────────────────┐ ┌─────────────┐
│ │ │ │ │ │
│ AI Client │ ◄─MCP──►│ Redmine MCP │ ◄─HTTP──►│ Redmine │
│ (Claude) │ │ Server │ │ Instance │
│ │ │ │ │ │
└─────────────┘ └──────────────────┘ └─────────────┘
- AI Client: Claude or other MCP-compatible AI assistant
- Redmine MCP Server: This application (translates MCP to Redmine API)
- Redmine Instance: Your Redmine installation
Error: "Missing required environment variable: REDMINE_URL"
- Make sure you have a
.envfile in the project root - Verify all required variables are set
Error: "Connection refused" or "Timeout"
- Check that your
REDMINE_URLis correct and accessible - Verify that Redmine's REST API is enabled (Administration → Settings → API)
- Test API access manually:
curl -H "X-Redmine-API-Key: YOUR_KEY" https://your-redmine.com/users/current.json
Error: "401 Unauthorized"
- Verify your API key is correct
- Check that the user associated with the API key has appropriate permissions
- Generate a new API key if necessary
Error: "Address already in use"
- Another process is using port 3100
- Change the port in
.env:MCP_PORT=3101 - Or stop the other process:
lsof -ti:3100 | xargs kill -9
- API Keys: Never commit
.envfiles to version control - Network: In production, use HTTPS for Redmine connections
- Firewall: Restrict MCP server access to trusted clients only
- Permissions: Use Redmine API keys with appropriate permissions (principle of least privilege)
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Write tests for new functionality
- Ensure all tests pass and code passes rubocop
- Submit a pull request
Copyright © 2025 Stoyan Zhekov zh@zhware.net
This project is available for use under the MIT License.
- Built with mcp_on_ruby
- Powered by Redmine REST API
- Uses Async for high-performance concurrent HTTP communication
- Served by Falcon, a modern async web server
For issues, questions, or contributions:
- GitHub Issues: Create an issue
- Documentation: Redmine REST API
- Stage 1: Project structure and configuration
- Stage 2: Redmine API client
- Stage 3: MCP base infrastructure
- Stage 4: Project CRUD operations
- Stage 4.5: Project copy, membership, and version management
- Stage 4.6: Issue management tools (13 tools)
- Stage 4.7: User management tools (5 tools)
- Stage 4.8: Group management tools (5 tools)
- Stage 5: Time entry tools (6 tools including bulk operations)
- Stage 5.5: Custom field management tools (4 tools)
- Stage 5.6: Performance optimizations (connection pooling, compression, metrics, batch execution)
- Stage 5.7: Query management tools (4 tools for saved filters)
- Stage 6: Wiki and attachment tools
- Stage 7: News and reference data tools
- Stage 8: Advanced features (caching, webhooks)
- Stage 9: Comprehensive test coverage
- Stage 10: Production deployment guides