@kontext-dev/js-sdk 0.3.0 → 1.1.0

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.
Files changed (63) hide show
  1. package/dist/adapters/ai/index.cjs +12 -2
  2. package/dist/adapters/ai/index.cjs.map +1 -1
  3. package/dist/adapters/ai/index.js +12 -2
  4. package/dist/adapters/ai/index.js.map +1 -1
  5. package/dist/adapters/cloudflare/index.cjs +13 -0
  6. package/dist/adapters/cloudflare/index.cjs.map +1 -1
  7. package/dist/adapters/cloudflare/index.js +13 -0
  8. package/dist/adapters/cloudflare/index.js.map +1 -1
  9. package/dist/adapters/cloudflare/react.cjs +12 -2
  10. package/dist/adapters/cloudflare/react.cjs.map +1 -1
  11. package/dist/adapters/cloudflare/react.js +12 -2
  12. package/dist/adapters/cloudflare/react.js.map +1 -1
  13. package/dist/adapters/react/index.cjs +12 -2
  14. package/dist/adapters/react/index.cjs.map +1 -1
  15. package/dist/adapters/react/index.js +12 -2
  16. package/dist/adapters/react/index.js.map +1 -1
  17. package/dist/client/index.cjs +108 -69
  18. package/dist/client/index.cjs.map +1 -1
  19. package/dist/client/index.d.cts +2 -0
  20. package/dist/client/index.d.ts +2 -0
  21. package/dist/client/index.js +109 -71
  22. package/dist/client/index.js.map +1 -1
  23. package/dist/errors.cjs +78 -0
  24. package/dist/errors.cjs.map +1 -1
  25. package/dist/errors.d.cts +7 -1
  26. package/dist/errors.d.ts +7 -1
  27. package/dist/errors.js +78 -1
  28. package/dist/errors.js.map +1 -1
  29. package/dist/index.cjs +151 -87
  30. package/dist/index.cjs.map +1 -1
  31. package/dist/index.d.cts +1 -1
  32. package/dist/index.d.ts +1 -1
  33. package/dist/index.js +152 -88
  34. package/dist/index.js.map +1 -1
  35. package/dist/{kontext-CgIBANFo.d.cts → kontext-CBPuE-hq.d.cts} +3 -0
  36. package/dist/{kontext-CgIBANFo.d.ts → kontext-CBPuE-hq.d.ts} +3 -0
  37. package/dist/management/index.cjs +15 -0
  38. package/dist/management/index.cjs.map +1 -1
  39. package/dist/management/index.d.cts +2 -2
  40. package/dist/management/index.d.ts +2 -2
  41. package/dist/management/index.js +15 -1
  42. package/dist/management/index.js.map +1 -1
  43. package/dist/mcp/index.cjs +32 -3
  44. package/dist/mcp/index.cjs.map +1 -1
  45. package/dist/mcp/index.d.cts +7 -1
  46. package/dist/mcp/index.d.ts +7 -1
  47. package/dist/mcp/index.js +33 -4
  48. package/dist/mcp/index.js.map +1 -1
  49. package/dist/oauth/index.cjs +12 -2
  50. package/dist/oauth/index.cjs.map +1 -1
  51. package/dist/oauth/index.d.cts +1 -1
  52. package/dist/oauth/index.d.ts +1 -1
  53. package/dist/oauth/index.js +12 -2
  54. package/dist/oauth/index.js.map +1 -1
  55. package/dist/server/index.cjs +55 -20
  56. package/dist/server/index.cjs.map +1 -1
  57. package/dist/server/index.d.cts +2 -2
  58. package/dist/server/index.d.ts +2 -2
  59. package/dist/server/index.js +56 -21
  60. package/dist/server/index.js.map +1 -1
  61. package/dist/{types-CzhnlJHW.d.cts → types-DicGI7ix.d.cts} +23 -1
  62. package/dist/{types-CzhnlJHW.d.ts → types-DicGI7ix.d.ts} +23 -1
  63. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
- export { I as IntegrationCredential, a as IntegrationName, b as IntegrationResolvedCredentials, K as KnownIntegration, c as Kontext, d as KontextOptions, M as McpServerFactory, e as McpServerOrFactory, f as MiddlewareOptions } from '../kontext-CgIBANFo.cjs';
1
+ export { I as IntegrationCredential, a as IntegrationName, b as IntegrationResolvedCredentials, K as KnownIntegration, c as Kontext, d as KontextOptions, M as McpServerFactory, e as McpServerOrFactory, f as MiddlewareOptions } from '../kontext-CBPuE-hq.cjs';
2
2
  export { K as KontextTokenVerifier } from '../verifier-CoJmYiw3.cjs';
3
3
  export { IntegrationConnectionRequiredError } from '../errors.cjs';
