tiny-http-mcp-server 0.1.39 → 0.1.40

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.39",
21
+ "version": "0.1.40",
22
22
  "license": "MIT"
23
23
  },
24
24
  {
@@ -95,6 +95,14 @@ without redeeming its refresh token again. A proven current token is refreshed
95
95
  on 401 even when the server omits `error="invalid_token"`. Invalid provenance
96
96
  fails without quoting token values.
97
97
 
98
+ The native provider also exposes `authenticate({ requestUrl, fetch, signal,
99
+ discover })` for explicit login, including servers whose initialization is
100
+ public. `discover` lazily supplies validated OAuth metadata and is skipped for
101
+ usable existing grants. Omit it to recover/reuse known sessions only; the method
102
+ returns `void` if a new discovery lookup is needed. It honors `allowInteractive`,
103
+ recovers pending refresh outcomes through consent, and returns an owned token
104
+ snapshot. Normal transport request authorization remains noninteractive.
105
+
98
106
  Configure `client.metadata.scope` to request a precise scope set; broader
99
107
  discovery metadata does not override it. Explicit scopes must match the cached
100
108
  or imported grant's scope set; ordering, repeated spaces and duplicates are
@@ -66,6 +66,26 @@ export function createDefaultOAuthClientProvider(options) {
66
66
  }
67
67
  let initialGrantConsumed = false;
68
68
  return {
69
+ async authenticate(input) {
70
+ input.signal?.throwIfAborted();
71
+ assertNoAccessTokenInUrl(input.requestUrl, "Protected resource request URL");
72
+ const resource = canonicalizeResourceIndicator(input.requestUrl);
73
+ let session = await ensureAuthorizedSession(resource, undefined, input.fetch, true, false, input.signal);
74
+ if (session?.tokens !== undefined && !isExpired(session.tokens, now))
75
+ return { ...session.tokens };
76
+ if (session === null && !initialGrantConsumed && initialGrant?.resource === resource &&
77
+ initialGrant.tokens !== undefined && !isExpired(initialGrant.tokens, now))
78
+ return { ...initialGrant.tokens };
79
+ if (input.discover === undefined)
80
+ return;
81
+ const discovery = await input.discover();
82
+ input.signal?.throwIfAborted();
83
+ assertRequestMatchesResource(resource, canonicalizeResourceIndicator(discovery.resource));
84
+ session = await ensureAuthorizedSession(resource, discovery, input.fetch, true, false, input.signal);
85
+ if (session?.tokens === undefined || isExpired(session.tokens, now))
86
+ throw new Error("OAuth authentication did not establish a usable grant");
87
+ return { ...session.tokens };
88
+ },
69
89
  async authorizeRequest(input) {
70
90
  assertNoAccessTokenInUrl(input.requestUrl, "Protected resource request URL");
71
91
  const requestUrl = canonicalizeResourceIndicator(input.requestUrl);
@@ -28,6 +28,14 @@ export interface OAuthUnauthorizedChallenge {
28
28
  raw: string;
29
29
  }
30
30
  export interface OAuthClientProvider {
31
+ /** Establish a grant explicitly, including when resource initialization is public. */
32
+ authenticate?(input: {
33
+ requestUrl: URL;
34
+ fetch: OAuthMetadataFetch;
35
+ /** Lazy validated discovery. Without it, recover/reuse known grants only. */
36
+ discover?: () => Promise<OAuthDiscoveryResult>;
37
+ signal?: AbortSignal;
38
+ }): Promise<StoredOAuthTokens | void>;
31
39
  authorizeRequest?(input: {
32
40
  requestUrl: URL;
33
41
  headers: Headers;
@@ -131,6 +131,14 @@ interface OAuthUnauthorizedChallenge {
131
131
  raw: string;
132
132
  }
133
133
  interface OAuthClientProvider {
134
+ /** Establish a grant explicitly, including when resource initialization is public. */
135
+ authenticate?(input: {
136
+ requestUrl: URL;
137
+ fetch: OAuthMetadataFetch;
138
+ /** Lazy validated discovery. Without it, recover/reuse known grants only. */
139
+ discover?: () => Promise<OAuthDiscoveryResult>;
140
+ signal?: AbortSignal;
141
+ }): Promise<StoredOAuthTokens | void>;
134
142
  authorizeRequest?(input: {
135
143
  requestUrl: URL;
136
144
  headers: Headers;
@@ -5172,6 +5172,25 @@ function createDefaultOAuthClientProvider(options) {
5172
5172
  }
5173
5173
  let initialGrantConsumed = false;
5174
5174
  return {
5175
+ async authenticate(input) {
5176
+ input.signal?.throwIfAborted();
5177
+ assertNoAccessTokenInUrl(input.requestUrl, "Protected resource request URL");
5178
+ const resource = canonicalizeResourceIndicator(input.requestUrl);
5179
+ let session = await ensureAuthorizedSession(resource, void 0, input.fetch, true, false, input.signal);
5180
+ if (session?.tokens !== void 0 && !isExpired(session.tokens, now))
5181
+ return { ...session.tokens };
5182
+ if (session === null && !initialGrantConsumed && initialGrant?.resource === resource && initialGrant.tokens !== void 0 && !isExpired(initialGrant.tokens, now))
5183
+ return { ...initialGrant.tokens };
5184
+ if (input.discover === void 0)
5185
+ return;
5186
+ const discovery = await input.discover();
5187
+ input.signal?.throwIfAborted();
5188
+ assertRequestMatchesResource(resource, canonicalizeResourceIndicator(discovery.resource));
5189
+ session = await ensureAuthorizedSession(resource, discovery, input.fetch, true, false, input.signal);
5190
+ if (session?.tokens === void 0 || isExpired(session.tokens, now))
5191
+ throw new Error("OAuth authentication did not establish a usable grant");
5192
+ return { ...session.tokens };
5193
+ },
5175
5194
  async authorizeRequest(input) {
5176
5195
  assertNoAccessTokenInUrl(input.requestUrl, "Protected resource request URL");
5177
5196
  const requestUrl = canonicalizeResourceIndicator(input.requestUrl);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tiny-http-mcp-server",
3
- "version": "0.1.39",
3
+ "version": "0.1.40",
4
4
  "description": "Minimal MCP server over HTTP built on tiny-stdio-mcp-server",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",