Skip to main content
Glama

Redmine local MCP POC

This server exposes thirty-five MCP tools over stdio:

  • list_projects lists projects visible to the configured Redmine API user, with pagination and documented project associations.

  • list_queries lists visible saved issue queries with collection pagination.

  • search searches visible global Redmine content with documented search filters and pagination.

  • list_issue_statuses lists all issue statuses in Redmine's configured order.

  • list_issue_priorities lists all issue priorities in Redmine's configured order.

  • list_time_entry_activities lists all shared time-entry activities in Redmine's configured order.

  • list_document_categories lists all shared document categories in Redmine's configured order.

  • list_trackers lists all trackers in Redmine's configured order.

  • list_roles lists non-built-in project-member roles in Redmine's configured order.

  • get_role reads one Redmine role by positive numeric role ID.

  • get_project reads one visible project by numeric ID or project identifier, with optional documented project associations.

  • list_project_issue_categories lists one project's issue categories by numeric ID or project identifier.

  • get_issue_category reads one visible issue category by positive numeric ID.

  • list_project_memberships lists a project's user and group memberships, roles, and pagination metadata by numeric project ID or project identifier.

  • get_project_membership reads one project membership by positive membership ID, including its user or group principal and roles.

  • list_project_versions lists a project's visible and shared versions by numeric project ID or project identifier.

  • list_project_files lists a project's files by numeric project ID or project identifier.

  • list_project_wiki_pages lists a project's wiki page index by numeric project ID or project identifier.

  • get_project_wiki_page reads one current project wiki page by numeric project ID or project identifier and title.

  • get_project_wiki_page_version reads one historic project wiki page revision by numeric project ID or project identifier, title, and version.

  • get_attachment reads one visible attachment by positive numeric attachment ID.

  • get_version reads one visible Redmine version by positive numeric version ID.

  • get_user reads one visible Redmine user by positive numeric ID, with optional visible project memberships.

  • get_current_user reads the Redmine user represented by the configured API token, with optional visible project memberships.

  • get_my_account reads the configured API user's own account from Redmine's /my/account.json endpoint.

  • get_issue reads one visible Redmine issue and optionally includes documented issue associations and journal history.

  • list_issue_relations lists the visible relations for one Redmine issue.

  • get_issue_relation reads one visible Redmine issue relation by positive numeric relation ID.

  • list_issues lists visible Redmine issues with pagination, sorting, documented filters, custom-field filters, attachments, and relations.

  • list_news lists visible global Redmine news with collection pagination.

  • get_news reads one visible Redmine news item by positive numeric ID, with optional documented associations.

  • list_project_news lists visible news for one project by numeric ID or project identifier, with collection pagination.

  • list_time_entries lists visible Redmine time entries with documented pagination, ID, project, activity, and date filters.

  • get_time_entry reads one visible Redmine time entry by positive numeric ID.

  • list_my_assigned_issues returns issues assigned to the Redmine user represented by REDMINE_API_TOKEN.

The server is read-only. It sends the token to Redmine in the X-Redmine-API-Key header. The token is not an MCP tool argument and is not included in tool results.

Run it

You need Node.js 20 or newer and pnpm.

Copy-Item .env.example .env

Edit .env:

REDMINE_BASE_URL=https://redmine.example.com
REDMINE_API_TOKEN=your-redmine-api-token

If Redmine lives under a path, include it in the URL, for example https://example.com/redmine.

Enable the REST API in Redmine under Administration > Settings > API, then install and build:

pnpm install
pnpm build

Related MCP server: mcp-server-redmine

Connect VS Code over stdio

The repository includes .vscode/mcp.json. VS Code starts dist/stdio.js itself, loads .env, and communicates over stdin and stdout.

After building, open this folder in VS Code and start redmine-test-mcp-server from the MCP server list. Rebuild after changing the TypeScript source.

To run the stdio process manually for troubleshooting:

pnpm start

Do not use pnpm start as the VS Code command. Package manager output can interfere with the stdio protocol. The included configuration starts Node directly.

Tool input

list_projects accepts the documented offset, limit, and page pagination controls. All are omitted by default, so Redmine applies its own defaults. limit is capped at 100. The include list is empty by default and accepts trackers, issue_categories, enabled_modules, time_entry_activities, and issue_custom_fields.

{
  "page": 2,
  "limit": 25,
  "include": ["trackers", "enabled_modules"]
}

list_queries reads the visible saved issue queries from /queries.json. It accepts only Redmine's documented collection pagination controls: offset, limit, and page. Redmine defaults to an offset of 0 and a limit of 25, caps the limit at 100, and gives offset precedence over page. The endpoint has no documented project, resource-type, or include filters; internal and administrator-only query selectors are not exposed. Results preserve Redmine's name order and map the API fields id, name, is_public, and project_id to id, name, isPublic, and projectId. Explicit null and omitted projectId values are preserved. Each url points to the corresponding filtered issue list (/issues?query_id=:id), which is Redmine's documented way to use a saved query because /queries/:id is not a show route.

Redmine's QueriesController#index accepts ordinary API authentication, uses IssueQuery by default, and obtains visibility through IssueQuery.visible. Public queries are visible to logged-in users, role-visible queries require a matching project membership role, and private queries are visible only to their owner (subject to the query's view permission and project visibility). The client sends an authenticated GET, allowlists only the documented response fields, and returns sealed 401, 403, or 404 errors without upstream response bodies. See Redmine's Queries REST API documentation, REST API pagination documentation, current queries controller, queries API view, routes, query model, issue query model, and application authorization source.

{
  "page": 2,
  "limit": 25
}

search reads the global /search.json endpoint for the configured Redmine API user. Its optional query input maps to Redmine's q parameter, which Redmine strips at both ends; omitting query is valid and returns an empty result collection on current Redmine. The tool accepts only the documented search controls: offset (nonnegative), limit (1 through 100), scope, all_words, titles_only, issues, news, documents, changesets, wiki_pages, messages, projects, open_issues, and attachments. It does not expose page, project_id, format, include, nometa, internal selectors, or administrator-only controls. Unknown, duplicated, malformed, and unsafe query inputs are rejected before the request is sent.

scope accepts all, subprojects, the current controller's my_projects and bookmarks, and the REST wiki's older my_project spelling. The client sends my_project as the current my_projects value. Because this tool intentionally calls the global route, subprojects has no project anchor and therefore behaves as the global scope. all_words defaults to Redmine's true; the client sends all_words=1 for true and an empty all_words value for false, matching Redmine's presence-based controller logic. The other boolean filters are sent as 1 only when true. attachments accepts exactly 0 for descriptions only, 1 for descriptions and attachments, or only for attachment-only search. Redmine applies its own default offset of 0, default limit of 25, and maximum limit of 100 when the pagination controls are omitted.

The output wrapper is results plus paging metadata and an echoed camelCase filters object. Each result allowlists id, title, type, url, description, and datetime; description and datetime preserve Redmine's explicit null or omission. Result type remains an opaque nonempty string so current core values and plugin-provided search types are preserved. The result array is returned in the exact order Redmine supplies. Current Redmine emits absolute result URLs. The client keeps a URL only when it is HTTP(S), same-origin, rooted under REDMINE_BASE_URL, and free of user info, fragments, path traversal, and credential-like query parameter names; an unsafe upstream URL becomes null and is never emitted verbatim.

This is an ordinary authenticated read. Redmine authorizes the global search action, then applies each searchable model's ordinary visibility and project-permission scopes, so results are limited to content visible to the configured API user. Search does not accept a project path in this tool; Redmine's route supports an optional project path, but the REST search contract does not require a project_id query input. The REST search API was added in Redmine 3.3.0. The current controller's plural my_projects and bookmarks scopes are documented in the later scope change. See Redmine's Search REST API documentation, REST API pagination documentation, search controller, search API view, routes, search engine, searchable model support, API authorization source, REST search feature, and search scope change.

{
  "query": "release notes",
  "offset": 0,
  "limit": 25,
  "scope": "all",
  "all_words": true,
  "titles_only": false,
  "issues": true,
  "wiki_pages": true,
  "attachments": "0"
}

list_issue_statuses reads all issue statuses from /issue_statuses.json. It accepts no query, include, or pagination controls because Redmine documents none for this collection and the controller loads every status in position order. The current API view returns id, name, is_closed, and description; the tool maps them to id, name, isClosed, and description, preserving the order Redmine sends and preserving an explicit null or an omitted description. It adds no browser links because Redmine's HTML index is admin-or-API-only and the routes define no status show page. Redmine accepts ordinary API authentication for this read and may return HTTP 401, 403, or 404 without exposing the upstream response body. See Redmine's Issue Statuses REST API documentation, current issue statuses controller, issue statuses API view, routes, and issue status model.

list_trackers reads all trackers from /trackers.json. It accepts no query, include, or pagination controls because Redmine documents none for this collection. The current API view returns id, name, default_status, description, and enabled_standard_fields; the tool maps them to id, name, defaultStatus, description, and enabledStandardFields, preserves Redmine's position order, and strips all other data. Redmine added description in 4.2.0 and enabled_standard_fields in 5.0.0, so those fields remain optional for older servers. Explicit null values remain null, and omitted fields remain omitted. The nested default status contains only its documented id and name. The result has no browser links because the HTML tracker index requires an administrator or API request and the routes define no tracker show page or ordinary status show page. Redmine accepts ordinary API authentication for this read and may return HTTP 401, 403, or 404 without exposing the upstream response body. See Redmine's Trackers REST API documentation, current trackers controller, trackers API view, routes, tracker model, and API authorization source.

list_roles reads /roles.json. It accepts no query, include, or pagination controls. Redmine's current controller returns Role.givable, which includes only non-built-in project-member roles and orders them by position. The current list API view returns only id and name; the tool preserves Redmine's response order, strips detail-only fields such as assignable, visibility settings, and permissions, and returns no browser links. Missing or null required fields are malformed responses, not optional values. Redmine accepts ordinary API authentication for this index, while the HTML roles page is restricted for non-admin users. Redmine may return HTTP 401, 403, or 404 without exposing the upstream response body. See Redmine's Roles REST API documentation, current roles controller, roles index API view, Role model, routes, API authorization source, and permission mapping.

get_role reads one role from /roles/:id.json. It accepts exactly one positive safe-integer role_id and sends no query string, include, pagination, or undocumented controls. The detail response is wrapped as role and maps the current API fields id, name, assignable, issues_visibility, time_entries_visibility, users_visibility, and permissions to id, name, assignable, issuesVisibility, timeEntriesVisibility, usersVisibility, and permissions. The visibility values are validated against Redmine's closed model domains: all, default, and own for issue visibility; all and own for time-entry visibility; and all and members_of_visible_projects for user visibility. Permissions remain opaque strings and retain Redmine's exact array order. The four assignability/visibility fields were added to the roles API in Redmine 4.0.0, so the client preserves their omission on older servers and preserves explicit null values when a server returns them. Unlike /roles.json, the detail route loads a role by ID and can return the built-in Non member and Anonymous roles when their IDs are known. The API route is available to ordinary API users, but the HTML role page is restricted to administrators for browser requests, so the result has no browser link. Redmine may return HTTP 401, 403, or 404 without exposing the upstream response body. See Redmine's Roles REST API documentation, the original role-detail API change, the Redmine 4.0 field change, current roles controller, role-detail API view, Role model, routes, and API authorization source.

get_project accepts a positive numeric project ID or a valid Redmine project identifier. Its include list is empty by default and accepts trackers, issue_categories, enabled_modules, time_entry_activities, and issue_custom_fields.

{
  "project_id": "redmine",
  "include": ["trackers", "enabled_modules"]
}

list_project_issue_categories reads /projects/:project_id/issue_categories.json. It accepts only the required project_id, using the same positive numeric ID or valid Redmine project identifier rules as the other project tools. The request is an authenticated GET with no query string because Redmine documents no pagination, filter, include, or other query controls for this collection. Redmine's current controller loads @project.issue_categories.to_a, so the result preserves the API response order. The issue_categories wrapper maps to issueCategories, and total_count maps to totalCount only when Redmine returns it, preserving an explicit null or omission. Each category allowlists id, project, name, and optional assigned_to, mapping the last field to assignedTo; unknown upstream fields are removed. A returned project reference gets a safe base-path browser URL. Categories do not get URLs because their HTML index and show routes redirect to project settings, and assignees do not get URLs because Redmine models assigned_to as a Principal, which may be a user or group. The tool returns HTTP 401, 403, or 404 as sealed errors without upstream response bodies.

This is a non-admin read. Redmine authorizes it through the project's view_issues permission with the issue_tracking module enabled, while project visibility and the normal application authorization checks still apply. See Redmine's Issue Categories REST API documentation, current issue categories controller, issue categories API view, issue category model, routes, issue-tracking permission map, and application authorization source.

{
  "project_id": "redmine"
}

get_issue_category reads /issue_categories/:id.json for one visible issue category. It accepts exactly one positive safe-integer issue_category_id and sends no query string, include, or undocumented controls. Redmine's detail response is wrapped as issue_category; the current serializer emits id, optional project { id, name }, name, and optional assigned_to { id, name }. The result maps these fields to camelCase, preserves explicit null values and omitted associations, and strips unknown upstream fields. Only a returned project reference gets a safe browser URL: the category HTML show action redirects to member-only project settings, while assigned_to is a Principal that may be a user or group, so category and assignee URLs are omitted. No version-dependent detail fields are documented. Redmine may return HTTP 401, 403, or 404, and the tool does not expose upstream error bodies.

