@codemem/mcp 0.37.0 → 0.37.1

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/http.js CHANGED
@@ -10,10 +10,10 @@ import { StreamableHTTPServerTransport as d } from "@modelcontextprotocol/sdk/se
10
10
  import f from "express";
11
11
  import { Buffer as p } from "node:buffer";
12
12
  import { createHash as m, createHmac as h, createPublicKey as g, randomBytes as _, randomUUID as v, timingSafeEqual as y, verify as b } from "node:crypto";
13
- import { existsSync as ee, mkdirSync as x, readFileSync as S, renameSync as te, writeFileSync as C } from "node:fs";
14
- import { chmod as w } from "node:fs/promises";
15
- import { homedir as T } from "node:os";
16
- import { dirname as E, join as D } from "node:path";
13
+ import { existsSync as x, mkdirSync as S, readFileSync as C, renameSync as ee, writeFileSync as w } from "node:fs";
14
+ import { chmod as T } from "node:fs/promises";
15
+ import { homedir as E } from "node:os";
16
+ import { dirname as D, join as te } from "node:path";
17
17
  import { AccessDeniedError as ne, InvalidClientError as re, InvalidClientMetadataError as O, InvalidGrantError as k, InvalidRequestError as ie, InvalidTokenError as ae, ServerError as oe, TemporarilyUnavailableError as A, UnsupportedResponseTypeError as se } from "@modelcontextprotocol/sdk/server/auth/errors.js";
18
18
  import { OAuthProtectedResourceMetadataSchema as ce, OAuthTokensSchema as le } from "@modelcontextprotocol/sdk/shared/auth.js";
19
19
  //#region \0rolldown/runtime.js
@@ -1114,21 +1114,21 @@ function We(e = process.env.CODEMEM_MCP_AUDIT) {
1114
1114
  let t = e?.trim().toLowerCase();
1115
1115
  return t === "0" || t === "false" || t === "no" ? Ue() : He();
1116
1116
  }
1117
- var Ge = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github.com/kunickiaj/codemem#readme", Ke = "https://claude.ai/api/mcp/auth_callback", qe = new Set([
1117
+ var Ge = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github.com/kunickiaj/codemem#readme", Ke = "https://claude.ai/api/mcp/auth_callback", qe = "https://chatgpt.com/connector_platform_oauth_redirect", Je = new Set([
1118
1118
  "localhost",
1119
1119
  "127.0.0.1",
1120
1120
  "::1"
