@dpesch/mantisbt-mcp-server 1.17.0 → 1.18.0
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 +18 -0
- package/README.de.md +3 -3
- package/README.md +3 -3
- package/dist/build-info.js +17 -0
- package/dist/build-info.json +5 -0
- package/dist/deprecation.js +4 -1
- package/dist/index.js +6 -8
- package/dist/tools/index.js +1 -1
- package/dist/tools/issues.js +62 -16
- package/dist/tools/version.js +6 -4
- package/docs/cookbook.de.md +44 -1
- package/docs/cookbook.md +44 -1
- package/package.json +4 -3
- package/server.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -11,6 +11,24 @@ This project adheres to [Semantic Versioning](https://semver.org/).
|
|
|
11
11
|
|
|
12
12
|
---
|
|
13
13
|
|
|
14
|
+
## [1.18.0] – 2026-11-09
|
|
15
|
+
|
|
16
|
+
### Deprecated
|
|
17
|
+
|
|
18
|
+
- The default of `response` in `update_issue` and `create_issue` changes from `"full"` to `"short"` in 2.0.0. Callers that rely on the whole issue in the response should pass `response: "full"` explicitly.
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- `update_issue` and `create_issue`: optional `response` parameter. `"short"` returns only what confirms the change instead of the whole issue with description, notes and history (#8598) — for `update_issue` `id`, `summary`, `status`, `resolution`, `updated_at`, `view_url` and the changed fields (custom fields and edited notes narrowed to the changed entries, an appended note to `id` and `view_url`); for `create_issue` `id`, `summary`, `project`, `category`, `status`, `handler`, `created_at` and `view_url`. On a fresh demo issue that is 529 instead of 4,046 characters; on an issue with many notes the gap is far larger. The default stays `"full"`.
|
|
23
|
+
- `get_version`: `mcp_server` now also contains `commit` (short hash of the build, `-dirty` with uncommitted changes) and `built_at` (build time), so an outdated build shows even when its version number is right (#8547).
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
|
|
27
|
+
- The server reported the version from `package.json` at runtime, not the one its code was built from — in the MCP handshake, `get_version`, `get_mcp_version`, the startup log and the HTTP `/health` endpoint. Between a version bump and `npm run build`, a local install therefore claimed the new version while running the old code (#8547). The build now writes `dist/build-info.json`, and the server reads its version from there. Only the release build in CI reports a plain version; every other build — a local `npm run build`, `npm run dev`, code run from `src/` — is marked `-dev`, e.g. `1.18.0-dev`. `npm publish` refuses any build that is not the release build of the package version (`prepublishOnly`). The npm package was not affected: it is always built right before publishing.
|
|
28
|
+
- `list_issues`: the client-side filters `status`, `assigned_to`, `reporter_id`, `updated_after`/`updated_before` and `created_after`/`created_before` returned an empty list when `select` did not contain the field they read (`status`, `handler`, `reporter`, `updated_at`, `created_at`). The `select` projection removed the field before the filter ran, so every issue failed it — silently, without an error (#8597). The fields a filter needs are now fetched as well and removed again after filtering, so the response still holds exactly the selected fields. `group_by` was not affected.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
14
32
|
## [1.17.0] – 2026-11-03
|
|
15
33
|
|
|
16
34
|
### Added
|
package/README.de.md
CHANGED
|
@@ -156,8 +156,8 @@ Veraltete Tools gehören immer zur gleichen Gruppe wie ihr Ersatz – eine Grupp
|
|
|
156
156
|
| `get_issue` | Ein Issue per `id` oder mehrere per `ids` (1–50) in einem Aufruf abrufen – genau eines von beiden angeben; mit `ids` lautet die Antwort `{ issues, requested, found, failed }`, nicht zugängliche IDs liefern `null` an ihrer Position; optionales `select` zur Feldauswahl |
|
|
157
157
|
| `get_issues` | **Veraltet:** stattdessen `get_issue` mit `ids` verwenden – wird in 2.0.0 entfernt |
|
|
158
158
|
| `list_issues` | Issues nach Projekt, Status, Autor u.v.m. filtern; optionales `select` für Feldprojektion und `status` für clientseitige Statusfilterung – kanonische englische Statusnamen (z.B. `"new"`, `"resolved"`) werden per ID abgeglichen und funktionieren damit sprachunabhängig auf lokalisierten Installationen; `group_by` (`"status"`, `"handler"`, `"priority"`, `"category"`) liefert statt einer Issue-Liste Zählwerte pro Gruppe – alle Filter greifen weiterhin, `page`, `page_size` und `select` werden ignoriert |
|
|
159
|
-
| `create_issue` | Neues Issue anlegen; `severity` und `priority` müssen kanonische englische Namen sein (z.B. `minor`, `major`, `normal`, `high`) – `get_issue_schema` 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); optionales `custom_fields` zum Setzen benutzerdefinierter Felder |
|
|
160
|
-
| `update_issue` | Bestehendes Issue bearbeiten; Enum-Felder (`status`, `priority`, `severity`, `resolution`, `reproducibility`) akzeptieren kanonische englische Namen, lokalisierte Namen oder numerische IDs – der Server löst Namen automatisch zu IDs auf; unterstützt `custom_fields` sowie einen optionalen `note`-Parameter, der im selben Aufruf eine Notiz anhängt; `fields` darf entfallen, wenn nur `add_monitors`, `remove_monitors` oder `note` angegeben werden; mit `add_monitors` / `remove_monitors` (Arrays von Login-Namen) können Beobachter hinzugefügt oder entfernt werden – die Antwort enthält einen `monitors`-Schlüssel mit der aktuellen und der geänderten Beobachterliste; mit `fields.notes` lassen sich bestehende Notizen per ID bearbeiten (Notiz-ID aus `get_issue`) |
|
|
159
|
+
| `create_issue` | Neues Issue anlegen; `severity` und `priority` müssen kanonische englische Namen sein (z.B. `minor`, `major`, `normal`, `high`) – `get_issue_schema` 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); optionales `custom_fields` zum Setzen benutzerdefinierter Felder; `response: "short"` liefert statt des ganzen Issues nur dessen Kernfelder (Standard `"full"`, ab 2.0.0 `"short"`) |
|
|
160
|
+
| `update_issue` | Bestehendes Issue bearbeiten; Enum-Felder (`status`, `priority`, `severity`, `resolution`, `reproducibility`) akzeptieren kanonische englische Namen, lokalisierte Namen oder numerische IDs – der Server löst Namen automatisch zu IDs auf; unterstützt `custom_fields` sowie einen optionalen `note`-Parameter, der im selben Aufruf eine Notiz anhängt; `fields` darf entfallen, wenn nur `add_monitors`, `remove_monitors` oder `note` angegeben werden; mit `add_monitors` / `remove_monitors` (Arrays von Login-Namen) können Beobachter hinzugefügt oder entfernt werden – die Antwort enthält einen `monitors`-Schlüssel mit der aktuellen und der geänderten Beobachterliste; mit `fields.notes` lassen sich bestehende Notizen per ID bearbeiten (Notiz-ID aus `get_issue`); `response: "short"` liefert statt des ganzen Issues mit Notizen und Historie nur die Kernfelder und die geänderten Felder (Standard `"full"`, ab 2.0.0 `"short"`) |
|
|
161
161
|
| `delete_issue` | Issue löschen |
|
|
162
162
|
|
|
163
163
|
### Notizen
|
|
@@ -251,7 +251,7 @@ npm install sqlite-vec better-sqlite3
|
|
|
251
251
|
| Tool | Beschreibung |
|
|
252
252
|
|---|---|
|
|
253
253
|
| `get_metadata` | Gecachte Metadaten abrufen: `detail: "summary"` (Standard) liefert Projekt-/Tag-Zählwerte und Benutzer-/Versions-/Kategorie-Zählwerte je Projekt; `detail: "full"` liefert den vollständigen rohen Cache; `refresh: true` lädt alle Daten zuerst von MantisBT nach; mit aktivierter semantischer Suche enthält die Antwort zusätzlich einen `search_index`-Block |
|
|
254
|
-
| `get_version` | Version dieses MCP-Servers und der verbundenen MantisBT-Installation in einer Antwort; `check_latest` (Standard `true`) vergleicht MantisBT mit dem neuesten GitHub-Release; `mantis` enthält `error`, wenn MantisBT nicht erreichbar ist |
|
|
254
|
+
| `get_version` | Version dieses MCP-Servers und der verbundenen MantisBT-Installation in einer Antwort; der Server-Teil nennt zusätzlich Commit und Build-Zeitpunkt (Anhang `-dev`, wenn es kein veröffentlichter Release ist); `check_latest` (Standard `true`) vergleicht MantisBT mit dem neuesten GitHub-Release; `mantis` enthält `error`, wenn MantisBT nicht erreichbar ist |
|
|
255
255
|
| `get_issue_schema` | Gültige `select`-Felder (`fields`, `fields_source`) und Enum-Werte (`enums`: severity, status, priority, resolution, reproducibility) für diesen MantisBT-Server in einer Antwort; optionale `project_id` schränkt die Feldermittlung ein – vor `create_issue` / `update_issue` oder beim Aufbau eines `select`-Strings verwenden |
|
|
256
256
|
| `get_issue_fields` | **Veraltet:** stattdessen `get_issue_schema` verwenden – wird in 2.0.0 entfernt |
|
|
257
257
|
| `get_issue_enums` | **Veraltet:** stattdessen `get_issue_schema` verwenden; die Ressource `mantis://enums` bleibt – wird in 2.0.0 entfernt |
|
package/README.md
CHANGED
|
@@ -156,8 +156,8 @@ Deprecated tools always belong to the same group as their replacement — disabl
|
|
|
156
156
|
| `get_issue` | Retrieve an issue by `id`, or several by `ids` (1–50) in one call — pass exactly one; with `ids` returns `{ issues, requested, found, failed }`, missing or inaccessible IDs give `null` at their position; optional `select` for field projection |
|
|
157
157
|
| `get_issues` | **Deprecated:** use `get_issue` with `ids` instead — will be removed in 2.0.0 |
|
|
158
158
|
| `list_issues` | Filter issues by project, status, author, and more; optional `select` for field projection and `status` for client-side status filtering — canonical English status names (e.g. `"new"`, `"resolved"`) are matched by ID, making the filter language-independent on localized installations; `group_by` (`"status"`, `"handler"`, `"priority"`, `"category"`) returns counts per group instead of an issue list — all filters still apply, `page`, `page_size`, and `select` are ignored |
|
|
159
|
-
| `create_issue` | Create a new issue; `severity` and `priority` must be canonical English names (e.g. `minor`, `major`, `normal`, `high`) — call `get_issue_schema` to see all valid values and their localized labels; optional `handler` parameter accepts a username as alternative to `handler_id` (resolved against project members); optional `custom_fields` to set custom field values |
|
|
160
|
-
| `update_issue` | Update an existing issue; enum fields (`status`, `priority`, `severity`, `resolution`, `reproducibility`) accept canonical English names, localized names, or numeric IDs — the server resolves names to IDs automatically; supports `custom_fields` and an optional `note` parameter that appends a note in the same call; `fields` may be omitted when only `add_monitors`, `remove_monitors`, or `note` are given; use `add_monitors` / `remove_monitors` (arrays of login names) to add or remove watchers — the response includes a `monitors` key with the current and changed monitor lists; use `fields.notes` to edit existing notes by ID (note ID from `get_issue`) |
|
|
159
|
+
| `create_issue` | Create a new issue; `severity` and `priority` must be canonical English names (e.g. `minor`, `major`, `normal`, `high`) — call `get_issue_schema` to see all valid values and their localized labels; optional `handler` parameter accepts a username as alternative to `handler_id` (resolved against project members); optional `custom_fields` to set custom field values; `response: "short"` returns only the core fields of the new issue instead of the whole issue (default `"full"`, changes to `"short"` in 2.0.0) |
|
|
160
|
+
| `update_issue` | Update an existing issue; enum fields (`status`, `priority`, `severity`, `resolution`, `reproducibility`) accept canonical English names, localized names, or numeric IDs — the server resolves names to IDs automatically; supports `custom_fields` and an optional `note` parameter that appends a note in the same call; `fields` may be omitted when only `add_monitors`, `remove_monitors`, or `note` are given; use `add_monitors` / `remove_monitors` (arrays of login names) to add or remove watchers — the response includes a `monitors` key with the current and changed monitor lists; use `fields.notes` to edit existing notes by ID (note ID from `get_issue`); `response: "short"` returns only the core fields and the changed ones instead of the whole issue with notes and history (default `"full"`, changes to `"short"` in 2.0.0) |
|
|
161
161
|
| `delete_issue` | Delete an issue |
|
|
162
162
|
|
|
163
163
|
### Notes
|
|
@@ -251,7 +251,7 @@ npm install sqlite-vec better-sqlite3
|
|
|
251
251
|
| Tool | Description |
|
|
252
252
|
|---|---|
|
|
253
253
|
| `get_metadata` | Retrieve cached metadata: `detail: "summary"` (default) returns project/tag counts and per-project user/version/category counts; `detail: "full"` returns the complete raw cache; `refresh: true` re-fetches from MantisBT first; with semantic search enabled the response also contains a `search_index` block |
|
|
254
|
-
| `get_version` | Version of this MCP server and of the connected MantisBT installation in one response; `check_latest` (default `true`) compares MantisBT with the latest GitHub release; `mantis` holds `error` when MantisBT cannot be reached |
|
|
254
|
+
| `get_version` | Version of this MCP server and of the connected MantisBT installation in one response; the server part also names the commit and build time (`-dev` suffix unless it is a published release); `check_latest` (default `true`) compares MantisBT with the latest GitHub release; `mantis` holds `error` when MantisBT cannot be reached |
|
|
255
255
|
| `get_issue_schema` | Valid `select` fields (`fields`, `fields_source`) and enum values (`enums`: severity, status, priority, resolution, reproducibility) for this MantisBT server in one response; optional `project_id` scopes the field discovery — use before `create_issue` / `update_issue` or when building a `select` string |
|
|
256
256
|
| `get_issue_fields` | **Deprecated:** use `get_issue_schema` instead — will be removed in 2.0.0 |
|
|
257
257
|
| `get_issue_enums` | **Deprecated:** use `get_issue_schema` instead; the resource `mantis://enums` stays — will be removed in 2.0.0 |
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
/**
|
|
4
|
+
* Reads build-info.json, which scripts/write-build-info.mjs writes next to the
|
|
5
|
+
* compiled code. The version thus belongs to the code that runs, even when
|
|
6
|
+
* package.json was bumped after the build (#8547). Code run straight from
|
|
7
|
+
* src/ (tests, tsx) has no build: it reports package.json's version as -dev.
|
|
8
|
+
*/
|
|
9
|
+
export function loadBuildInfo(codeDir) {
|
|
10
|
+
try {
|
|
11
|
+
return JSON.parse(readFileSync(join(codeDir, 'build-info.json'), 'utf-8'));
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
const pkg = JSON.parse(readFileSync(join(codeDir, '..', 'package.json'), 'utf-8'));
|
|
15
|
+
return { version: `${pkg.version}-dev` };
|
|
16
|
+
}
|
|
17
|
+
}
|
package/dist/deprecation.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* Next major version: deprecated tools are removed and announced default
|
|
3
|
+
* changes take effect (see versioning rules in CLAUDE.md).
|
|
4
|
+
*/
|
|
2
5
|
export const REMOVAL_VERSION = '2.0.0';
|
|
3
6
|
/**
|
|
4
7
|
* First line of the description of a deprecated tool. Keeping the wording in
|
package/dist/index.js
CHANGED
|
@@ -3,9 +3,9 @@ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
|
3
3
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
4
|
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
5
5
|
import { createServer } from 'node:http';
|
|
6
|
-
import { readFileSync } from 'node:fs';
|
|
7
6
|
import { fileURLToPath } from 'node:url';
|
|
8
|
-
import {
|
|
7
|
+
import { dirname } from 'node:path';
|
|
8
|
+
import { loadBuildInfo } from './build-info.js';
|
|
9
9
|
import { getConfig, getStartupConfig, assertHttpAuthConfigured } from './config.js';
|
|
10
10
|
import { MantisClient } from './client.js';
|
|
11
11
|
import { VersionHintService, setGlobalVersionHint } from './version-hint.js';
|
|
@@ -15,12 +15,10 @@ import { filterToolRegistration } from './toolsets.js';
|
|
|
15
15
|
import { registerPrompts } from './prompts/index.js';
|
|
16
16
|
import { registerResources } from './resources/index.js';
|
|
17
17
|
// ---------------------------------------------------------------------------
|
|
18
|
-
//
|
|
18
|
+
// Version of the running build (dist/build-info.json, see build-info.ts)
|
|
19
19
|
// ---------------------------------------------------------------------------
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
const packageJson = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'));
|
|
23
|
-
const version = packageJson.version;
|
|
20
|
+
const build = loadBuildInfo(dirname(fileURLToPath(import.meta.url)));
|
|
21
|
+
const version = build.version;
|
|
24
22
|
// ---------------------------------------------------------------------------
|
|
25
23
|
// Bootstrap
|
|
26
24
|
// ---------------------------------------------------------------------------
|
|
@@ -57,7 +55,7 @@ async function createMcpServer(transport) {
|
|
|
57
55
|
client,
|
|
58
56
|
cache,
|
|
59
57
|
versionHint,
|
|
60
|
-
|
|
58
|
+
build,
|
|
61
59
|
uploadDir: startupConfig.uploadDir,
|
|
62
60
|
transport,
|
|
63
61
|
searchIndexStatus,
|
package/dist/tools/index.js
CHANGED
|
@@ -30,5 +30,5 @@ export function registerAllTools(server, deps) {
|
|
|
30
30
|
registerConfigTools(server, client, cache);
|
|
31
31
|
registerMetadataTools(server, client, cache, deps.searchIndexStatus);
|
|
32
32
|
registerTagTools(server, client);
|
|
33
|
-
registerVersionTools(server, client, deps.versionHint, deps.
|
|
33
|
+
registerVersionTools(server, client, deps.versionHint, deps.build);
|
|
34
34
|
}
|
package/dist/tools/issues.js
CHANGED
|
@@ -9,7 +9,7 @@ import { fetchIssueEnumsWithCache } from './config.js';
|
|
|
9
9
|
import { postNote, noteEditsSchema, prepareNoteEdits, verifyNoteEdits } from './notes.js';
|
|
10
10
|
import { applyMonitorChanges } from './monitors.js';
|
|
11
11
|
import { firstIssue } from '../issue-envelope.js';
|
|
12
|
-
import { deprecationNote } from '../deprecation.js';
|
|
12
|
+
import { deprecationNote, REMOVAL_VERSION } from '../deprecation.js';
|
|
13
13
|
function errorText(msg) {
|
|
14
14
|
const vh = getVersionHint();
|
|
15
15
|
vh?.triggerLatestVersionFetch();
|
|
@@ -74,6 +74,37 @@ function makeIssueFilter({ status, assigned_to, reporter_id, dateFilter }) {
|
|
|
74
74
|
olderThanUpdatedAfter: (issue) => updatedAfterMs !== undefined && issue.updated_at !== undefined && new Date(issue.updated_at).getTime() <= updatedAfterMs,
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
|
+
// response: "short" for create_issue / update_issue (#8598) — the fields that
|
|
78
|
+
// confirm what happened, instead of the whole issue with notes and history.
|
|
79
|
+
const responseSchema = z.enum(['short', 'full']).default('full').describe(`"full" (default): the whole issue as MantisBT returns it, including description, notes and history. ` +
|
|
80
|
+
`"short": only the fields that confirm the change — far fewer tokens. The default changes to "short" in ${REMOVAL_VERSION}.`);
|
|
81
|
+
const SHORT_CREATE_FIELDS = ['id', 'summary', 'project', 'category', 'status', 'handler', 'created_at', 'view_url'];
|
|
82
|
+
const SHORT_UPDATE_FIELDS = ['id', 'summary', 'status', 'resolution', 'updated_at', 'view_url'];
|
|
83
|
+
/** Returns only the given top-level fields of an object (those it has). */
|
|
84
|
+
function pickFields(obj, fields) {
|
|
85
|
+
return Object.fromEntries(Object.entries(obj).filter(([key]) => fields.includes(key)));
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Short update_issue result: the core fields plus every changed field. Custom
|
|
89
|
+
* fields and notes are narrowed to the entries that were changed.
|
|
90
|
+
*/
|
|
91
|
+
function shortUpdatedIssue(issue, changes) {
|
|
92
|
+
const short = pickFields(issue, [...SHORT_UPDATE_FIELDS, ...Object.keys(changes)]);
|
|
93
|
+
const { custom_fields: changedCustomFields, notes: editedNotes } = changes;
|
|
94
|
+
if (short.custom_fields && changedCustomFields) {
|
|
95
|
+
short.custom_fields = short.custom_fields.filter(({ field }) => changedCustomFields.some(c => c.field.id === field.id || c.field.name === field.name));
|
|
96
|
+
}
|
|
97
|
+
if (short.notes && editedNotes) {
|
|
98
|
+
short.notes = short.notes.filter(n => editedNotes.some(e => e.id === n.id));
|
|
99
|
+
}
|
|
100
|
+
return short;
|
|
101
|
+
}
|
|
102
|
+
/** Returns the issue without the given top-level fields. */
|
|
103
|
+
function omitFields(issue, fields) {
|
|
104
|
+
if (fields.length === 0)
|
|
105
|
+
return issue;
|
|
106
|
+
return Object.fromEntries(Object.entries(issue).filter(([key]) => !fields.includes(key)));
|
|
107
|
+
}
|
|
77
108
|
// Worker-pool: runs `fn` over all `items` with at most `concurrency` in-flight at once.
|
|
78
109
|
// nextIndex is only incremented inside microtasks, so the ++ is safe without a lock.
|
|
79
110
|
async function runWithConcurrency(items, concurrency, fn) {
|
|
@@ -115,14 +146,21 @@ export function registerIssueTools(server, client, cache) {
|
|
|
115
146
|
* the current page once MantisBT's newest-first order shows the rest is
|
|
116
147
|
* older than updated_after. Returns truncated when maxPages ended the scan
|
|
117
148
|
* before either happened.
|
|
149
|
+
*
|
|
150
|
+
* select is the caller's projection. The filter reads its fields from each
|
|
151
|
+
* issue, so a select that omits them would fail every issue (#8597): they
|
|
152
|
+
* are fetched as well and removed again before onMatch sees the issue.
|
|
118
153
|
*/
|
|
119
|
-
async function scanMatchingIssues(params, filter, pageSize, maxPages, onMatch) {
|
|
154
|
+
async function scanMatchingIssues(params, select, filter, pageSize, maxPages, onMatch) {
|
|
155
|
+
const selected = select?.split(',').map(f => f.trim()).filter(Boolean);
|
|
156
|
+
const extraFields = selected ? filter.fields.filter(f => !selected.includes(f)) : [];
|
|
157
|
+
const fetchSelect = selected && [...selected, ...extraFields].join(',');
|
|
120
158
|
for (let page = 1; page <= maxPages; page++) {
|
|
121
|
-
const issues = (await client.get('issues', { ...params, page, page_size: pageSize })).issues ?? [];
|
|
159
|
+
const issues = (await client.get('issues', { ...params, select: fetchSelect, page, page_size: pageSize })).issues ?? [];
|
|
122
160
|
let stopAfterBatch = false;
|
|
123
161
|
for (const issue of issues) {
|
|
124
162
|
if (filter.matches(issue)) {
|
|
125
|
-
if (onMatch(issue) === false)
|
|
163
|
+
if (onMatch(omitFields(issue, extraFields)) === false)
|
|
126
164
|
return { truncated: false };
|
|
127
165
|
}
|
|
128
166
|
else if (filter.olderThanUpdatedAfter(issue)) {
|
|
@@ -139,10 +177,9 @@ export function registerIssueTools(server, client, cache) {
|
|
|
139
177
|
* the fields grouping and filters need.
|
|
140
178
|
*/
|
|
141
179
|
async function groupIssues(groupBy, params, filter) {
|
|
142
|
-
const select = [...new Set(['id', groupBy, ...filter.fields])].join(',');
|
|
143
180
|
const groups = new Map();
|
|
144
181
|
let total = 0;
|
|
145
|
-
const { truncated } = await scanMatchingIssues(
|
|
182
|
+
const { truncated } = await scanMatchingIssues(params, `id,${groupBy}`, filter, GROUP_BY_PAGE_SIZE, GROUP_BY_MAX_PAGES, issue => {
|
|
146
183
|
const ref = issue[groupBy];
|
|
147
184
|
const key = ref?.id ?? null;
|
|
148
185
|
let group = groups.get(key);
|
|
@@ -300,7 +337,7 @@ Use "select" to fetch only some fields, e.g. select: "notes" for just the notes
|
|
|
300
337
|
const MAX_API_PAGES = 10; // hard cap: scan at most 500 issues
|
|
301
338
|
const neededTotal = page * page_size; // need this many matches to serve page N
|
|
302
339
|
const matching = [];
|
|
303
|
-
const { truncated } = await scanMatchingIssues(baseParams, filter, API_PAGE_SIZE, MAX_API_PAGES, issue => {
|
|
340
|
+
const { truncated } = await scanMatchingIssues(baseParams, select, filter, API_PAGE_SIZE, MAX_API_PAGES, issue => {
|
|
304
341
|
matching.push(issue);
|
|
305
342
|
return matching.length < neededTotal;
|
|
306
343
|
});
|
|
@@ -324,7 +361,7 @@ Use "select" to fetch only some fields, e.g. select: "notes" for just the notes
|
|
|
324
361
|
// ---------------------------------------------------------------------------
|
|
325
362
|
server.registerTool('create_issue', {
|
|
326
363
|
title: 'Create Issue',
|
|
327
|
-
description: `Create a new MantisBT issue. Returns the full created issue object including the assigned id, summary, status, priority, severity, category, reporter, created_at, and view_url.
|
|
364
|
+
description: `Create a new MantisBT issue. Returns the full created issue object including the assigned id, summary, status, priority, severity, category, reporter, created_at, and view_url. With response: "short" only id, summary, project, category, status, handler, created_at and view_url (default "full"; it changes to "short" in ${REMOVAL_VERSION}).
|
|
328
365
|
|
|
329
366
|
Required fields: summary, description, project_id, category. All other fields are optional with sensible defaults (priority: "normal", severity: "minor").
|
|
330
367
|
|
|
@@ -353,13 +390,14 @@ For the handler, prefer the username field (resolved server-side) over handler_i
|
|
|
353
390
|
reproducibility: z.string().optional().describe('How reliably the issue reproduces. Canonical English names: always, sometimes, random, have not tried, unable to reproduce, N/A. Use get_issue_schema to see localized labels.'),
|
|
354
391
|
view_state: z.enum(['public', 'private']).optional().describe('Visibility of the issue: "public" (visible to all, default) or "private" (restricted to higher-access users).'),
|
|
355
392
|
custom_fields: z.array(customFieldEntry).optional().describe('Custom field values: [{field: {id|name}, value: "<string>"}]. Use get_issue_schema or get_metadata to discover available custom fields per project.'),
|
|
393
|
+
response: responseSchema,
|
|
356
394
|
}),
|
|
357
395
|
annotations: {
|
|
358
396
|
readOnlyHint: false,
|
|
359
397
|
destructiveHint: false,
|
|
360
398
|
idempotentHint: false,
|
|
361
399
|
},
|
|
362
|
-
}, async ({ summary, description, project_id, category, priority, severity, handler_id, handler, version, target_version, fixed_in_version, steps_to_reproduce, additional_information, reproducibility, view_state, custom_fields }) => {
|
|
400
|
+
}, async ({ summary, description, project_id, category, priority, severity, handler_id, handler, version, target_version, fixed_in_version, steps_to_reproduce, additional_information, reproducibility, view_state, custom_fields, response }) => {
|
|
363
401
|
// Resolve handler username to handler_id when only a name is given
|
|
364
402
|
let resolvedHandlerId = handler_id;
|
|
365
403
|
if (resolvedHandlerId === undefined && handler !== undefined) {
|
|
@@ -425,19 +463,22 @@ For the handler, prefer the username field (resolved server-side) over handler_i
|
|
|
425
463
|
const partial = firstIssue(raw) ?? raw;
|
|
426
464
|
let issue = partial;
|
|
427
465
|
if (!('summary' in partial)) {
|
|
428
|
-
// Older MantisBT returned only { id: N } — fetch the
|
|
466
|
+
// Older MantisBT returned only { id: N } — fetch the issue (only the
|
|
467
|
+
// short fields when those are all that is returned).
|
|
429
468
|
// Suppress GET errors: the issue was already created.
|
|
430
469
|
try {
|
|
431
|
-
const
|
|
470
|
+
const select = response === 'short' ? SHORT_CREATE_FIELDS.filter(f => f !== 'view_url').join(',') : undefined;
|
|
471
|
+
const fetched = await client.get(`issues/${partial.id}`, { select });
|
|
432
472
|
issue = firstIssue(fetched) ?? partial;
|
|
433
473
|
}
|
|
434
474
|
catch {
|
|
435
475
|
// unable to fetch details — return minimal object
|
|
436
476
|
}
|
|
437
477
|
}
|
|
438
|
-
const
|
|
478
|
+
const enriched = enrichIssue(issue, await client.getBaseUrl());
|
|
479
|
+
const result = response === 'short' ? pickFields(enriched, SHORT_CREATE_FIELDS) : enriched;
|
|
439
480
|
return {
|
|
440
|
-
content: [{ type: 'text', text: JSON.stringify(
|
|
481
|
+
content: [{ type: 'text', text: JSON.stringify(result, null, 2) }],
|
|
441
482
|
};
|
|
442
483
|
}
|
|
443
484
|
catch (error) {
|
|
@@ -495,6 +536,8 @@ Use the optional "note" parameter to append a note in the same call (e.g. the re
|
|
|
495
536
|
|
|
496
537
|
Use "add_monitors" / "remove_monitors" (lists of MantisBT login names) to change who watches the issue — "fields" may be omitted then. The response contains "monitors" with added/removed/not_monitoring and the current monitor list. Adding or removing other users requires the monitor_add_others_bug_threshold / monitor_delete_others_bug_threshold access level.
|
|
497
538
|
|
|
539
|
+
The response is the updated issue. With response: "short" it holds only id, summary, status, resolution, updated_at, view_url and the fields that were changed (custom_fields and notes narrowed to the changed entries; an appended note as { id, view_url }) — use it for routine changes. Default is "full"; it changes to "short" in ${REMOVAL_VERSION}.
|
|
540
|
+
|
|
498
541
|
Steps run in order: fields, monitors, note. Once one step succeeded, a later failure is reported inline ("notes_error" when a note edit was not applied, "monitors_error", "note_error") instead of failing the call — do not retry the steps that went through. Only if every requested step failed is the call an error.`,
|
|
499
542
|
inputSchema: z.object({
|
|
500
543
|
id: z.coerce.number().int().positive().describe('Numeric issue ID to update'),
|
|
@@ -503,6 +546,7 @@ Steps run in order: fields, monitors, note. Once one step succeeded, a later fai
|
|
|
503
546
|
dry_run: z.preprocess(coerceBool, z.boolean().optional()).describe('If true, return the patch payload that would be sent without actually updating the issue. Useful for previewing changes before committing them.'),
|
|
504
547
|
note: z.string().min(1).optional().describe('Optional note text appended after a successful update (e.g. reason for a status change). Replaces a separate add_note call.'),
|
|
505
548
|
note_view_state: z.enum(['public', 'private']).default('public').describe('Visibility of the appended note: "public" (default) or "private". Only used when "note" is set.'),
|
|
549
|
+
response: responseSchema,
|
|
506
550
|
fields: z.preprocess((v) => {
|
|
507
551
|
if (typeof v !== 'string')
|
|
508
552
|
return v;
|
|
@@ -537,7 +581,7 @@ Steps run in order: fields, monitors, note. Once one step succeeded, a later fai
|
|
|
537
581
|
destructiveHint: false,
|
|
538
582
|
idempotentHint: false,
|
|
539
583
|
},
|
|
540
|
-
}, async ({ id, fields, dry_run, note, note_view_state, add_monitors, remove_monitors }) => {
|
|
584
|
+
}, async ({ id, fields, dry_run, note, note_view_state, add_monitors, remove_monitors, response: responseMode }) => {
|
|
541
585
|
const fieldChanges = fields ?? {};
|
|
542
586
|
const hasFields = Object.keys(fieldChanges).length > 0;
|
|
543
587
|
const hasMonitorChanges = add_monitors !== undefined || remove_monitors !== undefined;
|
|
@@ -574,9 +618,10 @@ Steps run in order: fields, monitors, note. Once one step succeeded, a later fai
|
|
|
574
618
|
}],
|
|
575
619
|
};
|
|
576
620
|
}
|
|
621
|
+
const short = responseMode === 'short';
|
|
577
622
|
const patched = hasFields ? await patchIssueFields(id, patchFields) : undefined;
|
|
578
623
|
const response = patched
|
|
579
|
-
? { ...patched }
|
|
624
|
+
? (short ? shortUpdatedIssue(patched, fieldChanges) : { ...patched })
|
|
580
625
|
: { id, view_url: buildIssueViewUrl(await client.getBaseUrl(), id) };
|
|
581
626
|
// MantisBT skips note edits it does not apply without an error, so the
|
|
582
627
|
// response is checked.
|
|
@@ -614,7 +659,8 @@ Steps run in order: fields, monitors, note. Once one step succeeded, a later fai
|
|
|
614
659
|
}
|
|
615
660
|
if (note !== undefined) {
|
|
616
661
|
try {
|
|
617
|
-
|
|
662
|
+
const posted = await postNote(client, id, note, note_view_state);
|
|
663
|
+
response['note'] = short ? pickFields(posted, ['id', 'view_url']) : posted;
|
|
618
664
|
succeeded = true;
|
|
619
665
|
}
|
|
620
666
|
catch (noteError) {
|
package/dist/tools/version.js
CHANGED
|
@@ -2,7 +2,7 @@ import { z } from 'zod';
|
|
|
2
2
|
import { coerceBool } from '../coerce.js';
|
|
3
3
|
import { parseVersion, compareVersions } from '../version-hint.js';
|
|
4
4
|
import { deprecationNote } from '../deprecation.js';
|
|
5
|
-
export function registerVersionTools(server, client, versionHint,
|
|
5
|
+
export function registerVersionTools(server, client, versionHint, build) {
|
|
6
6
|
/**
|
|
7
7
|
* Installed MantisBT version (X-Mantis-Version header), optionally compared
|
|
8
8
|
* with the latest MantisBT release on GitHub.
|
|
@@ -40,7 +40,9 @@ export function registerVersionTools(server, client, versionHint, mcpVersion) {
|
|
|
40
40
|
server.registerTool('get_version', {
|
|
41
41
|
title: 'Get Versions',
|
|
42
42
|
description: `Return the version of this mantisbt-mcp-server and of the connected MantisBT installation in one response:
|
|
43
|
-
{ mcp_server: { version }, mantis: { installed_version, latest_version?, status?, github_note? } }
|
|
43
|
+
{ mcp_server: { version, commit?, built_at? }, mantis: { installed_version, latest_version?, status?, github_note? } }
|
|
44
|
+
|
|
45
|
+
mcp_server describes the running build: version ends in "-dev" unless it is a published release; commit is the short hash it was built from ("-dirty" with uncommitted changes), built_at the ISO-8601 build time.
|
|
44
46
|
|
|
45
47
|
The MantisBT version is read from the X-Mantis-Version response header. With check_latest (default: true) it is compared against the latest MantisBT release on GitHub (outbound HTTPS request, up to 5 seconds); status is "up-to-date", "update-available", "newer-than-release" or "unknown". If MantisBT cannot be reached, mantis contains "error" instead and mcp_server is still returned.`,
|
|
46
48
|
inputSchema: z.object({ check_latest: checkLatestSchema }),
|
|
@@ -54,7 +56,7 @@ The MantisBT version is read from the X-Mantis-Version response header. With che
|
|
|
54
56
|
error: error instanceof Error ? error.message : String(error),
|
|
55
57
|
}));
|
|
56
58
|
return {
|
|
57
|
-
content: [{ type: 'text', text: JSON.stringify({ mcp_server:
|
|
59
|
+
content: [{ type: 'text', text: JSON.stringify({ mcp_server: build, mantis }, null, 2) }],
|
|
58
60
|
};
|
|
59
61
|
});
|
|
60
62
|
// ---------------------------------------------------------------------------
|
|
@@ -70,7 +72,7 @@ The MantisBT version is read from the X-Mantis-Version response header. With che
|
|
|
70
72
|
idempotentHint: true,
|
|
71
73
|
},
|
|
72
74
|
}, async () => ({
|
|
73
|
-
content: [{ type: 'text', text: JSON.stringify({ version:
|
|
75
|
+
content: [{ type: 'text', text: JSON.stringify({ version: build.version }, null, 2) }],
|
|
74
76
|
}));
|
|
75
77
|
// ---------------------------------------------------------------------------
|
|
76
78
|
// get_mantis_version
|
package/docs/cookbook.de.md
CHANGED
|
@@ -779,6 +779,47 @@ Löst ein Issue auf und schließt es. **Immer beide Felder** `status` und `resol
|
|
|
779
779
|
|
|
780
780
|
---
|
|
781
781
|
|
|
782
|
+
### Kurze Antwort statt des ganzen Issues
|
|
783
|
+
|
|
784
|
+
Standardmäßig geben `update_issue` und `create_issue` das ganze Issue zurück, mit Beschreibung, Notizen und Historie – bei einem lebhaften Issue mehrere tausend Token. Mit `response: "short"` kommt nur zurück, was die Änderung bestätigt.
|
|
785
|
+
|
|
786
|
+
**Tool:** `update_issue` (bei `create_issue` genauso)
|
|
787
|
+
|
|
788
|
+
**Parameter:**
|
|
789
|
+
- `response` – _(optional)_ `"full"` (Standard) oder `"short"`. In 2.0.0 wird `"short"` zum Standard.
|
|
790
|
+
|
|
791
|
+
**Request:**
|
|
792
|
+
|
|
793
|
+
```json
|
|
794
|
+
{
|
|
795
|
+
"id": 1042,
|
|
796
|
+
"fields": {
|
|
797
|
+
"status": { "name": "resolved" },
|
|
798
|
+
"resolution": { "id": 20 }
|
|
799
|
+
},
|
|
800
|
+
"note": "Behoben in Commit abc123.",
|
|
801
|
+
"response": "short"
|
|
802
|
+
}
|
|
803
|
+
```
|
|
804
|
+
|
|
805
|
+
**Response:**
|
|
806
|
+
|
|
807
|
+
```json
|
|
808
|
+
{
|
|
809
|
+
"id": 1042,
|
|
810
|
+
"summary": "Login schlägt auf iOS fehl",
|
|
811
|
+
"status": { "id": 80, "name": "resolved", "label": "erledigt" },
|
|
812
|
+
"resolution": { "id": 20, "name": "fixed", "label": "erledigt" },
|
|
813
|
+
"updated_at": "2026-11-09T13:21:00+01:00",
|
|
814
|
+
"view_url": "https://mantis.example.com/view.php?id=1042",
|
|
815
|
+
"note": { "id": 4957, "view_url": "https://mantis.example.com/view.php?id=1042#bugnote4957" }
|
|
816
|
+
}
|
|
817
|
+
```
|
|
818
|
+
|
|
819
|
+
`update_issue` liefert `id`, `summary`, `status`, `resolution`, `updated_at`, `view_url` und jedes geänderte Feld; `custom_fields` und `notes` (Änderungen über `fields.notes`) sind auf die geänderten Einträge beschränkt, eine angehängte Notiz auf `id` und `view_url`. `monitors` und die `*_error`-Schlüssel erscheinen wie bei `"full"`. `create_issue` liefert `id`, `summary`, `project`, `category`, `status`, `handler`, `created_at` und `view_url`.
|
|
820
|
+
|
|
821
|
+
---
|
|
822
|
+
|
|
782
823
|
### Benutzerdefinierte Felder setzen
|
|
783
824
|
|
|
784
825
|
Schreibt Custom-Field-Werte beim Anlegen oder Aktualisieren. Dasselbe `custom_fields`-Format funktioniert bei `create_issue` und `update_issue` (dort innerhalb von `fields`).
|
|
@@ -2344,7 +2385,7 @@ Gibt die Version dieses mantisbt-mcp-servers und der verbundenen MantisBT-Instal
|
|
|
2344
2385
|
|
|
2345
2386
|
```json
|
|
2346
2387
|
{
|
|
2347
|
-
"mcp_server": { "version": "1.
|
|
2388
|
+
"mcp_server": { "version": "1.18.0", "commit": "9ebef4c", "built_at": "2026-11-09T12:00:00.000Z" },
|
|
2348
2389
|
"mantis": {
|
|
2349
2390
|
"installed_version": "2.27.0",
|
|
2350
2391
|
"latest_version": "2.27.1",
|
|
@@ -2355,6 +2396,8 @@ Gibt die Version dieses mantisbt-mcp-servers und der verbundenen MantisBT-Instal
|
|
|
2355
2396
|
|
|
2356
2397
|
Mögliche Werte für `status`: `up-to-date`, `update-available`, `newer-than-release`, `unknown`. Mit `check_latest: false` den GitHub-Vergleich überspringen.
|
|
2357
2398
|
|
|
2399
|
+
`mcp_server` beschreibt den laufenden Build, nicht die aktuelle `package.json`: `version` ist die Version, aus der gebaut wurde, `commit` der kurze Commit-Hash (mit `-dirty`, wenn es nicht committete Änderungen gab), `built_at` der Build-Zeitpunkt. Nur ein veröffentlichter Release meldet eine reine Versionsnummer; ein lokaler Build, `npm run dev` oder Code direkt aus `src/` meldet z. B. `1.18.0-dev`. Ohne Git fehlt `commit`; Code direkt aus `src/` hat weder `commit` noch `built_at`.
|
|
2400
|
+
|
|
2358
2401
|
> **Veraltet:** `get_mcp_version` und `get_mantis_version` werden in 2.0.0 entfernt – stattdessen `get_version` wie oben gezeigt verwenden.
|
|
2359
2402
|
|
|
2360
2403
|
---
|
package/docs/cookbook.md
CHANGED
|
@@ -779,6 +779,47 @@ Changes the status and appends a note explaining the change — in one `update_i
|
|
|
779
779
|
|
|
780
780
|
---
|
|
781
781
|
|
|
782
|
+
### Get a short response instead of the whole issue
|
|
783
|
+
|
|
784
|
+
By default `update_issue` and `create_issue` return the whole issue, including description, notes and history — several thousand tokens on a busy issue. With `response: "short"` you get only what confirms the change.
|
|
785
|
+
|
|
786
|
+
**Tool:** `update_issue` (works the same way for `create_issue`)
|
|
787
|
+
|
|
788
|
+
**Parameters:**
|
|
789
|
+
- `response` — _(optional)_ `"full"` (default) or `"short"`. The default changes to `"short"` in 2.0.0.
|
|
790
|
+
|
|
791
|
+
**Request:**
|
|
792
|
+
|
|
793
|
+
```json
|
|
794
|
+
{
|
|
795
|
+
"id": 1042,
|
|
796
|
+
"fields": {
|
|
797
|
+
"status": { "name": "resolved" },
|
|
798
|
+
"resolution": { "id": 20 }
|
|
799
|
+
},
|
|
800
|
+
"note": "Fixed in commit abc123.",
|
|
801
|
+
"response": "short"
|
|
802
|
+
}
|
|
803
|
+
```
|
|
804
|
+
|
|
805
|
+
**Response:**
|
|
806
|
+
|
|
807
|
+
```json
|
|
808
|
+
{
|
|
809
|
+
"id": 1042,
|
|
810
|
+
"summary": "Login fails on iOS",
|
|
811
|
+
"status": { "id": 80, "name": "resolved", "label": "resolved" },
|
|
812
|
+
"resolution": { "id": 20, "name": "fixed", "label": "fixed" },
|
|
813
|
+
"updated_at": "2026-11-09T13:21:00+01:00",
|
|
814
|
+
"view_url": "https://mantis.example.com/view.php?id=1042",
|
|
815
|
+
"note": { "id": 4957, "view_url": "https://mantis.example.com/view.php?id=1042#bugnote4957" }
|
|
816
|
+
}
|
|
817
|
+
```
|
|
818
|
+
|
|
819
|
+
`update_issue` returns `id`, `summary`, `status`, `resolution`, `updated_at`, `view_url` and every field you changed; `custom_fields` and `notes` (edits via `fields.notes`) are narrowed to the entries you changed, an appended note to `id` and `view_url`. `monitors` and the `*_error` keys appear as with `"full"`. `create_issue` returns `id`, `summary`, `project`, `category`, `status`, `handler`, `created_at` and `view_url`.
|
|
820
|
+
|
|
821
|
+
---
|
|
822
|
+
|
|
782
823
|
### Set custom fields
|
|
783
824
|
|
|
784
825
|
Writes custom field values on create or update. The same `custom_fields` format works for both `create_issue` and `update_issue` (inside `fields`).
|
|
@@ -2344,7 +2385,7 @@ Returns the version of this mantisbt-mcp-server and of the connected MantisBT in
|
|
|
2344
2385
|
|
|
2345
2386
|
```json
|
|
2346
2387
|
{
|
|
2347
|
-
"mcp_server": { "version": "1.
|
|
2388
|
+
"mcp_server": { "version": "1.18.0", "commit": "9ebef4c", "built_at": "2026-11-09T12:00:00.000Z" },
|
|
2348
2389
|
"mantis": {
|
|
2349
2390
|
"installed_version": "2.27.0",
|
|
2350
2391
|
"latest_version": "2.27.1",
|
|
@@ -2355,6 +2396,8 @@ Returns the version of this mantisbt-mcp-server and of the connected MantisBT in
|
|
|
2355
2396
|
|
|
2356
2397
|
Possible values for `status`: `up-to-date`, `update-available`, `newer-than-release`, `unknown`. Set `check_latest: false` to skip the GitHub comparison.
|
|
2357
2398
|
|
|
2399
|
+
`mcp_server` describes the running build, not the current `package.json`: `version` is the version it was built from, `commit` the short commit hash (with `-dirty` if there were uncommitted changes), `built_at` the build time. Only a published release reports a plain version; a local build, `npm run dev` or code run straight from `src/` reports e.g. `1.18.0-dev`. Without git, `commit` is left out; code run from `src/` has neither `commit` nor `built_at`.
|
|
2400
|
+
|
|
2358
2401
|
> **Deprecated:** `get_mcp_version` and `get_mantis_version` will be removed in 2.0.0 — use `get_version` as shown above.
|
|
2359
2402
|
|
|
2360
2403
|
---
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dpesch/mantisbt-mcp-server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.18.0",
|
|
4
4
|
"mcpName": "io.github.dpesch/mantisbt-mcp-server",
|
|
5
5
|
"description": "MCP server for MantisBT REST API – read and manage bug tracker issues",
|
|
6
6
|
"author": "Dominik Pesch",
|
|
@@ -32,10 +32,11 @@
|
|
|
32
32
|
},
|
|
33
33
|
"type": "module",
|
|
34
34
|
"scripts": {
|
|
35
|
-
"build": "tsc -p tsconfig.build.json",
|
|
35
|
+
"build": "tsc -p tsconfig.build.json && node scripts/write-build-info.mjs",
|
|
36
36
|
"typecheck": "tsc --noEmit",
|
|
37
37
|
"start": "node dist/index.js",
|
|
38
|
-
"dev": "tsc -p tsconfig.build.json --watch",
|
|
38
|
+
"dev": "node scripts/write-build-info.mjs && tsc -p tsconfig.build.json --watch",
|
|
39
|
+
"prepublishOnly": "node scripts/check-release-build.mjs",
|
|
39
40
|
"dev:start": "npm run typecheck && npm run build && node dist/index.js",
|
|
40
41
|
"test": "vitest run",
|
|
41
42
|
"test:watch": "vitest",
|
package/server.json
CHANGED
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
"name": "io.github.dpesch/mantisbt-mcp-server",
|
|
4
4
|
"title": "MantisBT MCP Server",
|
|
5
5
|
"description": "MantisBT MCP server – manage issues, notes, files, tags, and relationships. With semantic search.",
|
|
6
|
-
"version": "1.
|
|
6
|
+
"version": "1.18.0",
|
|
7
7
|
"packages": [
|
|
8
8
|
{
|
|
9
9
|
"registryType": "npm",
|
|
10
10
|
"identifier": "@dpesch/mantisbt-mcp-server",
|
|
11
|
-
"version": "1.
|
|
11
|
+
"version": "1.18.0",
|
|
12
12
|
"runtimeHint": "npx",
|
|
13
13
|
"transport": {
|
|
14
14
|
"type": "stdio"
|