{
  "issue_category_id": 2
}

See Redmine's Issue Categories REST API documentation, current issue categories controller, issue category detail API view, issue category model, routes, issue-tracking and category permission map, and application authorization source.

list_project_memberships accepts a positive numeric project ID or valid Redmine project identifier, plus the documented collection pagination controls offset, limit, and page. These controls are omitted by default so Redmine applies its defaults. Redmine uses a limit of 25 by default, caps it at 100, and gives offset precedence over page. Each result identifies its principal as a user or group and preserves inherited roles. This endpoint is not admin-only, but Redmine still enforces project visibility and permissions, so a user without the relevant project permission may receive HTTP 403.

{
  "project_id": "redmine",
  "page": 2,
  "limit": 25
}

get_project_membership accepts only a positive safe-integer membership_id and sends no query parameters. It reads one membership from /memberships/:id.json, distinguishes user and group principals, preserves inherited roles, and returns null for a group principal URL because Redmine's group endpoint is administrative. This endpoint is not admin-only, but Redmine still enforces the membership's project visibility and permissions, so a user without the relevant project permission may receive HTTP 403.

{
  "membership_id": 1
}

list_project_versions accepts only a positive numeric project ID or valid Redmine project identifier. It reads /projects/:project_id/versions.json and sends no pagination, filter, or include parameters because Redmine's documented versions collection does not define them. Redmine may include shared versions from other projects, adds total_count, and the current API controller preserves the response order rather than applying the HTML roadmap sort. Visible custom fields are returned when Redmine's API view includes them. Redmine handles API authentication, project authorization, and version visibility, so the tool may return HTTP 401, 403, or 404 without exposing upstream error bodies. See Redmine's Versions REST API documentation, current versions controller, versions API view, custom-field API renderer, application authorization source, project shared-version source, and version model.

{
  "project_id": "redmine"
}

list_project_files accepts only a positive numeric project ID or valid Redmine project identifier and reads /projects/:project_id/files.json. Redmine documents no pagination, filters, include, or other query controls for this collection, so the request sends no query string. The files array is returned in the exact order Redmine supplies it; the current controller assembles project attachments and version attachments without this client reordering them. The tool returns the documented id, filename, filesize, content_type, description, content_url, optional thumbnail_url, optional author { id, name }, created_on, optional version { id, name }, digest, and downloads fields with camelCase names. Optional fields remain omitted when Redmine omits them, and explicit nulls remain null. The result also includes filters.projectId, safe attachment url and downloadUrl links, and safe browser links for returned authors and versions. Upstream content and thumbnail URLs are kept only when they use the configured Redmine origin and subpath, have no credentials or fragments, contain no path traversal, and have no credential-like query parameter names. No pagination metadata is added.

This is an ordinary authenticated, non-admin read. FilesController#index accepts API authentication and authorizes the project with the view_files permission. Project and version attachments use the same project-level attachment visibility rules, and Redmine may return HTTP 401, 403, or 404 without the tool exposing the upstream response body. See Redmine's Files REST API documentation, current FilesController#index, files API view, routes, attachment model, version model, file permission map, and application authorization source.

{
  "project_id": "redmine"
}

list_project_wiki_pages accepts only a positive numeric project ID or valid Redmine project identifier and reads /projects/:project_id/wiki/index.json. Redmine's documented wiki-page index defines no pagination, filters, include, or nometa controls, so the tool sends no query parameters. The current API view returns wiki_pages in Redmine's title-and-parent order with title, optional parent.title, version, optional project { id, name }, created_on, and updated_on; the tool maps these fields to camelCase, preserves explicit null values and omitted optional fields, and adds safe base-path browser URLs for the page and returned project. This is an ordinary authenticated API read authorized by the project's view_wiki_pages permission; Redmine may return HTTP 401, 403, or 404 without exposing upstream error bodies. See Redmine's Wiki Pages REST API documentation, current wiki controller, wiki index API view, routes, and application authorization source.

{
  "project_id": "redmine"
}

get_project_wiki_page reads /projects/:project_id/wiki/:title.json for the configured Redmine API user. project_id accepts a positive numeric project ID or valid Redmine project identifier. title must be a safe, nonempty string. The client rejects path separators and control characters, applies Redmine's title lookup normalization, and percent-encodes the resulting path segment. The only documented include is attachments.

The result unwraps Redmine's wiki_page response and includes title, parent, text, version, author, comments, project, createdOn, updatedOn, and url. attachments is returned only when Redmine includes it. The mapper keeps explicit null values and does not create fields that Redmine omitted. It removes credentials, fragments, and credential-like query parameters from attachment URLs, and adds browser links rooted under REDMINE_BASE_URL.

This is an ordinary authenticated read authorized by the project's view_wiki_pages permission. It does not read historic versions or change Redmine data. Redmine may return HTTP 401, 403, or 404, and the server does not expose those response bodies. See Redmine's Wiki Pages REST API documentation, current wiki controller, wiki detail API view, wiki index API view, routes, application authorization source, and attachment API renderer.

{
  "project_id": "redmine",
  "title": "UsersGuide",
  "include": ["attachments"]
}

get_project_wiki_page_version reads /projects/:project_id/wiki/:title/:version.json for one historic project wiki page revision. It accepts the same project selector, title, and attachments include as get_project_wiki_page, plus a positive safe-integer version. The client sends the exact versioned path after applying the shared Redmine title normalization and percent-encoding. The response uses the same wiki_page wrapper and allowlisted fields as the current-page detail response, but its url includes the returned historic version. Explicit null values remain null, omitted fields remain omitted, and attachment URLs are sanitized before they reach the tool result.

Redmine's WikiController#show authorizes the project normally with view_wiki_pages, then requires view_wiki_edits whenever a version is requested. A missing revision returns 404. This tool does not read the history listing and never writes to Redmine. Redmine may return HTTP 401, 403, or 404 without exposing upstream error bodies. See Redmine's Wiki Pages REST API documentation, the current wiki controller, wiki detail API view, routes, application authorization source, and attachment API renderer.

{
  "project_id": "redmine",
  "title": "UsersGuide",
  "version": 23,
  "include": ["attachments"]
}

get_attachment reads /attachments/:id.json for the configured Redmine API user. attachment_id must be one positive safe integer. Redmine documents no query or include controls for this GET, so the client sends the exact path and no query string.

The response unwraps Redmine's attachment wrapper and allowlists id, filename, filesize, content_type, description, content_url, optional thumbnail_url, optional author { id, name }, and created_on. The result uses camelCase field names, preserves explicit null values and omitted optional fields, sanitizes the returned content and thumbnail URLs, and adds safe base-path url and downloadUrl links for Redmine's browser and named-download routes. It does not download file bytes or implement PATCH or DELETE.

Redmine accepts ordinary API authentication for this read and checks Attachment#visible?, which delegates to the owning object's attachment visibility rules or limits unattached files to their author. Redmine may return HTTP 401, 403, or 404; the client does not expose those response bodies. See Redmine's Attachments REST API documentation, current attachments controller, attachment API view, attachment helper, routes, attachment model, and application authentication source.

{
  "attachment_id": 6243
}

get_version accepts only a positive safe-integer version_id and reads /versions/:id.json with no query parameters because Redmine's documented version detail GET defines no pagination, filters, or include controls. The response wrapper is version; the result reuses the documented version fields and visible custom fields from the versions API, and adds estimatedHours and spentHours only when the detail API view returns them for an API user allowed to view time entries. Explicit Redmine null values remain null, while omitted fields remain omitted. The tool adds safe browser links rooted under REDMINE_BASE_URL, and Redmine enforces ordinary API authentication plus version/project visibility, so it may return HTTP 401, 403, or 404 without exposing upstream error bodies. See Redmine's Versions REST API documentation, current versions controller, version detail API view, custom-field API renderer, application authorization source, and version model.

{
  "version_id": 2
}

get_user accepts only a positive safe-integer user_id. Its only optional include is memberships, which Redmine documents and permits for non-admin callers; the result contains only memberships in projects visible to the requesting user. The server rejects administrator-only groups and auth_source includes and omits administrator-only or private fields such as admin, status, API keys, two-factor settings, password metadata, and authentication-source details. Redmine may omit email when the user's profile hides it, and it may omit version-dependent profile fields or custom values when Redmine does not return them. A visible user can be read by an ordinary authenticated API user, while an invisible or locked user may produce HTTP 404 and insufficient visibility may produce HTTP 403. See Redmine's Users REST API documentation and the current users API view for the upstream visibility and include rules.

{
  "user_id": 3,
  "include": ["memberships"]
}

get_current_user reads the user represented by the configured API token from /users/current.json; it does not accept a user_id. Its only optional include is memberships, which Redmine also permits for ordinary authenticated callers and filters to projects visible to the requesting user. The result shares get_user's safe public profile contract, so it omits self-only fields such as the API key, administrator status, two-factor settings, password metadata, authentication-source details, and groups. Redmine may return HTTP 401 or 403 when the token is rejected or the endpoint is not permitted. See Redmine's Users REST API documentation and users API view.

{
  "include": ["memberships"]
}

get_my_account reads the configured API user's own account from /my/account.json. It accepts an empty object only and sends no query, include, pagination, or administrator controls. The result maps the official account view's safe profile fields and visible custom fields to camelCase, preserves explicit nulls and omitted fields, strips the API key and administrator flag, and adds the ordinary-user /my/account browser URL. The account controller accepts ordinary API authentication for this GET action. Preferences are not returned because the official API view does not serialize them. Redmine may return HTTP 401 or 403 without exposing the upstream response body. See Redmine's MyAccount REST API documentation, current routes, MyController, account API view, User model, UserPreference model, and custom-field API renderer.

{}

get_issue requires one positive Redmine issue ID. Its include list is empty by default and accepts children, attachments, relations, changesets, journals, watchers, allowed_statuses, and reactions. Use journals to retrieve the issue journal history; reactions also adds reactions to returned journals when both associations are requested.

{
  "issue_id": 42,
  "include": ["children", "journals", "reactions"]
}

list_issue_relations reads /issues/:issue_id/relations.json for one issue. It accepts exactly one positive safe numeric issue_id and sends no query parameters because Redmine's issue-relations route documents no filters or pagination. The result preserves Redmine's relation order, which the current source sorts by relation type order and then relation ID. It supports the documented relates, duplicates, duplicated, blocks, blocked, precedes, follows, copied_to, and copied_from relation types, preserves explicit delay nulls and omitted delays, and adds url, issueUrl, and issueToUrl only for valid IDs. These links are rooted under REDMINE_BASE_URL; the tool does not follow them or implement relation detail or write operations. Redmine authenticates the ordinary API user, enforces requested-issue and related-project visibility, and may return HTTP 401, 403, or 404 without exposing the upstream response body. See Redmine's Issue Relations REST API documentation, current issue-relations controller, issue-relations API view, issue model, issue-relation model, and routes.

{
  "issue_id": 42
}

get_issue_relation reads /relations/:id.json for one relation. It accepts exactly one positive safe numeric relation_id and sends no query parameters. The result preserves Redmine's documented relation fields, including all nine directional relation types and the explicit delay value or omission returned by Redmine, and adds url, issueUrl, and issueToUrl only for valid IDs. These links are rooted under REDMINE_BASE_URL. Redmine's current controller accepts API authentication for this GET action and checks that both linked issues are visible to the authenticated user; it does not require an administrator-only action. The tool does not implement relation creation or deletion and does not expose upstream response bodies on HTTP 401, 403, or 404. See Redmine's Issue Relations REST API documentation, REST API authentication documentation, current issue-relations controller, detail API view, issue-relation model, and routes.

{
  "relation_id": 1819
}

All list_issues fields are optional. The defaults are an open-issue page of 25 items, sorted by updated_on:desc, with no associations included.

{
  "status_id": "open",
  "project_id": 12,
  "assigned_to_id": "me",
  "created_on": ">=2026-01-01",
  "custom_fields": [
    { "id": 4, "value": "~customer" }
  ],
  "sort": "updated_on:desc,priority:desc",
  "include": ["attachments", "relations"],
  "limit": 25,
  "offset": 0
}

Supported filters are issue_id, project_id, subproject_id, tracker_id, status_id, assigned_to_id, parent_id, query_id, created_on, and updated_on. Single-ID filters accept one positive numeric ID. issue_id also accepts comma-separated IDs. subproject_id also accepts !*. status_id accepts open, closed, *, or one status ID. assigned_to_id accepts me or one user ID. Date filters accept Redmine operators such as >=2026-01-01 and ranges such as ><2026-01-01|2026-01-31.

Custom-field filters use { "id": number, "value": string | number | boolean } entries. The server turns each entry into the Redmine cf_<id> query parameter and rejects non-numeric field IDs. include is empty by default and accepts attachments and relations when requested; limit is capped at 100. list_my_assigned_issues keeps its existing status, limit, and offset input.

list_news reads the global /news.json collection for the configured API user. It accepts only the documented offset, limit, and page pagination controls. Redmine uses a default limit of 25, caps it at 100, and gives offset precedence over page. The result contains only the documented news fields, maps visible project and author references to base-path-safe browser URLs, and preserves fields Redmine omits or returns as null. Redmine applies its ordinary project and news visibility rules. See Redmine's News REST API documentation, the current news API view, news controller, and news model.

