mcp-google-multi 6.0.0-alpha.66 → 6.0.0-alpha.67

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.
@@ -85,6 +85,7 @@ export declare class HttpTransportHost {
85
85
  private readonly depth;
86
86
  private readonly sockets;
87
87
  private readonly pending;
88
+ private readonly served;
88
89
  private readonly handling;
89
90
  private closing;
90
91
  private graceful?;
@@ -70,6 +70,10 @@ const MAX_GRACE_MS = 2 ** 31 - 1;
70
70
  function endAfterFlush(socket) {
71
71
  if (socket.destroyed || socket.writableEnded)
72
72
  return;
73
+ // Node arms a keep-alive timer when a response finishes and destroys the
74
+ // socket when it fires, which would cut a slow reader's unread tail just as
75
+ // an early destroy does. Only the client's FIN or the grace ends it now.
76
+ socket.setTimeout(0);
73
77
  socket.end();
74
78
  }
75
79
  // A request that arrives while closing is never answered, so Node keeps it
@@ -109,6 +113,9 @@ export class HttpTransportHost {
109
113
  // every handle() that has not settled.
110
114
  sockets = new Set();
111
115
  pending = new Map();
116
+ // Sockets that have accepted a request: nothing pending means the last
117
+ // response finished writing, but its tail can still sit in kernel buffers.
118
+ served = new WeakSet();
112
119
  handling = new Set();
113
120
  closing = false;
114
121
  graceful;
@@ -143,6 +150,7 @@ export class HttpTransportHost {
143
150
  stopReading(socket);
144
151
  return;
145
152
  }
153
+ this.served.add(socket);
146
154
  const entry = this.pending.get(socket);
147
155
  if (entry) {
148
156
  entry.count++;
@@ -232,7 +240,8 @@ export class HttpTransportHost {
232
240
  this.httpServer = undefined;
233
241
  return;
234
242
  }
235
- // Starting over would destroy every socket in its lingering close.
243
+ // Starting over would arm a second grace, and a shorter one would cut
244
+ // what the first still lets finish.
236
245
  this.graceful ??= this.closeGracefully(s, graceMs).finally(() => (this.graceful = undefined));
237
246
  return this.graceful;
238
247
  }
@@ -249,15 +258,19 @@ export class HttpTransportHost {
249
258
  // after the last of them: that one says so if it has not started, and the
250
259
  // settle hook in start() ends the socket once it finishes. Node itself
251
260
  // destroys a socket once a Connection: close response is flushed, which
252
- // resets it just as endAfterFlush explains, so that end lingers too.
261
+ // resets it just as endAfterFlush explains, so that end lingers too. A
262
+ // socket with nothing pending may still be delivering the tail of its
263
+ // last response, so only one that never accepted a request is destroyed.
253
264
  for (const socket of this.sockets) {
254
265
  const entry = this.pending.get(socket);
255
- if (!entry) {
266
+ if (!entry && !this.served.has(socket)) {
256
267
  socket.destroy();
257
268
  continue;
258
269
  }
259
270
  socket.destroySoon = () => endAfterFlush(socket);
260
- if (!entry.last.headersSent)
271
+ if (!entry)
272
+ endAfterFlush(socket);
273
+ else if (!entry.last.headersSent)
261
274
  entry.last.setHeader('Connection', 'close');
262
275
  }
263
276
  let timer;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-google-multi",
3
- "version": "6.0.0-alpha.66",
3
+ "version": "6.0.0-alpha.67",
4
4
  "mcpName": "io.github.bakissation/mcp-google-multi",
5
5
  "description": "Local MCP server for Google Workspace (Gmail, Drive, Calendar, Sheets, Docs, Contacts, Tasks, Meet, Search Console, +Forms/Chat/Admin) across multiple accounts — OAuth-only, encrypted token storage, deny-by-default writes.",
6
6
  "type": "module",