Skip to main content

Production-ready MCP server for Redmine with security, pagination, and enterprise features

Project description

Redmine MCP Server

PyPI Version License Python Version GitHub Issues CI

A Model Context Protocol (MCP) server that integrates with Redmine project management systems. This server provides seamless access to Redmine data through MCP tools, enabling AI assistants to interact with your Redmine instance.

Features

  • Redmine Integration: List projects, view/create/update issues, download attachments
  • HTTP File Serving: Secure file access via UUID-based URLs with automatic expiry
  • MCP Compliant: Full Model Context Protocol support with FastMCP and streamable HTTP transport
  • Flexible Authentication: Username/password or API key
  • File Management: Automatic cleanup of expired files with storage statistics
  • Docker Ready: Complete containerization support
  • Comprehensive Testing: Unit, integration, and connection tests

Installation

Prerequisites

  • Python 3.13+
  • uv package manager
  • Access to a Redmine instance

Quick Start

# Clone and setup
git clone https://github.com/jztan/redmine-mcp-server
cd redmine-mcp-server

# Install dependencies
uv venv
source .venv/bin/activate
uv pip install -e .

# Configure environment
cp .env.example .env
# Edit .env with your Redmine settings

# Run the server
uv run python -m redmine_mcp_server.main

The server runs on http://localhost:8000 with the MCP endpoint at /mcp, health check at /health, and file serving at /files/{file_id}.

Configuration

Edit your .env file with the following settings:

# Required: Redmine connection
REDMINE_URL=https://your-redmine-server.com

# Authentication (choose one)
REDMINE_USERNAME=your_username
REDMINE_PASSWORD=your_password
# OR
# REDMINE_API_KEY=your_api_key

# Optional: Server settings
SERVER_HOST=0.0.0.0
SERVER_PORT=8000

# Optional: File management
ATTACHMENTS_DIR=./attachments
AUTO_CLEANUP_ENABLED=true
CLEANUP_INTERVAL_MINUTES=10
ATTACHMENT_EXPIRES_MINUTES=60

File Management Configuration

  • ATTACHMENTS_DIR: Directory where downloaded attachments are stored (default: ./attachments)
  • AUTO_CLEANUP_ENABLED: Enable automatic cleanup of expired files (default: true)
  • CLEANUP_INTERVAL_MINUTES: How often cleanup runs to check for expired files (default: 10 minutes)
  • ATTACHMENT_EXPIRES_MINUTES: Default expiry time for downloaded attachments (default: 60 minutes)

Example configurations:

# Quick cleanup for development/testing
CLEANUP_INTERVAL_MINUTES=1
ATTACHMENT_EXPIRES_MINUTES=5

# Production settings
CLEANUP_INTERVAL_MINUTES=30
ATTACHMENT_EXPIRES_MINUTES=120

Note: API key authentication is preferred for security.

Usage

Running the Server

uv run python -m redmine_mcp_server.main

The same command is used for both development and production. Configure environment-specific settings in your .env file.

MCP Client Configuration

Claude Code

Add to Claude Code using the CLI command:

claude mcp add --transport http redmine http://127.0.0.1:8000/mcp

Or configure manually in your Claude Code (~/.claude.json):

{
  "mcpServers": {
    "my-local-server": {
      "type": "http",
      "url": "http://127.0.0.1:8000/mcp"
    }
  }
}

Other MCP Clients

Configure your MCP client (e.g., VS Code settings.json):

{
  "mcp": {
    "servers": {
      "redmine": {
        "url": "http://127.0.0.1:8000/mcp"
      }
    }
  }
}

Testing Your Setup

# Test Redmine connection
python tests/test_connection.py

# Run full test suite
python tests/run_tests.py --all

Available Tools

This MCP server provides the following tools for interacting with your Redmine instance:

Project Management

list_redmine_projects

Lists all accessible projects in the Redmine instance.

Parameters: None

Returns: List of project dictionaries with id, name, identifier, and description

summarize_project_status

Provide a comprehensive summary of project status based on issue activity over a specified time period.

Parameters:

  • project_id (integer, required): The ID of the project to summarize
  • days (integer, optional): Number of days to analyze. Default: 30

Returns: Comprehensive project status summary including:

  • Recent activity metrics (issues created/updated)
  • Status, priority, and assignee breakdowns
  • Project totals and overall statistics
  • Activity insights and trends

Issue Operations

get_redmine_issue

Retrieve detailed information about a specific Redmine issue.

Parameters:

  • issue_id (integer, required): The ID of the issue to retrieve
  • include_journals (boolean, optional): Include journals (comments) in result. Default: true
  • include_attachments (boolean, optional): Include attachments metadata. Default: true

Returns: Issue dictionary with details, journals, and attachments

list_my_redmine_issues

Lists issues assigned to the authenticated user.

Parameters:

  • **filters (optional): Additional query parameters (e.g., status_id, project_id)

Returns: List of issue dictionaries assigned to current user

search_redmine_issues

Search issues using text queries.

Parameters:

  • query (string, required): Text to search for in issues
  • **options (optional): Additional search options passed to Redmine API

Returns: List of matching issue dictionaries

create_redmine_issue

Creates a new issue in the specified project.

Parameters:

  • project_id (integer, required): Target project ID
  • subject (string, required): Issue subject/title
  • description (string, optional): Issue description. Default: ""
  • **fields (optional): Additional Redmine fields (e.g., priority_id, assigned_to_id)

Returns: Created issue dictionary

update_redmine_issue

Updates an existing issue with the provided fields.

Parameters:

  • issue_id (integer, required): ID of the issue to update
  • fields (object, required): Dictionary of fields to update

Returns: Updated issue dictionary