{
  "page": 2,
  "limit": 25
}

list_project_news reads /projects/:project_id/news.json for one project. project_id accepts a positive numeric project ID or valid Redmine project identifier. It accepts only the documented offset, limit, and page collection pagination controls. Redmine uses a default limit of 25, caps it at 100, and gives offset precedence over page. The result uses the same news fields, mapping, null and omission behavior, and base-path-safe browser URLs as list_news. Redmine enforces the configured API user's project and news visibility and may return HTTP 401, 403, or 404. See Redmine's News REST API documentation, current news controller, and news model.

{
  "project_id": "redmine",
  "page": 2,
  "limit": 25
}

get_news reads /news/:id.json for one news item. news_id must be a positive safe numeric ID. Its include list is empty by default and accepts attachments, comments, and reactions. Reactions on comments are returned only when both comments and reactions are requested. The tool sends no other query controls. It reuses the list-news fields and mappings, preserves fields Redmine omits or returns as null, and adds only the association fields returned by Redmine's detail serializer. Attachment URLs are sanitized before they reach the tool result. Redmine enforces the item's news and project visibility and may return HTTP 401, 403, or 404. See Redmine's News REST API documentation, news detail API view, news controller, news model, and the official reactions REST API change.

{
  "news_id": 54,
  "include": ["attachments", "comments", "reactions"]
}

list_time_entries reads /time_entries.json for the configured API user. It accepts the collection pagination controls offset, limit, and page, plus user_id, project_id, issue_id, activity_id, spent_on, from, and to. user_id accepts one positive numeric ID or me; the other ID filters accept one positive numeric ID. project_id also accepts a Redmine project identifier. spent_on accepts only a bare YYYY-MM-DD date, =, >=, or <= followed by one date, or the exact ><YYYY-MM-DD|YYYY-MM-DD range form with the dates in chronological order. from and to accept only real YYYY-MM-DD calendar dates. Surrounding whitespace is trimmed, but timestamps, impossible dates, operators on from/to, internal whitespace, malformed ranges, and unknown or admin-only query controls are rejected. Redmine still enforces the API user's view time entries permission and time-entry visibility rules.

The result contains allowlisted time-entry fields, visible custom fields when Redmine returns them, browser URLs rooted under REDMINE_BASE_URL, and paging metadata with the upstream offset, limit, and total_count. The server sends only GET /time_entries.json with the shared API-key transport and does not expose upstream error bodies. See Redmine's Time Entries REST API documentation, the current time-entry list API view, and the current time-entry query source.

get_time_entry reads /time_entries/:id.json for the configured API user. It accepts exactly one time_entry_id, which must be a positive safe numeric ID, and sends no query parameters. Its result uses the same allowlisted time-entry fields and browser-link rules as list_time_entries, preserves fields that Redmine omits or returns as null, and includes visible custom fields when Redmine returns them. Redmine enforces the API user's view_time_entries permission and time-entry visibility; 401, 403, and 404 responses are returned as safe status errors without upstream response bodies. See Redmine's time-entry REST API documentation, detail API view, time-entry controller, and time-entry visibility source.

{
  "project_id": "redmine",
  "user_id": 3,
  "activity_id": 9,
  "from": "2026-01-01",
  "to": "2026-01-31",
  "page": 2,
  "limit": 25
}

list_issue_priorities reads all issue priorities from /enumerations/issue_priorities.json. It accepts no query, include, or pagination controls. Redmine's current controller selects shared global IssuePriority records and returns them in the model's position order, which the Redmine guide describes as lower priority to higher priority. The API view returns id, name, is_default, active, and visible custom_fields when present; the tool maps them to id, name, isDefault, active, and customFields, strips every other field, preserves the upstream order, and keeps custom-field null values and omitted version-dependent fields. Redmine added active to the enumeration API in 4.1.0 and enumeration custom-field values in 3.4.0, so older servers may omit those fields. The API index has no ordinary priority show route, and its HTML view is restricted to administrators or API requests, so results have no browser links. Redmine may return HTTP 401, 403, or 404 without exposing the upstream response body. See Redmine's Enumerations REST API documentation, enumerations controller, enumerations API view, IssuePriority model, Enumeration model and ordering scopes, custom-field API renderer, routes, API authorization source, active-field change, and enumeration custom-field change.

list_time_entry_activities reads all shared time-entry activities from /enumerations/time_entry_activities.json. It accepts no query, include, or pagination controls. Redmine's current controller selects shared TimeEntryActivity records and returns them in the enumeration position order. That global collection includes inactive activities and does not return project-specific activity overrides; use the documented project include=time_entry_activities response when project-specific activity availability is needed. The API view returns id, name, is_default, active, and visible custom_fields when present; the tool maps them to id, name, isDefault, active, and customFields, strips every other field, preserves the upstream order, explicit custom-field null values, and omitted version-dependent fields. Redmine added active to the enumeration API in 4.1.0 and enumeration custom-field values in 3.4.0, so older servers may omit those fields. Ordinary API authentication can read this index, while the HTML index is restricted to administrators or API requests. Redmine defines no time-entry-activity show route, so results have no browser links. Redmine may return HTTP 401, 403, or 404 without exposing the upstream response body. See Redmine's Enumerations REST API documentation, Projects REST API documentation, enumerations controller, enumerations API view, TimeEntryActivity model, Enumeration model and ordering scopes, custom-field API renderer, routes, API authorization source, project time-entry activity source, active-field change, and enumeration custom-field change.

list_document_categories reads all shared document categories from /enumerations/document_categories.json. It accepts no query, include, or pagination controls because Redmine's documented endpoint defines none. The current controller selects DocumentCategory.shared.sorted, so the result contains global/shared categories in Redmine's position order and excludes project-specific enumeration overrides. The collection includes inactive categories; current Redmine returns active, while servers older than 4.1.0 may omit it. The current API view returns id, name, is_default, active, and visible custom_fields; enumeration custom-field values were added in Redmine 3.4.0, so older servers may omit custom_fields. The tool maps these fields to id, name, isDefault, active, and customFields, preserves order, explicit custom-field null values, and omitted version-dependent fields, and strips all other upstream data. Redmine accepts ordinary API authentication for this read. Its HTML index is admin-or-API-only for non-admin users and the routes define no document-category show page, so results have no browser links. Redmine may return HTTP 401, 403, or 404 without exposing the upstream response body. See Redmine's Enumerations REST API documentation, enumerations controller, enumerations API view, DocumentCategory model, Enumeration model and ordering scopes, DocumentCategory custom-field model, custom-field API renderer, routes, API authorization source, active-field change, and enumeration custom-field change.

Quick checks

$env:NODE_EXTRA_CA_CERTS = (Resolve-Path .cert\localhost-cert.pem)
node -e 'fetch("https://127.0.0.1:3000/health").then(async response => console.log(await response.text()))'
pnpm test

For HTTP clients, point the MCP client at https://127.0.0.1:3000/mcp. Configure that client to trust the local certificate, or supply a certificate signed by a CA it already trusts. The server supports current MCP HTTP requests and the stateless legacy fallback supplied by the official SDK.

POC boundaries

This cut intentionally has no issue updates, time-entry writes, token rotation, MCP-side authentication, caching, or retries. Anyone who can access the local HTTPS endpoint can read whatever the configured Redmine token can read, which is why the HTTPS process only listens on loopback. Stdio does not open a network port.

Available Tools

35 tools
get_attachmentGet a Redmine attachmentA
Read-onlyIdempotent

Read one visible Redmine attachment from GET /attachments/:id.json for the configured API user. The required attachment_id is a positive safe integer. This endpoint has no documented query or include controls. Results contain the documented attachment metadata, sanitized content and thumbnail URLs, and safe base-path browser and download links. Redmine enforces attachment visibility and may return HTTP 401, 403, or 404. This tool never downloads files, changes attachment metadata, or deletes attachments.

ParametersJSON Schema
NameRequiredDescriptionDefault
attachment_idYesPositive safe-integer Redmine attachment ID

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
urlYes
authorNo
filenameYes
filesizeNo
createdOnNo
contentUrlNo
contentTypeNo
descriptionNo
downloadUrlYes
thumbnailUrlNo

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral context beyond annotations: it explicitly states the tool never downloads files, never changes metadata, and never deletes attachments, and it discloses that Redmine enforces visibility and may return 401/403/404. This is meaningful additional transparency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded: the core action and endpoint appear in the first sentence, followed by parameter constraints, response contents, error behavior, and explicit non-actions. Every sentence earns its place; no filler or repetition of schema details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (one parameter, no nested objects, output schema present), the description is complete. It covers the endpoint, parameter constraint, response contents, error conditions, and non-behaviors. The output schema handles return-value details, so the description need not explain them.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already fully documents the single parameter (attachment_id as a positive safe integer). The description reinforces this by restating the requirement ('required attachment_id is a positive safe integer') and noting there are no query or include controls, which adds a small amount of context beyond the schema. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Read'), a specific resource ('one visible Redmine attachment'), and the exact endpoint (GET /attachments/:id.json). It clearly distinguishes this from sibling tools like list_project_files or get_issue by focusing on the attachment resource. The scope ('for the configured API user') adds precision.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly indicates when to use this tool: to read a single attachment by ID. It does not explicitly name alternative tools for listing attachments or downloading files, but it does state what this tool does not do ('never downloads files'), which helps an agent avoid misusing it. The visibility enforcement and possible HTTP error codes provide context for when the call may fail.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_current_userGet the current Redmine userA
Read-onlyIdempotent

Read the Redmine user represented by the configured API credentials from GET /users/current.json. This non-admin read requires no user_id and accepts only the documented memberships include, which Redmine filters to projects visible to the requesting user. The result uses the same safe public profile contract as get_user and never exposes self-only API keys, administrator status, two-factor settings, password metadata, authentication-source data, or groups. Redmine may return HTTP 401 or 403 when credentials are rejected or the endpoint is not permitted. This tool never changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault
includeNoCurrent-user associations to include: memberships

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
urlYes
emailNo
loginNo
lastNameYes
avatarUrlNo
createdOnNo
firstNameYes
updatedOnNo
lastLoginOnNo
membershipsNo
customFieldsNo

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Despite strong annotations, the description adds meaningful behavior: it documents 401/403 failure modes, Redmine's project-visibility filtering, the safe public profile contract, and the explicit exclusion of self-only fields. It also reassures non-mutation, consistent with readOnlyHint and destructiveHint.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but well-structured, leading with the action and endpoint, then constraints, privacy behavior, and error cases. The final sentence 'This tool never changes Redmine data' is somewhat redundant with the annotations, but the rest of the text earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only tool with one parameter and an output schema, this description is complete: it covers prerequisites, permissions, accepted parameter values, filtering behavior, privacy exclusions, and possible HTTP errors. No important operational context is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% for the single include parameter, so the baseline is 3. The description adds value by explaining that memberships are filtered to projects visible to the requesting user and that no user_id is accepted, which goes beyond the schema's property definition.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb ('Read'), a specific resource ('Redmine user represented by the configured API credentials'), and the exact endpoint ('GET /users/current.json'). It also distinguishes itself from sibling get_user by stating it requires no user_id and returns the authenticated user's profile.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It clearly establishes when to use this tool: for the current authenticated user, as a non-admin read with no user_id. It mentions the only valid include and the visibility filtering, but it does not explicitly state a when-not case or name an alternative to prefer for fetching other users by ID.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_issueGet a Redmine issueA
Read-onlyIdempotent

Read one visible Redmine issue from GET /issues/:id.json for the configured API user. The required issue_id is a positive issue ID. Optionally include children, attachments, relations, changesets, journals, watchers, allowed_statuses, and reactions. This tool never changes Redmine data; include=journals also returns the issue's journal history.

ParametersJSON Schema
NameRequiredDescriptionDefault
includeNoIssue associations to include: children, attachments, relations, changesets, journals, watchers, allowed_statuses, or reactions
issue_idYesPositive Redmine issue ID

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
urlYes
authorYes
parentYes
statusYes
dueDateYes
projectYes
subjectYes
trackerYes
categoryYes
childrenYes
closedOnYes
journalsYes
priorityYes
watchersYes
createdOnYes
doneRatioYes
isPrivateYes
reactionsYes
relationsYes
startDateYes
updatedOnYes
assignedToYes
changesetsYes
spentHoursYes
attachmentsYes
descriptionYes
customFieldsYes
fixedVersionYes
estimatedHoursYes
allowedStatusesYes
totalSpentHoursYes
totalEstimatedHoursYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, and the description reinforces this with 'This tool never changes Redmine data.' It adds a specific behavioral detail about include=journals returning journal history, which goes beyond the schema. It does not mention auth specifics or rate limits, but for a read-only tool the description is sufficiently transparent given the annotation coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the primary action and endpoint, followed by a brief behavioral note. Every sentence earns its place; there is no redundant fluff or repetition of schema content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only tool with a simple parameter set and an output schema (mentioned as present), the description covers purpose, parameter constraints, and a key behavioral detail. It does not need to explain return format since the output schema exists, and error handling is not required for a basic read operation. Sibling differentiation is implicit but sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters are fully documented in the schema. The description adds a useful clarification that issue_id must be positive (already in schema) and highlights the journal history behavior for the include parameter, which adds value beyond the schema. It does not explain each include option's semantics, but the schema already lists them.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb (Read), resource (one visible Redmine issue), and even the exact API endpoint (GET /issues/:id.json). It distinguishes from siblings like list_issues by explicitly limiting to a single issue, and from get_issue_relation by focusing on the issue itself. The addition of 'for the configured API user' adds precision.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly implies usage for a single issue retrieval ('Read one visible Redmine issue'), which distinguishes it from list_issues for bulk retrieval. It does not explicitly name alternatives or exclusion conditions, but the context is unambiguous enough for an agent to infer when to use it. The include parameter guidance is also implicit rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_issue_categoryGet a Redmine issue categoryA
Read-onlyIdempotent

