@dpesch/mantisbt-mcp-server 1.8.1 → 1.8.2

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
@@ -11,6 +11,13 @@ This project adheres to [Semantic Versioning](https://semver.org/).
11
11
 
12
12
  ---
13
13
 
14
+ ## [1.8.2] – 2026-03-27
15
+
16
+ ### Fixed
17
+ - HTTP transport (`TRANSPORT=http`): race condition when multiple sequential requests arrive quickly (e.g. `initialize` followed immediately by `ping`). The `res.on('close')` handler that calls `transport.close()` fires asynchronously, so the next request could arrive while the previous transport was still registered — causing `connect()` to throw "Already connected". Fixed by calling `await server.close()` before each `server.connect()` call (a no-op when not connected). Also added a `res.headersSent` guard in the error handler to prevent a secondary "Cannot set headers after they are sent" error from closing the socket without a response.
18
+
19
+ ---
20
+
14
21
  ## [1.8.1] – 2026-03-27
15
22
 
16
23
  ### Fixed
package/dist/index.js CHANGED
@@ -107,13 +107,20 @@ async function runHttp() {
107
107
  sessionIdGenerator: undefined,
108
108
  enableJsonResponse: true,
109
109
  });
110
- res.on('close', () => transport.close());
110
+ res.on('close', () => { void transport.close(); });
111
+ // Disconnect from any previous transport before connecting the new one.
112
+ // The res.on('close') handler above closes the transport asynchronously,
113
+ // but the next request may arrive before it fires — causing connect() to
114
+ // throw "Already connected". Explicitly closing first avoids that race.
115
+ await server.close();
111
116
  await server.connect(transport);
112
117
  await transport.handleRequest(req, res, body);
113
118
  }
114
119
  catch {
115
- res.writeHead(400, { 'Content-Type': 'application/json' });
116
- res.end(JSON.stringify({ error: 'Bad Request' }));
120
+ if (!res.headersSent) {
121
+ res.writeHead(400, { 'Content-Type': 'application/json' });
122
+ res.end(JSON.stringify({ error: 'Bad Request' }));
123
+ }
117
124
  }
118
125
  });
119
126
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dpesch/mantisbt-mcp-server",
3
- "version": "1.8.1",
3
+ "version": "1.8.2",
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",
@@ -111,6 +111,16 @@ rl.on('close', () => {
111
111
  const branches = lines.filter(l => l.split(' ')[2]?.startsWith('refs/heads/'));
112
112
  const others = lines.filter(l => !l.split(' ')[2]?.startsWith('refs/heads/'));
113
113
 
114
+ // Batch-fetch all tags from Codeberg (single ls-remote call, ref → sha).
115
+ const remoteTagsRaw = gitOptional(`ls-remote --tags "${remoteUrl}"`);
116
+ const remoteTagMap = new Map(
117
+ remoteTagsRaw
118
+ ? remoteTagsRaw.split('\n').filter(Boolean)
119
+ .map(l => { const [sha, ref] = l.split(/\s+/); return [ref, sha]; })
120
+ .filter(([ref]) => ref)
121
+ : []
122
+ );
123
+
114
124
  // localSha → filteredSha, accumulated across all refs in this push.
115
125
  const shaMap = {};
116
126
  let pushed = 0;
@@ -124,6 +134,17 @@ rl.on('close', () => {
124
134
 
125
135
  const label = remoteRef.replace('refs/heads/', '').replace('refs/tags/', '');
126
136
 
137
+ if (remoteRef.startsWith('refs/tags/')) {
138
+ if (remoteTagMap.has(remoteRef)) {
139
+ console.log(` ↷ ${label} already on Codeberg — skipping`);
140
+ continue;
141
+ }
142
+ if (!gitOptional(`rev-parse --verify "${localSha}"`)) {
143
+ console.warn(` ⚠ ${label} — commit ${localSha.slice(0, 8)} not found locally, skipping`);
144
+ continue;
145
+ }
146
+ }
147
+
127
148
  // If this commit was already filtered as part of a branch push, reuse it.
128
149
  if (localSha in shaMap) {
129
150
  try {
@@ -137,9 +158,11 @@ rl.on('close', () => {
137
158
  continue;
138
159
  }
139
160
 
140
- // Get the actual current SHA on Codeberg for this ref.
141
- const lsOut = gitOptional(`ls-remote "${remoteUrl}" "${remoteRef}"`);
142
- const actualRemoteSha = lsOut ? lsOut.split(/\s+/)[0] : '';
161
+ // Tags: existing ones were skipped above, so only new tags reach here — no remote anchor.
162
+ // Branches: query individually to find the incremental anchor for filtered chain building.
163
+ const actualRemoteSha = remoteRef.startsWith('refs/tags/')
164
+ ? ''
165
+ : (gitOptional(`ls-remote "${remoteUrl}" "${remoteRef}"`)?.split(/\s+/)[0] ?? '');
143
166
 
144
167
  if (!actualRemoteSha) {
145
168
  // New ref on Codeberg — filter the tip with no parent.
@@ -167,15 +190,8 @@ rl.on('close', () => {
167
190
  shaMap[sha] = makeFilteredCommit(sha, filteredTree, mappedParents);
168
191
  }
169
192
  } else {
170
- // Fallback: anchor not found.
171
- // If the remote SHA doesn't exist locally (filtered commit from a prior push),
172
- // tags can be safely skipped (immutable — already correct on Codeberg).
173
- // Branches fall back to orphan filtering (best effort).
193
+ // Fallback: anchor not found — branch only (tags exit early above).
174
194
  const remoteExists = !!gitOptional(`rev-parse --verify "${actualRemoteSha}"`);
175
- if (!remoteExists && remoteRef.startsWith('refs/tags/')) {
176
- console.log(` ↷ ${label} already on Codeberg — skipping`);
177
- continue;
178
- }
179
195
  console.warn(` ⚠ Could not find local base for ${label}, filtering tip only`);
180
196
  shaMap[localSha] = makeFilteredCommit(localSha, filterTree(localSha), remoteExists ? [actualRemoteSha] : []);
181
197
  }
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.8.1",
6
+ "version": "1.8.2",
7
7
  "packages": [
8
8
  {
9
9
  "registryType": "npm",
10
10
  "identifier": "@dpesch/mantisbt-mcp-server",
11
- "version": "1.8.1",
11
+ "version": "1.8.2",
12
12
  "runtimeHint": "npx",
13
13
  "transport": {
14
14
  "type": "stdio"