@oka-core/reason 0.2.14 → 0.2.15

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/dist/auth.d.ts CHANGED
@@ -39,6 +39,21 @@ export declare function resolveApiKey(): string;
39
39
  * Async version that tries token refresh before giving up.
40
40
  */
41
41
  export declare function resolveApiKeyWithRefresh(): Promise<string>;
42
+ export declare class McpTokenManager {
43
+ private refreshTimer;
44
+ /**
45
+ * Get a valid token, refreshing proactively if needed.
46
+ * This is the single entry point for auth — replaces resolveApiKey().
47
+ */
48
+ getValidToken(): Promise<string>;
49
+ /**
50
+ * Schedule a background refresh REFRESH_BEFORE_EXPIRY_S before token expires.
51
+ */
52
+ private scheduleRefresh;
53
+ private backgroundRefresh;
54
+ private clearTimer;
55
+ destroy(): void;
56
+ }
42
57
  export interface LoginResult {
43
58
  success: boolean;
44
59
  message: string;
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAWD,wBAAgB,qBAAqB,IAAI,iBAAiB,GAAG,IAAI,CAOhE;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAa/D;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAW1D;AAID,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CA0B7C;AAOD;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiCxB;AAED;;;GAGG;AACH,wBAAgB,UAAU,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOnD;AAID;;;;;;;;GAQG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAuBtC;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,MAAM,CAAC,CAwBhE;AAuGD,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,aAAa,CAAC,EAAE,MAAM,EACtB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,WAAW,CAAC,CAsCtB"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAWD,wBAAgB,qBAAqB,IAAI,iBAAiB,GAAG,IAAI,CAOhE;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAa/D;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAW1D;AAID,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CA0B7C;AAOD;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiCxB;AAED;;;GAGG;AACH,wBAAgB,UAAU,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOnD;AAID;;;;;;;;GAQG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAuBtC;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,MAAM,CAAC,CAwBhE;AASD,qBAAa,eAAe;IAC1B,OAAO,CAAC,YAAY,CAA8C;IAElE;;;OAGG;IACG,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAsCtC;;OAEG;IACH,OAAO,CAAC,eAAe;YAeT,iBAAiB;IAQ/B,OAAO,CAAC,UAAU;IAOlB,OAAO,IAAI,IAAI;CAGhB;AAuGD,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,aAAa,CAAC,EAAE,MAAM,EACtB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,WAAW,CAAC,CAsCtB"}
package/dist/auth.js CHANGED
@@ -191,6 +191,83 @@ export async function resolveApiKeyWithRefresh() {
191
191
  }
192
192
  return "";
193
193
  }