Read one visible Redmine issue category from GET /issue_categories/:id.json for the configured Redmine API user. The required issue_category_id is a positive safe integer. This endpoint accepts no query, include, or undocumented controls, and results contain only the current issue-category serializer fields with camelCase names, preserving explicit nulls and omitted associations. A safe browser URL is added only to the returned project reference. The category HTML show route redirects to member-only project settings, and assigned_to is a Principal that may be a user or group, so categories and assignees receive no browser URLs. This is a non-admin read authorized by the category project's view_issues permission with the issue_tracking module enabled, subject to Redmine's project visibility and ordinary permission checks. Redmine may return HTTP 401, 403, or 404. This tool never changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault
issue_category_idYesPositive safe-integer Redmine issue category ID

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
nameYes
projectNo
assignedToNo

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark this as read-only and idempotent, but the description goes well beyond them: it specifies the exact HTTP endpoint, the lack of query/include/undocumented controls, serializer behavior (camelCase, explicit nulls, omitted associations), browser URL handling, permission requirements, possible HTTP 401/403/404 responses, and explicitly states 'This tool never changes Redmine data.' This is rich, non-redundant behavioral disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but front-loaded: the core purpose appears in the first sentence, followed by tightly packed operational details. Each sentence earns its place by covering parameters, response shape, URL behavior, permissions, errors, or mutation guarantees. There is no filler or repetition that bloats the definition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter read with an output schema and strong annotations, the description is complete. It covers authentication/permission context, expected error statuses, response serialization nuances, non-mutation, and the exact resource path. No critical information an agent needs to call this tool correctly appears to be missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%: issue_category_id is fully described as a positive safe-integer Redmine issue category ID with constraints. The description repeats 'required issue_category_id is a positive safe integer' and ties it to the endpoint path placeholder, but adds no meaning beyond the schema. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Read one visible Redmine issue category from GET /issue_categories/:id.json.' The singular 'one' and the explicit endpoint clearly distinguish this from the sibling list_project_issue_categories. The title and description align without tautology.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly implies this tool is for fetching a single issue category by ID, and it provides useful context about permissions and error responses. However, it never explicitly names alternative tools such as list_project_issue_categories or states when to prefer one over the other. Usage is implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_issue_relationGet a Redmine issue relationA
Read-onlyIdempotent

Read one visible Redmine issue relation from GET /relations/:id.json for the configured API user. The required relation_id is one positive safe numeric ID. This route has no query controls. The result contains only documented relation fields and safe base-path browser links for valid issue and relation IDs, preserving Redmine's explicit null or omitted delay. Redmine accepts ordinary API authentication, enforces visibility for both linked issues, and may return HTTP 401, 403, or 404. This tool never changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault
relation_idYesPositive Redmine issue relation ID

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
urlNo
delayNo
issueIdYes
issueUrlNo
issueToIdYes
issueToUrlNo
relationTypeYes

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, the description discloses authentication expectations ('ordinary API authentication'), visibility constraints on both linked issues, possible HTTP 401/403/404 outcomes, and preservation of Redmine's null/omitted delay. It also states that no data is changed, reinforcing the read-only annotation. No contradiction with annotations exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description leads with the purpose, then quickly covers the required parameter and behavioral caveats. It is organized and mostly economical, though the final 'never changes Redmine data' sentence largely duplicates the readOnlyHint/destructiveHint annotations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With one well-constrained parameter and an output schema present, the description covers the remaining operational context: visibility rules, auth, error codes, and result contents. It is complete enough for an agent to decide whether to call the tool and to know what to expect.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents relation_id as a positive integer with bounds. The description adds little beyond the word 'safe' and the requirement that the ID be a positive numeric ID; no parameter semantics are missing.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Read'), a precise resource ('Redmine issue relation'), and the exact endpoint ('GET /relations/:id.json'), plus the scope 'one visible ... for the configured API user.' The singularity of the resource and endpoint distinguish it from listing siblings such as list_issue_relations, even though that sibling is not named.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly sets the invocation context: use this tool to read a single, visible issue relation by relation_id for the configured API user. It also notes there are no query controls and that visibility is enforced for both linked issues. It does not explicitly name alternatives like list_issue_relations for multi-result needs, so it stops short of the strongest usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_my_accountGet my Redmine accountA
Read-onlyIdempotent

Read the current user's own Redmine account from GET /my/account.json for the configured API credentials. This endpoint accepts an empty object only and sends no query, include, pagination, or administrator controls. The result allowlists the official account view's safe profile fields and visible custom fields, strips the API key and administrator flag, preserves explicit nulls and omitted version-dependent fields, and adds the ordinary-user /my/account browser URL. Redmine may return HTTP 401 or 403 when credentials are rejected or the endpoint is not permitted. This tool never changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
urlYes
emailNo
loginYes
lastNameYes
createdOnNo
firstNameYes
lastLoginOnNo
customFieldsNo

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes well beyond the annotations. It confirms read-only, idempotent, and non-destructive behavior as annotations, but adds specific behavioral details: 'preserves explicit nulls and omitted version-dependent fields', 'strips the API key and administrator flag', and 'adds the ordinary-user /my/account browser URL'. It also discloses possible HTTP 401 or 403 responses. This is rich, useful context that annotations do not provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is informative but long, containing multiple clauses about field stripping, null preservation, and URL addition. While each sentence adds value, the description is dense and could be front-loaded with the core purpose. The first sentence is clear, but the subsequent details make it wordy. It is not overly verbose, but there is room for better structure.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the zero parameters, rich annotations, and an available output schema, the description is complete. It covers the endpoint's input expectations, behavioral transformations, error conditions, and safety. The agent has all necessary information to invoke the tool correctly without further inference. The output schema handles return details.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With zero parameters, the schema provides no parameter details. The description compensates by explaining that the endpoint accepts an empty object only and sends no query/include/pagination controls. This is crucial for an agent to know that no parameters are needed and that the tool has no configuration options. The baseline for 0 params is 4, but the explicit statement about the empty object and lack of controls pushes it to 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool reads the current user's own Redmine account data from a specific endpoint, and it names the endpoint and HTTP method, distinguishing it from sibling tools like get_current_user and get_user. It is explicit about scope ('current user's own') and action ('Read'), fully differentiating it from other read tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description does not explicitly state when to use this tool versus alternatives, nor does it mention alternatives like get_current_user. It implies it is for reading the current user's account, but an agent might not know when to choose this over get_current_user or get_user. No exclusions are given for when not to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_newsGet a Redmine news itemA
Read-onlyIdempotent

Read one visible Redmine news item from GET /news/:id.json for the configured API user. The required news_id is one positive safe numeric ID. Optionally include the documented attachments, comments, and reactions associations. Redmine enforces news and project visibility and may return HTTP 401, 403, or 404. This tool never changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault
includeNoNews associations to include: attachments, comments, or reactions
news_idYesPositive Redmine news ID

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
urlYes
titleYes
authorNo
projectNo
summaryNo
commentsNo
createdOnYes
reactionsNo
attachmentsNo
descriptionYes

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, openWorld, idempotent, and non-destructive. The description adds genuinely useful context beyond those: Redmine enforces news and project visibility, and may return HTTP 401, 403, or 404. The 'never changes Redmine data' line repeats destructiveHint=false but serves as reinforcement rather than a contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four front-loaded sentences with no filler; the core purpose leads, followed by parameter notes, error behavior, and a safety statement. Each sentence earns its place. The closing 'never changes data' is slightly redundant given annotations, keeping it from a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description need not explain return values. It covers purpose, parameter constraints, error behavior, and visibility limits for a single-item read tool, which is sufficient for correct invocation. Only sibling routing is absent, a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so both parameters are already documented in the schema. The description adds slight value by framing news_id as a 'positive safe numeric ID' (echoing the exclusiveMinimum and MAX_SAFE_INTEGER bounds) and labeling the include associations, but it does not materially expand on the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

'Read one visible Redmine news item from GET /news/:id.json' states a specific verb, resource, and exact endpoint. The qualifier 'one' cleanly distinguishes this single-item fetch from the sibling list tools (list_news, list_project_news), and 'for the configured API user' pins down the identity context.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the tool is for fetching a specific known news_id, and the visibility/error discussion hints at when it may fail. However, it never names alternatives or states when to prefer this over list_news or list_project_news, leaving the selection decision to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_projectGet a Redmine projectA
Read-onlyIdempotent

Read one visible Redmine project from GET /projects/:id.json for the configured API user. The required project_id is a positive numeric project ID or valid project identifier. Optionally include trackers, issue_categories, enabled_modules, time_entry_activities, and issue_custom_fields. This tool never changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault
includeNoProject associations to include: trackers, issue_categories, enabled_modules, time_entry_activities, or issue_custom_fields
project_idYesPositive numeric project ID or valid Redmine project identifier

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
urlYes
nameYes
parentYes
statusYes
homepageYes
isPublicYes
trackersYes
createdOnYes
updatedOnYes
identifierYes
descriptionYes
customFieldsYes
defaultVersionYes
enabledModulesYes
inheritMembersYes
defaultAssigneeYes
issueCategoriesYes
issueCustomFieldsYes
timeEntryActivitiesYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, and the description adds useful context: 'for the configured API user', the visibility qualifier, and the explicit guarantee 'This tool never changes Redmine data'. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core action is front-loaded in the first sentence, and the final sentence adds value with the safety guarantee. The second sentence largely mirrors the schema, creating slight redundancy, but the overall description remains compact and well organized.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and read-only annotations covering safety, the description provides everything needed to invoke the tool correctly: endpoint, required parameter, optional includes, user scoping, and non-mutation guarantee. Nothing critical is missing for this low-complexity, two-parameter tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents project_id and include meaning. The description restates these semantics ('positive numeric project ID or valid project identifier', 'Optionally include...') without adding format, syntax, or behavioral detail beyond the schema, meriting the baseline 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Read one visible Redmine project from GET /projects/:id.json'. 'One' differentiates it from list-style siblings like list_projects, and the endpoint plus 'visible' scoping makes the purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clear usage context is provided: the tool reads a single project by ID or identifier, with optional association includes. It doesn't explicitly name alternatives such as list_projects for enumerating all projects, so the when-not guidance is implied rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_project_membershipGet a Redmine project membershipA
Read-onlyIdempotent

Read one project membership from GET /memberships/:id.json for the configured Redmine API user. The required membership_id is a positive safe integer, and this endpoint has no query parameters. Results distinguish user and group principals, preserve roles including inherited flags, and never expose administrative group links. This is a non-admin read, but Redmine still enforces the membership's project visibility and permissions and may return HTTP 403 when the user lacks the relevant project permission. This tool never changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault
membership_idYesPositive Redmine membership ID

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
rolesYes
projectYes
principalYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false. The description adds meaningful behavioral context: it explains permission enforcement, possible HTTP 403, result characteristics (user/group distinction, inherited flags, no admin group links), and confirms no data mutation. This goes beyond annotations and provides valuable safety and error-handling information.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is structured efficiently, leading with the core purpose, then parameter detail, result specifics, permission behavior, and a final safety note. Each sentence contributes unique information without redundancy, and the length is justified by the richness of context provided.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the existence of an output schema, the description need not detail return structures. It covers the tool's action, parameter constraints, permission outcomes, and result nuances, making it sufficiently complete for an agent to invoke correctly. Minor omissions like explicit pagination or full output format are covered by the output schema, so this is well-rounded.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already fully describes membership_id as a positive safe integer with bounds, and description coverage is 100%. The description repeats 'positive safe integer' and adds that the endpoint has no query parameters, but does not introduce new parameter meaning beyond what the schema provides. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description explicitly states 'Read one project membership' and identifies the resource and endpoint. It clearly distinguishes itself from the sibling list_project_memberships by specifying it retrieves a single item by ID, making the purpose unambiguous and differentiating from related tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage when a single membership is needed by ID and notes it is a non-admin read that may return 403. However, it does not explicitly contrast with list_project_memberships or state when to prefer this tool over others, leaving some selection guidance implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_project_wiki_pageGet a Redmine project wiki pageA
Read-onlyIdempotent

Read one current project wiki page from GET /projects/:project_id/wiki/:title.json for the configured Redmine API user. The required project_id is a positive numeric project ID or valid Redmine project identifier, and title must be a safe nonempty wiki page title. The only documented include is attachments. Results contain the current page fields and safe base-path browser links. Redmine enforces the ordinary view_wiki_pages permission and may return HTTP 401, 403, or 404. This tool does not read historic versions or change Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault
titleYesNonempty Redmine wiki page title
includeNoWiki page associations to include: attachments
project_idYesPositive numeric project ID or valid Redmine project identifier

Output Schema

ParametersJSON Schema
NameRequiredDescription
urlYes
textYes
titleYes
authorNo
parentNo
projectNo
versionYes
commentsYes
createdOnNo
updatedOnNo
attachmentsNo

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already convey read-only, idempotent, non-destructive behavior. The description adds meaningful behavioral context: required view_wiki_pages permission, possible HTTP 401/403/404 responses, and confirmation that no Redmine data is changed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three dense sentences front-load the core action and endpoint, then cover parameter constraints, include options, permissions, error behavior, and exclusions. Every sentence earns its place with no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need no elaboration. The description covers endpoint, parameters, permissions, error cases, and scope limitations, making it fully adequate for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds value by clarifying the 'safe nonempty' title constraint and noting that the only documented include is attachments, which reinforces the schema enum without repeating it verbatim.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource ('Read one current project wiki page') and names the exact endpoint. It clearly distinguishes itself from the sibling get_project_wiki_page_version by stating it does not read historic versions.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context about what this tool retrieves and explicitly excludes historic versions, which routes agents away from the version endpoint. It does not explicitly name the alternative, but the exclusion is concrete enough for correct selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_project_wiki_page_versionGet a historic Redmine project wiki page revisionA
Read-onlyIdempotent

Read one historic project wiki page revision from GET /projects/:project_id/wiki/:title/:version.json for the configured Redmine API user. The required project_id is a positive numeric project ID or valid Redmine project identifier, title must be a safe nonempty wiki page title, and version must be a positive safe integer. The only documented include is attachments. Results use the historic revision fields and a safe browser link that includes the revision number. Redmine authorizes the ordinary view_wiki_pages permission and separately requires view_wiki_edits for versioned reads; it may return HTTP 401, 403, or 404. This tool never reads the history listing or changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault
titleYesNonempty Redmine wiki page title
includeNoWiki page associations to include: attachments
versionYesPositive safe-integer wiki page version
project_idYesPositive numeric project ID or valid Redmine project identifier

Output Schema

ParametersJSON Schema
NameRequiredDescription
urlYes
textYes
titleYes
authorNo
parentNo
projectNo
versionYes
commentsYes
createdOnNo
updatedOnNo
attachmentsNo

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and destructiveHint=false, but the description adds valuable behavioral context: required Redmine permissions (view_wiki_pages plus view_wiki_edits), possible HTTP 401/403/404 responses, and the guarantee that it never reads the history listing or mutates data. This exceeds the annotation baseline.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Five dense, front-loaded sentences cover endpoint, constraints, includes, results, permissions, errors, and side effects without redundancy. Every sentence earns its place, and the most important scoping information appears first.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description is complete for a read-only tool: it specifies the endpoint path, parameter constraints, the only include option, permission requirements, error responses, and confirms no mutation. The presence of an output schema covers return-value details, so nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents all four parameters fully. The description adds some semantics by mapping parameters to the URL path and emphasizing 'safe' positive integers, but these largely restate the schema constraints. It does not meaningfully change how an agent would fill in the parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Read one historic project wiki page revision,' which clearly identifies the action and object. It also distinguishes itself from the sibling get_project_wiki_page by emphasizing 'historic' and 'revision,' making its scope unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context: it reads a specific versioned revision, never reads the history listing, and does not change Redmine data. It does not explicitly name an alternative like get_project_wiki_page for current revisions, but the historical vs. current distinction is strong enough that an agent can infer when to use it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_roleGet a Redmine roleA
Read-onlyIdempotent

Read one Redmine role from GET /roles/:id.json for the configured Redmine API user. The required role_id is a positive safe integer. This detail endpoint accepts ordinary API authentication, sends no query, include, pagination, or undocumented controls, and can return a built-in Non member or Anonymous role when its ID is known; unlike GET /roles.json, it is not limited to givable project-member roles. Results map the current serializer fields id, name, assignable, issues_visibility, time_entries_visibility, users_visibility, and ordered permissions to camelCase, validate the closed visibility enum domains, preserve permission order, preserve explicit nulls, and preserve omission of the Redmine 4.0+ assignable and visibility fields on older servers. The HTML roles page is admin-only for ordinary browser requests, so results have no browser links. Redmine may return HTTP 401, 403, or 404 without exposing the upstream response body. This tool never changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault
role_idYesPositive Redmine role ID

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
nameYes
assignableNo
permissionsYes
usersVisibilityNo
issuesVisibilityNo
timeEntriesVisibilityNo

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false. The description adds substantial context beyond this: it explains the endpoint's behavior (sends no query/include/pagination), that it can return built-in roles, that it preserves field order, nulls, and omission of fields on older servers, and that Redmine may return 401/403/404 without exposing the response body. It also explicitly states 'This tool never changes Redmine data,' reinforcing the read-only nature. No contradictions with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is detailed but every sentence carries meaningful information. It is front-loaded with the core purpose and endpoint, followed by parameter note, usage distinction, response behavior, and error handling. No fluff or redundant statements; it earns its length with actionable details.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the presence of an output schema, the description does not need to explain return values. It covers authentication, endpoint, parameter constraints, usage distinction, response mapping details, and error behavior. For a single-parameter tool, this is comprehensive and leaves no critical gaps for an agent to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already provides full description and constraints for role_id (positive integer, maximum, exclusiveMinimum). The description restates 'positive safe integer' which adds little beyond the schema. Since schema coverage is 100%, the baseline is 3, and the description does not introduce new parameter semantics beyond restating what is already known.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Read'), resource ('one Redmine role'), and the exact endpoint ('GET /roles/:id.json'). It explicitly distinguishes this from the sibling list_roles tool by noting it is not limited to givable project-member roles, which allows an agent to select the correct tool without ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides explicit guidance on when to use this tool: when a specific role ID is known and the role may be a built-in (Non member or Anonymous) role. It also contrasts with list_roles, clarifies that it accepts ordinary API authentication, and notes what it does not do (no query, include, pagination, or undocumented controls). This leaves no ambiguity about usage context or alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_time_entryGet a Redmine time entryA
Read-onlyIdempotent

