tiny-http-mcp-server 0.1.50 → 0.1.52

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.
@@ -18,7 +18,7 @@
18
18
  },
19
19
  {
20
20
  "name": "tiny-http-mcp-server",
21
- "version": "0.1.50",
21
+ "version": "0.1.52",
22
22
  "license": "MIT"
23
23
  },
24
24
  {
@@ -187,7 +187,7 @@ export function createDefaultOAuthClientProvider(options) {
187
187
  if (forceRefresh && rejectedTokens !== undefined && (rejectedTokens === null || session?.tokens === undefined || !sameTokenGrant(session.tokens, rejectedTokens)))
188
188
  forceRefresh = false;
189
189
  const sessionDiscovery = resolveDiscovery(discovery, session);
190
- if ((options.client.mode === "static" || configuredClient?.registration !== undefined || initialGrant !== undefined) && session !== null && (session.tokens !== undefined || session.refreshState === "pending")) {
190
+ if ((options.client.mode === "static" || configuredClient !== null || initialGrant !== undefined) && session !== null && (session.tokens !== undefined || session.refreshState === "pending")) {
191
191
  const configured = configuredClient;
192
192
  if (configured === null || configured.clientId !== session.client.clientId || configured.clientSecret !== session.client.clientSecret)
193
193
  throw new Error("Stored session belongs to a different OAuth client; use separate persistence or explicitly reset it");
@@ -22,12 +22,23 @@ console.log(result.structuredContent);
22
22
  await client.close();
23
23
  ```
24
24
 
25
- `Tool` includes MCP `outputSchema` when a server advertises typed tool output. `CallToolResult` includes `structuredContent?: Record<string, unknown>` for typed results; legacy/content-block tools still use `content[]`.
25
+ Omit `protocolVersion` for automatic modern discovery and legacy negotiation.
26
+ Set it to `"2025-03-26"` or `"2026-07-28"` to pin a protocol. A modern pin
27
+ rejects failed or timed-out discovery without sending legacy initialization.
28
+ Unsupported pins fail before connection setup.
29
+
30
+ `Tool` includes MCP `outputSchema` when a server advertises typed tool output.
31
+ `CallToolResult.structuredContent` preserves modern JSON values; legacy servers
32
+ require an object. Complete `content[]` blocks remain available in either case.
26
33
 
27
34
  Set `requestTimeoutMs` on `McpClient` or `timeoutMs` on individual requests.
28
35
  Numeric deadlines must be finite, nonnegative and no greater than
29
36
  2,147,483,647 ms; oversized values fail before a request is sent. Individual
30
37
  JSON-RPC requests also accept `timeoutMs: null` to disable their timer.
38
+ The deadline covers the complete request, including modern input callbacks and
39
+ continuation rounds. On expiry, callback signals abort and late input cannot
40
+ submit another round. Successful requests, cancellation and disposal clear the
41
+ timer; a timeout releases request capacity so later operations can proceed.
31
42
 
32
43
  ## Transports
33
44
 
@@ -5398,7 +5398,7 @@ function createDefaultOAuthClientProvider(options) {
5398
5398
  if (forceRefresh && rejectedTokens !== void 0 && (rejectedTokens === null || session?.tokens === void 0 || !sameTokenGrant(session.tokens, rejectedTokens)))
5399
5399
  forceRefresh = false;
5400
5400
  const sessionDiscovery = resolveDiscovery(discovery, session);
5401
- if ((options.client.mode === "static" || configuredClient?.registration !== void 0 || initialGrant !== void 0) && session !== null && (session.tokens !== void 0 || session.refreshState === "pending")) {
5401
+ if ((options.client.mode === "static" || configuredClient !== null || initialGrant !== void 0) && session !== null && (session.tokens !== void 0 || session.refreshState === "pending")) {
5402
5402
  const configured = configuredClient;
5403
5403
  if (configured === null || configured.clientId !== session.client.clientId || configured.clientSecret !== session.client.clientSecret)
5404
5404
  throw new Error("Stored session belongs to a different OAuth client; use separate persistence or explicitly reset it");
@@ -6685,6 +6685,8 @@ var McpClient = class {
6685
6685
  }
6686
6686
  async connect(transport, options = {}) {
6687
6687
  options.signal?.throwIfAborted();
6688
+ if (this.options.protocolVersion !== void 0 && this.options.protocolVersion !== MCP_PROTOCOL_VERSION && this.options.protocolVersion !== "2026-07-28")
6689
+ throw new Error("Unsupported protocolVersion; use 2025-03-26 or 2026-07-28");
6688
6690
  if (this.currentState !== "disconnected" && this.currentState !== "closed") {
6689
6691
  throw new Error("MCP client is already connected");
6690
6692
  }
@@ -6861,6 +6863,7 @@ var McpClient = class {
6861
6863
  }, { signal: options.signal, timeoutMs: this.options.protocolVersion === "2026-07-28" ? this.options.requestTimeoutMs ?? 3e4 : Math.min(this.options.requestTimeoutMs ?? 3e4, 1e3) });
6862
6864
  } catch (error) {
6863
6865
  options.signal?.throwIfAborted();
6866
+ if (this.options.protocolVersion === "2026-07-28") throw error;
6864
6867
  if (error instanceof McpError && [-32020, -32021, -32022].includes(error.code)) throw error;
6865
6868
  }
6866
6869
  if (discovery !== void 0) {
@@ -8481,6 +8484,7 @@ var JsonRpcMessageLayer = class {
8481
8484
  rejectAbort = reject;
8482
8485
  });
8483
8486
  const cancel = () => {
8487
+ clearTimeout(deadline);
8484
8488
  if (currentRequestId !== void 0) this.cancelRequest(currentRequestId, controller.signal.reason);
8485
8489
  rejectAbort(controller.signal.reason);
8486
8490
  };
@@ -8492,6 +8496,15 @@ var JsonRpcMessageLayer = class {
8492
8496
  currentRequestId = id;
8493
8497
  onRequestId?.(id);
8494
8498
  } };
8499
+ const deadline = timeoutMs === null ? void 0 : setTimeout(() => {
8500
+ let reason = new Error(`JSON-RPC request "${method}" timed out after ${timeoutMs}ms`);
8501
+ try {
8502
+ if (currentRequestId !== void 0) options.onTimeout?.(currentRequestId);
8503
+ } catch (error) {
8504
+ reason = error;
8505
+ }
8506
+ controller.abort(reason);
8507
+ }, timeoutMs);
8495
8508
  if (callerSignal?.aborted) forwardAbort();
8496
8509
  const work = (async () => {
8497
8510
  let retryParams = originalParams;
@@ -8564,6 +8577,7 @@ var JsonRpcMessageLayer = class {
8564
8577
  throw new McpError(ERROR_INTERNAL, "Unreachable MCP retry state");
8565
8578
  })();
8566
8579
  return Promise.race([work, aborted]).finally(() => {
8580
+ clearTimeout(deadline);
8567
8581
  callerSignal?.removeEventListener("abort", forwardAbort);
8568
8582
  controller.signal.removeEventListener("abort", cancel);
8569
8583
  this.exchangeControllers.delete(controller);
@@ -8575,8 +8589,6 @@ var JsonRpcMessageLayer = class {
8575
8589
  }
8576
8590
  const id = this.nextRequestId;
8577
8591
  this.nextRequestId += 1;
8578
- const timeoutMs = options.timeoutMs === null ? null : options.timeoutMs ?? this.requestTimeoutMs;
8579
- if (timeoutMs !== null) validateRequestTimer(timeoutMs, "timeoutMs");
8580
8592
  if (options.onRequestId !== void 0) {
8581
8593
  options.onRequestId(id);
8582
8594
  }
@@ -8599,16 +8611,10 @@ var JsonRpcMessageLayer = class {
8599
8611
  message.params = params;
8600
8612
  }
8601
8613
  return new Promise((resolve, reject) => {
8602
- const timeout = timeoutMs === null ? void 0 : setTimeout(() => {
8603
- this.pendingRequests.delete(id);
8604
- options.onTimeout?.(id);
8605
- reject(new Error(`JSON-RPC request "${method}" timed out after ${timeoutMs}ms`));
8606
- }, timeoutMs);
8607
- this.pendingRequests.set(id, { resolve, reject, timeout });
8614
+ this.pendingRequests.set(id, { resolve, reject });
8608
8615
  try {
8609
8616
  this.output.write(serializeJsonRpcMessage(message));
8610
8617
  } catch (error) {
8611
- clearTimeout(timeout);
8612
8618
  this.pendingRequests.delete(id);
8613
8619
  reject(error);
8614
8620
  }
@@ -8620,7 +8626,6 @@ var JsonRpcMessageLayer = class {
8620
8626
  return false;
8621
8627
  }
8622
8628
  this.pendingRequests.delete(requestId);
8623
- clearTimeout(pending.timeout);
8624
8629
  pending.reject(reason);
8625
8630
  return true;
8626
8631
  }
@@ -8631,7 +8636,6 @@ var JsonRpcMessageLayer = class {
8631
8636
  this.disposedError = reason;
8632
8637
  for (const controller of this.exchangeControllers) controller.abort(reason);
8633
8638
  for (const pending of this.pendingRequests.values()) {
8634
- clearTimeout(pending.timeout);
8635
8639
  pending.reject(reason);
8636
8640
  }
8637
8641
  this.pendingRequests.clear();
@@ -8769,7 +8773,6 @@ var JsonRpcMessageLayer = class {
8769
8773
  return;
8770
8774
  }
8771
8775
  this.pendingRequests.delete(parsed.message.id);
8772
- clearTimeout(pending.timeout);
8773
8776
  if ("result" in parsed.message) {
8774
8777
  pending.resolve(parsed.message.result);
8775
8778
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tiny-http-mcp-server",
3
- "version": "0.1.50",
3
+ "version": "0.1.52",
4
4
  "description": "Minimal MCP server over HTTP built on tiny-stdio-mcp-server",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",