194
+ // ─── MCP Token Manager ──────────────────────────────────────────
195
+ // Proactive token refresh adapted for Node.js file-based credentials.
196
+ // Same pattern as @oka/auth-sdk TokenManager but reads ~/.oka/credentials.json
197
+ // instead of window.localStorage.
198
+ const REFRESH_BEFORE_EXPIRY_S = 300; // 5 minutes
199
+ export class McpTokenManager {
200
+ refreshTimer = null;
201
+ /**
202
+ * Get a valid token, refreshing proactively if needed.
203
+ * This is the single entry point for auth — replaces resolveApiKey().
204
+ */
205
+ async getValidToken() {
206
+ // 1. Environment variable always wins
207
+ const envKey = process.env["OKA_API_KEY"];
208
+ if (envKey)
209
+ return envKey;
210
+ // 2. Check stored credentials
211
+ const stored = loadStoredCredentials();
212
+ if (stored?.api_key)
213
+ return stored.api_key;
214
+ if (stored?.access_token) {
215
+ const now = Date.now() / 1000;
216
+ const exp = extractJwtExp(stored.access_token) ?? stored.expires_at ?? 0;
217
+ const expiringSoon = exp - now < REFRESH_BEFORE_EXPIRY_S;
218
+ if (!expiringSoon) {
219
+ this.scheduleRefresh(exp);
220
+ return stored.access_token;
221
+ }
222
+ // Token expired or expiring soon — refresh now
223
+ if (stored.refresh_token) {
224
+ const newToken = await tryRefresh();
225
+ if (newToken) {
226
+ const newExp = extractJwtExp(newToken) ?? 0;
227
+ this.scheduleRefresh(newExp);
228
+ return newToken;
229
+ }
230
+ }
231
+ // Refresh failed but token might still be technically valid
232
+ if (exp > now) {
233
+ return stored.access_token;
234
+ }
235
+ }
236
+ return "";
237
+ }
238
+ /**
239
+ * Schedule a background refresh REFRESH_BEFORE_EXPIRY_S before token expires.
240
+ */
241
+ scheduleRefresh(expiresAtSec) {
242
+ this.clearTimer();
243
+ const delayMs = (expiresAtSec - REFRESH_BEFORE_EXPIRY_S - Date.now() / 1000) * 1000;
244
+ if (delayMs <= 0)
245
+ return; // Already in refresh window, handled by getValidToken
246
+ this.refreshTimer = setTimeout(() => {
247
+ void this.backgroundRefresh();
248
+ }, delayMs);
249
+ // Don't let the timer prevent Node.js from exiting
250
+ if (this.refreshTimer && typeof this.refreshTimer === "object") {
251
+ this.refreshTimer.unref();
252
+ }
253
+ }
254
+ async backgroundRefresh() {
255
+ const newToken = await tryRefresh();
256
+ if (newToken) {
257
+ const exp = extractJwtExp(newToken) ?? 0;
258
+ this.scheduleRefresh(exp);
259
+ }
260
+ }
261
+ clearTimer() {
262
+ if (this.refreshTimer) {
263
+ clearTimeout(this.refreshTimer);
264
+ this.refreshTimer = null;
265
+ }
266
+ }
267
+ destroy() {
268
+ this.clearTimer();
269
+ }
270
+ }
194
271
  const DEFAULT_AUTH_SERVER = "https://id.oka.so";
195
272
  const DEFAULT_CLIENT_ID = "oka-reason-mcp";