Read one visible Redmine time entry from GET /time_entries/:id.json for the configured API user. The required time_entry_id is one positive safe numeric ID. The result contains only the documented time-entry fields, visible custom fields when returned, and base-path-safe browser URLs. Redmine enforces the user's view_time_entries permission and time-entry visibility and may return 401, 403, or 404. This tool never changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault
time_entry_idYesPositive Redmine time-entry ID

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
urlYes
userNo
hoursYes
issueNo
projectNo
spentOnNo
activityNo
commentsNo
createdOnNo
updatedOnNo
customFieldsNo

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Even with readOnlyHint and destructiveHint annotations, the description adds meaningful behavioral context: the exact endpoint, permission requirements, possible 401/403/404 responses, visible custom fields, URL behavior, and an explicit statement that it never changes Redmine data. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but every sentence contributes: the action and endpoint are front-loaded, followed by parameter, result, permission/error behavior, and safety. There is no filler or unnecessary repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter read tool with an output schema and strong annotations, the description covers everything needed to invoke it correctly: endpoint, required ID, permission/error behavior, result shape, and side-effect-free guarantee. It is fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the parameter is well-documented in the schema. The description adds that the ID is 'positive safe numeric' and required, but this mostly restates the schema's exclusiveMinimum and integer type, so it only marginally adds meaning.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description is explicit: 'Read one visible Redmine time entry from GET /time_entries/:id.json for the configured API user.' This names a specific verb, resource, and endpoint, and the singular 'one' clearly distinguishes it from list-oriented siblings like list_time_entries.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly positions this as a single-resource read by ID and notes the configured API user and visibility constraints. It does not explicitly name alternatives or state when not to use it, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_userGet a Redmine userA
Read-onlyIdempotent

Read one visible Redmine user from GET /users/:id.json for the configured API user. The required user_id is a positive safe integer. Optionally include memberships, which Redmine documents for non-admin callers and filters to projects visible to the requesting user. Redmine omits private or administrator-only fields such as email when hidden, status, API keys, two-factor settings, authentication sources, groups, and password metadata. This is a non-admin read, but Redmine still enforces user visibility and may return HTTP 403 or 404. This tool never changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault
includeNoUser associations to include: memberships
user_idYesPositive Redmine user ID

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
urlYes
emailNo
loginNo
lastNameYes
avatarUrlNo
createdOnNo
firstNameYes
updatedOnNo
lastLoginOnNo
membershipsNo
customFieldsNo

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral context beyond annotations: it explains that Redmine may return 403/404 due to visibility enforcement, that private fields are omitted, and that memberships are filtered to visible projects. It also explicitly states 'This tool never changes Redmine data,' reinforcing the read-only nature. This is strong behavioral disclosure for a read tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded: it opens with the core action and endpoint, then adds parameter semantics, then behavioral caveats, and ends with a clear safety statement. Every sentence earns its place, and there is no redundant repetition of schema or annotation content. It is appropriately sized for the tool's complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (2 params, 1 required), the rich annotations, and the presence of an output schema, the description is complete. It covers the endpoint, parameter semantics, visibility/error behavior, field filtering, and read-only guarantee. An agent has everything needed to select and invoke this tool correctly without opening the schema or output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents both parameters. The description adds meaning by explaining that user_id must be a 'positive safe integer' and by elaborating on the include parameter's behavior: memberships are documented for non-admin callers and filtered to visible projects. This goes beyond the schema's terse descriptions and helps an agent understand the practical effect of the parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Read'), a specific resource ('one visible Redmine user'), and the exact endpoint ('GET /users/:id.json'). It also clarifies the scope ('for the configured API user') and distinguishes it from list-style siblings by emphasizing 'one' user. This is unambiguous and clearly differentiates from sibling tools like get_current_user or list_projects.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context on when to use this tool: to read a single user by ID, with optional memberships inclusion. It does not explicitly name alternative tools or state when not to use it, but the context is strong enough that an agent can infer it is for single-user reads rather than listing or current-user operations. The mention of non-admin behavior and visibility rules adds useful usage context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_versionGet a Redmine versionA
Read-onlyIdempotent

Read one visible Redmine version from GET /versions/:id.json for the configured Redmine API user. The required version_id is a positive safe integer, and this route has no query parameters or documented include controls. Results include the documented version fields and visible custom fields, plus estimatedHours and spentHours only when Redmine returns them. Redmine enforces version and project visibility and may return HTTP 401, 403, or 404. This tool never changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault
version_idYesPositive Redmine version ID

Output Schema

ParametersJSON Schema
NameRequiredDescription
idYes
urlYes
nameYes
statusNo
dueDateNo
projectNo
sharingNo
createdOnNo
updatedOnNo
spentHoursNo
descriptionNo
customFieldsNo
wikiPageTitleNo
estimatedHoursNo

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral context: it explicitly states 'This tool never changes Redmine data,' notes that visibility is enforced by Redmine, and discloses possible HTTP error codes (401, 403, 404). It also explains that estimatedHours and spentHours are included only when Redmine returns them, which is useful conditional behavior. This goes beyond the annotations without contradicting them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is compact and front-loaded: it opens with the core action and resource, then adds route details, parameter constraints, response behavior, and error conditions in a logical order. Every sentence adds value, and there is no repetition of schema or annotation content. It is appropriately sized for the tool's simplicity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter read tool with a rich output schema, the description covers everything an agent needs: the route, the parameter, the response fields, visibility/error behavior, and the no-mutation guarantee. The output schema exists, so return values need not be enumerated in the description. The tool is simple, and the description is complete for its complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents version_id as a positive Redmine version ID. The description adds meaning by specifying that version_id must be a 'positive safe integer' and that the route has no query parameters or include controls, which clarifies the parameter's role and constraints beyond the schema. This is a solid complement to the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Read'), a specific resource ('one visible Redmine version'), and the exact API route ('GET /versions/:id.json'). It also clarifies the scope ('for the configured Redmine API user') and distinguishes it from list_project_versions by focusing on a single version by ID. This is unambiguous and clearly differentiated from siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly states when to use this tool: to read one visible Redmine version by ID. It also implicitly distinguishes it from list_project_versions (which lists versions) and other get_* tools. However, it does not explicitly name alternatives or state when not to use it, so it falls just short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_document_categoriesList Redmine document categoriesA
Read-onlyIdempotent

Read all shared Redmine document categories from GET /enumerations/document_categories.json for the configured Redmine API user. This endpoint accepts no query, include, or pagination controls and preserves Redmine's shared position order. Results map id, name, is_default, active, and visible custom_fields to id, name, isDefault, active, and customFields, preserving upstream order, explicit custom-field null values, and omitted version-dependent fields. The active field is available since Redmine 4.1.0 and enumeration custom-field values since 3.4.0. The shared collection includes inactive categories when Redmine returns them and does not include project-specific enumeration overrides. The HTML index is admin-or-API-only for non-admin users and Redmine has no document-category show route, so results have no browser links. Redmine may return HTTP 401, 403, or 404 without exposing the upstream response body. This tool never changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
documentCategoriesYes

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint/idempotentHint annotations, the description discloses several meaningful behaviors: no query/include/pagination controls, preservation of upstream order, explicit field mapping, version-dependent field availability, error behavior with 401/403/404, and the absence of browser links. This is rich, accurate behavior disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense and front-loaded, with the core purpose in the first sentence and every later sentence adding relevant behavioral or versioning detail. It is somewhat long, and the final sentence ('This tool never changes Redmine data') largely restates the annotations, which costs it a perfect score.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a no-parameter read tool with an output schema, this description is unusually complete: it states the endpoint, field mapping, version thresholds, shared-versus-project scope, browser-link absence, error behavior, and mutation safety. Nothing an agent needs to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters and the schema is empty, so there is no parameter semantics to document. The description still adds useful context by confirming that the endpoint accepts no query, include, or pagination controls, which exceeds the baseline for a zero-parameter tool.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb ('Read') and resource ('all shared Redmine document categories') and even identifies the exact endpoint. This clearly distinguishes the tool from siblings like list_issue_categories and list_projects without needing to inspect schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear contextual scope by explaining that the result is the shared collection, includes inactive categories when Redmine returns them, and excludes project-specific enumeration overrides. It does not explicitly name alternative tools, but no sibling directly competes with this resource, so the context is sufficient.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_issue_prioritiesList Redmine issue prioritiesA
Read-onlyIdempotent