4
- export { T as TokenExchangeRequest, a as TokenExchangeResponse } from '../types-CzhnlJHW.cjs';
4
+ export { T as TokenExchangeRequest, a as TokenExchangeResponse } from '../types-DicGI7ix.cjs';
5
5
  export { AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types.js';
6
6
  export { OAuthTokenVerifier } from '@modelcontextprotocol/sdk/server/auth/provider.js';
7
7
  import 'express';
@@ -1,7 +1,7 @@
1
- export { I as IntegrationCredential, a as IntegrationName, b as IntegrationResolvedCredentials, K as KnownIntegration, c as Kontext, d as KontextOptions, M as McpServerFactory, e as McpServerOrFactory, f as MiddlewareOptions } from '../kontext-CgIBANFo.js';
1
+ export { I as IntegrationCredential, a as IntegrationName, b as IntegrationResolvedCredentials, K as KnownIntegration, c as Kontext, d as KontextOptions, M as McpServerFactory, e as McpServerOrFactory, f as MiddlewareOptions } from '../kontext-CBPuE-hq.js';
2
2
  export { K as KontextTokenVerifier } from '../verifier-CoJmYiw3.js';
3
3
  export { IntegrationConnectionRequiredError } from '../errors.js';
4
- export { T as TokenExchangeRequest, a as TokenExchangeResponse } from '../types-CzhnlJHW.js';
4
+ export { T as TokenExchangeRequest, a as TokenExchangeResponse } from '../types-DicGI7ix.js';
5
5
  export { AuthInfo } from '@modelcontextprotocol/sdk/server/auth/types.js';
6
6
  export { OAuthTokenVerifier } from '@modelcontextprotocol/sdk/server/auth/provider.js';
7
7
  import 'express';
@@ -1,7 +1,7 @@
1
1
  import { createHash } from 'crypto';
2
2
  import { createRequire } from 'module';
3
3
  import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
4
- import { isInitializeRequest } from '@modelcontextprotocol/sdk/types.js';
4
+ import { ErrorCode, isInitializeRequest } from '@modelcontextprotocol/sdk/types.js';
5
5
  import { mcpAuthMetadataRouter, getOAuthProtectedResourceMetadataUrl } from '@modelcontextprotocol/sdk/server/auth/router.js';
6
6
  import { requireBearerAuth } from '@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js';
7
7
  import { InvalidTokenError } from '@modelcontextprotocol/sdk/server/auth/errors.js';
@@ -12,8 +12,7 @@ import { jwtVerify, errors, decodeProtectedHeader, createRemoteJWKSet } from 'jo
12
12
  // src/management/types.ts
13
13
  var TOKEN_EXCHANGE_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:token-exchange";
14
14
  var TOKEN_TYPE_ACCESS_TOKEN = "urn:ietf:params:oauth:token-type:access_token";
15
-
16
- // src/errors.ts
15
+ var TOKEN_TYPE_USER_ID = "urn:kontext:user-id";
17
16
  var KontextError = class extends Error {
18
17
  /** Brand field for type narrowing without instanceof */
19
18
  kontextError = true;
@@ -84,6 +83,17 @@ var IntegrationConnectionRequiredError = class extends KontextError {
84
83
  this.connectUrl = options?.connectUrl;
85
84
  }
86
85
  };
86
+ ({
87
+ [ErrorCode.ParseError]: { },
88
+ [ErrorCode.InvalidRequest]: { },
89
+ [ErrorCode.MethodNotFound]: { },
90
+ [ErrorCode.InvalidParams]: { },
91
+ [ErrorCode.InternalError]: {
92
+ },
93
+ [ErrorCode.RequestTimeout]: {
94
+ },
95
+ [ErrorCode.ConnectionClosed]: { }
96
+ });
87
97
 
88
98
  // src/oauth/token-exchange.ts
89
99
  async function exchangeToken(config, subjectToken, resource, scope, subjectTokenType = TOKEN_TYPE_ACCESS_TOKEN) {
@@ -563,7 +573,7 @@ var Kontext = class _Kontext {
563
573
  oauthMetadata = null;
564
574
  metadataFetchedAt = 0;
565
575
  metadataPromise = null;
566
- // Token exchange caching: keyed by `${integration}\0${subjectToken}`
576
+ // Token exchange caching: keyed by `${mode}\0${integration}\0${subjectToken}`
567
577
  credentialCache = /* @__PURE__ */ new Map();
568
578
  resolvedCredentialCache = /* @__PURE__ */ new Map();
569
579
  runtimeAuthCache = /* @__PURE__ */ new Map();
@@ -721,23 +731,28 @@ var Kontext = class _Kontext {
721
731
  router.delete(mcpPath, mcpHandler.delete);
722
732
  return router;
723
733
  }
724
- // ===========================================================================
725
- // require()
726
- // ===========================================================================
727
- /**
728
- * Exchange a user's access token for an integration credential.
729
- *
730
- * @param integration - Integration name (e.g., "github")
731
- * @param token - The user's Bearer token (from `authInfo.token`)
732
- * @returns Integration credential with `accessToken` and `authorization` header
733
- *
734
- * @throws {IntegrationConnectionRequiredError} User hasn't connected this integration
735
- * @throws {OAuthError} Token exchange failed
736
- */
737
- async require(integration, token) {
734
+ async require(integration, tokenOrOpts) {
735
+ let isUserIdMode = false;
736
+ let subjectToken = "";
737
+ if (typeof tokenOrOpts === "string") {
738
+ subjectToken = tokenOrOpts;
739
+ } else if (tokenOrOpts !== null && typeof tokenOrOpts === "object" && typeof tokenOrOpts.userId === "string") {
740
+ isUserIdMode = true;
741
+ subjectToken = tokenOrOpts.userId.trim();
742
+ if (!subjectToken) {
743
+ throw new TypeError(
744
+ "Kontext.require() expects a non-empty userId when called with { userId }."
745
+ );
746
+ }
747
+ } else {
748
+ throw new TypeError(
749
+ "Kontext.require() expects a token string or { userId: string }."
750
+ );
751
+ }
752
+ const subjectTokenType = isUserIdMode ? TOKEN_TYPE_USER_ID : void 0;
738
753
  const now = Date.now();
739
754
  this.evictExpiredCredentials(now);
740
- const cacheKey = `${integration}\0${token}`;
755
+ const cacheKey = isUserIdMode ? `u\0${integration}\0${subjectToken}` : `t\0${integration}\0${subjectToken}`;
741
756
  const cached = this.credentialCache.get(cacheKey);
742
757
  if (cached && now < cached.expiresAt) {
743
758
  this.credentialCache.delete(cacheKey);
@@ -754,13 +769,25 @@ var Kontext = class _Kontext {
754
769
  };
755
770
  let response;
756
771
  try {
757
- response = await exchangeToken(exchangeConfig, token, integration);
772
+ response = await exchangeToken(
773
+ exchangeConfig,
774
+ subjectToken,
775
+ integration,
776
+ void 0,
777
+ subjectTokenType
778
+ );
758
779
  } catch (err) {
759
780
  if (err instanceof OAuthError) {
760
781
  if (err.errorCode === "integration_required" || err.message.includes("not connected") || err.message.includes("expired") && err.message.includes("reconnect")) {
761
782
  const integrationId = err.meta.integrationId || integration;
783
+ if (isUserIdMode) {
784
+ throw new IntegrationConnectionRequiredError(integrationId, {
785
+ integrationName: err.meta.integrationName,
786
+ message: err.message
787
+ });
788
+ }
762
789
  const connectUrl = await this.fetchConnectUrl(
763
- token,
790
+ subjectToken,
764
791
  integrationId,
765
792
  exchangeConfig
766
793
  );
@@ -1271,6 +1298,12 @@ var Kontext = class _Kontext {
1271
1298
  // ===========================================================================
1272
1299
  createAgentSession(userToken, mcpSessionId, metadata) {
1273
1300
  if (!this.clientSecret || !userToken) return;
1301
+ if (!metadata?.authenticatedUserId) {
1302
+ console.warn(
1303
+ "[kontext:sessions] create skipped: missing authenticated user id"
1304
+ );
1305
+ return;
1306
+ }
1274
1307
  const tokenIdentifier = createHash("sha256").update(userToken).digest("hex");
1275
1308
  this.getServiceToken().then(
1276
1309
  (token) => fetch(`${this.apiUrl}/api/v1/agent-sessions`, {
@@ -1281,6 +1314,7 @@ var Kontext = class _Kontext {
1281
1314
  },
1282
1315
  body: JSON.stringify({
1283
1316
  tokenIdentifier,
1317
+ authenticatedUserId: metadata.authenticatedUserId,
1284
1318
  clientSessionId: mcpSessionId,
1285
1319
  hostname: metadata?.hostname,
1286
1320
  userAgent: metadata?.userAgent,
@@ -1502,6 +1536,7 @@ var Kontext = class _Kontext {
1502
1536
  status: "ok"
1503
1537
  });
1504
1538
  this.createAgentSession(authInfo?.token, sid, {
1539
+ authenticatedUserId: typeof authInfo?.extra?.sub === "string" ? authInfo.extra.sub : void 0,
1505
1540
  hostname: req.headers["x-forwarded-for"],
1506
1541
  userAgent: req.headers["user-agent"],
1507
1542
  tokenExpiresAt: authInfo?.expiresAt