196
273
  async function requestDeviceCode(authServerUrl, clientId) {
package/dist/client.d.ts CHANGED
@@ -183,6 +183,7 @@ export declare class OkaClient {
183
183
  private readonly agentId;
184
184
  private readonly sessionId;
185
185
  private readonly timeout;
186
+ private readonly tokenManager;
186
187
  /** Maps learning_id → feedback_id for LTR attribution across tool calls. */
187
188
  private readonly searchContext;
188
189
  /** Reverse map: short ID prefix → full UUID */
@@ -243,12 +244,8 @@ export declare class OkaClient {
243
244
  */
244
245
  triggerConsolidation(req: ConsolidateRequest): Promise<ConsolidateResponse>;
245
246
  private authHeaders;
247
+ private buildHeaders;
246
248
  private get;
247
249
  private post;
248
- /**
249
- * On 401, attempt to refresh the token and retry the request once.
250
- * Returns the parsed JSON response on success, or null if refresh failed.
251
- */
252
- private retryWithRefresh;
253
250
  }
254
251
  //# sourceMappingURL=client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/client.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { EventBuffer } from "./buffer.js";
2
- import { resolveApiKey, resolveApiKeyWithRefresh } from "./auth.js";
2
+ import { McpTokenManager } from "./auth.js";
3
3
  /**
4
4
  * Unified HTTP client for Oka Reason API.
5
5
  *
@@ -21,6 +21,7 @@ export class OkaClient {
21
21
  agentId;
22
22
  sessionId;
23
23
  timeout;
24
+ tokenManager;
24
25
  /** Maps learning_id → feedback_id for LTR attribution across tool calls. */
25
26
  searchContext = new Map();
26
27
  /** Reverse map: short ID prefix → full UUID */
@@ -35,6 +36,7 @@ export class OkaClient {
35
36
  this.sessionId = process.env["SESSION_ID"] || `session-${Date.now()}`;
36
37
  this.buffer = new EventBuffer(100);
37
38
  this.timeout = 15_000;
39
+ this.tokenManager = new McpTokenManager();
38
40
  }
39
41
  updateApiKey(key) {
40
42
  this.apiKey = key;
@@ -56,12 +58,10 @@ export class OkaClient {
56
58
  if (events.length === 0)
57
59
  return;
58
60
  try {
61
+ const headers = await this.authHeaders();
59
62
  await fetch(`${this.apiUrl}/api/reasoning/ingest`, {
60
63
  method: "POST",
61
- headers: {
62
- "Content-Type": "application/json",
63
- ...this.authHeaders(),
64
- },
64
+ headers,
65
65
  body: JSON.stringify({ events }),
66
66
  signal: AbortSignal.timeout(5_000),
67
67
  });
@@ -100,8 +100,9 @@ export class OkaClient {
100
100
  if (v)
101
101
  url.searchParams.set(k, v);
102
102
  }
103
+ const headers = await this.authHeaders();
103
104
  const res = await fetch(url.toString(), {
104
- headers: this.authHeaders(),
105
+ headers,
105
106
  signal: AbortSignal.timeout(10_000),
106
107
  });
107
108
  if (!res.ok)
@@ -296,17 +297,16 @@ export class OkaClient {
296
297
  return this.post("/api/reasoning/consolidate", body, 120_000);
297
298
  }
298
299
  // ─── HTTP helpers ───────────────────────────────────────────────
299
- authHeaders() {
300
- // Resolve credentials fresh each call so .env / credentials.json
301
- // changes (e.g. after `login`) are picked up without MCP restart.
302
- const key = this.apiKey || resolveApiKey();
300
+ async authHeaders() {
301
+ const key = this.apiKey || (await this.tokenManager.getValidToken());
302
+ return this.buildHeaders(key);
303
+ }
304
+ buildHeaders(key) {
303
305
  const headers = {
304
306
  "Content-Type": "application/json",
305
307
  };
306
308
  if (key) {
307
309
  // JWTs have dots (header.payload.signature); API keys don't.
308
- // Sending both headers causes the server to try Bearer first and fail
309
- // when the value is an API key, never falling back to X-Api-Key.
310
310
  const isJwt = key.includes(".");
311
311
  if (isJwt) {
312
312
  headers["Authorization"] = `Bearer ${key}`;
@@ -318,22 +318,20 @@ export class OkaClient {
318
318
  return headers;
319
319
  }
320
320
  async get(path) {
321
+ const headers = await this.authHeaders();
321
322
  const controller = new AbortController();
322
323
  const timer = setTimeout(() => controller.abort(), this.timeout);
323
324
  try {
324
325
  const response = await fetch(`${this.apiUrl}${path}`, {
325
326
  method: "GET",
326
- headers: this.authHeaders(),
327
+ headers,
327
328
  signal: controller.signal,
328
329
  });
329
- if (response.status === 401) {
330
- const retried = await this.retryWithRefresh("GET", path);
331
- if (retried !== null)
332
- return retried;
333
- throw new Error("HTTP 401: authentication failed — run mcp__oka__login to re-authenticate");
330
+ if (!response.ok) {
331
+ throw new Error(response.status === 401
332
+ ? "HTTP 401: authentication failed — run mcp__oka__login to re-authenticate"
333
+ : `HTTP ${response.status}`);
334
334
  }
335
- if (!response.ok)
336
- throw new Error(`HTTP ${response.status}`);
337
335
  return response.json();
338
336
  }
339
337
  finally {
@@ -341,22 +339,20 @@ export class OkaClient {
341
339
  }
342
340
  }
343
341
  async post(path, body, timeout) {
342
+ const headers = await this.authHeaders();
344
343
  const controller = new AbortController();
345
344
  const timer = setTimeout(() => controller.abort(), timeout ?? this.timeout);
346
345
  try {
347
346
  const response = await fetch(`${this.apiUrl}${path}`, {
348
347
  method: "POST",
349
- headers: this.authHeaders(),
348
+ headers,
350
349
  body: JSON.stringify(body),
351
350
  signal: controller.signal,
352
351
  });
353
- if (response.status === 401) {
354
- const retried = await this.retryWithRefresh("POST", path, body);
355
- if (retried !== null)
356
- return retried;
357
- throw new Error("HTTP 401: authentication failed — run mcp__oka__login to re-authenticate");
358
- }
359
352
  if (!response.ok) {
353
+ if (response.status === 401) {
354
+ throw new Error("HTTP 401: authentication failed — run mcp__oka__login to re-authenticate");
355
+ }
360
356
  const text = await response.text().catch(() => "");
361
357
  throw new Error(`HTTP ${response.status}: ${text}`);
362
358
  }
@@ -366,35 +362,4 @@ export class OkaClient {
366
362
  clearTimeout(timer);
367
363
  }
368
364
  }
369
- /**
370
- * On 401, attempt to refresh the token and retry the request once.
371
- * Returns the parsed JSON response on success, or null if refresh failed.
372
- */
373
- async retryWithRefresh(method, path, body) {
374
- const newKey = await resolveApiKeyWithRefresh();
375
- if (!newKey)
376
- return null;
377
- const headers = {
378
- "Content-Type": "application/json",
379
- };
380
- const isJwt = newKey.includes(".");
381
- if (isJwt) {
382
- headers["Authorization"] = `Bearer ${newKey}`;
383
- }
384
- else {
385
- headers["X-Api-Key"] = newKey;
386
- }
387
- const opts = {
388
- method,
389
- headers,
390
- signal: AbortSignal.timeout(this.timeout),
391
- };
392
- if (body !== undefined) {
393
- opts.body = JSON.stringify(body);
394
- }
395
- const retryResponse = await fetch(`${this.apiUrl}${path}`, opts);
396
- if (!retryResponse.ok)
397
- return null;
398
- return retryResponse.json();
399
- }
400
365
  }
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/tools/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAQ9C;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CA8I5E"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/tools/auth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAU9C;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CA8I5E"}
@@ -1,5 +1,6 @@
1
1
  import { z } from "zod";
2
- import { deviceAuthLogin, loadStoredCredentials, resolveApiKey, resolveApiKeyWithRefresh, } from "../auth.js";
2
+ import { McpTokenManager, deviceAuthLogin, loadStoredCredentials, resolveApiKey, } from "../auth.js";
3
+ const tokenManager = new McpTokenManager();
3
4
  /**
4
5
  * Register auth tools on the MCP server.
5
6
  */
@@ -29,10 +30,10 @@ export function registerAuthTools(server, client) {
29
30
  ],
30
31
  };
31
32
  }
32
- // Token might be expired — try refresh before opening browser
33
+ // Token might be expired — try proactive refresh before opening browser
33
34
  const stored = loadStoredCredentials();
34
35
  if (stored?.refresh_token) {
35
- const refreshed = await resolveApiKeyWithRefresh();
36
+ const refreshed = await tokenManager.getValidToken();
36
37
  if (refreshed) {
37
38
  client.updateApiKey(refreshed);
38
39
  return {
@@ -83,11 +84,11 @@ export function registerAuthTools(server, client) {
83
84
  }
84
85
  });
85
86
  server.tool("whoami", "Check current authentication status — whether the MCP server has valid credentials.", {}, async () => {
86
- // First try sync resolution
87
- let key = resolveApiKey();
88
- // If no key found, try async refresh
87
+ // Try token manager (proactive refresh)
88
+ let key = await tokenManager.getValidToken();
89
+ // If token manager returned empty, key might still be in sync path
89
90
  if (!key) {
90
- key = await resolveApiKeyWithRefresh();
91
+ key = resolveApiKey();
91
92
  if (key) {
92
93
  return {
93
94
  content: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oka-core/reason",
3
- "version": "0.2.14",
3
+ "version": "0.2.15",
4
4
  "description": "MCP server for institutional knowledge capture, semantic search, and consolidation",
5
5
  "private": false,
6
6
  "publishConfig": {