npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

redmine-devrelay

v0.10.0

Published

Redmine MCP server for Cursor/Claude/Codex ??read issues and create/comment/update with confirm gate (DevRelay)

Readme

redmine-devrelay

Korean

Redmine MCP server for Cursor · Claude Code · Codex.

Quick start (STDIO)

STDIO is the default transport. Local IDE plugins use this path.

npx -y [email protected]

| Env var | Description | | --- | --- | | REDMINE_URL | Redmine base URL (may include /redmine path) | | REDMINE_API_KEY | REST API key | | REDMINE_ALLOWED_HOSTS | (optional) Host allowlist. Private IPv4 HTTP is allowed separately | | REDMINE_PREVIEW_STORE_DIR | (optional) Directory for previewToken files. Set it when running several HTTP-mode server processes so a dry-run on one and a confirm on another share tokens. Unset = in-process memory | | REDMINE_CA_CERT_PATH | (optional) Private CA PEM |

HTTP mode (--http) · BYOK

For remote / Streamable HTTP deployments. The Codex Git marketplace keeps STDIO npx and does not switch to a remote URL.

npx -y [email protected] --http
# or after build
pnpm --filter redmine-devrelay start:http
# port: --port 9090 or PORT (default 8080)

Endpoints:

| Path | Description | | --- | --- | | POST /mcp | MCP Streamable HTTP | | GET /healthz | Health check | | GET /.well-known/openai-apps-challenge | OpenAI Apps challenge (see below) |

BYOK headers (per request)

In production, pass Redmine credentials on each request:

| Header | Description | | --- | --- | | X-Redmine-Url | Redmine base URL | | X-Redmine-Api-Key | REST API key |

Missing headers → 401 (BYOK required).

OPENAI_APPS_CHALLENGE_TOKEN

When set, GET /.well-known/openai-apps-challenge returns the token as plain text. Unset → 404.

HTTP_ALLOW_ENV_FALLBACK=1 (demo only)

When 1, missing BYOK headers fall back to process env REDMINE_URL / REDMINE_API_KEY.

Warning: env credentials are shared by every client of that HTTP process. Demo/local only — turn off in production and use X-Redmine-Url / X-Redmine-Api-Key per request.

Invalid URL / config validation failures → 400 (API key never included in the response). Missing headers → 401.

HTTP session limits

| Env var | Default | Description | | --- | --- | --- | | MCP_MAX_SESSIONS | 100 | Concurrent session cap; new initialize returns 503 when full | | MCP_SESSION_TTL_MS | 1800000 (30m) | Idle TTL; expired sessions pruned on access |

Write rules

dry-run → confirm → confirm=true + previewToken.
You cannot apply without the previewToken from the dry-run response (TTL 10 minutes, single-use).

This Redmine uses HTML bodies. Pass plain text and the client converts it.

| Field | Auto conversion | | --- | --- | | description | Plain text lines → <p>…</p> (left as-is if already HTML) | | notes / comments | Newlines → <br />. Plain text only — Textile/Markdown is blocked in dry-run |

Keeping raw REST out

The confirm gate only protects calls that go through these tools. Two things in the repo close the ways around it:

| Path | What it is | | --- | --- | | scripts/redmine-call.mjs | One tool call from a terminal, through the real server — so a session without the MCP tools still gets dry-run -> previewToken -> confirm | | plugins/claude-code/hooks/ | A PreToolUse hook shipped with the Claude Code plugin. It refuses shell commands and file writes that POST/PUT/DELETE to Redmine directly. Reads are untouched |

previewToken proves a dry-run ran with the same payload — it is not evidence the user approved. Never call dry-run and confirm=true in the same turn.

Read APIs

| Tool | Description | | --- | --- | | redmine_test_connection | Verify connection as the current user with URL and API key | | redmine_list_projects | List accessible projects | | redmine_list_project_members | List project members (for assignee / watchers) | | redmine_search_users | Search all users (may require permission) | | redmine_search_issues | Search issues (default: open; supports assignedTo: "me"). Rows include dueDate and doneRatio. Filters: trackerId/priorityId/status/fixedVersionId/categoryId by id or name, assignedTo/authorId/watcherId as "me"/id/name, date ranges dueAfter/dueBefore, createdAfter/createdBefore, updatedAfter/updatedBefore (YYYY-MM-DD, inclusive). resolved echoes what each name became | | redmine_search_text | Full-text search (GET /search.json, Redmine 3.3+): query, optional projectId, types (default issues), titlesOnly, openIssuesOnly. Older servers get an error pointing at subjectContains | | redmine_get_issue | Issue detail (includes journals, children, etc.) | | redmine_list_issue_relations | Related issues with their relationId (needed to update/remove one) | | redmine_list_metadata | Trackers / statuses / priorities / activities (+ versions, categories, custom fields with projectId) as id+name | | redmine_get_attachment | Download an attachment (attachmentId from redmine_get_issue include=["attachments"]) to destDir (default: OS temp) and return path; text files also return text (first 200 KiB). Only the configured Redmine host is fetched; maxBytes default 10 MiB, hard max 50 MiB | | redmine_list_time_entries | Time entries by issue / project / user ("me", the default when no issue or project is given) / spentFrom–spentTo; returns totalHours of the returned rows |

Write APIs