Read all Redmine issue priorities from GET /enumerations/issue_priorities.json for the configured Redmine API user. This endpoint accepts no query, include, or pagination controls and returns shared global priorities in Redmine's lower-to-higher position order. Results map id, name, is_default, active, and visible custom_fields to id, name, isDefault, active, and customFields, preserving upstream order, explicit custom-field null values, and omitted version-dependent fields. The active field is available since Redmine 4.1.0 and enumeration custom-field values since 3.4.0. The HTML index is admin-or-API-only for non-admin users and Redmine has no priority show route, so results have no browser links. Redmine may return HTTP 401, 403, or 404 without exposing the upstream response body. This tool never changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
issuePrioritiesYes

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond annotations by disclosing that the tool never changes Redmine data, that upstream errors may surface as 401/403/404 without response body exposure, and that ordering, custom-field nulls, omitted version-dependent fields, and result mapping have specific behavior. This gives agents practical expectations not available from readOnlyHint/idempotentHint alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The first sentence front-loads the purpose and endpoint, and every subsequent sentence adds operational detail such as ranking order, field mapping, version availability, browser-link absence, and error behavior. It is dense rather than verbose, though a few edge-case details could be considered extra for a zero-parameter tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers the endpoint, parameter restrictions, ordering, field mapping, version caveats, upstream error handling, lack of browser links, and non-mutation guarantee. Since an output schema exists, return-value documentation is already covered, and no critical calling guidance appears missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has zero parameters and schema description coverage is 100%, so the baseline is 4. The description reinforces this by stating there are no query, include, or pagination controls, which helps the agent avoid inventing unsupported options.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clearly states the verb and resource: 'Read all Redmine issue priorities from GET /enumerations/issue_priorities.json...' and defines scope with 'shared global priorities' and 'lower-to-higher position order.' This distinguishes it from sibling list tools like list_issue_statuses and list_document_categories.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides clear context by specifying this is a read-only enumeration for the configured Redmine API user and explicitly notes the endpoint accepts no query, include, or pagination controls. It does not name alternatives or direct when-not-to-use conditions, but the resource is unique among the sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_issue_relationsList Redmine issue relationsA
Read-onlyIdempotent

Read the visible relations for one Redmine issue from GET /issues/:issue_id/relations.json for the configured API user. The required issue_id is one positive safe numeric ID. This Redmine route has no query controls or pagination. Results contain only relation fields and safe base-path browser links for valid issue and relation IDs. Redmine enforces issue and related-project visibility and may return HTTP 401, 403, or 404. This tool never changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault
issue_idYesPositive Redmine issue ID

Output Schema

ParametersJSON Schema
NameRequiredDescription
relationsYes

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly, idempotent, and non-destructive behavior; the description adds valuable context beyond that: error semantics ('may return HTTP 401, 403, or 404'), Redmine's issue and related-project visibility enforcement, absence of pagination, and that returned links are safe base-path browser links for valid IDs. The closing line 'This tool never changes Reddit data' is consistent with the annotations and reinforces the safety profile.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is five sentences, slightly longer than strictly minimal, but every sentence carries distinct information: endpoint and scope, input constraint, absence of pagination, response/link behavior, and error/visibility semantics. It is front-loaded with the primary purpose and contains no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter read-only tool with an output schema that covers return shape, the description is nearly complete: it covers input constraints, mutational safety, auth failures (401), visibility enforcement (403/404), and the out-of-scope behaviors (no filter or pagination). That depth of context is still slightly above what a simple read tool needs.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the schema already documents issue_id as a positive integer with an exclusive minimum of 0 and a safe-integer maximum. The description repeats 'one positive safe numeric ID,' adding a safety framing but no new format or meaning beyond the schema. Baseline 3 is appropriate since the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence states a specific verb ('Read'), an exact resource ('visible relations for one Redmine issue'), and the precise endpoint ('GET /issues/:issue_id/relations.json'). The scope ('one issue', all visible relations, no query controls) distinguishes it from the sibling get_issue_relation, which fetches a single relation. This makes the tool's role unambiguous against the 33 sibling tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear situational context: it lists all visible relations for one issue for the configured API user, and explicitly notes the route 'has no query controls or pagination' so an agent knows it cannot filter or page results. It does not explicitly name alternatives like get_issue_relation or state when not to use it, so it stops short of a full exclusions-based 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_issuesList Redmine issuesA
Read-onlyIdempotent

Read visible Redmine issues from GET /issues.json for the configured API user. Supports offset and limit up to 100, sorting, attachments and relations, issue_id, project_id, subproject_id, tracker_id, status_id, assigned_to_id, parent_id, query_id, created_on, updated_on, and numeric-ID custom-field filters. This tool never changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault
sortNoComma-separated Redmine sort fields, each optionally followed by :asc or :descupdated_on:desc
limitNoNumber of issues to return. Redmine caps this at 100.
offsetNoNumber of issues to skip
includeNoIssue associations to include
issue_idNoIssue ID or comma-separated issue IDs
query_idNoSaved query ID
parent_idNoParent issue ID
status_idNoStatus ID, open, closed, or * for open and closed issuesopen
created_onNoRedmine date or date-time filter, including operators and ranges
project_idNoProject ID
tracker_idNoTracker ID
updated_onNoRedmine date or date-time filter, including operators and ranges
custom_fieldsNoCustom field filters as [{ id, value }] or an object keyed by numeric field ID
subproject_idNoSubproject ID or !* to exclude subprojects
assigned_to_idNoAssignee ID or me for the API user

Output Schema

ParametersJSON Schema
NameRequiredDescription
issuesYes
pagingYes
filtersYes

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With annotations already declaring readOnlyHint and non-destructive behavior, the description's 'never changes Redmine data' adds little. It does provide useful behavioral context beyond annotations: only issues visible to the configured API user are returned. No error, rate-limit, or pagination behavior beyond what the schema specifies is disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description opens with a clear purpose statement and then lists capabilities in a dense, readable second sentence. The final, third sentence about not changing data is redundant given annotations, but the description remains concise and efficient overall.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a list tool with 15 parameters and a rich output schema, the description provides enough context: the endpoint, scope (visible to API user), and full filter support. It does not explain return format or indicate when to consult siblings, but the output schema and sibling names cover those gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so each parameter already has a detailed description. The tool description merely enumerates the filter names and restates the offset/limit caps already present in the schema, adding no new meaning or operator examples beyond that.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Read visible Redmine issues from GET /issues.json') and clearly scopes it to the configured API user. The extensive list of filters differentiates it from sibling single-issue and resource-specific tools like get_issue and list_my_assigned_issues.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage for listing issues with arbitrary filters but does not explicitly say when to choose this tool versus alternatives such as list_my_assigned_issues or get_issue. It provides clear context on capabilities but no exclusions or alternative routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_issue_statusesList Redmine issue statusesA
Read-onlyIdempotent

Read all Redmine issue statuses from GET /issue_statuses.json for the configured Redmine API user. This endpoint accepts no query, include, or pagination controls. Results preserve Redmine's position order and map the current API fields id, name, is_closed, and description to id, name, isClosed, and description, preserving an explicit null or an omitted description. Redmine accepts ordinary API authentication for this index, but its HTML index is admin-or-API-only and there is no status show route, so the result has no browser links. Redmine may return HTTP 401, 403, or 404 without exposing the upstream response body. This tool never changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
issueStatusesYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark the tool read-only and idempotent. The description goes well beyond them by disclosing the field-name mapping to camelCase, null/omitted description handling, lack of browser links, and possible HTTP 401/403/404 responses without an exposed body.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but every sentence carries unique information: endpoint, scope, lack of controls, field mapping, auth/browser-link caveats, error behavior, and non-mutating guarantee. Nothing is wasted or redundant with the annotations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter read tool, the description covers endpoint, auth expectations, response mapping, error behavior, and safety. An output schema exists for return values, so the description is fully sufficient for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are zero parameters, and the schema already reflects this. The description adds meaningful value by explicitly stating that the endpoint accepts no query, include, or pagination controls, removing any doubt about hidden options.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb, resource, and endpoint: 'Read all Redmine issue statuses from GET /issue_statuses.json.' The scope ('all') and resource are unambiguous, and the resource is distinct from every sibling tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides clear context: this is a complete read with no query/include/pagination controls and uses ordinary authentication. It does not name alternative tools, but no sibling covers issue statuses, so the omission is acceptable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_my_assigned_issuesList my assigned Redmine issuesA
Read-onlyIdempotent

List Redmine issues assigned to the user represented by the server's configured API token. Results are ordered by most recently updated.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum issues to return. Redmine caps this at 100.
offsetNoPagination offset
statusNoIssue status to includeopen

Output Schema

ParametersJSON Schema
NameRequiredDescription
userYes
issuesYes
pagingYes
filtersYes

TDQS

A4/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, and openWorldHint=true. The description adds the authentication context and ordering, which are useful behavioral traits not covered by annotations. However, it doesn't disclose pagination defaults or that it only returns issues visible to the token user (e.g., permissions limitations), so it doesn't go far beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no waste. The primary purpose and scope are front-loaded, and it's appropriately sized for a simple list tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the simplicity, 3 params (all optional with defaults), rich annotations, and presence of an output schema, the description is nearly complete. It might benefit from noting that results are limited to issues visible to the token's user (permissions), but the tool name already implies this. Minor gap, so 4.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all three parameters (limit, offset, status) with descriptions, defaults, and constraints. The description adds no information about these parameters, but the baseline is 3 because the schema does the heavy lifting. No need for extra parameter explanation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('List'), resource ('Redmine issues assigned to the user...'), and the authentication context ('represented by the server's configured API token'), clearly distinguishing it from general list_issues. It is specific and unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly specifies the scope (only issues assigned to the token user) and ordering (most recently updated). It implies that this is the tool to use for personal assigned issues, but it does not explicitly contrast with list_issues or mention when not to use it. Given the naming and sibling context, the guidance is strong but not exhaustive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_newsList Redmine newsA
Read-onlyIdempotent

Read visible global Redmine news from GET /news.json for the configured API user. Supports the documented offset, limit, and page collection pagination controls. Redmine applies its ordinary news and project visibility rules; this tool never changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number. Redmine converts it to an offset using the selected limit.
limitNoNumber of news items to return. Redmine caps this at 100.
offsetNoNumber of news items to skip

Output Schema

ParametersJSON Schema
NameRequiredDescription
newsYes
pagingYes
filtersYes

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the description's 'never changes Redmine data' is redundant. It adds value by specifying visibility rules, the configured API user scope, and pagination behavior beyond what the schema provides. No contradiction with annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the core action, no wasted words. Efficient and to the point.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Low-complexity tool with full schema coverage and annotations covering safety. Output schema exists. The description covers scope, pagination, visibility rules, and read-only behavior. Nothing essential is missing for an agent to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so each parameter is fully described in the schema. The description only mentions pagination controls generically without adding syntax or format details beyond the schema. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (read) and resource (global Redmine news) with the endpoint, and implicitly distinguishes from the sibling list_project_news by saying 'global'. The tool's scope is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clearly implies use for site-wide news rather than project-specific news, and notes it never changes data, reinforcing read-only usage. However, it does not explicitly name the alternative tool (list_project_news) or provide explicit when-not guidance, leaving some inference to the agent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_project_filesList Redmine project filesA
Read-onlyIdempotent

Read a project's files from GET /projects/:project_id/files.json for the configured Redmine API user. The required project_id is a positive numeric project ID or valid project identifier. This endpoint has no documented pagination, filter, include, or other query controls, so the request sends no query string and preserves Redmine's response order. Results allowlist the file metadata fields, preserve optional and null values, sanitize upstream content and thumbnail URLs against the configured Redmine origin and subpath, and add safe browser and download links for the attachment plus ordinary version and author pages. Redmine authorizes this ordinary non-admin read with the project's view_files permission and project visibility and may return HTTP 401, 403, or 404 without exposing the upstream response body. This tool never downloads files or changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault
project_idYesPositive numeric project ID or valid Redmine project identifier

Output Schema

ParametersJSON Schema
NameRequiredDescription
filesYes
filtersYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already indicate readOnlyHint=true, idempotentHint=true, destructiveHint=false, so the description doesn't need to repeat safety. It adds valuable context: the tool never downloads files, changes data, and describes auth failures (401/403/404) and response sanitization. However, it doesn't describe the output schema details (though an output schema exists) and the allowance of fields, but that's beyond annotations. It adds significant behavioral context beyond the hints, but could include more about rate limits or response size (minor).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single dense paragraph that's front-loaded with the core action and resource, then lists constraints and behaviors. It's efficient, with no fluff, but could be structured with bullet points for readability. The information is all relevant, and the length is justified given the complexity of the behaviors described.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a read-only, one-parameter tool with a rich output schema. The description covers the essential call details (no query string, response ordering, sanitization, links, auth permissions, error codes, and non-destructive nature). Given the output schema exists, the description doesn't need to detail return fields. It's complete for an agent to call correctly, with no obvious missing information.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with a detailed description of project_id (positive numeric ID or valid identifier). The description adds the nuance that the ID must be positive numeric or valid identifier, but the schema already says that. The description doesn't add much beyond the schema, so baseline 3 is appropriate. It could clarify what 'valid project identifier' means (e.g., the pattern in schema) but that's already in schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the specific action ('Read a project's files') and the resource (GET /projects/:project_id/files.json). It distinguishes itself from siblings by specifying it's for the configured Redmine API user and focuses on files, which is distinct from list_projects, get_issue, etc. The purpose is precise and actionable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when to use this tool: to read a project's files, and explicitly notes it doesn't support pagination, filters, or includes, guiding the agent to use plain requests. It doesn't explicitly name alternatives like 'use list_projects to find project IDs' or when not to use it, but the context is clear enough for a read tool. It lacks explicit 'when-not-to-use' but the endpoint specification is sufficient.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_project_issue_categoriesList Redmine project issue categoriesA
Read-onlyIdempotent