Note: You can use either status_id or status_name in fields. When status_name is provided, the tool automatically resolves the corresponding status ID.


File Operations

get_redmine_attachment_download_url(attachment_id)

Get an HTTP download URL for a Redmine attachment. The attachment is downloaded to server storage and a time-limited URL is returned for client access.

Parameters:

  • attachment_id (int): The ID of the attachment to download

Returns:

{
    "download_url": "http://localhost:8000/files/12345678-1234-5678-9abc-123456789012",
    "filename": "document.pdf",
    "content_type": "application/pdf",
    "size": 1024,
    "expires_at": "2025-09-22T10:30:00Z",
    "attachment_id": 123
}

Security Features:

  • Server-controlled storage location and expiry policy
  • UUID-based filenames prevent path traversal attacks
  • No client control over server configuration

download_redmine_attachment(attachment_id, save_dir, expires_hours) ⚠️ DEPRECATED

DEPRECATED: This function will be removed in v0.5.0. Use get_redmine_attachment_download_url() instead.

Security Warning: The save_dir parameter is vulnerable to path traversal attacks. The expires_hours parameter inappropriately exposes server policies to clients.

cleanup_attachment_files

Removes expired attachment files and provides cleanup statistics.

Parameters: None

Returns: Cleanup statistics:

  • cleaned_files: Number of files removed
  • cleaned_bytes: Total bytes cleaned up
  • cleaned_mb: Total megabytes cleaned up (rounded)

Docker Deployment

Quick Start with Docker

# Configure environment
cp .env.example .env.docker
# Edit .env.docker with your Redmine settings

# Run with docker-compose
docker-compose up --build

# Or run directly
docker build -t redmine-mcp-server .
docker run -p 8000:8000 --env-file .env.docker redmine-mcp-server

Production Deployment

Use the automated deployment script:

chmod +x deploy.sh
./deploy.sh

Development

Architecture

The server is built using:

  • FastMCP: Model Context Protocol implementation with streamable HTTP transport
  • python-redmine: Official Redmine Python library

Project Structure

redmine-mcp-server/
├── src/redmine_mcp_server/
│   ├── main.py              # FastMCP application entry point
│   ├── redmine_handler.py   # MCP tools and Redmine integration
│   └── file_manager.py      # Attachment file management and cleanup
├── tests/                   # Comprehensive test suite
├── .env.example            # Environment configuration template
├── Dockerfile              # Container configuration
├── docker-compose.yml      # Multi-container setup
├── deploy.sh              # Deployment automation
└── pyproject.toml         # Project configuration

Adding New Tools

Add your tool function to src/redmine_mcp_server/redmine_handler.py:

@mcp.tool()
async def your_new_tool(param: str) -> Dict[str, Any]:
    """Tool description"""
    # Implementation here
    return {"result": "data"}

The tool will automatically be available through the MCP interface.

Testing

The project includes unit tests, integration tests, and connection validation.

Run tests:

# Install test dependencies
uv pip install -e .[test]
# All tests
python tests/run_tests.py --all

# Unit tests only (default)
python tests/run_tests.py

# Integration tests (requires Redmine connection)
python tests/run_tests.py --integration

# With coverage report
python tests/run_tests.py --coverage

Test Requirements:

  • Unit tests: No external dependencies (use mocks)
  • Integration tests: Require valid Redmine server connection

Troubleshooting

Common Issues

  1. Connection refused: Verify your REDMINE_URL and network connectivity
  2. Authentication failed: Check your credentials in .env
  3. Import errors: Ensure dependencies are installed: uv pip install -e .
  4. Port conflicts: Modify SERVER_PORT in .env if port 8000 is in use

Debug Mode

Enable debug logging by setting mcp.settings.debug = True in main.py.

Contributing

Contributions are welcome! Please:

# Install development dependencies (for code quality and testing)
uv pip install -e .[dev]
  1. Open an issue for discussion
  2. Run the full test suite: python tests/run_tests.py --all
  3. Run code quality checks:
    # PEP 8 compliance check
    uv run flake8 src/ --max-line-length=88
    
    # Auto-format code
    uv run black src/ --line-length=88
    
    # Check formatting without making changes
    uv run black --check src/
    
  4. Submit a pull request

License

This project is licensed under the MIT License - see the LICENSE file for details.

Additional Resources

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

redmine_mcp_server-0.4.2.tar.gz (73.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

redmine_mcp_server-0.4.2-py3-none-any.whl (19.2 kB view details)

Uploaded Python 3

File details

Details for the file redmine_mcp_server-0.4.2.tar.gz.

File metadata

  • Download URL: redmine_mcp_server-0.4.2.tar.gz
  • Upload date:
  • Size: 73.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for redmine_mcp_server-0.4.2.tar.gz
Algorithm Hash digest
SHA256 b24df2a2820801b8aa1e589be70aa41af67f144e74a9635cbddf4f3a039da514
MD5 ec9a975fcd69b9f0a2cda309127df4b3
BLAKE2b-256 836695396e99b4e4d601c90c7d6912acadc4f5e74094a01314bb1dc4e20d31c2

See more details on using hashes here.

File details

Details for the file redmine_mcp_server-0.4.2-py3-none-any.whl.

File metadata

File hashes

Hashes for redmine_mcp_server-0.4.2-py3-none-any.whl
Algorithm Hash digest
SHA256 4c3a34c504a50cf4fcf5fae08726945a1fbd2200740ca9206dcd68c7d14b8e1a
MD5 4118d171b7ffbf98c0381c841dab2c57
BLAKE2b-256 79b273bb5a433e7720e315566d9e5d85d409260d1e68ed26fe72dbf44baef9e5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page