AI Agent Integration
redmine-cli ships two complementary integrations, both vendor-neutral:
- Agent Skill – a
SKILL.mdinstruction set following the open Agent Skills standard, supported by 35+ agents (Claude, Codex, Gemini, Cursor, Copilot, Cline, Goose, Windsurf, Roo, Junie, …). Teaches the agent how to drive the CLI effectively. - MCP Server –
redmine mcp serveexposes the CLI over the Model Context Protocol. Best for hosts that discover tools through MCP.
For most hosts you want both. Several major hosts (Claude Code, Codex CLI, Gemini CLI) support a one-step plugin install that bundles them together.
Quick install
Section titled “Quick install”npx skills add aarondpn/redmine-cli/plugin marketplace add aarondpn/redmine-cli/plugin install redmine@redmine-clicodex plugin marketplace add aarondpn/redmine-cli/plugins # install Redmine from the added marketplacegemini extensions install https://github.com/aarondpn/redmine-cliredmine mcp serve- Any agent uses the skills.sh installer (
npx skills add), which detects your agent and writesSKILL.mdto the right location (.claude/skills/,.codex/skills/,.gemini/skills/, or the cross-vendor.agents/skills/fallback). The bundled wrapper isredmine install-skill [--global]. - Claude Code / Codex CLI / Gemini CLI bundle the skill and MCP server in a single plugin install. After installing, run
/reload-plugins(Claude) or restart the CLI to activate. - MCP host is the manual route for Cursor, VS Code, Zed, Claude Desktop, and other MCP-aware hosts. Add
redmine mcp serve(with optional--profile,--enable-writes,--enable-groups, …) to your host’s MCP config; see your host’s MCP setup docs for the exact file path and JSON shape. - Docker runs the MCP server from the
ghcr.io/aarondpn/redmine-mcpimage without installingredmineat all. See Run with Docker.
Agent Skill
Section titled “Agent Skill”The skill teaches the agent what --help cannot: output formats, pagination, filtering, name resolution, and common workflows. After installing it the agent knows to use -o json, resolve ambiguous values by querying first, and pick the right flags without guessing.
The full skill source: skills/redmine-cli/SKILL.md. Copy directly into your agent’s instructions if you prefer not to run an installer.
MCP Server
Section titled “MCP Server”redmine mcp serve exposes the CLI as a Model Context Protocol server over stdio by default, or over streamable HTTP when --http is passed. MCP-aware hosts can then drive Redmine through tool calls, reusing the same profile-backed authentication as every other redmine command.
How it works
Section titled “How it works”- Transport: stdio by default. The host can spawn
redmine mcp serveand talk JSON-RPC over its standard streams, or you can pass--http :8080to expose the same server over streamable HTTP. - Authentication: the active profile is used by default. Override with
--profile <name>,--server/--api-key, or theREDMINE_*environment variables – exactly like every other subcommand. - Read-only by default. Mutating tools (create / update / delete, comment, close, reopen, and similar write operations) are registered only when
--enable-writesis passed. Without the flag they never appear intools/list. For a second, transport-level guarantee, set read-only mode (read_only: truein the profile orREDMINE_READ_ONLY=1) – it blocks every write at the HTTP layer, even when--enable-writesis passed. - Configurable surface.
--enable-groups/--disable-groupsconstrain the registered tools to specific categories (issues,wiki,time, …). For sharper control,--enable-tools/--disable-toolsallow- or deny-list individual tool names. Runredmine mcp toolsto print the full catalog.
Run with Docker
Section titled “Run with Docker”The ghcr.io/aarondpn/redmine-mcp image (linux/amd64 and linux/arm64) runs redmine mcp serve directly. You don’t need a local install, a profile, or a keyring. Pass the server URL and API key as environment variables instead. Every REDMINE_* variable and every redmine mcp serve flag works the same way inside the container. Flags go after the image name.
| Tag | Tracks |
|---|---|
latest |
Newest stable release |
2, 2.13, 2.13.0 |
Major, minor, or exact release |
Local: stdio
Section titled “Local: stdio”The MCP host starts a fresh container per session and talks to it over stdin/stdout. -i is required; --rm cleans up afterwards. The -e NAME form (without =value) forwards the variable from the host’s environment, so the key never lands in the args list.
Claude Code:
claude mcp add redmine \ -e REDMINE_SERVER=https://redmine.example.com \ -e REDMINE_API_KEY=your-api-key \ -- docker run -i --rm -e REDMINE_SERVER -e REDMINE_API_KEY ghcr.io/aarondpn/redmine-mcpClaude Desktop, Cursor, Windsurf, and other hosts using the mcpServers JSON shape:
{ "mcpServers": { "redmine": { "command": "docker", "args": ["run", "-i", "--rm", "-e", "REDMINE_SERVER", "-e", "REDMINE_API_KEY", "ghcr.io/aarondpn/redmine-mcp"], "env": { "REDMINE_SERVER": "https://redmine.example.com", "REDMINE_API_KEY": "your-api-key" } } }}One-click install:
VS Code prompts for the URL and API key and stores the key as a secret. Cursor installs placeholder values: open the server in Cursor’s MCP settings and replace REDMINE_SERVER and REDMINE_API_KEY afterwards.
To enable writes or narrow the tool surface, add flags after the image name (... ghcr.io/aarondpn/redmine-mcp --enable-writes --enable-groups issues,time) or forward the matching REDMINE_MCP_* variable.
Already have a ~/.redmine-cli.yaml with profiles? Mount it read-only and pick a profile. --user keeps the file readable even though redmine auth login writes it with mode 0600. Profiles that store their secret in the system keyring can’t be read inside the container; supply REDMINE_API_KEY for those.
docker run -i --rm --user "$(id -u):$(id -g)" \ -v "$HOME/.redmine-cli.yaml:/config.yaml:ro" \ ghcr.io/aarondpn/redmine-mcp --config /config.yaml --profile workShared: HTTP server with Docker Compose
Section titled “Shared: HTTP server with Docker Compose”To run one server for a whole team, use the HTTP transport. The repository ships a ready-made compose.yaml and .env.example:
curl -fsSLO https://raw.githubusercontent.com/aarondpn/redmine-cli/main/docker/compose.yamlcurl -fsSL https://raw.githubusercontent.com/aarondpn/redmine-cli/main/docker/.env.example -o .env# set REDMINE_SERVER, REDMINE_API_KEY and REDMINE_MCP_AUTH_TOKEN (openssl rand -hex 32) in .envdocker compose up -dThen point clients at the server with the token:
claude mcp add --transport http redmine http://localhost:8080/ \ --header "Authorization: Bearer $REDMINE_MCP_AUTH_TOKEN"The compose file only publishes the port on 127.0.0.1. Set REDMINE_MCP_PUBLISH=0.0.0.0:8080 in .env to reach it from other machines, and put a TLS-terminating reverse proxy in front so the bearer token isn’t sent in clear text.
Without Compose, the same server is a single command. REDMINE_MCP_HTTP replaces the --http flag:
docker run -d --name redmine-mcp -p 127.0.0.1:8080:8080 \ -e REDMINE_SERVER -e REDMINE_API_KEY -e REDMINE_MCP_AUTH_TOKEN \ -e REDMINE_MCP_HTTP=0.0.0.0:8080 \ ghcr.io/aarondpn/redmine-mcpIf you leave out REDMINE_MCP_AUTH_TOKEN, the server generates a token at startup and prints it to the container log (docker logs redmine-mcp). That token changes on every restart, so set your own for anything long-lived.
HTTP transport
Section titled “HTTP transport”Pass --http <addr> to expose the server over streamable HTTP instead of stdio. The address shorthand :8080 (no host) is rewritten to 127.0.0.1:8080 so the server is never accidentally reachable from other machines. Pass an explicit host to listen elsewhere:
# Loopback only -- safe defaultredmine mcp serve --http :8080
# Explicit loopback (equivalent)redmine mcp serve --http 127.0.0.1:8080
# Listen on every interface -- always pair with --auth-tokenredmine mcp serve --http 0.0.0.0:8080 --auth-token "$(openssl rand -hex 32)"When a non-loopback bind is detected without --auth-token, the server generates a random token for that run and prints it to stderr. Pass --no-auth (or REDMINE_MCP_NO_AUTH=1) only if something in front of the server, such as an authenticating reverse proxy, already checks clients; the CLI then prints a warning and serves without a token. The server applies ReadHeaderTimeout=10s, ReadTimeout=30s, and IdleTimeout=120s; WriteTimeout is left unbounded so slow Redmine instances don’t terminate in-flight tool calls.
The HTTP transport is stateless, so it speaks MCP revision 2026-07-28 (sessionless, server/discover instead of the initialize handshake). Every tool call is a self-contained Redmine API request, so there is no session to keep. Practical consequences: only POST is served (GET and DELETE answer 405), and stream resumption via Last-Event-ID is not available. Older clients negotiate down to 2025-11-25 and keep working unchanged.
Clients must send the bearer token on every request:
POST / HTTP/1.1Authorization: Bearer <token>Content-Type: application/jsonThe token can also live in the config block (mcp.auth_token) or REDMINE_MCP_AUTH_TOKEN, and the listen address in mcp.http or REDMINE_MCP_HTTP. Flags override both.
Narrowing the exposed tools
Section titled “Narrowing the exposed tools”For an issue-only assistant, drop everything but the issues group:
redmine mcp serve --enable-groups issuesTo enable writes everywhere except destructive deletes, combine the flags:
redmine mcp serve --enable-writes --disable-tools delete_issue,delete_project,delete_wiki_pageThe same defaults can live in ~/.redmine-cli.yaml per profile, and CLI flags override them:
profiles: internal: server: https://redmine.internal api_key: ... mcp: enable_writes: true enable_groups: [issues, wiki] disable_tools: [delete_issue]Environment variables (REDMINE_MCP_ENABLE_GROUPS, REDMINE_MCP_DISABLE_GROUPS, REDMINE_MCP_ENABLE_TOOLS, REDMINE_MCP_DISABLE_TOOLS, REDMINE_MCP_ENABLE_WRITES, REDMINE_MCP_AUTH_TOKEN, REDMINE_MCP_HTTP, REDMINE_MCP_NO_AUTH) override the config block.
Prerequisite
Section titled “Prerequisite”redmine must be on the host’s PATH and a profile must already be logged in (redmine auth login). No Node.js required. With Docker, you only need Docker and an API key.
Troubleshooting
Section titled “Troubleshooting”-
Host reports “command not found”. The spawned process inherits the host’s
PATH, which often differs from your shell. Use an absolute path (which redmine) in thecommandfield. -
Tools list is empty or missing mutations.
--enable-writeswas not passed, the surface was narrowed via--enable-groups/--enable-tools, or the host cached an oldertools/list. Runredmine mcp toolsto see the full catalog and restart the host after changing args. -
401 / “no profile” errors. No profile is logged in, or
--profile <name>points at one that does not exist. Runredmine auth listto confirm.