1121
- ]), Je = new Set(["authorization_code", "refresh_token"]), Ye = new Set(["code"]), B = 3600, V = 720 * 60 * 60, Xe = 100, Ze = 100, Qe = 100, $e = 32, et = 43, tt = /^[A-Za-z0-9_-]{43}$/, nt = /^[A-Za-z0-9_-]{43}$/, rt = class {
1121
+ ]), Ye = new Set(["authorization_code", "refresh_token"]), Xe = new Set(["code"]), B = 3600, V = 720 * 60 * 60, Ze = 100, Qe = 100, $e = 100, et = 32, tt = 43, nt = /^[A-Za-z0-9_-]{43}$/, rt = /^[A-Za-z0-9_-]{43}$/, it = /^[A-Za-z0-9_-]{1,128}$/, at = class {
1122
1122
  #e = /* @__PURE__ */ new Map();
1123
1123
  getClient(e) {
1124
1124
  return this.#e.get(e);
1125
1125
  }
1126
1126
  registerClient(e) {
1127
- let t = yt(e.redirect_uris);
1127
+ let t = xt(e.redirect_uris);
1128
1128
  if (t) throw new O(t);
1129
1129
  if (e.client_secret || e.token_endpoint_auth_method !== "none") throw new O("Only public clients with token_endpoint_auth_method=none are supported");
1130
- if (e.grant_types && !H(e.grant_types, Je)) throw new O("Only authorization_code and refresh_token grant_types are supported");
1131
- if (e.response_types && !H(e.response_types, Ye)) throw new O("Only code response_type is supported");
1130
+ if (e.grant_types && !H(e.grant_types, Ye)) throw new O("Only authorization_code and refresh_token grant_types are supported");
1131
+ if (e.response_types && !H(e.response_types, Xe)) throw new O("Only code response_type is supported");
1132
1132
  if (this.#e.size >= 100) {
1133
1133
  let e = this.#e.keys().next().value;
1134
1134
  e && this.#e.delete(e);
@@ -1143,10 +1143,10 @@ var Ge = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github
1143
1143
  };
1144
1144
  return this.#e.set(n.client_id, n), n;
1145
1145
  }
1146
- }, it = class {
1146
+ }, ot = class {
1147
1147
  #e = /* @__PURE__ */ new Map();
1148
1148
  issueCode(e, t = Date.now()) {
1149
- if (this.#t(t), this.#e.size >= Xe) return;
1149
+ if (this.#t(t), this.#e.size >= Ze) return;
1150
1150
  let n = v();
1151
1151
  return this.#e.set(n, {
1152
1152
  ...e,
@@ -1164,12 +1164,12 @@ var Ge = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github
1164
1164
  #t(e) {
1165
1165
  for (let [t, n] of this.#e) n.expiresAt <= e && this.#e.delete(t);
1166
1166
  }
1167
- }, at = class {
1167
+ }, st = class {
1168
1168
  #e = /* @__PURE__ */ new Map();
1169
1169
  #t = _(32);
1170
1170
  issueToken(e, t = Date.now(), n, r, i = []) {
1171
- if (this.#n(t), this.#e.size >= Ze) return;
1172
- let a = _($e), o = Tt(a, this.#t);
1171
+ if (this.#n(t), this.#e.size >= Qe) return;
1172
+ let a = _(et), o = kt(a, this.#t);
1173
1173
  return this.#e.set(o, {
1174
1174
  clientId: e,
1175
1175
  grantId: r,
@@ -1191,7 +1191,7 @@ var Ge = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github
1191
1191
  ok: !1,
1192
1192
  reason: "unknown_token"
1193
1193
  };
1194
- let r = Tt(n, this.#t), i = this.#e.get(r);
1194
+ let r = kt(n, this.#t), i = this.#e.get(r);
1195
1195
  return !i || !J(i.tokenHash, r) ? {
1196
1196
  ok: !1,
1197
1197
  reason: "unknown_token"
@@ -1209,7 +1209,7 @@ var Ge = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github
1209
1209
  revokeToken(e, t = Date.now()) {
1210
1210
  let n = W(e);
1211
1211
  if (!n) return !1;
1212
- let r = Tt(n, this.#t), i = this.#e.get(r);
1212
+ let r = kt(n, this.#t), i = this.#e.get(r);
1213
1213
  return !i || !J(i.tokenHash, r) ? !1 : (i.revokedAt === null && (i.revokedAt = t), !0);
1214
1214
  }
1215
1215
  revokeTokensForGrant(e, t = Date.now()) {
@@ -1220,13 +1220,13 @@ var Ge = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github
1220
1220
  #n(e) {
1221
1221
  for (let [t, n] of this.#e) (n.expiresAt <= e || n.revokedAt !== null) && this.#e.delete(t);
1222
1222
  }
1223
- }, ot = class {
1223
+ }, ct = class {
1224
1224
  #e = /* @__PURE__ */ new Map();
1225
1225
  #t = /* @__PURE__ */ new Map();
1226
1226
  #n = /* @__PURE__ */ new Map();
1227
1227
  #r = _(32);
1228
1228
  issueGrant(e, t = Date.now()) {
1229
- if (this.#i(t), this.#e.size >= Qe) return;
1229
+ if (this.#i(t), this.#e.size >= $e) return;
1230
1230
  let n = G(), r = K(n, this.#r);
1231
1231
  if (!r) return;
1232
1232
  let i = {
@@ -1281,7 +1281,7 @@ var Ge = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github
1281
1281
  reason: "client_mismatch",
1282
1282
  grantId: a
1283
1283
  };
1284
- if (!Dt(n.scopes ?? o.scopes, o.scopes)) return {
1284
+ if (!jt(n.scopes ?? o.scopes, o.scopes)) return {
1285
1285
  ok: !1,
1286
1286
  reason: "scope_mismatch",
1287
1287
  grantId: a
@@ -1333,7 +1333,7 @@ var Ge = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github
1333
1333
  }
1334
1334
  this.#t.delete(e.currentRefreshTokenHash), e.previousRefreshTokenHash && this.#t.delete(e.previousRefreshTokenHash);
1335
1335
  }
1336
- }, st = class {
1336
+ }, lt = class {
1337
1337
  #e;
1338
1338
  #t = /* @__PURE__ */ new Map();
1339
1339
  #n = /* @__PURE__ */ new Map();
@@ -1341,18 +1341,18 @@ var Ge = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github
1341
1341
  #i = /* @__PURE__ */ new Map();
1342
1342
  #a = /* @__PURE__ */ new Map();
1343
1343
  #o = /* @__PURE__ */ new Map();
1344
- constructor(e = pt()) {
1344
+ constructor(e = ht()) {
1345
1345
  this.#e = e, this.#s();
1346
1346
  }
1347
1347
  getClient(e) {
1348
1348
  return this.#n.get(e);
1349
1349
  }
1350
1350
  registerClient(e) {
1351
- let t = yt(e.redirect_uris);
1351
+ let t = xt(e.redirect_uris);
1352
1352
  if (t) throw new O(t);
1353
1353
  if (e.client_secret || e.token_endpoint_auth_method !== "none") throw new O("Only public clients with token_endpoint_auth_method=none are supported");
1354
- if (e.grant_types && !H(e.grant_types, Je)) throw new O("Only authorization_code and refresh_token grant_types are supported");
1355
- if (e.response_types && !H(e.response_types, Ye)) throw new O("Only code response_type is supported");
1354
+ if (e.grant_types && !H(e.grant_types, Ye)) throw new O("Only authorization_code and refresh_token grant_types are supported");
1355
+ if (e.response_types && !H(e.response_types, Xe)) throw new O("Only code response_type is supported");
1356
1356
  if (this.#u(Date.now()), this.#n.size >= 100) {
1357
1357
  let e = this.#n.keys().next().value;
1358
1358
  e && this.#n.delete(e);
@@ -1368,7 +1368,7 @@ var Ge = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github
1368
1368
  return this.#n.set(n.client_id, n), this.#c(), n;
1369
1369
  }
1370
1370
  issueCode(e, t = Date.now()) {
1371
- if (this.#l(t), this.#t.size >= Xe) return;
1371
+ if (this.#l(t), this.#t.size >= Ze) return;
1372
1372
  let n = v();
1373
1373
  return this.#t.set(n, {
1374
1374
  ...e,
@@ -1384,7 +1384,7 @@ var Ge = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github
1384
1384
  if (!(!t || t.used)) return t.used = !0, t;
1385
1385
  }
1386
1386
  issueToken(e, t = Date.now(), n, r, i = []) {
1387
- if (this.#u(t), this.#r.size >= Ze) return;
1387
+ if (this.#u(t), this.#r.size >= Qe) return;
1388
1388
  let a = G(), o = q(a);
1389
1389
  if (o) return this.#r.set(o, {
1390
1390
  clientId: e,
@@ -1437,7 +1437,7 @@ var Ge = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github
1437
1437
  return n > 0 && this.#c(), n;
1438
1438
  }
1439
1439
  issueGrant(e, t = Date.now()) {
1440
- if (this.#u(t), this.#i.size >= Qe) return;
1440
+ if (this.#u(t), this.#i.size >= $e) return;
1441
1441
  let n = G(), r = q(n);
1442
1442
  if (!r) return;
1443
1443
  let i = {
@@ -1492,7 +1492,7 @@ var Ge = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github
1492
1492
  reason: "client_mismatch",
1493
1493
  grantId: a
1494
1494
  };
1495
- if (!Dt(n.scopes ?? o.scopes, o.scopes)) return {
1495
+ if (!jt(n.scopes ?? o.scopes, o.scopes)) return {
1496
1496
  ok: !1,
1497
1497
  reason: "scope_mismatch",
1498
1498
  grantId: a
@@ -1533,10 +1533,10 @@ var Ge = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github
1533
1533
  return n ? n.revokedAt === null ? (n.revokedAt = t, this.#d(n), this.#c(), !0) : !0 : !1;
1534
1534
  }
1535
1535
  #s() {
1536
- if (!ee(this.#e)) return;
1536
+ if (!x(this.#e)) return;
1537
1537
  let e;
1538
1538
  try {
1539
- e = JSON.parse(S(this.#e, "utf8"));
1539
+ e = JSON.parse(C(this.#e, "utf8"));
1540
1540
  } catch {
1541
1541
  return;
1542
1542
  }
@@ -1551,7 +1551,7 @@ var Ge = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github
1551
1551
  }
1552
1552
  }
1553
1553
  #c() {
1554
- x(E(this.#e), {
1554
+ S(D(this.#e), {
1555
1555
  recursive: !0,
1556
1556
  mode: 448
1557
1557
  });
@@ -1562,7 +1562,7 @@ var Ge = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github
1562
1562
  refreshGrants: [...this.#i.values()],
1563
1563
  refreshHashesByGrantId: Object.fromEntries([...this.#o.entries()].map(([e, t]) => [e, [...t]]))
1564
1564
  }, t = `${this.#e}.${process.pid}.${Date.now()}.tmp`;
1565
- C(t, `${JSON.stringify(e, null, 2)}\n`, { mode: 384 }), te(t, this.#e), w(this.#e, 384).catch(() => void 0);
1565
+ w(t, `${JSON.stringify(e, null, 2)}\n`, { mode: 384 }), ee(t, this.#e), T(this.#e, 384).catch(() => void 0);
1566
1566
  }
1567
1567
  #l(e) {
1568
1568
  for (let [t, n] of this.#t) n.expiresAt <= e && this.#t.delete(t);
@@ -1583,29 +1583,29 @@ var Ge = "codemem MCP", R = ["memory:read", "memory:write"], z = "https://github
1583
1583
  this.#a.delete(e.currentRefreshTokenHash), e.previousRefreshTokenHash && this.#a.delete(e.previousRefreshTokenHash);
1584
1584
  }
1585
1585
  };
1586
- function ct() {
1587
- return new rt();
1588
- }
1589
- function lt() {
1590
- return new it();
1591
- }
1592
1586
  function ut() {
1593
1587
  return new at();
1594
1588
  }
1595
1589
  function dt() {
1596
1590
  return new ot();
1597
1591
  }
1598
- function ft(e) {
1599
- return new st(e);
1592
+ function ft() {
1593
+ return new st();
1600
1594
  }
1601
1595
  function pt() {
1602
- return D(process.env.HOME?.trim() || T(), ".codemem", "mcp-oauth-state.json");
1596
+ return new ct();
1603
1597
  }
1604
1598
  function mt(e) {
1605
- let t = vt(_t(e.mcpUrl));
1599
+ return new lt(e);
1600
+ }
1601
+ function ht() {
1602
+ return te(process.env.HOME?.trim() || E(), ".codemem", "mcp-oauth-state.json");
1603
+ }
1604
+ function gt(e) {
1605
+ let t = bt(yt(e.mcpUrl));
1606
1606
  return {
1607
1607
  ...c({
1608
- provider: Ot(e.clientsStore),
1608
+ provider: Mt(e.clientsStore),
1609
1609
  issuerUrl: t,
1610
1610
  baseUrl: t
1611
1611
  }),
@@ -1618,10 +1618,10 @@ function mt(e) {
1618
1618
  client_id_metadata_document_supported: !1
1619
1619
  };
1620
1620
  }
1621
- function ht(e) {
1622
- let t = _t(e), n = {
1621
+ function _t(e) {
1622
+ let t = yt(e), n = {
1623
1623
  resource: t.href,
1624
- authorization_servers: [vt(t).href],
1624
+ authorization_servers: [bt(t).href],
1625
1625
  scopes_supported: R,
1626
1626
  bearer_methods_supported: ["header"],
1627
1627
  resource_name: Ge,
@@ -1629,12 +1629,12 @@ function ht(e) {
1629
1629
  };
1630
1630
  return ce.parse(n);
1631
1631
  }
1632
- function gt(e, t) {
1633
- let n = e.get("client_id") ?? "", r = e.get("redirect_uri") ?? "", i = e.get("response_type") ?? "", a = e.get("code_challenge") ?? "", o = e.get("code_challenge_method") ?? "", s = e.get("resource"), c = Ct(e.get("scope")), l = e.get("state");
1632
+ function vt(e, t) {
1633
+ let n = e.get("client_id") ?? "", r = e.get("redirect_uri") ?? "", i = e.get("response_type") ?? "", a = e.get("code_challenge") ?? "", o = e.get("code_challenge_method") ?? "", s = e.get("resource"), c = Dt(e.get("scope")), l = e.get("state");
1634
1634
  if (i !== "code") return U("unsupported_response_type");
1635
1635
  if (o !== "S256") return U("invalid_request", "PKCE code_challenge_method=S256 is required");
1636
- if (!nt.test(a)) return U("invalid_request", "Valid PKCE S256 code_challenge is required");
1637
- let u = wt(t, n);
1636
+ if (!rt.test(a)) return U("invalid_request", "Valid PKCE S256 code_challenge is required");
1637
+ let u = Ot(t, n);
1638
1638
  return u ? u.redirect_uris.includes(r) ? {
1639
1639
  clientId: n,
1640
1640
  redirectUri: r,
@@ -1644,43 +1644,50 @@ function gt(e, t) {
1644
1644
  state: l
1645
1645
  } : U("invalid_request", "redirect_uri is not registered for this client") : U("invalid_client", "Unknown OAuth client_id");
1646
1646
  }
1647
- function _t(e) {
1647
+ function yt(e) {
1648
1648
  let t;
1649
1649
  try {
1650
1650
  t = new URL(e);
1651
1651
  } catch {
1652
1652
  throw Error("Invalid MCP HTTP public URL; expected an HTTPS /mcp URL");
1653
1653
  }
1654
- if (t.protocol !== "https:" && !xt(t)) throw Error("Invalid MCP HTTP public URL; use HTTPS for non-loopback URLs");
1654
+ if (t.protocol !== "https:" && !Tt(t)) throw Error("Invalid MCP HTTP public URL; use HTTPS for non-loopback URLs");
1655
1655
  if (t.username || t.password || t.search || t.hash) throw Error("Invalid MCP HTTP public URL; credentials, query strings, and fragments are not allowed");
1656
1656
  if (t.pathname === "/" && (t.pathname = "/mcp"), t.pathname !== "/mcp") throw Error("Invalid MCP HTTP public URL; expected /mcp path");
1657
1657
  return t;
1658
1658
  }
1659
- function vt(e) {
1659
+ function bt(e) {
1660
1660
  return new URL(e.origin);
1661
1661
  }
1662
- function yt(e) {
1662
+ function xt(e) {
1663
1663
  for (let t of e) {
1664
1664
  let e = new URL(t);
1665
- if (e.username || e.password || e.hash) return `Invalid redirect URI: ${t}`;
1666
- if (e.href !== Ke && !bt(e)) return `Unsupported redirect URI: ${t}`;
1665
+ if (e.username || e.password || e.hash) return "Invalid redirect URI";
1666
+ if (!St(e) && !wt(e)) return "Unsupported redirect URI";
1667
1667
  }
1668
1668
  return null;
1669
1669
  }
1670
+ function St(e) {
1671
+ return e.search === "" ? e.href === Ke || e.href === qe ? !0 : e.protocol === "https:" && e.hostname === "chatgpt.com" && Ct(e) : !1;
1672
+ }
1673
+ function Ct(e) {
1674
+ let t = e.pathname.split("/").filter(Boolean);
1675
+ return t.length === 3 && t[0] === "connector" && t[1] === "oauth" && it.test(t[2] ?? "");
1676
+ }
1670
1677
  function H(e, t) {
1671
1678
  return e.length > 0 && e.every((e) => t.has(e));
1672
1679
  }
1673
- function bt(e) {
1674
- return e.protocol === "http:" && qe.has(St(e.hostname)) && e.pathname === "/callback" && e.search === "";
1680
+ function wt(e) {
1681
+ return e.protocol === "http:" && Je.has(Et(e.hostname)) && (e.pathname === "/callback" || e.pathname === "/oauth/callback") && e.search === "";
1675
1682
  }
1676
- function xt(e) {
1677
- let t = St(e.hostname);
1678
- return e.protocol === "http:" && qe.has(t);
1683
+ function Tt(e) {
1684
+ let t = Et(e.hostname);
1685
+ return e.protocol === "http:" && Je.has(t);
1679
1686
  }
1680
- function St(e) {
1687
+ function Et(e) {
1681
1688
  return e.replace(/^\[(.*)]$/, "$1").toLowerCase();
1682
1689
  }
1683
- function Ct(e) {
1690
+ function Dt(e) {
1684
1691
  return e?.split(/\s+/).map((e) => e.trim()).filter(Boolean) ?? [];
1685
1692
  }
1686
1693
  function U(e, t) {
@@ -1692,42 +1699,42 @@ function U(e, t) {
1692
1699
  } : { error: e }
1693
1700
  };
1694
1701
  }
1695
- function wt(e, t) {
1702
+ function Ot(e, t) {
1696
1703
  let n = e.getClient(t);
1697
1704
  if (n instanceof Promise) throw Error("Asynchronous OAuth client stores are not supported by this HTTP bootstrap yet");
1698
1705
  return n;
1699
1706
  }
1700
1707
  function W(e) {
1701
- if (typeof e != "string" || e.length !== et || !tt.test(e)) return null;
1708
+ if (typeof e != "string" || e.length !== tt || !nt.test(e)) return null;
1702
1709
  let t = Buffer.from(e, "base64url");
1703
- return t.length === $e ? t : null;
1710
+ return t.length === et ? t : null;
1704
1711
  }
1705
1712
  function G() {
1706
- return _($e).toString("base64url");
1713
+ return _(et).toString("base64url");
1707
1714
  }
1708
1715
  function K(e, t) {
1709
1716
  let n = W(e);
1710
- return n ? Et(n, t) : null;
1717
+ return n ? At(n, t) : null;
1711
1718
  }
1712
1719
  function q(e) {
1713
1720
  let t = W(e);
1714
1721
  return t ? m("sha256").update(t).digest("base64url") : null;
1715
1722
  }
1716
- function Tt(e, t) {
1717
- return Et(e, t);
1723
+ function kt(e, t) {
1724
+ return At(e, t);
1718
1725
  }
1719
- function Et(e, t) {
1726
+ function At(e, t) {
1720
1727
  return h("sha256", t).update(e).digest("base64url");
1721
1728
  }
1722
1729
  function J(e, t) {
1723
1730
  let n = Buffer.from(e), r = Buffer.from(t);
1724
1731
  return n.length === r.length && y(n, r);
1725
1732
  }
1726
- function Dt(e, t) {
1733
+ function jt(e, t) {
1727
1734
  let n = new Set(t);
1728
1735
  return e.every((e) => n.has(e));
1729
1736
  }
1730
- function Ot(e) {
1737
+ function Mt(e) {
1731
1738
  return {
1732
1739
  clientsStore: e,
1733
1740
  async authorize() {
@@ -1749,14 +1756,14 @@ function Ot(e) {
1749
1756
  }
1750
1757
  //#endregion
1751
1758
  //#region src/oidc.ts
1752
- var kt = "CODEMEM_MCP_OIDC_ISSUER_URL", At = "CODEMEM_MCP_OIDC_CLIENT_ID", jt = "CODEMEM_MCP_OIDC_CLIENT_SECRET", Mt = "CODEMEM_MCP_OAUTH_ALLOWED_SUBJECT", Nt = "CODEMEM_MCP_OAUTH_ALLOWED_EMAIL", Pt = 300 * 1e3, Ft = 100, It = 300 * 1e3, Lt = class {
1759
+ var Nt = "CODEMEM_MCP_OIDC_ISSUER_URL", Pt = "CODEMEM_MCP_OIDC_CLIENT_ID", Ft = "CODEMEM_MCP_OIDC_CLIENT_SECRET", It = "CODEMEM_MCP_OAUTH_ALLOWED_SUBJECT", Lt = "CODEMEM_MCP_OAUTH_ALLOWED_EMAIL", Rt = 300 * 1e3, zt = 100, Bt = 300 * 1e3, Vt = class {
1753
1760
  #e = /* @__PURE__ */ new Map();
1754
1761
  issue(e, t = Date.now()) {
1755
- if (this.#t(t), this.#e.size >= Ft) return;
1762
+ if (this.#t(t), this.#e.size >= zt) return;
1756
1763
  let n = v();
1757
1764
  return this.#e.set(n, {
1758
1765
  ...e,
1759
- expiresAt: t + Pt
1766
+ expiresAt: t + Rt
1760
1767
  }), n;
1761
1768
  }
1762
1769
  consume(e) {
@@ -1767,11 +1774,11 @@ var kt = "CODEMEM_MCP_OIDC_ISSUER_URL", At = "CODEMEM_MCP_OIDC_CLIENT_ID", jt =
1767
1774
  for (let [t, n] of this.#e) n.expiresAt <= e && this.#e.delete(t);
1768
1775
  }
1769
1776
  };
1770
- function Rt() {
1771
- return new Lt();
1777
+ function Ht() {
1778
+ return new Vt();
1772
1779
  }
1773
- function zt(e = process.env) {
1774
- let t = e[kt]?.trim(), n = e[At]?.trim(), r = e[jt]?.trim(), i = e[Mt]?.trim(), a = e[Nt]?.trim().toLowerCase();
1780
+ function Ut(e = process.env) {
1781
+ let t = e[Nt]?.trim(), n = e[Pt]?.trim(), r = e[Ft]?.trim(), i = e[It]?.trim(), a = e[Lt]?.trim().toLowerCase();
1775
1782
  if (!(!t && !n && !r && !i && !a)) {
1776
1783
  if (!t || !n || !r) throw Error("Incomplete MCP OIDC configuration");
1777
1784
  if (Y(t, "issuer", { allowLoopbackHttp: !0 }), !i && !a) throw Error("MCP OIDC requires CODEMEM_MCP_OAUTH_ALLOWED_SUBJECT or CODEMEM_MCP_OAUTH_ALLOWED_EMAIL");
@@ -1784,39 +1791,39 @@ function zt(e = process.env) {
1784
1791
  };
1785
1792
  }
1786
1793
  }
1787
- async function Bt(e, t, n, r, i, a = Date.now()) {
1794
+ async function Wt(e, t, n, r, i, a = Date.now()) {
1788
1795
  if (!r) return X("temporarily_unavailable", "OIDC is not configured");
1789
- let o = gt(e, t);
1796
+ let o = vt(e, t);
1790
1797
  if ("status" in o) return o;
1791
- let s = await Ut(r.issuerUrl), c = v(), l = n.issue({
1798
+ let s = await qt(r.issuerUrl), c = v(), l = n.issue({
1792
1799
  oauthParams: e.toString(),
1793
1800
  nonce: c
1794
1801
  }, a);
1795
1802
  if (!l) return X("temporarily_unavailable", "Too many pending OIDC authorizations");
1796
- let u = Ht(i), d = new URL(s.authorization_endpoint);
1803
+ let u = Kt(i), d = new URL(s.authorization_endpoint);
1797
1804
  return d.searchParams.set("response_type", "code"), d.searchParams.set("client_id", r.clientId), d.searchParams.set("redirect_uri", u), d.searchParams.set("scope", "openid email"), d.searchParams.set("state", l), d.searchParams.set("nonce", c), {
1798
1805
  status: 302,
1799
1806
  location: d.href
1800
1807
  };
1801
1808
  }
1802
- async function Vt(e, t, n, r, i = Date.now()) {
1809
+ async function Gt(e, t, n, r, i = Date.now()) {
1803
1810
  try {
1804
1811
  let a = e.get("code") ?? "", o = e.get("state") ?? "";
1805
1812
  if (!o) return X("invalid_request", "Missing OIDC state");
1806
1813
  let s = t.consume(o);
1807
1814
  if (!s || s.expiresAt <= i) return X("invalid_request", "Expired or unknown OIDC state");
1808
1815
  if (!a) return X("invalid_request", "Missing OIDC code");
1809
- let c = await Ut(n.issuerUrl), l = await Wt(c.token_endpoint, n, Ht(r), a);
1810
- return l.id_token ? Yt(await Gt(l.id_token, c, n.clientId, s.nonce, i), n) ? { oauthParams: new URLSearchParams(s.oauthParams) } : X("access_denied", "OIDC identity is not allowed") : X("invalid_request", "OIDC token exchange failed");
1816
+ let c = await qt(n.issuerUrl), l = await Jt(c.token_endpoint, n, Kt(r), a);
1817
+ return l.id_token ? $t(await Yt(l.id_token, c, n.clientId, s.nonce, i), n) ? { oauthParams: new URLSearchParams(s.oauthParams) } : X("access_denied", "OIDC identity is not allowed") : X("invalid_request", "OIDC token exchange failed");
1811
1818
  } catch {
1812
1819
  return X("access_denied", "OIDC identity verification failed");
1813
1820
  }
1814
1821
  }
1815
- function Ht(e) {
1822
+ function Kt(e) {
1816
1823
  let t = new URL(e);
1817
1824
  return new URL("/oauth/callback", t.origin).href;
1818
1825
  }
1819
- async function Ut(e) {
1826
+ async function qt(e) {
1820
1827
  let t = new URL(e);
1821
1828
  if (t.search || t.hash) throw Error("OIDC issuer must not include query or fragment");
1822
1829
  if (t.username || t.password) throw Error("OIDC issuer must not include credentials");
@@ -1825,10 +1832,10 @@ async function Ut(e) {
1825
1832
  let i = await r.json();
1826
1833
  if (i.issuer !== t.href && i.issuer !== t.href.replace(/\/$/, "")) throw Error("OIDC discovery issuer mismatch");
1827
1834
  if (!i.authorization_endpoint || !i.token_endpoint || !i.jwks_uri) throw Error("OIDC discovery metadata is incomplete");
1828
- let a = t.protocol === "http:" && Xt(t.hostname);
1835
+ let a = t.protocol === "http:" && en(t.hostname);
1829
1836
  return Y(i.authorization_endpoint, "authorization endpoint", { allowLoopbackHttp: a }), Y(i.token_endpoint, "token endpoint", { allowLoopbackHttp: a }), Y(i.jwks_uri, "JWKS URI", { allowLoopbackHttp: a }), i;
1830
1837
  }
1831
- async function Wt(e, t, n, r) {
1838
+ async function Jt(e, t, n, r) {
1832
1839
  let i = new URLSearchParams({
1833
1840
  grant_type: "authorization_code",
1834
1841
  code: r,
@@ -1843,17 +1850,17 @@ async function Wt(e, t, n, r) {
1843
1850
  if (!a.ok) throw Error("OIDC token request failed");
1844
1851
  return await a.json();
1845
1852
  }
1846
- async function Gt(e, t, n, r, i) {
1853
+ async function Yt(e, t, n, r, i) {
1847
1854
  let [a, o, s] = e.split(".");
1848
1855
  if (!a || !o || !s) throw Error("Invalid OIDC id_token");
1849
- let c = Kt(a), l = Kt(o);
1856
+ let c = Xt(a), l = Xt(o);
1850
1857
  if (c.alg !== "RS256" || !c.kid) throw Error("Unsupported OIDC id_token signature");
1851
1858
  if (l.iss !== t.issuer) throw Error("OIDC id_token issuer mismatch");
1852
- if (!qt(l.aud, n)) throw Error("OIDC id_token audience mismatch");
1853
- if (!Jt(l.aud, l.azp, n)) throw Error("OIDC id_token authorized party mismatch");
1859
+ if (!Zt(l.aud, n)) throw Error("OIDC id_token audience mismatch");
1860
+ if (!Qt(l.aud, l.azp, n)) throw Error("OIDC id_token authorized party mismatch");
1854
1861
  if (typeof l.exp != "number" || !Number.isFinite(l.exp) || l.exp * 1e3 <= i) throw Error("OIDC id_token is expired");
1855
1862
  if (typeof l.iat != "number" || !Number.isFinite(l.iat)) throw Error("OIDC id_token issued-at time is missing");
1856
- if (l.iat * 1e3 > i + It) throw Error("OIDC id_token issued-at time is in the future");
1863
+ if (l.iat * 1e3 > i + Bt) throw Error("OIDC id_token issued-at time is in the future");
1857
1864
  if (l.nonce !== r) throw Error("OIDC id_token nonce mismatch");
1858
1865
  if (!l.sub) throw Error("OIDC id_token subject is missing");
1859
1866
  let u = await fetch(t.jwks_uri);
@@ -1867,24 +1874,24 @@ async function Gt(e, t, n, r, i) {
1867
1874
  if (!b("RSA-SHA256", Buffer.from(p), f, Buffer.from(s, "base64url"))) throw Error("OIDC id_token signature verification failed");
1868
1875
  return l;
1869
1876
  }
1870
- function Kt(e) {
1877
+ function Xt(e) {
1871
1878
  return JSON.parse(Buffer.from(e, "base64url").toString("utf8"));
1872
1879
  }
1873
- function qt(e, t) {
1880
+ function Zt(e, t) {
1874
1881
  return Array.isArray(e) ? e.includes(t) : e === t;
1875
1882
  }
1876
- function Jt(e, t, n) {
1883
+ function Qt(e, t, n) {
1877
1884
  return t && t !== n ? !1 : !Array.isArray(e) || e.length <= 1 || t === n;
1878
1885
  }
1879
- function Yt(e, t) {
1886
+ function $t(e, t) {
1880
1887
  return t.allowedSubject && e.sub === t.allowedSubject ? !0 : t.allowedEmail ? e.email_verified === !0 && e.email?.toLowerCase() === t.allowedEmail : !1;
1881
1888
  }
1882
1889
  function Y(e, t, n = {}) {
1883
1890
  let r = new URL(e);
1884
1891
  if (r.username || r.password) throw Error(`OIDC ${t} must not include credentials`);
1885
- if (r.protocol !== "https:" && !(n.allowLoopbackHttp && r.protocol === "http:" && Xt(r.hostname))) throw Error(`OIDC ${t} must use HTTPS`);
1892
+ if (r.protocol !== "https:" && !(n.allowLoopbackHttp && r.protocol === "http:" && en(r.hostname))) throw Error(`OIDC ${t} must use HTTPS`);
1886
1893
  }
1887
- function Xt(e) {
1894
+ function en(e) {
1888
1895
  let t = e.replace(/^\[(.*)]$/, "$1").toLowerCase();
1889
1896
  return t === "localhost" || t === "127.0.0.1" || t === "::1";
1890
1897
  }
@@ -1899,7 +1906,7 @@ function X(e, t) {
1899
1906
  }
1900
1907
  //#endregion
1901
1908
  //#region src/provider.ts
1902
- var Zt = class {
1909
+ var tn = class {
1903
1910
  #e;
1904
1911
  #t;
1905
1912
  #n;
@@ -1909,19 +1916,19 @@ var Zt = class {
1909
1916
  #o;
1910
1917
  #s;
1911
1918
  constructor(e) {
1912
- this.#e = e.clientsStore, this.#t = e.codeStore, this.#n = e.tokenStore, this.#r = e.refreshTokenStore ?? dt(), this.#i = e.publicMcpUrl, this.#a = new URL(e.publicMcpUrl).href, this.#o = e.oidc, this.#s = e.now ?? Date.now;
1919
+ this.#e = e.clientsStore, this.#t = e.codeStore, this.#n = e.tokenStore, this.#r = e.refreshTokenStore ?? pt(), this.#i = e.publicMcpUrl, this.#a = new URL(e.publicMcpUrl).href, this.#o = e.oidc, this.#s = e.now ?? Date.now;
1913
1920
  }
1914
1921
  get clientsStore() {
1915
1922
  return this.#e;
1916
1923
  }
1917
1924
  async authorize(e, t, n) {
1918
1925
  if (!this.#o) throw new A("OIDC is not configured");
1919
- let r = await Bt(Qt(e, t), this.#e, this.#o.pendingStore, this.#o.config, this.#i, this.#s());
1926
+ let r = await Wt(nn(e, t), this.#e, this.#o.pendingStore, this.#o.config, this.#i, this.#s());
1920
1927
  if (r.status === 302) {
1921
1928
  n.redirect(302, r.location);
1922
1929
  return;
1923
1930
  }
1924
- throw $t(r.body);
1931
+ throw rn(r.body);
1925
1932
  }
1926
1933
  async challengeForAuthorizationCode(e, t) {
1927
1934
  let n = this.#t.peekCode(t);
@@ -1937,7 +1944,7 @@ var Zt = class {
1937
1944
  if (o.clientId !== e.client_id) throw this.#t.consumeCode(t), new k("Code does not match client");
1938
1945
  if (r === void 0 || o.redirectUri !== r) throw this.#t.consumeCode(t), new k("Code does not match redirect_uri");
1939
1946
  if ((o.resource ?? null) !== (i?.href ?? null)) throw this.#t.consumeCode(t), new k("Code does not match resource");
1940
- let s = tn(o.scopes) ?? [], c = this.#r.issueGrant({
1947
+ let s = on(o.scopes) ?? [], c = this.#r.issueGrant({
1941
1948
  clientId: e.client_id,
1942
1949
  scopes: s,
1943
1950
  resource: o.resource
@@ -1955,10 +1962,10 @@ var Zt = class {
1955
1962
  }
1956
1963
  async exchangeRefreshToken(e, t, n, r) {
1957
1964
  let i = this.#s(), a = this.#r.rotateRefreshToken(e.client_id, t, {
1958
- scopes: tn(n),
1965
+ scopes: on(n),
1959
1966
  ...r ? { resource: r.href } : {}
1960
1967
  }, i);
1961
- if (!a.ok) throw a.reason === "refresh_token_replay" && a.grantId && this.#n.revokeTokensForGrant?.(a.grantId, i), new k(en(a.reason));
1968
+ if (!a.ok) throw a.reason === "refresh_token_replay" && a.grantId && this.#n.revokeTokensForGrant?.(a.grantId, i), new k(an(a.reason));
1962
1969
  let o = this.#n.issueToken(e.client_id, i, a.grant.resource, a.grant.grantId, a.grant.scopes);
1963
1970
  if (!o) throw new A("Too many active access tokens");
1964
1971
  return le.parse({
@@ -1990,11 +1997,11 @@ var Zt = class {
1990
1997
  r && this.#n.revokeTokensForGrant?.(r, n);
1991
1998
  }
1992
1999
  };
1993
- function Qt(e, t) {
2000
+ function nn(e, t) {
1994
2001
  let n = new URLSearchParams();
1995
2002
  return n.set("client_id", e.client_id), n.set("redirect_uri", t.redirectUri), n.set("response_type", "code"), n.set("code_challenge", t.codeChallenge), n.set("code_challenge_method", "S256"), t.state && n.set("state", t.state), t.scopes?.length && n.set("scope", t.scopes.join(" ")), t.resource && n.set("resource", t.resource.href), n;
1996
2003
  }
1997
- function $t(e) {
2004
+ function rn(e) {
1998
2005
  let t = e.error_description ?? e.error;
1999
2006
  switch (e.error) {
2000
2007
  case "temporarily_unavailable": return new A(t);
@@ -2005,7 +2012,7 @@ function $t(e) {
2005
2012
  default: return new oe(t);
2006
2013
  }
2007
2014
  }
2008
- function en(e) {
2015
+ function an(e) {
2009
2016
  switch (e) {
2010
2017
  case "expired_refresh_token": return "Refresh token has expired";
2011
2018
  case "revoked_refresh_token": return "Refresh token has been revoked";
@@ -2016,34 +2023,34 @@ function en(e) {
2016
2023
  default: return "Invalid refresh token";
2017
2024
  }
2018
2025
  }
2019
- function tn(e) {
2026
+ function on(e) {
2020
2027
  let t = e?.map((e) => e.trim()).filter(Boolean).map((e) => e === "memory:read_access" ? "memory:read" : e === "memory:write_access" ? "memory:write" : e);
2021
2028
  return t && t.length > 0 ? t : void 0;
2022
2029
  }
2023
2030
  //#endregion
2024
2031
  //#region src/http.ts
2025
- var nn = "127.0.0.1", rn = 38889, an = 80, on = new Set(["https://claude.ai"]), sn = "authorization,content-type,mcp-session-id", cn = "600", ln = 256, un = 900 * 1e3, dn = 600, fn = /^[a-zA-Z0-9.-]+$/, pn = new Set([
2032
+ var sn = "127.0.0.1", cn = 38889, ln = 80, un = new Set(["https://chatgpt.com", "https://claude.ai"]), dn = "authorization,content-type,mcp-session-id", fn = "600", pn = 256, mn = 900 * 1e3, hn = 600, gn = /^[a-zA-Z0-9.-]+$/, _n = new Set([
2026
2033
  "127.0.0.1",
2027
2034
  "::1",
2028
2035
  "localhost"
2029
2036
  ]);
2030
- function mn(e, t = !1) {
2037
+ function vn(e, t = !1) {
2031
2038
  let r = e?.trim() || "127.0.0.1";
2032
- if (r.includes("://") || r.includes("/") || r.includes("\\") || !(n(r) || r === "localhost" || fn.test(r))) throw Error(`Invalid MCP HTTP host: ${e}`);
2039
+ if (r.includes("://") || r.includes("/") || r.includes("\\") || !(n(r) || r === "localhost" || gn.test(r))) throw Error(`Invalid MCP HTTP host: ${e}`);
2033
2040
  if (!t && !Z(r)) throw Error(`Refusing unsafe MCP HTTP host ${r}; set CODEMEM_MCP_HTTP_UNSAFE_PUBLIC=1 to allow non-loopback binding`);
2034
2041
  return r;
2035
2042
  }
2036
2043
  function Z(e) {
2037
- return pn.has(Q(e));
2044
+ return _n.has(Q(e));
2038
2045
  }
2039
- function hn(e = process.env.CODEMEM_MCP_HTTP_UNSAFE_PUBLIC) {
2046
+ function yn(e = process.env.CODEMEM_MCP_HTTP_UNSAFE_PUBLIC) {
2040
2047
  return e === "1" || e?.toLowerCase() === "true" || e?.toLowerCase() === "yes";
2041
2048
  }
2042
- function gn(e, t) {
2043
- let n = yn(e);
2044
- return !n || !Z(n.host) ? !1 : n.port === null ? t === an : n.port === t;
2049
+ function bn(e, t) {
2050
+ let n = Cn(e);
2051
+ return !n || !Z(n.host) ? !1 : n.port === null ? t === ln : n.port === t;
2045
2052
  }
2046
- function _n(e, t) {
2053
+ function xn(e, t) {
2047
2054
  if (!e) return !0;
2048
2055
  try {
2049
2056
  let n = new URL(e), r = n.port ? Number(n.port) : n.protocol === "https:" ? 443 : 80;
@@ -2052,13 +2059,13 @@ function _n(e, t) {
2052
2059
  return !1;
2053
2060
  }
2054
2061
  }
2055
- function vn(e) {
2062
+ function Sn(e) {
2056
2063
  return e ? Z(e.replace(/^::ffff:/, "")) : !1;
2057
2064
  }
2058
2065
  function Q(e) {
2059
2066
  return e.replace(/^\[(.*)]$/, "$1").toLowerCase();
2060
2067
  }
2061
- function yn(e) {
2068
+ function Cn(e) {
2062
2069
  if (!e) return null;
2063
2070
  if (e.startsWith("[")) {
2064
2071
  let t = /^\[([^\]]+)]:(\d+)$/.exec(e);
@@ -2083,70 +2090,70 @@ function yn(e) {
2083
2090
  port: r
2084
2091
  } : null;
2085
2092
  }
2086
- function bn(e) {
2087
- if (e === void 0 || e === "") return rn;
2093
+ function wn(e) {
2094
+ if (e === void 0 || e === "") return cn;
2088
2095
  let t = typeof e == "number" ? e : Number(e);
2089
2096
  if (!Number.isInteger(t) || t < 0 || t > 65535) throw Error(`Invalid MCP HTTP port: ${e}`);
2090
2097
  return t;
2091
2098
  }
2092
- async function xn(n = {}) {
2093
- let r = mn(n.host ?? process.env.CODEMEM_MCP_HTTP_HOST, n.allowUnsafePublic ?? hn()), i = bn(n.port ?? process.env.CODEMEM_MCP_HTTP_PORT), c = n.publicUrl ?? process.env.CODEMEM_MCP_HTTP_PUBLIC_URL, p = c ? _t(c) : void 0, m = new a(n.dbPath ?? o()), h = n.oauthAccessTokenStore ? void 0 : ft(n.oauthStatePath), g = h ?? ct(), _ = h ?? lt(), v = n.oauthAccessTokenStore ?? h ?? ut(), y = zt(), b = Rt(), ee = p !== void 0 || y !== void 0, x = Ve(n.auditEmitter ?? We()), S = /* @__PURE__ */ new Set(), te = null, C = f();
2094
- C.disable("x-powered-by"), C.set("trust proxy", "loopback");
2095
- let w = t(C);
2099
+ async function Tn(n = {}) {
2100
+ let r = vn(n.host ?? process.env.CODEMEM_MCP_HTTP_HOST, n.allowUnsafePublic ?? yn()), i = wn(n.port ?? process.env.CODEMEM_MCP_HTTP_PORT), c = n.publicUrl ?? process.env.CODEMEM_MCP_HTTP_PUBLIC_URL, p = c ? yt(c) : void 0, m = new a(n.dbPath ?? o()), h = n.oauthAccessTokenStore ? void 0 : mt(n.oauthStatePath), g = h ?? ut(), _ = h ?? dt(), v = n.oauthAccessTokenStore ?? h ?? ft(), y = Ut(), b = Ht(), x = p !== void 0 || y !== void 0, S = Ve(n.auditEmitter ?? We()), C = /* @__PURE__ */ new Set(), ee = null, w = f();
2101
+ w.disable("x-powered-by"), w.set("trust proxy", "loopback");
2102
+ let T = t(w);
2096
2103
  await new Promise((e, t) => {
2097
- w.once("error", t), w.listen({
2104
+ T.once("error", t), T.listen({
2098
2105
  host: r,
2099
2106
  port: i
2100
2107
  }, () => {
2101
- w.off("error", t), e();
2108
+ T.off("error", t), e();
2102
2109
  });
2103
2110
  });
2104
- let T = p?.href ?? Mn(w, r), E = new URL(T), D = Nn(E, $(w)), ne = new Zt({
2111
+ let E = p?.href ?? In(T, r), D = new URL(E), te = Ln(D, $(T)), ne = new tn({
2105
2112
  clientsStore: g,
2106
2113
  codeStore: _,
2107
2114
  tokenStore: v,
2108
- publicMcpUrl: T,
2115
+ publicMcpUrl: E,
2109
2116
  ...h ? { refreshTokenStore: h } : {},
2110
2117
  ...y ? { oidc: {
2111
2118
  config: y,
2112
2119
  pendingStore: b
2113
2120
  } } : {}
2114
- }), re = l(E);
2115
- C.use(Re({
2116
- windowMs: un,
2117
- limit: dn,
2121
+ }), re = l(D);
2122
+ w.use(Re({
2123
+ windowMs: mn,
2124
+ limit: hn,
2118
2125
  standardHeaders: "draft-8",
2119
2126
  legacyHeaders: !1,
2120
2127
  ipv6Subnet: !1
2121
- })), C.use((e, t, n) => {
2122
- let r = $(w), i = Fn(e.path);
2128
+ })), w.use((e, t, n) => {
2129
+ let r = $(T), i = zn(e.path);
2123
2130
  if (i === "/mcp") {
2124
- if (Sn(e, r, p)) {
2125
- if (En(e, t, p), e.method === "OPTIONS") {
2131
+ if (En(e, r, p)) {
2132
+ if (An(e, t, p), e.method === "OPTIONS") {
2126
2133
  t.status(204).send("");
2127
2134
  return;
2128
2135
  }
2129
2136
  return n();
2130
2137
  }
2131
- On(e, i, p), t.status(403).type("text/plain").send("Forbidden");
2138
+ Mn(e, i, p), t.status(403).type("text/plain").send("Forbidden");
2132
2139
  return;
2133
2140
  }
2134
- if (Pn(i)) {
2135
- if (wn(e, r, p)) {
2136
- if (En(e, t, p), e.method === "OPTIONS") {
2141
+ if (Rn(i)) {
2142
+ if (On(e, r, p)) {
2143
+ if (An(e, t, p), e.method === "OPTIONS") {
2137
2144
  t.status(204).send("");
2138
2145
  return;
2139
2146
  }
2140
2147
  return n();
2141
2148
  }
2142
- On(e, i, p), t.status(403).type("text/plain").send("Forbidden");
2149
+ Mn(e, i, p), t.status(403).type("text/plain").send("Forbidden");
2143
2150
  return;
2144
2151
  }
2145
2152
  n();
2146
- }), C.use(In(x)), C.get("/oauth/callback", async (e, t) => {
2153
+ }), w.use(Bn(S)), w.get("/oauth/callback", async (e, t) => {
2147
2154
  let n = e.socket.remoteAddress ?? void 0;
2148
2155
  if (!y) {
2149
- x(L("oidc_callback", {
2156
+ S(L("oidc_callback", {
2150
2157
  outcome: "denied",
2151
2158
  reason: "oidc_not_configured",
2152
2159
  remoteAddress: n
@@ -2156,9 +2163,9 @@ async function xn(n = {}) {
2156
2163
  });
2157
2164
  return;
2158
2165
  }
2159
- let r = await Vt(new URLSearchParams(e.query), b, y, T);
2166
+ let r = await Gt(new URLSearchParams(e.query), b, y, E);
2160
2167
  if ("status" in r) {
2161
- x(L("oidc_callback", {
2168
+ S(L("oidc_callback", {
2162
2169
  outcome: "denied",
2163
2170
  reason: r.body.error,
2164
2171
  remoteAddress: n
@@ -2169,12 +2176,12 @@ async function xn(n = {}) {
2169
2176
  clientId: r.oauthParams.get("client_id") ?? "",
2170
2177
  redirectUri: r.oauthParams.get("redirect_uri") ?? "",
2171
2178
  codeChallenge: r.oauthParams.get("code_challenge") ?? "",
2172
- scopes: Gn(r.oauthParams.get("scope")),
2179
+ scopes: Yn(r.oauthParams.get("scope")),
2173
2180
  ...r.oauthParams.get("resource") ? { resource: r.oauthParams.get("resource") ?? void 0 } : {},
2174
2181
  expiresAt: Date.now() + 300 * 1e3
2175
2182
  });
2176
2183
  if (!a) {
2177
- x(L("oidc_callback", {
2184
+ S(L("oidc_callback", {
2178
2185
  outcome: "denied",
2179
2186
  reason: "temporarily_unavailable",
2180
2187
  clientId: i,
@@ -2188,99 +2195,99 @@ async function xn(n = {}) {
2188
2195
  let o = new URL(r.oauthParams.get("redirect_uri") ?? "");
2189
2196
  o.searchParams.set("code", a);
2190
2197
  let s = r.oauthParams.get("state");
2191
- s && o.searchParams.set("state", s), x(L("oidc_callback", {
2198
+ s && o.searchParams.set("state", s), S(L("oidc_callback", {
2192
2199
  outcome: "success",
2193
2200
  reason: "code_issued",
2194
2201
  clientId: i,
2195
2202
  remoteAddress: n
2196
2203
  })), t.redirect(302, o.href);
2197
- }), C.get("/.well-known/oauth-authorization-server", (e, t) => {
2198
- t.status(200).json(mt({
2199
- mcpUrl: T,
2204
+ }), w.get("/.well-known/oauth-authorization-server", (e, t) => {
2205
+ t.status(200).json(gt({
2206
+ mcpUrl: E,
2200
2207
  clientsStore: g
2201
2208
  }));
2202
- }), C.get("/.well-known/oauth-protected-resource/mcp", (e, t) => {
2203
- t.status(200).json(ht(T));
2204
- }), C.use(u({
2209
+ }), w.get("/.well-known/oauth-protected-resource/mcp", (e, t) => {
2210
+ t.status(200).json(_t(E));
2211
+ }), w.use(u({
2205
2212
  provider: ne,
2206
- issuerUrl: D,
2207
- baseUrl: D,
2208
- resourceServerUrl: E,
2213
+ issuerUrl: te,
2214
+ baseUrl: te,
2215
+ resourceServerUrl: D,
2209
2216
  resourceName: Ge,
2210
2217
  scopesSupported: R,
2211
2218
  serviceDocumentationUrl: new URL(z),
2212
2219
  clientRegistrationOptions: { clientSecretExpirySeconds: 0 }
2213
2220
  }));
2214
- let O = ee ? s({
2221
+ let O = x ? s({
2215
2222
  verifier: ne,
2216
2223
  resourceMetadataUrl: re
2217
- }) : (e, t, n) => n(), k = ee ? Un(x, v) : (e, t, n) => n();
2218
- return C.post("/mcp", k, O, async (t, n) => {
2219
- t.auth && x(L("bearer", {
2224
+ }) : (e, t, n) => n(), k = x ? qn(S, v) : (e, t, n) => n();
2225
+ return w.post("/mcp", k, O, async (t, n) => {
2226
+ t.auth && S(L("bearer", {
2220
2227
  outcome: "success",
2221
2228
  clientId: t.auth.clientId,
2222
2229
  remoteAddress: t.socket.remoteAddress ?? void 0
2223
2230
  }));
2224
2231
  let r = e(m), i = new d({ sessionIdGenerator: void 0 }), a = { mcpServer: r };
2225
- S.add(a);
2232
+ C.add(a);
2226
2233
  try {
2227
2234
  await r.connect(i), await i.handleRequest(t, n);
2228
2235
  } finally {
2229
- S.delete(a), await r.close();
2236
+ C.delete(a), await r.close();
2230
2237
  }
2231
- }), C.all("/mcp", (e, t) => {
2238
+ }), w.all("/mcp", (e, t) => {
2232
2239
  t.setHeader("Allow", "POST"), t.status(405).type("text/plain").send("Method not allowed");
2233
- }), C.use((e, t) => {
2240
+ }), w.use((e, t) => {
2234
2241
  t.status(404).type("text/plain").send("Not found");
2235
2242
  }), {
2236
- server: w,
2243
+ server: T,
2237
2244
  store: m,
2238
- url: `http://${jn(r)}:${$(w)}/mcp`,
2239
- close: () => (te ??= (async () => {
2240
- await Promise.allSettled([...S].map(({ mcpServer: e }) => e.close())), await new Promise((e, t) => {
2241
- w.close((n) => {
2245
+ url: `http://${Fn(r)}:${$(T)}/mcp`,
2246
+ close: () => (ee ??= (async () => {
2247
+ await Promise.allSettled([...C].map(({ mcpServer: e }) => e.close())), await new Promise((e, t) => {
2248
+ T.close((n) => {
2242
2249
  if (!n || n.code === "ERR_SERVER_NOT_RUNNING") {
2243
2250
  e();
2244
2251
  return;
2245
2252
  }
2246
2253
  t(n);
2247
- }), w.closeAllConnections();
2254
+ }), T.closeAllConnections();
2248
2255
  }), m.close();
2249
- })(), te)
2256
+ })(), ee)
2250
2257
  };
2251
2258
  }
2252
- function Sn(e, t, n) {
2253
- return Cn(e, t) ? !0 : n ? An(e.headers.host, n) && Tn(e.headers.origin, n) : !1;
2259
+ function En(e, t, n) {
2260
+ return Dn(e, t) ? !0 : n ? Pn(e.headers.host, n) && kn(e.headers.origin, n) : !1;
2254
2261
  }
2255
- function Cn(e, t) {
2256
- return vn(e.socket.remoteAddress) && gn(e.headers.host, t) && _n(e.headers.origin, t);
2262
+ function Dn(e, t) {
2263
+ return Sn(e.socket.remoteAddress) && bn(e.headers.host, t) && xn(e.headers.origin, t);
2257
2264
  }
2258
- function wn(e, t, n) {
2259
- return Cn(e, t) ? !0 : n ? An(e.headers.host, n) && Tn(e.headers.origin, n) : !1;
2265
+ function On(e, t, n) {
2266
+ return Dn(e, t) ? !0 : n ? Pn(e.headers.host, n) && kn(e.headers.origin, n) : !1;
2260
2267
  }
2261
- function Tn(e, t) {
2268
+ function kn(e, t) {
2262
2269
  if (!e) return !0;
2263
2270
  try {
2264
2271
  let n = new URL(e);
2265
- return n.origin === t.origin || on.has(n.origin);
2272
+ return n.origin === t.origin || un.has(n.origin);
2266
2273
  } catch {
2267
2274
  return !1;
2268
2275
  }
2269
2276
  }
2270
- function En(e, t, n) {
2277
+ function An(e, t, n) {
2271
2278
  if (!n) return;
2272
- let r = Dn(e.headers.origin, n);
2273
- r && (t.setHeader("Access-Control-Allow-Origin", r), t.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS"), t.setHeader("Access-Control-Allow-Headers", e.headers["access-control-request-headers"] ?? sn), t.setHeader("Access-Control-Max-Age", cn), t.setHeader("Vary", "Origin"));
2279
+ let r = jn(e.headers.origin, n);
2280
+ r && (t.setHeader("Access-Control-Allow-Origin", r), t.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS"), t.setHeader("Access-Control-Allow-Headers", e.headers["access-control-request-headers"] ?? dn), t.setHeader("Access-Control-Max-Age", fn), t.setHeader("Vary", "Origin"));
2274
2281
  }
2275
- function Dn(e, t) {
2282
+ function jn(e, t) {
2276
2283
  if (e) try {
2277
2284
  let n = new URL(e).origin;
2278
- if (n === t.origin || on.has(n)) return n;
2285
+ if (n === t.origin || un.has(n)) return n;
2279
2286
  } catch {
2280
2287
  return;
2281
2288
  }
2282
2289
  }
2283
- function On(e, t, n) {
2290
+ function Mn(e, t, n) {
2284
2291
  console.warn(JSON.stringify({
2285
2292
  source: "codemem-mcp-http-guard",
2286
2293
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -2288,50 +2295,50 @@ function On(e, t, n) {
2288
2295
  reason: "host_or_origin_mismatch",
2289
2296
  method: e.method,
2290
2297
  path: t,
2291
- host: kn(e.headers.host),
2292
- origin: kn(e.headers.origin),
2298
+ host: Nn(e.headers.host),
2299
+ origin: Nn(e.headers.origin),
2293
2300
  expectedOrigin: n?.origin,
2294
2301
  remoteAddress: e.socket.remoteAddress ?? void 0
2295
2302
  }));
2296
2303
  }
2297
- function kn(e) {
2298
- return !e || e.length <= ln ? e : `${e.slice(0, ln)}…`;
2304
+ function Nn(e) {
2305
+ return !e || e.length <= pn ? e : `${e.slice(0, pn)}…`;
2299
2306
  }
2300
- function An(e, t) {
2301
- let n = yn(e);
2307
+ function Pn(e, t) {
2308
+ let n = Cn(e);
2302
2309
  if (!n) return !1;
2303
2310
  let r = t.port ? Number(t.port) : t.protocol === "https:" ? 443 : 80, i = t.protocol === "https:" ? 443 : 80, a = n.port ?? i;
2304
2311
  return Q(n.host) === Q(t.hostname) && a === r;
2305
2312
  }
2306
2313
  function $(e) {
2307
2314
  let t = e.address();
2308
- return !t || typeof t == "string" ? rn : t.port;
2315
+ return !t || typeof t == "string" ? cn : t.port;
2309
2316
  }
2310
- function jn(e) {
2317
+ function Fn(e) {
2311
2318
  return n(e) === 6 ? `[${e}]` : e;
2312
2319
  }
2313
- function Mn(e, t) {
2314
- return `http://${jn(t)}:${$(e)}/mcp`;
2320
+ function In(e, t) {
2321
+ return `http://${Fn(t)}:${$(e)}/mcp`;
2315
2322
  }
2316
- function Nn(e, t) {
2323
+ function Ln(e, t) {
2317
2324
  return e.protocol === "https:" || Z(e.hostname) && Q(e.hostname) !== "::1" ? new URL(e.origin) : new URL(`http://localhost:${t}/`);
2318
2325
  }
2319
- function Pn(e) {
2326
+ function Rn(e) {
2320
2327
  return e === "/register" || e === "/authorize" || e === "/token" || e === "/revoke" || e === "/oauth/callback" || e === "/.well-known/oauth-authorization-server" || e === "/.well-known/oauth-protected-resource/mcp";
2321
2328
  }
2322
- function Fn(e) {
2329
+ function zn(e) {
2323
2330
  return e.length > 1 ? e.replace(/\/+$/, "") : e;
2324
2331
  }
2325
- function In(e) {
2332
+ function Bn(e) {
2326
2333
  return (t, n, r) => {
2327
2334
  let i = t.path;
2328
- if (!Ln(i)) return r();
2335
+ if (!Vn(i)) return r();
2329
2336
  let a, o = n.json.bind(n);
2330
2337
  n.json = ((e) => (a = e, o(e))), n.on("finish", () => {
2331
2338
  if (i === "/oauth/callback") return;
2332
- let r = Rn(i, t);
2339
+ let r = Hn(i, t);
2333
2340
  if (!r) return;
2334
- let o = Bn(n, a), s = Hn(t, a);
2341
+ let o = Wn(n, a), s = Kn(t, a);
2335
2342
  e(L(r, {
2336
2343
  outcome: o ? "denied" : "success",
2337
2344
  ...o ? { reason: o } : {},
@@ -2341,17 +2348,17 @@ function In(e) {
2341
2348
  }), r();
2342
2349
  };
2343
2350
  }
2344
- function Ln(e) {
2345
- return zn(e) !== null;
2351
+ function Vn(e) {
2352
+ return Un(e) !== null;
2346
2353
  }
2347
- function Rn(e, t) {
2348
- return e === "/token" && t.body?.grant_type === "refresh_token" ? "refresh" : zn(e);
2354
+ function Hn(e, t) {
2355
+ return e === "/token" && t.body?.grant_type === "refresh_token" ? "refresh" : Un(e);
2349
2356
  }
2350
- function zn(e) {
2357
+ function Un(e) {
2351
2358
  return e === "/register" ? "registration" : e === "/authorize" ? "authorize" : e === "/token" ? "token" : e === "/revoke" ? "revocation" : null;
2352
2359
  }
2353
- function Bn(e, t) {
2354
- let n = Vn(t);
2360
+ function Wn(e, t) {
2361
+ let n = Gn(t);
2355
2362
  if (n) return n;
2356
2363
  let r = e.getHeader("location");
2357
2364
  if (typeof r == "string") try {
@@ -2360,15 +2367,15 @@ function Bn(e, t) {
2360
2367
  return;
2361
2368
  }
2362
2369
  }
2363
- function Vn(e) {
2370
+ function Gn(e) {
2364
2371
  if (typeof e == "object" && e && "error" in e && typeof e.error == "string") return e.error;
2365
2372
  }
2366
- function Hn(e, t) {
2373
+ function Kn(e, t) {
2367
2374
  return typeof t == "object" && t && "client_id" in t && typeof t.client_id == "string" ? t.client_id : (typeof e.body?.client_id == "string" ? e.body.client_id : void 0) || (typeof e.query.client_id == "string" ? e.query.client_id : void 0);
2368
2375
  }
2369
- function Un(e, t) {
2376
+ function qn(e, t) {
2370
2377
  return (n, r, i) => {
2371
- let a = Wn(n.headers.authorization, t);
2378
+ let a = Jn(n.headers.authorization, t);
2372
2379
  a && e(L("bearer", {
2373
2380
  outcome: "denied",
2374
2381
  reason: a,
@@ -2376,22 +2383,22 @@ function Un(e, t) {
2376
2383
  })), i();
2377
2384
  };
2378
2385
  }
2379
- function Wn(e, t) {
2386
+ function Jn(e, t) {
2380
2387
  if (!e) return "missing_authorization_header";
2381
2388
  let [n, r, i] = e.trim().split(/\s+/);
2382
2389
  if (!n || !r || i || n.toLowerCase() !== "bearer") return "malformed_authorization_header";
2383
2390
  let a = t.verifyToken(r);
2384
2391
  return a.ok ? null : a.reason;
2385
2392
  }
2386
- function Gn(e) {
2393
+ function Yn(e) {
2387
2394
  return e?.split(/\s+/).map((e) => e.trim()).filter(Boolean) ?? [];
2388
2395
  }
2389
- function Kn() {
2396
+ function Xn() {
2390
2397
  let e = process.argv[1];
2391
2398
  return e ? import.meta.url === i(e).href : !1;
2392
2399
  }
2393
- async function qn() {
2394
- let e = await xn();
2400
+ async function Zn() {
2401
+ let e = await Tn();
2395
2402
  console.error(`codemem MCP HTTP server listening at ${e.url}`);
2396
2403
  let t = async () => {
2397
2404
  try {
@@ -2401,10 +2408,10 @@ async function qn() {
2401
2408
  };
2402
2409
  process.on("SIGINT", t), process.on("SIGTERM", t);
2403
2410
  }
2404
- Kn() && qn().catch((e) => {
2411
+ Xn() && Zn().catch((e) => {
2405
2412
  console.error("codemem MCP HTTP server failed to start:", e), process.exit(1);
2406
2413
  });
2407
2414
  //#endregion
2408
- export { nn as DEFAULT_MCP_HTTP_HOST, rn as DEFAULT_MCP_HTTP_PORT, gn as isAllowedMcpHttpRequestHost, _n as isAllowedMcpHttpRequestOrigin, vn as isAllowedMcpHttpRequestRemoteAddress, Z as isLoopbackHost, hn as isUnsafePublicBindAllowed, bn as parseMcpHttpPort, xn as startCodememMcpHttpServer, mn as validateMcpHttpHost };
2415
+ export { sn as DEFAULT_MCP_HTTP_HOST, cn as DEFAULT_MCP_HTTP_PORT, bn as isAllowedMcpHttpRequestHost, xn as isAllowedMcpHttpRequestOrigin, Sn as isAllowedMcpHttpRequestRemoteAddress, Z as isLoopbackHost, yn as isUnsafePublicBindAllowed, wn as parseMcpHttpPort, Tn as startCodememMcpHttpServer, vn as validateMcpHttpHost };
2409
2416
 
2410
2417
  //# sourceMappingURL=http.js.map