tiny-http-mcp-server 0.1.63 → 0.1.64

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.63",
21
+ "version": "0.1.64",
22
22
  "license": "MIT"
23
23
  },
24
24
  {
@@ -126,7 +126,11 @@ timeoutMs })`. Reset acquires the raw identity backend lock, so it can recover
126
126
  corrupt or undecryptable records without reading their old contents. It atomically
127
127
  retires the identity's grant and registrations and writes a marker that suppresses
128
128
  stale initial grants. The default lock wait is 30 seconds. Other names/profiles
129
- are untouched, and symlink paths are still refused.
129
+ are untouched, and symlink paths are still refused. Native reset, import and
130
+ transaction callbacks retain their original signal while locks or reconciliation
131
+ wait; replacing a caller handle cannot change subsequent cancellation checks.
132
+ Cancellation after a completed identity write prevents the transaction callback
133
+ from running and retains that already persisted identity.
130
134
 
131
135
  Configure `client.metadata.scope` to request a precise scope set; broader
132
136
  discovery metadata does not override it. Explicit scopes must match the cached
@@ -256,7 +260,11 @@ transient retry or restoration of the original grant. Gateway error pages do not
256
260
  Native persisted OAuth reads always reject corrupt encrypted documents and
257
261
  invalid stored JSON, with diagnostics that omit decrypted contents. They retain
258
262
  the existing record for explicit reset rather than interpreting corruption as
259
- an absent session and reviving an initial grant. Caller file-backend settings
263
+ an absent session and reviving an initial grant. Persisted access tokens that
264
+ cannot be sent as HTTP headers fail with diagnostics that omit token contents;
265
+ the original record remains available for explicit recovery. Token responses are
266
+ checked before activation or persistence. An unusable rotated access token keeps
267
+ refresh intent pending, preventing rotating-token replay. Caller file-backend settings
260
268
  cannot disable this policy.
261
269
 
262
270
  ## Environment Variables
@@ -591,11 +591,16 @@ function normalizeLoadedSession(session) {
591
591
  if (client === null) {
592
592
  return { ...session, client: { clientId: "" }, tokens: undefined };
593
593
  }
594
- return {
595
- ...session,
596
- client,
597
- tokens: normalizeStoredTokens(getOwnEntry(session, "tokens"))
598
- };
594
+ const tokens = normalizeStoredTokens(getOwnEntry(session, "tokens"));
595
+ if (tokens !== undefined) {
596
+ try {
597
+ new Headers({ Authorization: `Bearer ${tokens.accessToken}` });
598
+ }
599
+ catch {
600
+ throw new Error("Stored OAuth access token is not a valid HTTP header value");
601
+ }
602
+ }
603
+ return { ...session, client, tokens };
599
604
  }
600
605
  function normalizeImportedTokens(value, now) {
601
606
  if (!isObjectRecord(value))
@@ -51,6 +51,7 @@ export function createResourceBoundOAuthStores(options, namespace, identity) {
51
51
  }
52
52
  };
53
53
  async function replace(record, options) {
54
+ options = { ...options };
54
55
  options.signal?.throwIfAborted();
55
56
  const timeoutMs = options.timeoutMs ?? 30_000;
56
57
  if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 2_147_483_647)
@@ -124,6 +125,7 @@ export function createResourceBoundOAuthStores(options, namespace, identity) {
124
125
  }
125
126
  result.sessionStore = {
126
127
  async withLock(resource, operation, options) {
128
+ options = { ...options };
127
129
  if (store.withLock === undefined)
128
130
  throw new Error("OAuth resource identity backend must support transaction locks");
129
131
  return store.withLock(async () => {
@@ -105,6 +105,12 @@ async function requestTokens(input) {
105
105
  throw new Error("OAuth token response missing access_token");
106
106
  }
107
107
  const normalizedAccessToken = accessToken.trim();
108
+ try {
109
+ new Headers({ Authorization: `Bearer ${normalizedAccessToken}` });
110
+ }
111
+ catch {
112
+ throw new Error("OAuth token response access_token is not a valid HTTP header value");
113
+ }
108
114
  const tokenType = normalizeBearerTokenType(getOwnEntry(payload, "token_type"));
109
115
  if (tokenType === null) {
110
116
  throw new Error("OAuth token response missing token_type=Bearer");
@@ -4793,6 +4793,7 @@ function createResourceBoundOAuthStores(options, namespace, identity) {
4793
4793
  }
4794
4794
  };
4795
4795
  async function replace(record2, options2) {
4796
+ options2 = { ...options2 };
4796
4797
  options2.signal?.throwIfAborted();
4797
4798
  const timeoutMs = options2.timeoutMs ?? 3e4;
4798
4799
  if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 2147483647)
@@ -4858,6 +4859,7 @@ function createResourceBoundOAuthStores(options, namespace, identity) {
4858
4859
  }
4859
4860
  result.sessionStore = {
4860
4861
  async withLock(resource, operation, options2) {
4862
+ options2 = { ...options2 };
4861
4863
  if (store.withLock === void 0)
4862
4864
  throw new Error("OAuth resource identity backend must support transaction locks");
4863
4865
  return store.withLock(async () => {
@@ -5114,6 +5116,11 @@ async function requestTokens(input) {
5114
5116
  throw new Error("OAuth token response missing access_token");
5115
5117
  }
5116
5118
  const normalizedAccessToken = accessToken.trim();
5119
+ try {
5120
+ new Headers({ Authorization: `Bearer ${normalizedAccessToken}` });
5121
+ } catch {
5122
+ throw new Error("OAuth token response access_token is not a valid HTTP header value");
5123
+ }
5117
5124
  const tokenType = normalizeBearerTokenType(getOwnEntry5(payload, "token_type"));
5118
5125
  if (tokenType === null) {
5119
5126
  throw new Error("OAuth token response missing token_type=Bearer");
@@ -5825,11 +5832,15 @@ function normalizeLoadedSession(session) {
5825
5832
  if (client === null) {
5826
5833
  return { ...session, client: { clientId: "" }, tokens: void 0 };
5827
5834
  }
5828
- return {
5829
- ...session,
5830
- client,
5831
- tokens: normalizeStoredTokens(getOwnEntry6(session, "tokens"))
5832
- };
5835
+ const tokens = normalizeStoredTokens(getOwnEntry6(session, "tokens"));
5836
+ if (tokens !== void 0) {
5837
+ try {
5838
+ new Headers({ Authorization: `Bearer ${tokens.accessToken}` });
5839
+ } catch {
5840
+ throw new Error("Stored OAuth access token is not a valid HTTP header value");
5841
+ }
5842
+ }
5843
+ return { ...session, client, tokens };
5833
5844
  }
5834
5845
  function normalizeImportedTokens(value, now) {
5835
5846
  if (!isObjectRecord3(value))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tiny-http-mcp-server",
3
- "version": "0.1.63",
3
+ "version": "0.1.64",
4
4
  "description": "Minimal MCP server over HTTP built on tiny-stdio-mcp-server",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",