Read one project's issue categories from GET /projects/:project_id/issue_categories.json for the configured Redmine API user. The required project_id is a positive numeric project ID or valid Redmine project identifier. This collection has no documented pagination, filters, include, or other query controls, so the request sends no query string and preserves Redmine's response order. Results map id, project, name, and optional assigned_to to camelCase, preserve total_count when Redmine returns it, and add a safe browser URL only to a returned project reference. Category HTML routes redirect to project settings, and assigned_to is a Principal that may be a user or group, so categories and assignees receive no browser URLs. This is a non-admin read authorized by the project's view_issues permission with the issue_tracking module enabled, subject to Redmine's project visibility and ordinary permission checks. Redmine may return HTTP 401, 403, or 404. This tool never changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault
project_idYesPositive numeric project ID or valid Redmine project identifier

Output Schema

ParametersJSON Schema
NameRequiredDescription
filtersYes
totalCountNo
issueCategoriesYes

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, it discloses the lack of pagination/filters, response order preservation, camelCase mapping, total_count passthrough, safe URL handling, why categories/assignees get no URLs, permission requirements, and possible HTTP error codes. This is thorough and materially helps an agent anticipate behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but each sentence delivers a distinct piece of useful information: endpoint, query behavior, mapping, URL rules, authorization, errors, and side-effect guarantee. It is dense rather than padded, though slightly heavy for a single-parameter read tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and annotations covering read-only/idempotent behavior, the description adds endpoint, authorization, error handling, transformation details, and a non-mutation guarantee. Nothing needed to call the tool correctly seems missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already fully documents project_id with 100% coverage, and the description mostly restates it ('positive numeric project ID or valid Redmine project identifier'). It adds no new parameter-specific behavior, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Read one project's issue categories from GET /projects/:project_id/issue_categories.json'. This clearly identifies the operation and distinguishes it from sibling tools like list_projects (all projects) and get_issue_category (a single category).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear usage context: this reads categories for one project, for the configured API user, subject to the project's view_issues permission. It does not explicitly name alternatives or provide 'when not to use' guidance, but the intended scope is unmistakable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_project_membershipsList Redmine project membershipsA
Read-onlyIdempotent

Read the paginated memberships from GET /projects/:project_id/memberships.json for the configured Redmine API user. The required project_id is a positive numeric project ID or valid project identifier. Optional offset, limit, and page parameters use Redmine's collection pagination rules, including a default limit of 25 and a maximum limit of 100. Results distinguish user and group principals and preserve roles, including inherited roles. This is a non-admin read, but Redmine still enforces project visibility and permissions and may return HTTP 403 when the user lacks the relevant project permission. This tool never changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number. Redmine converts it to an offset using the selected limit.
limitNoNumber of project memberships to return. Redmine caps this at 100.
offsetNoNumber of project memberships to skip
project_idYesPositive numeric project ID or valid Redmine project identifier

Output Schema

ParametersJSON Schema
NameRequiredDescription
pagingYes
filtersYes
membershipsYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral context beyond annotations: it is paginated, results distinguish user vs group principals, roles including inherited roles are preserved, and Redmine may return HTTP 403 based on permissions. It also explicitly states 'This tool never changes Redmine data,' reinforcing the read-only nature. This is strong added context, though it doesn't detail the output schema shape (which is covered by the output schema).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single dense paragraph that front-loads the core action and resource, then covers pagination, result contents, permissions, and safety. Every sentence adds information. It is slightly long but not bloated; the structure is logical. A 5 would require even tighter organization, but this is well above average.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a paginated read tool with a rich output schema, the description covers the essential context: the endpoint, the required parameter, pagination behavior, result contents, permission caveats, and safety. The output schema exists, so return values need not be described. The 403 caveat and non-admin note are particularly useful for an agent deciding whether to call this tool. Nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all four parameters. The description adds meaning by explaining pagination semantics: default limit of 25, maximum limit of 100, and that page is converted to an offset using the selected limit. It also clarifies that project_id can be a numeric ID or a valid project identifier. This goes beyond the schema's field-level descriptions, so a 4 is warranted.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Read'), a specific resource ('paginated memberships from GET /projects/:project_id/memberships.json'), and the API context. It distinguishes itself from the sibling get_project_membership by focusing on the paginated list, and it names the configured Redmine API user as the actor. This is unambiguous and clearly differentiated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context: it is a non-admin read, uses Redmine's pagination rules, and requires a project_id. It does not explicitly name an alternative tool for single-membership retrieval, but the sibling list get_project_membership is implicitly the alternative. It also notes that Redmine enforces project visibility and may return 403, which helps an agent decide when to use it. Missing an explicit 'use get_project_membership for a single membership' statement, so not a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_project_newsList Redmine project newsA
Read-onlyIdempotent

Read visible news for one Redmine project from GET /projects/:project_id/news.json for the configured API user. The required project_id is a positive numeric project ID or valid project identifier. Supports the documented offset, limit, and page collection pagination controls. Redmine applies its ordinary project and news visibility rules; this tool never changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number. Redmine converts it to an offset using the selected limit.
limitNoNumber of news items to return. Redmine caps this at 100.
offsetNoNumber of news items to skip
project_idYesPositive numeric project ID or valid Redmine project identifier

Output Schema

ParametersJSON Schema
NameRequiredDescription
newsYes
pagingYes
filtersYes

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds useful context: it never changes Redmine data, it respects Redmine's visibility rules, and it operates as the configured API user. This goes beyond the annotations without contradicting them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences with no filler. The core action and endpoint are front-loaded, followed by the parameter requirement, pagination support, and a clear read-only guarantee. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is a simple read-only list operation with a rich schema and output schema, so the description covers the essentials: endpoint, required parameter, pagination, and safety. It does not describe the response shape, but the output schema exists and the annotations carry the safety profile, so nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all four parameters. The description adds the endpoint context and confirms project_id accepts a numeric ID or identifier, but it does not add meaning beyond the schema's own descriptions. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Read'), a specific resource ('visible news for one Redmine project'), and the exact API endpoint. It also distinguishes itself from the sibling list_news by scoping to a single project, so an agent can tell them apart.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly states the tool reads news for one project and mentions the required project_id, which implies when to use it. It does not explicitly name alternatives or exclusions, but the single-project scope and the sibling list_news provide enough context for selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_projectsList Redmine projectsA
Read-onlyIdempotent

Read projects visible to the configured Redmine API user from GET /projects.json. Supports the documented offset, limit, and page pagination controls, plus trackers, issue_categories, enabled_modules, time_entry_activities, and issue_custom_fields associations. This tool never changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number. Redmine uses the selected limit to calculate the offset.
limitNoNumber of projects to return. Redmine caps this at 100.
offsetNoNumber of projects to skip
includeNoProject associations to include: trackers, issue_categories, enabled_modules, time_entry_activities, or issue_custom_fields

Output Schema

ParametersJSON Schema
NameRequiredDescription
pagingYes
filtersYes
projectsYes

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false; the description reinforces this with 'This tool never changes Redmine data.' It also adds useful behavioral context beyond annotations: only projects visible to the configured API user are returned, and pagination plus association inclusion are supported.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences with the core action front-loaded, followed by pagination and association capabilities, then a safety guarantee. Every sentence serves a purpose, though the explicit endpoint string and the word 'documented' add minor redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and rich annotations, the description covers the essential invocation context: resource scope, visibility, pagination controls, associations, and read-only behavior. Nothing critical is missing for an agent to call this tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema fully documents all four parameters. The description adds context that offset, limit, and page are pagination controls and that the include parameter supports the five listed associations, but this largely restates what the schema already provides. No critical parameter meaning is missing.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb ('Read') and names the exact resource ('projects visible to the configured Redmine API user from GET /projects.json'). It clearly distinguishes this list operation from sibling getter tools like get_project by its scope (multiple projects) and the mention of pagination and associations.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context for what the tool does, but it does not explicitly state when to use it over alternatives such as get_project or list_project_issue_categories. There is no when-not-to-use guidance, though the 'never changes Redmine data' statement implicitly rules out write purposes.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_project_versionsList Redmine project versionsA
Read-onlyIdempotent

Read the visible/shared versions from GET /projects/:project_id/versions.json for the configured Redmine API user. The required project_id is a positive numeric project ID or valid Redmine project identifier. This route has no pagination, filters, or documented include controls, and Redmine preserves its response order. This tool never changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault
project_idYesPositive numeric project ID or valid Redmine project identifier

Output Schema

ParametersJSON Schema
NameRequiredDescription
filtersYes
versionsYes
totalCountNo

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and no destructiveness, and the description reinforces this with 'This tool never changes Redmine data.' Beyond the annotations, it discloses meaningful behavioral traits: no pagination, no filters, no documented include controls, and Redmine preserves response order. This adds route-specific expectations that structured hints cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is only four sentences and front-loads the core action and endpoint first. Every sentence adds value: the parameter format sentence is somewhat redundant with the schema, but the no-pagination/order-preservation and read-only assurances are highly relevant. It is tight without being terse, though slightly more concise phrasing of the parameter sentence would push it to a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter, single-output tool with an output schema present, the description is fully complete. It covers the purpose, endpoint, parameter requirements, route limitations, response ordering, and non-mutating behavior. Nothing an agent needs to invoke this correctly is missing, and the presence of a sibling get_version is implicitly distinguishable via the list-vs-single semantics.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description's parameter sentence, 'The required project_id is a positive numeric project ID or valid Redmine project identifier,' largely restates the schema property description without adding new semantics. It does not clarify behavior like validation errors, resolution order, or how identifier strings are treated, but the schema already documents the valid formats.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description starts with a precise verb and resource: 'Read the visible/shared versions from GET /projects/:project_id/versions.json'. It names the exact endpoint and scopes the operation to a specific project, making the tool's function unmistakable. The phrase 'visible/shared versions' adds semantic nuance that differentiates this listing from a raw dump, and the singular sibling get_version is clearly a different operation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context that this is a read-only list operation for a given project, and the 'for the configured Redmine API user' clarifies visibility scope. However, it does not explicitly say when to prefer this tool over alternatives like get_version or list_projects, nor does it state exclusions. The usage guidance is implied by the endpoint and verb rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_project_wiki_pagesList Redmine project wiki pagesA
Read-onlyIdempotent

Read the wiki page index from GET /projects/:project_id/wiki/index.json for the configured Redmine API user. The required project_id is a positive numeric project ID or valid Redmine project identifier. This route has no pagination, filters, or documented include controls; results preserve Redmine's title-and-parent order, include only the current index fields, and add safe browser links. Redmine enforces the ordinary view_wiki_pages permission and may return HTTP 401, 403, or 404. This tool never changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault
project_idYesPositive numeric project ID or valid Redmine project identifier

Output Schema

ParametersJSON Schema
NameRequiredDescription
filtersYes
wikiPagesYes

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes well beyond the annotations by disclosing ordering behavior (title-and-parent order), inclusion of safe browser links, reliance on the view_wiki_pages permission, and potential HTTP 401/403/404 errors. It also explicitly confirms non-mutating behavior, giving the agent a thorough understanding of side effects and failure modes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is well organized and information-dense, front-loading the purpose, then covering route characteristics, permissions, and non-mutation. It is slightly long but every sentence contributes value, and the structure is logical.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter read-only tool with an output schema, the description is remarkably complete. It covers purpose, route limitations, output field specifics, permission requirements, expected HTTP errors, and explicitly confirms no data mutation, giving an agent all necessary context to invoke the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema already documents the project_id parameter with a clear description and 100% coverage. The description repeats this information without adding new meaning, meeting the baseline expected when the schema handles parameter semantics.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'read' and the specific resource 'wiki page index' from an explicit API endpoint, distinguishing it from sibling tools that fetch individual pages or versions. It unambiguously communicates what the tool returns.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context about the tool's scope (no pagination, no filters, limited fields) and its read-only nature, informing when it is appropriate to use. However, it does not explicitly name alternative tools or state exclusion conditions, so it falls short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_queriesList Redmine saved queriesA
Read-onlyIdempotent

