Skip to content

AI Agent Integration

redmine-cli ships two complementary integrations, both vendor-neutral:

  • Agent Skill – a SKILL.md instruction 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 serve exposes 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.

Terminal window
npx skills add aarondpn/redmine-cli
Terminal window
/plugin marketplace add aarondpn/redmine-cli
/plugin install redmine@redmine-cli
Terminal window
codex plugin marketplace add aarondpn/redmine-cli
/plugins # install Redmine from the added marketplace
Terminal window
gemini extensions install https://github.com/aarondpn/redmine-cli
Terminal window
redmine mcp serve
  • Any agent uses the skills.sh installer (npx skills add), which detects your agent and writes SKILL.md to the right location (.claude/skills/, .codex/skills/, .gemini/skills/, or the cross-vendor .agents/skills/ fallback). The bundled wrapper is redmine 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-mcp image without installing redmine at all. See Run with Docker.

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.

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.

  • Transport: stdio by default. The host can spawn redmine mcp serve and talk JSON-RPC over its standard streams, or you can pass --http :8080 to expose the same server over streamable HTTP.
  • Authentication: the active profile is used by default. Override with --profile <name>, --server / --api-key, or the REDMINE_* 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-writes is passed. Without the flag they never appear in tools/list. For a second, transport-level guarantee, set read-only mode (read_only: true in the profile or REDMINE_READ_ONLY=1) – it blocks every write at the HTTP layer, even when --enable-writes is passed.
  • Configurable surface. --enable-groups / --disable-groups constrain the registered tools to specific categories (issues, wiki, time, …). For sharper control, --enable-tools / --disable-tools allow- or deny-list individual tool names. Run redmine mcp tools to print the full catalog.

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

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:

Terminal window
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-mcp

Claude 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:

Install in VS Code Add to Cursor

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.

Terminal window
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 work

To run one server for a whole team, use the HTTP transport. The repository ships a ready-made compose.yaml and .env.example:

Terminal window
curl -fsSLO https://raw.githubusercontent.com/aarondpn/redmine-cli/main/docker/compose.yaml
curl -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 .env
docker compose up -d

Then point clients at the server with the token:

Terminal window
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:

Terminal window
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-mcp

If 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.

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:

Terminal window
# Loopback only -- safe default
redmine mcp serve --http :8080
# Explicit loopback (equivalent)
redmine mcp serve --http 127.0.0.1:8080
# Listen on every interface -- always pair with --auth-token
redmine 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.1
Authorization: Bearer <token>
Content-Type: application/json

The 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.

For an issue-only assistant, drop everything but the issues group:

Terminal window
redmine mcp serve --enable-groups issues

To enable writes everywhere except destructive deletes, combine the flags:

Terminal window
redmine mcp serve --enable-writes --disable-tools delete_issue,delete_project,delete_wiki_page

The 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.

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.

  1. 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 the command field.

  2. Tools list is empty or missing mutations. --enable-writes was not passed, the surface was narrowed via --enable-groups / --enable-tools, or the host cached an older tools/list. Run redmine mcp tools to see the full catalog and restart the host after changing args.

  3. 401 / “no profile” errors. No profile is logged in, or --profile <name> points at one that does not exist. Run redmine auth list to confirm.