| Tool | Description | | --- | --- | | redmine_create_issue | Create issue. Dry-run returns wouldApply preview | | redmine_update_issue | Update issue. Dry-run returns before→after changes[] | | redmine_add_comment | Add comment (plain text only; Textile/Markdown blocked) | | redmine_add_attachment | Attach a local file to an existing issue | | redmine_update_status | Change issue status (statusId) only | | redmine_bulk_update_status | Same status (id or name) for 1–50 issueIds. Dry-run reads every issue → rows[] (subject, from→to, unchanged/error flags) + one previewToken; confirm applies one by one and returns updated/skipped/failed. Optional plain-text notes on every issue | | redmine_bulk_update_issue | 1–50 issues in one preview. issues[] holds per-issue fields (doneRatio, statusId, assignedTo, notes …), common applies to every row and a row wins on the same field. Dry-run → rows[] (subject, changes[], unchanged/error) + one previewToken; confirm applies one by one → updated/skipped/failed. Subject, description and parent are single-issue only | | redmine_log_time | Record a time entry: issueId or projectId, hours, spentOn (default today), activityId (id or name), comments. Dry-run shows the issue subject | | redmine_add_issue_relation | Link two issues (relationType; delay for precedes/follows) | | redmine_update_issue_relation | Change a relation by relationId (remove + re-create) | | redmine_remove_issue_relation | Remove a relation by relationId — both issues stay |

Subtasks (하위일감)

There is no separate subtask tool — the parent link is a field:

| Call | Effect | | --- | --- | | redmine_create_issue + parentIssueId | Create a new subtask under that parent | | redmine_update_issue + parentIssueId: <id> | Attach an existing issue / move it to another parent | | redmine_update_issue + parentIssueId: null | Detach the subtask — the issue itself is never deleted | | redmine_search_issues + parentIssueId | List a parent's children |

This server has no issue-delete tool by design; deleting an issue in Redmine is irreversible and cascades to its descendants.

Optional create / update fields

| Field | Meaning | | --- | --- | | trackerId | Tracker — id or name (2 or "기능추가") | | statusId | Status — id or name (2 or "진행") | | priorityId | Priority — id or name (4 or "긴급") | | fixedVersionId | Target version — id or name; null clears it (update only) | | categoryId | Category — id or name; null clears it (update only) | | customFields | Custom fields [{ id \| name, value }] — name resolves against the project's issue custom fields; "" clears, string array for multi-select; only the listed fields change | | startDate / dueDate | Start / due date (YYYY-MM-DD) | | doneRatio | Done ratio (0–100) | | assignedTo | Assignee ("me" / id / name) | | watchers | Watchers (id or name array; full replace on update) | | attachments | Local files [{ path, filename?, description? }] (create / add_attachment) | | confirm | false (default) = preview (+ previewToken), true = apply (previewToken required) | | previewToken | Token from dry-run. Invalid if payload changes |

Changelog (summary)

| Version | Notes | | --- | --- | | 0.10.0 | redmine_bulk_update_issue — 1–50 issues in one preview, issues[] per-issue and common shared (a row wins on the same field), so a shared status with a different note per issue is one confirm | | 0.9.2 | Fix: redmine_update_status and redmine_bulk_update_status report the real status name after a write — Redmine answers the PUT with 204, so the status id used to appear in the name ({ id: 2, name: "2" }) | | 0.9.0 | Time entries (redmine_log_time, redmine_list_time_entries, activities kind), redmine_get_attachment (same-host download, inline text), search filters by name + date ranges and redmine_search_text, redmine_bulk_update_status, journal details, REDMINE_PREVIEW_STORE_DIR file-backed preview tokens | | 0.8.0 | Custom fields on create/update (customFields: [{ id \| name, value }], names resolved per project, "" clears, arrays for multi-select); customFields kind in redmine_list_metadata with customFieldsSource; Redmine older than 4.2 falls back to /custom_fields.json, then to sampling recent issues | | 0.7.5 | Fix: assignedTo="me" is resolved to the current user id on create/update — Redmine drops the literal me on writes, so issues were created unassigned | | 0.7.4 | Ships the Redmine write guard with the Claude Code plugin (PreToolUse hook) and documents scripts/redmine-call.mjs | | 0.7.3 | Instructions spell out that previewToken is not user approval: dry-run and confirm must not happen in the same turn | | 0.7.2 | Fix HTML body conversion: plain text with angle brackets is wrapped and escaped again, notes keep every line break, and the tag allowlist matches what Redmine renders. People lookup falls back to recent assignees when the memberships API is forbidden | | 0.7.1 | dueDate/doneRatio in search results, so a due-date column needs no per-issue fetch | | 0.7.0 | Names accepted for status/tracker/priority/version/category, redmine_list_metadata, fixedVersionId/categoryId | | 0.6.0 | Issue relations (list/add/update/remove) and subtasks via parentIssueId; Streamable HTTP + BYOK headers, --http CLI, OpenAI Apps challenge, demo-only env fallback | | 0.5.2 | English npm README; Claude Code marketplace install (redmine-devrelay plugin id) | | 0.5.1 | Codex marketplace install CLI alignment (ON_USE, plugin add) + pin | | 0.5.0 | Block Textile/Markdown in notes, previewToken confirm gate | | 0.4.1 | Docs/example IP cleanup, Antigravity plugin pin | | 0.4.0 | Attachments: create attachments + redmine_add_attachment | | 0.3.3 | Sync npm README, plugin pins, install docs | | 0.3.2 | Auto-convert plain description → <p> HTML | | 0.3.1 | notes \n → <br /> | | 0.3.0 | update_issue, expanded create fields and preview | | 0.2.x | create / comment / status, members · watchers, private HTTP | | 0.1.x | Read-only (Phase 1) |

License

MIT