Read visible saved issue queries from GET /queries.json for the configured Redmine API user. Supports the documented offset, limit, and page collection pagination controls; Redmine defaults to 25 items, caps the limit at 100, orders by query name, and applies ordinary public/private/role visibility. This tool does not expose project, resource-type, or include filters and never changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number. Redmine converts it to an offset using the selected limit.
limitNoNumber of queries to return. Redmine defaults to 25 and caps this at 100.
offsetNoNumber of queries to skip

Output Schema

ParametersJSON Schema
NameRequiredDescription
pagingYes
filtersYes
queriesYes

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, idempotent, and non-destructive behavior. The description adds valuable behavioral specifics: endpoint semantics, configured-user scoping, pagination defaults and caps, ordering by query name, visibility rules, and an explicit 'never changes Redmine data' statement. This goes well beyond what annotations provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three compact sentences with the primary action front-loaded, followed by useful pagination/ordering behavior and then exclusions. Every sentence adds relevant information with no redundancy or filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema exists and annotations cover safety, the description fully covers the invocation context: endpoint, user scope, pagination behavior, ordering, visibility, and unsupported filters. An agent has enough information to call the tool correctly without surprises.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description restates pagination controls, defaults, and caps, but adds no new per-parameter semantics beyond the schema. The 'orders by query name' detail is a collection behavior, not an additional parameter explanation.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses specific verbs ('Read', 'List') and identifies the exact resource ('saved issue queries') and endpoint ('GET /queries.json'). It clearly distinguishes from sibling tools like list_issues or list_my_assigned_issues by clarifying that these are saved queries, not issues.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage context by naming the resource and listing exclusions ('does not expose project, resource-type, or include filters'), but it does not explicitly mention alternatives or state when to prefer sibling tools. This is implied usage rather than explicit when-to-use/when-not-to-use guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_rolesList Redmine rolesA
Read-onlyIdempotent

Read Redmine's non-built-in project-member roles from GET /roles.json for the configured Redmine API user. This endpoint accepts no query, include, or pagination controls and preserves Redmine's position order. The list response contains only id and name; it does not expose permissions, visibility settings, or other fields from the separate role-detail response. Redmine accepts ordinary API authentication for this index, but the HTML roles page is restricted for non-admin users, so results have no browser links. Redmine may return HTTP 401, 403, or 404 without exposing the upstream response body. This tool never changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
rolesYes

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint/idempotentHint, lowering the bar, yet the description adds substantial context beyond them: the absence of query/include/pagination controls, preservation of Redmine's position order, the id-and-name-only response shape, API-vs-HTML auth asymmetry, and the specific 401/403/404 error behavior with no upstream body exposed. This is exactly the kind of behavioral disclosure that prevents agent confusion.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded in sentence one, and nearly every sentence carries behavioral value. It is slightly longer than necessary: the note about the HTML roles page being restricted for non-admins only explains the marginal fact that results have no browser links, and the final 'never changes Redmine data' sentence mostly restates readOnlyHint. Overall efficient but not maximally lean.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only list tool with an output schema and four safety annotations, the description covers everything needed to invoke it correctly: purpose, endpoint, response scope, ordering, auth requirements, and error behavior. Nothing material is missing for the agent to call this tool successfully.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With 0 parameters, the baseline is 4. The description earns it by explicitly warning that the endpoint 'accepts no query, include, or pagination controls,' which stops an agent from attempting unsupported filters — a real semantic addition given the empty schema offers no such guidance.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence states a specific verb ('Read'), a precise resource ('Redmine's non-built-in project-member roles'), and the exact endpoint (GET /roles.json). The scope qualifier 'non-built-in' and the clarification that the list carries only id and name differentiate it from the sibling get_role, which covers the role-detail response.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context: it explicitly notes the list 'does not expose permissions, visibility settings, or other fields from the separate role-detail response,' which implicitly routes an agent needing detail to the get_role sibling. However, it never names the alternative tool explicitly or states a when-to-use/when-not-to-use rule, so it falls short of the top tier.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_time_entriesList Redmine time entriesA
Read-onlyIdempotent

Read visible Redmine time entries from GET /time_entries.json for the configured API user. Supports offset, limit, and page pagination, a positive numeric user_id or me, project_id, issue_id, activity_id, exact Redmine spent_on date/range forms, and real YYYY-MM-DD from/to filters. Redmine enforces the user's view-time-entry permissions and visibility. This tool never changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault
toNoLatest real YYYY-MM-DD spent-on date, inclusive
fromNoEarliest real YYYY-MM-DD spent-on date, inclusive
pageNoPage number. Redmine converts it to an offset using the selected limit.
limitNoNumber of time entries to return. Redmine caps this at 100.
offsetNoNumber of time entries to skip
user_idNoUser ID or `me` whose visible time entries should be returned
issue_idNoIssue ID whose visible time entries should be returned
spent_onNoBare date, =date, >=date, <=date, or ><date|date spent-on filter
project_idNoProject ID or Redmine project identifier
activity_idNoTime-entry activity ID

Output Schema

ParametersJSON Schema
NameRequiredDescription
pagingYes
filtersYes
timeEntriesYes

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint, and non-destructive behavior. The description adds useful context beyond those annotations by noting that Redmine enforces the configured API user's view-time-entry permissions and visibility, and by explicitly stating the tool never changes Redmine data. This is relevant behavioral context for the agent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is four sentences, front-loaded with the tool's purpose and endpoint, followed by capability, permission context, and a safety note. Every sentence contributes new, non-redundant information and the length is proportionate to the tool's complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the rich input schema, output schema, and annotations, the description is complete enough. It covers the endpoint, filtering capabilities, pagination, permission-dependent visibility, and non-mutating behavior. No essential context for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds value by summarizing parameter groups and emphasizing distinctions such as 'exact Redmine spent_on date/range forms' versus 'real YYYY-MM-DD from/to filters,' which helps the agent understand the differing parameter semantics without opening every schema definition.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: 'Read visible Redmine time entries from GET /time_entries.json for the configured API user.' It clearly identifies the operation as a read/list action and is distinguishable from siblings like get_time_entry and list_time_entry_activities by the endpoint and resource scope.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context that this is the list endpoint for time entries and enumerates the available filters, so an agent can infer when to use it. It does not explicitly exclude alternatives such as get_time_entry for single entries or list_time_entry_activities for activities, but the context is not misleading.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_time_entry_activitiesList Redmine time-entry activitiesA
Read-onlyIdempotent

Read all shared Redmine time-entry activities from GET /enumerations/time_entry_activities.json for the configured Redmine API user. This endpoint accepts no query, include, or pagination controls and preserves Redmine's shared position order. Results map id, name, is_default, active, and visible custom_fields to id, name, isDefault, active, and customFields, preserving upstream order, explicit custom-field null values, and omitted version-dependent fields. The active field is available since Redmine 4.1.0 and enumeration custom-field values since 3.4.0. Project-specific activity overrides are not returned by this global collection. The HTML index is admin-or-API-only for non-admin users and Redmine has no time-entry-activity show route, so results have no browser links. Redmine may return HTTP 401, 403, or 404 without exposing the upstream response body. This tool never changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
timeEntryActivitiesYes

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readonly, idempotent, and non-destructive behavior, and the description adds substantial context beyond that: no query/include/pagination controls, preserved ordering, field-name mapping, version-dependent field availability, lack of project-specific overrides, absence of browser links, and explicit HTTP error behavior. This is rich behavioral disclosure that helps the agent anticipate edge cases.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The first sentence front-loads the core purpose, followed by logically grouped behavioral details, version caveats, and error behavior. It is longer than strictly necessary, and some statements like 'This tool never changes Redmine data' partly duplicate annotations, but for a tool with Redmine-specific quirks the detail is mostly earned.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description covers endpoint, field mapping, ordering, null handling, version support, scope limitations, error behavior, and safety profile. With an output schema already available, the description leaves no important gap for an agent deciding whether and how to call this tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so there is no parameter burden to carry. The description still clarifies that the endpoint 'accepts no query, include, or pagination controls', which prevents the agent from inventing unsupported arguments. This is appropriate for a no-parameter schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Read all shared Redmine time-entry activities from GET /enumerations/time_entry_activities.json'. It clearly distinguishes this tool from sibling list tools by naming the exact endpoint, the global scope, and by noting that project-specific overrides are not returned.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context about what the endpoint returns and explicitly states that project-specific activity overrides are not included, which is a useful exclusion. However, it never names an alternative tool or says when to use this one versus a sibling like list_time_entries or list_issue_statuses, so the usage guidance is implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_trackersList Redmine trackersA
Read-onlyIdempotent

Read all Redmine trackers from GET /trackers.json for the configured Redmine API user. This endpoint accepts ordinary API authentication and has no documented query, include, or pagination controls. Results preserve Redmine's configured position order and map id, name, default_status, description, and enabled_standard_fields to id, name, defaultStatus, description, and enabledStandardFields. Description is available since Redmine 4.2.0 and enabledStandardFields since Redmine 5.0.0. The HTML index is admin-or-API-only and Redmine has no tracker show route, so results have no browser links. Redmine may return HTTP 401, 403, or 404 without exposing the upstream response body. This tool never changes Redmine data.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription
trackersYes

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, idempotentHint=true, destructiveHint=false, so the safety profile is covered. The description adds valuable behavioral context: no pagination controls, field name mapping (id→id, name→name, etc.), version-dependent availability of description and enabledStandardFields, absence of browser links due to no show route, and error behavior (HTTP 401/403/404 without upstream body). It also explicitly states 'This tool never changes Redmine data,' reinforcing the read-only nature beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but every sentence adds information: endpoint, auth, lack of controls, field mapping, version notes, link absence, error behavior, and safety guarantee. It is front-loaded with the core action and endpoint. Slightly long but justified given the version-dependent field details and error behavior; no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has zero parameters, an output schema exists, and annotations cover safety. The description covers endpoint, auth, field mapping, version caveats, error behavior, and the absence of pagination/links. For a simple list tool, nothing an agent needs to call it correctly is missing. The output schema handles return values, so the description needn't repeat them.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, and the schema is empty with 100% coverage. The description explains that there are no query, include, or pagination controls, which is meaningful context for an agent that might otherwise expect parameters. Since there are no parameters to document, the description's clarification that no controls exist is valuable and earns above the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool reads all Redmine trackers from a specific endpoint (GET /trackers.json) for the configured API user. It distinguishes itself from sibling tools by naming the resource (trackers) and the read-only nature, and the title reinforces the resource. The verb 'Read' is specific and the scope is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains that this endpoint accepts ordinary API authentication and has no query/include/pagination controls, which tells the agent when this tool is appropriate (simple list retrieval) and that no filtering is possible. It doesn't explicitly name alternatives, but the sibling list (e.g., list_projects, list_issue_statuses) makes the resource-specific usage clear. It also notes the HTML index is admin-or-API-only, implying this API path is the accessible route.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 35 tool updatesv0.1.0
    • First observedget_attachment
    • First observedget_current_user
    • First observedget_issue
    • First observedget_issue_category
    • First observedget_issue_relation
    • First observedget_my_account
    • First observedget_news
    • First observedget_project
    • First observedget_project_membership
    • First observedget_project_wiki_page
    • First observedget_project_wiki_page_version
    • First observedget_role
    • First observedget_time_entry
    • First observedget_user
    • First observedget_version
    • First observedlist_document_categories
    • First observedlist_issue_priorities
    • First observedlist_issue_relations
    • First observedlist_issue_statuses
    • First observedlist_issues
    • First observedlist_my_assigned_issues
    • First observedlist_news
    • First observedlist_project_files
    • First observedlist_project_issue_categories
    • First observedlist_project_memberships
    • First observedlist_project_news
    • First observedlist_project_versions
    • First observedlist_project_wiki_pages
    • First observedlist_projects
    • First observedlist_queries
    • First observedlist_roles
    • First observedlist_time_entries
    • First observedlist_time_entry_activities
    • First observedlist_trackers
    • First observedsearch

TDQS

A3.9/5.0

Scored across 35 tools

Disambiguation5/5

Every tool is clearly distinct: list_* for collections, get_* for single resources, and each maps to a specific Redmine API endpoint. Even similar tools like get_project and list_projects differ obviously by cardinality. Semantic overlaps (e.g., get_version vs get_project_wiki_page_version) are unambiguous from context.

Naming Consistency4/5

The naming pattern is overwhelmingly consistent: list_* for index endpoints, get_* for show endpoints, with clear resource nouns. Minor deviations like get_my_account instead of get_current_user and list_my_assigned_issues being slightly longer than other list_* names are easy to predict but not perfectly uniform.

Tool Count2/5

With 35 tools, this is above the 15-25 range considered 'heavy' and closer to the chaotic end. While Redmine has many resource types, the count feels bloated—several read-only variants (e.g., list_project_issues vs list_all_issues) could be consolidated. Users face a steep CLI surface.

Completeness2/5

The tool set is exclusively read-only. While it covers a broad set of GET endpoints (projects, issues, wiki, memberships, etc.), there are no create, update, or delete operations. A complete Redmine integration would at least allow issue mutations, leaving major dead ends for agents that need to take actions.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers