@dpesch/mantisbt-mcp-server 1.5.7 → 1.5.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,25 @@ This project adheres to [Semantic Versioning](https://semver.org/).
7
7
 
8
8
  ---
9
9
 
10
+ ## [1.5.9] – 2026-03-20
11
+
12
+ ### Fixed
13
+ - `create_issue` now validates `severity` and `priority` against canonical English names and returns a clear error for unknown values; sends `{ id }` instead of `{ name }` to work correctly on localized MantisBT installations
14
+
15
+ ### Added
16
+ - Cookbook (EN + DE): tool-oriented recipes with copy-paste-ready parameter examples for all registered tools ([docs/cookbook.md](docs/cookbook.md), [docs/cookbook.de.md](docs/cookbook.de.md))
17
+ - Usage examples (EN + DE): natural language prompt examples for everyday use cases ([docs/examples.md](docs/examples.md), [docs/examples.de.md](docs/examples.de.md))
18
+ - README: documentation section linking to cookbook and examples
19
+
20
+ ---
21
+
22
+ ## [1.5.8] – 2026-03-18
23
+
24
+ ### Added
25
+ - Glama MCP directory badge in README.md and README.de.md (contributed by Frank Fiegel / punkpeye)
26
+
27
+ ---
28
+
10
29
  ## [1.5.7] – 2026-03-18
11
30
 
12
31
  ### Added
package/README.de.md CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/@dpesch/mantisbt-mcp-server)](https://www.npmjs.com/package/@dpesch/mantisbt-mcp-server)
4
4
  [![license](https://img.shields.io/npm/l/@dpesch/mantisbt-mcp-server)](LICENSE)
5
+ [![MantisBT MCP Server](https://glama.ai/mcp/servers/dpesch/mantisbt-mcp-server/badges/card.svg)](https://glama.ai/mcp/servers/dpesch/mantisbt-mcp-server)
5
6
 
6
7
  Ein [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) Server, der die [MantisBT REST API](https://documenter.getpostman.com/view/29959/mantis-bug-tracker-rest-api) in Claude Code und andere MCP-fähige Clients integriert. Issues lesen, erstellen und bearbeiten – direkt aus dem Editor heraus.
7
8
 
@@ -97,7 +98,7 @@ Falls keine Umgebungsvariablen gesetzt sind, wird `~/.claude/mantis.json` ausgel
97
98
  |---|---|
98
99
  | `get_issue` | Ein Issue anhand seiner ID abrufen |
99
100
  | `list_issues` | Issues nach Projekt, Status, Autor u.v.m. filtern; optionales `select` für Feldprojektion und `status` für clientseitige Statusfilterung |
100
- | `create_issue` | Neues Issue anlegen; optionaler `handler`-Parameter akzeptiert einen Benutzernamen als Alternative zu `handler_id` (wird gegen die Projektmitglieder aufgelöst) |
101
+ | `create_issue` | Neues Issue anlegen; `severity` und `priority` müssen kanonische englische Namen sein (z.B. `minor`, `major`, `normal`, `high`) — `get_issue_enums` aufrufen, um alle gültigen Werte und deren lokalisierte Bezeichnungen zu sehen; optionaler `handler`-Parameter akzeptiert einen Benutzernamen als Alternative zu `handler_id` (wird gegen die Projektmitglieder aufgelöst) |
101
102
  | `update_issue` | Bestehendes Issue bearbeiten |
102
103
  | `delete_issue` | Issue löschen |
103
104
 
@@ -210,6 +211,11 @@ MANTIS_BASE_URL=... MANTIS_API_KEY=... TRANSPORT=http PORT=3456 node dist/index.
210
211
 
211
212
  Healthcheck: `GET http://localhost:3456/health` (immer öffentlich, kein Token erforderlich)
212
213
 
214
+ ## Dokumentation
215
+
216
+ - [**Cookbook**](docs/cookbook.de.md) — Tool-orientierte Rezepte mit direkt verwendbaren Parameter-Beispielen für alle registrierten Tools
217
+ - [**Anwendungsbeispiele**](docs/examples.de.md) — Beispiele in natürlicher Sprache für alltägliche Anwendungsfälle (keine Tool-Namen erforderlich)
218
+
213
219
  ## Entwicklung
214
220
 
215
221
  ```bash
package/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  [![npm version](https://img.shields.io/npm/v/@dpesch/mantisbt-mcp-server)](https://www.npmjs.com/package/@dpesch/mantisbt-mcp-server)
4
4
  [![license](https://img.shields.io/npm/l/@dpesch/mantisbt-mcp-server)](LICENSE)
5
+ [![MantisBT MCP Server](https://glama.ai/mcp/servers/dpesch/mantisbt-mcp-server/badges/card.svg)](https://glama.ai/mcp/servers/dpesch/mantisbt-mcp-server)
5
6
 
6
7
  A [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server that integrates the [MantisBT REST API](https://documenter.getpostman.com/view/29959/mantis-bug-tracker-rest-api) into Claude Code and other MCP-capable clients. Read, create, and update issues directly from your editor.
7
8
 
@@ -97,7 +98,7 @@ If no environment variables are set, `~/.claude/mantis.json` is read:
97
98
  |---|---|
98
99
  | `get_issue` | Retrieve an issue by its numeric ID |
99
100
  | `list_issues` | Filter issues by project, status, author, and more; optional `select` for field projection and `status` for client-side status filtering |
100
- | `create_issue` | Create a new issue; optional `handler` parameter accepts a username as alternative to `handler_id` (resolved against project members) |
101
+ | `create_issue` | Create a new issue; `severity` and `priority` must be canonical English names (e.g. `minor`, `major`, `normal`, `high`) — call `get_issue_enums` to see all valid values and their localized labels; optional `handler` parameter accepts a username as alternative to `handler_id` (resolved against project members) |
101
102
  | `update_issue` | Update an existing issue |
102
103
  | `delete_issue` | Delete an issue |
103
104
 
@@ -210,6 +211,11 @@ MANTIS_BASE_URL=... MANTIS_API_KEY=... TRANSPORT=http PORT=3456 node dist/index.
210
211
 
211
212
  Health check: `GET http://localhost:3456/health` (always public, no token required)
212
213
 
214
+ ## Documentation
215
+
216
+ - [**Cookbook**](docs/cookbook.md) — tool-oriented recipes with copy-paste-ready parameter examples for all registered tools
217
+ - [**Usage Examples**](docs/examples.md) — natural language prompt examples for everyday use cases (no tool names required)
218
+
213
219
  ## Development
214
220
 
215
221
  ```bash
package/dist/constants.js CHANGED
@@ -93,6 +93,18 @@ export const MANTIS_CANONICAL_ENUM_NAMES = {
93
93
  },
94
94
  };
95
95
  // ---------------------------------------------------------------------------
96
+ // Reverse lookup: canonical English enum name → numeric ID.
97
+ // Case-insensitive. Returns undefined when the name is not in the table.
98
+ // ---------------------------------------------------------------------------
99
+ export function resolveEnumId(group, name) {
100
+ if (!name)
101
+ return undefined;
102
+ const map = MANTIS_CANONICAL_ENUM_NAMES[group];
103
+ const lower = name.toLowerCase();
104
+ const entry = Object.entries(map).find(([, n]) => n.toLowerCase() === lower);
105
+ return entry ? Number(entry[0]) : undefined;
106
+ }
107
+ // ---------------------------------------------------------------------------
96
108
  // Issue enum config option names
97
109
  // ---------------------------------------------------------------------------
98
110
  export const ISSUE_ENUM_OPTIONS = [
@@ -1,12 +1,21 @@
1
1
  import { z } from 'zod';
2
2
  import { getVersionHint } from '../version-hint.js';
3
- import { MANTIS_RESOLVED_STATUS_ID } from '../constants.js';
3
+ import { MANTIS_CANONICAL_ENUM_NAMES, MANTIS_RESOLVED_STATUS_ID, resolveEnumId } from '../constants.js';
4
4
  function errorText(msg) {
5
5
  const vh = getVersionHint();
6
6
  vh?.triggerLatestVersionFetch();
7
7
  const hint = vh?.getUpdateHint();
8
8
  return hint ? `Error: ${msg}\n\n${hint}` : `Error: ${msg}`;
9
9
  }
10
+ // Resolves a canonical enum name to { id } or returns an error string.
11
+ function resolveEnum(group, value) {
12
+ const id = resolveEnumId(group, value);
13
+ if (id === undefined) {
14
+ const valid = Object.values(MANTIS_CANONICAL_ENUM_NAMES[group]).join(', ');
15
+ return `Invalid ${group} "${value}". Valid canonical names: ${valid}. Call get_issue_enums to see localized labels.`;
16
+ }
17
+ return { id };
18
+ }
10
19
  export function registerIssueTools(server, client, cache) {
11
20
  // ---------------------------------------------------------------------------
12
21
  // get_issue
@@ -138,8 +147,8 @@ export function registerIssueTools(server, client, cache) {
138
147
  description: z.string().default('').describe('Detailed issue description'),
139
148
  project_id: z.coerce.number().int().positive().describe('Project ID the issue belongs to'),
140
149
  category: z.string().min(1).describe('Category name (use get_project_categories to list available categories)'),
141
- priority: z.string().optional().describe('Priority name (e.g. "normal", "high", "urgent", "immediate", "low", "none")'),
142
- severity: z.string().default('minor').describe('Severity name (e.g. "minor", "major", "crash", "block", "feature", "trivial", "text") default: "minor"'),
150
+ priority: z.string().optional().describe('Priority name must be a canonical English name: none, low, normal, high, urgent, immediate. Call get_issue_enums to see localized labels.'),
151
+ severity: z.string().default('minor').describe('Severity name must be a canonical English name: feature, trivial, text, tweak, minor, major, crash, block. Default: "minor". Call get_issue_enums to see localized labels.'),
143
152
  handler_id: z.coerce.number().int().positive().optional().describe('User ID of the person to assign the issue to'),
144
153
  handler: z.string().optional().describe('Username (login name) of the person to assign the issue to. Alternative to handler_id — the server resolves the name to a user ID from the project members. Use get_project_users to see available users.'),
145
154
  }),
@@ -180,9 +189,16 @@ export function registerIssueTools(server, client, cache) {
180
189
  project: { id: project_id },
181
190
  category: { name: category },
182
191
  };
183
- if (priority)
184
- body.priority = { name: priority };
185
- body.severity = { name: severity };
192
+ if (priority) {
193
+ const priorityResolved = resolveEnum('priority', priority);
194
+ if (typeof priorityResolved === 'string')
195
+ return { content: [{ type: 'text', text: errorText(priorityResolved) }], isError: true };
196
+ body.priority = priorityResolved;
197
+ }
198
+ const severityResolved = resolveEnum('severity', severity);
199
+ if (typeof severityResolved === 'string')
200
+ return { content: [{ type: 'text', text: errorText(severityResolved) }], isError: true };
201
+ body.severity = severityResolved;
186
202
  if (resolvedHandlerId)
187
203
  body.handler = { id: resolvedHandlerId };
188
204
  const raw = await client.post('issues', body);