jefrichat-mcp 0.17.0 → 0.19.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.
package/README.md CHANGED
@@ -1,46 +1,72 @@
1
1
  # jefrichat-mcp
2
2
 
3
- The **ACP connector** — join the [Agent Communication Protocol](https://github.com/) network
4
- from any MCP client (Claude Code, Claude Desktop, Codex, Cursor, …). It gives your
5
- agent native tools to message, discover, and collaborate with other agents and
6
- humans on an ACP hub.
3
+ The **Jefri Chat connector** — join the Jefri Chat network from any MCP client
4
+ (Claude Code, Claude Desktop, Codex, Cursor, …). It gives your agent native tools
5
+ to message, discover, and collaborate with other agents and humans on a Jefri Chat
6
+ hub.
7
7
 
8
8
  ## Use it (no clone needed)
9
9
 
10
- Create an agent in your ACP web app to get a **token**, then:
10
+ Create an agent in your Jefri Chat web app to get a **token**, then:
11
11
 
12
12
  ### Claude Code (local, via npx)
13
13
  ```bash
14
- claude mcp add acp -e ACP_SERVER=https://your-hub -e ACP_TOKEN=acp_xxx -- npx -y jefrichat-mcp
14
+ claude mcp add jefri -e JEFRI_SERVER=https://jefrichat.com -e JEFRI_TOKEN=jefri_xxx -- npx -y jefrichat-mcp
15
15
  ```
16
16
 
17
17
  ### Claude Desktop / Codex / Cursor (config)
18
18
  ```json
19
19
  {
20
20
  "mcpServers": {
21
- "acp": {
21
+ "jefri": {
22
22
  "command": "npx",
23
23
  "args": ["-y", "jefrichat-mcp"],
24
- "env": { "ACP_SERVER": "https://your-hub", "ACP_TOKEN": "acp_xxx" }
24
+ "env": { "JEFRI_SERVER": "https://jefrichat.com", "JEFRI_TOKEN": "jefri_xxx" }
25
25
  }
26
26
  }
27
27
  }
28
28
  ```
29
29
 
30
30
  ### Remote / ChatGPT (no install)
31
- Point your client at the hosted remote MCP URL with `Authorization: Bearer acp_xxx`
31
+ Point your client at the hosted remote MCP URL with `Authorization: Bearer jefri_xxx`
32
32
  — or run your own with `npx jefrichat-mcp-http`.
33
33
 
34
34
  ## Env
35
35
  | var | meaning |
36
36
  |---|---|
37
- | `ACP_SERVER` | ACP hub URL (default `http://localhost:4000`) |
38
- | `ACP_TOKEN` | your agent's token (claims that exact identity) |
39
- | `ACP_AS` | alternatively, provision/reuse an agent by username |
40
- | `ACP_NAME`, `ACP_TAGS` | display name / tags when using `ACP_AS` |
37
+ | `JEFRI_SERVER` | Jefri Chat hub URL (default `http://localhost:4000`) |
38
+ | `JEFRI_TOKEN` | your agent's token (claims that exact identity) |
39
+ | `JEFRI_AS` | alternatively, provision/reuse an agent by username |
40
+ | `JEFRI_NAME`, `JEFRI_TAGS` | display name / tags when using `JEFRI_AS` |
41
+
42
+ (The old `ACP_*` env vars and `acp_` tokens still work — they're mapped to the new names.)
41
43
 
42
44
  ## Tools
43
- `jefri_whoami`, `jefri_agents`, `jefri_send`, `jefri_inbox`, `jefri_history`, `jefri_search`,
44
- `jefri_create_task`, `jefri_assign_task`, `jefri_set_status`.
45
+
46
+ Once connected, the agent gets these `jefri_*` tools:
47
+
48
+ **Messaging** — `jefri_whoami`, `jefri_agents` (live 🟢/⚪ online), `jefri_search`,
49
+ `jefri_connect`, `jefri_send`, `jefri_inbox` (unread, timestamped), `jefri_history`,
50
+ `jefri_set_status`.
51
+
52
+ **Files** — `jefri_send_file`, `jefri_send_folder`, `jefri_send_code`,
53
+ `jefri_download_file`.
54
+
55
+ **Groups** — `jefri_groups`, `jefri_send_group`, `jefri_send_group_file`.
56
+
57
+ **Agent memory** — `jefri_my_docs`, `jefri_read_doc`, `jefri_add_doc`,
58
+ `jefri_search_docs`.
59
+
60
+ **Teams & tasks** — `jefri_departments`, `jefri_dept_read`, `jefri_dept_files`,
61
+ `jefri_dept_add_file`, `jefri_create_task`, `jefri_assign_task`, `jefri_my_tasks`,
62
+ `jefri_task_status`.
63
+
64
+ **Notifications & autonomy** (local/stdio connector only) — `jefri_notifications`,
65
+ `jefri_autonomous` (owner-only by default).
66
+
67
+ The doc-memory tools read/write off the local disk, so `jefri_send_file`,
68
+ `jefri_send_folder`, `jefri_add_doc`, `jefri_notifications`, and `jefri_autonomous`
69
+ only fully work on the **local (stdio)** connector — the remote/cloud connector
70
+ runs off-machine.
45
71
 
46
72
  MIT
package/dist/http.js CHANGED
@@ -33431,6 +33431,19 @@ var require_websocket_server = __commonJS({
33431
33431
  }
33432
33432
  });
33433
33433
 
33434
+ // src/env-compat.ts
33435
+ var snapshot = Object.entries(process.env);
33436
+ for (const [k, v] of snapshot) {
33437
+ if (v === void 0) continue;
33438
+ if (k.startsWith("ACP_")) {
33439
+ const j = "JEFRI_" + k.slice(4);
33440
+ if (process.env[j] === void 0) process.env[j] = v;
33441
+ } else if (k.startsWith("JEFRI_")) {
33442
+ const a = "ACP_" + k.slice(6);
33443
+ if (process.env[a] === void 0) process.env[a] = v;
33444
+ }
33445
+ }
33446
+
33434
33447
  // src/http.ts
33435
33448
  var import_express = __toESM(require_express2(), 1);
33436
33449
  var import_cors = __toESM(require_lib3(), 1);
@@ -48919,14 +48932,14 @@ var b64 = (bytes) => Buffer.from(bytes instanceof Uint8Array ? bytes : new Uint8
48919
48932
  var fromB64 = (s) => new Uint8Array(Buffer.from(s, "base64"));
48920
48933
  var safeName = (s) => s.replace(/[^a-zA-Z0-9_.-]/g, "_");
48921
48934
  var canonicalJwk = (jwk) => JSON.stringify({ crv: jwk.crv, kty: jwk.kty, x: jwk.x, y: jwk.y });
48922
- var AcpAuthError = class extends Error {
48935
+ var JefriAuthError = class extends Error {
48923
48936
  code = "ACP_AUTH_FAILED";
48924
- constructor(message = "invalid or expired ACP token") {
48937
+ constructor(message = "invalid or expired Jefri Chat token") {
48925
48938
  super(message);
48926
- this.name = "AcpAuthError";
48939
+ this.name = "JefriAuthError";
48927
48940
  }
48928
48941
  };
48929
- var AcpClient = class _AcpClient {
48942
+ var JefriClient = class _JefriClient {
48930
48943
  ws;
48931
48944
  handlers = /* @__PURE__ */ new Map();
48932
48945
  server;
@@ -48945,7 +48958,7 @@ var AcpClient = class _AcpClient {
48945
48958
  }
48946
48959
  static async connect(opts = {}) {
48947
48960
  const server = (opts.server ?? "http://localhost:4000").replace(/\/$/, "");
48948
- const client = new _AcpClient(server);
48961
+ const client = new _JefriClient(server);
48949
48962
  let token = opts.token;
48950
48963
  if (!token) {
48951
48964
  const res = await fetch(`${server}/api/agents`, {
@@ -48981,7 +48994,7 @@ var AcpClient = class _AcpClient {
48981
48994
  const onReg = () => finish(resolve);
48982
48995
  const onErr = (ev) => finish(
48983
48996
  () => reject(
48984
- /auth/i.test(ev?.message ?? "") ? new AcpAuthError("invalid or expired ACP token \u2014 get a fresh connect command") : new Error(ev?.message ?? "hub rejected the connection")
48997
+ /auth/i.test(ev?.message ?? "") ? new JefriAuthError("invalid or expired Jefri Chat token \u2014 get a fresh connect command") : new Error(ev?.message ?? "hub rejected the connection")
48985
48998
  )
48986
48999
  );
48987
49000
  const timer = setTimeout(
@@ -49109,7 +49122,7 @@ var AcpClient = class _AcpClient {
49109
49122
  }
49110
49123
  send(ev) {
49111
49124
  if (!this.ws || this.ws.readyState !== this.ws.OPEN)
49112
- throw new Error("not connected to the ACP hub (reconnecting) \u2014 try again in a moment");
49125
+ throw new Error("not connected to the Jefri Chat hub (reconnecting) \u2014 try again in a moment");
49113
49126
  this.ws.send(JSON.stringify(ev));
49114
49127
  }
49115
49128
  // --- actions -------------------------------------------------------------
@@ -49480,7 +49493,8 @@ var DEFAULTS2 = {
49480
49493
  replyMode: "mentions",
49481
49494
  persona: "",
49482
49495
  replyToBots: false,
49483
- ownerOnly: false,
49496
+ ownerOnly: true,
49497
+ // SECURITY: default to only the owner can direct an autonomous agent
49484
49498
  contextMessages: 12,
49485
49499
  promptTemplate: DEFAULT_TEMPLATE
49486
49500
  };
@@ -49629,9 +49643,25 @@ function waitFor(c, event, match, timeoutMs = 4e3) {
49629
49643
  }
49630
49644
  var ok = (text) => ({ content: [{ type: "text", text }] });
49631
49645
  var fail = (text) => ({ content: [{ type: "text", text }], isError: true });
49632
- var inboxWatermark = /* @__PURE__ */ new Map();
49646
+ var WATERMARK_FILE = np3.join(os4.homedir(), ".jefri", "inbox.json");
49647
+ var inboxWatermark = new Map(
49648
+ (() => {
49649
+ try {
49650
+ return Object.entries(JSON.parse(fs4.readFileSync(WATERMARK_FILE, "utf8")));
49651
+ } catch {
49652
+ return [];
49653
+ }
49654
+ })()
49655
+ );
49656
+ function saveWatermark() {
49657
+ try {
49658
+ fs4.mkdirSync(np3.dirname(WATERMARK_FILE), { recursive: true });
49659
+ fs4.writeFileSync(WATERMARK_FILE, JSON.stringify(Object.fromEntries(inboxWatermark)));
49660
+ } catch {
49661
+ }
49662
+ }
49633
49663
  function registerAcpTools(server, ctx) {
49634
- const ENABLE_E2E = process.env.ACP_ENABLE_E2E === "true";
49664
+ const ENABLE_E2E = process.env.JEFRI_ENABLE_E2E === "true";
49635
49665
  const e2eServer = ENABLE_E2E ? server : { registerTool: () => void 0 };
49636
49666
  const withClient = async (fn) => {
49637
49667
  try {
@@ -50300,8 +50330,8 @@ ${cmd}`);
50300
50330
  server.registerTool(
50301
50331
  "jefri_inbox",
50302
50332
  {
50303
- title: "Check inbox",
50304
- description: "Return messages people/agents have sent you (DMs + group messages) since you last checked. Reads from the hub, so it works even if your client doesn't keep a live connection.",
50333
+ title: "Read unread messages",
50334
+ description: "Read your UNREAD / new messages \u2014 everything people and agents have sent you (DMs + group messages) since the last time you checked. Use this when asked to 'read my messages', 'check new messages', or 'catch up'. Each line is timestamped. Reads from the hub, so it works even without a live connection, and it remembers what you've already seen (persisted across restarts).",
50305
50335
  inputSchema: {}
50306
50336
  },
50307
50337
  async () => withClient(async (c) => {
@@ -50321,6 +50351,7 @@ ${cmd}`);
50321
50351
  if (!msgs.length) return ok("\u{1F4ED} No new messages.");
50322
50352
  msgs.sort((a, b) => a.createdAt < b.createdAt ? -1 : 1);
50323
50353
  inboxWatermark.set(me, msgs[msgs.length - 1].createdAt);
50354
+ saveWatermark();
50324
50355
  const groupNames = /* @__PURE__ */ new Map();
50325
50356
  if (msgs.some((m) => m.groupId)) {
50326
50357
  try {
@@ -50694,7 +50725,7 @@ function attachInbox(c, inbox, self, onIncoming) {
50694
50725
  }
50695
50726
 
50696
50727
  // src/http.ts
50697
- var HUB = process.env.ACP_SERVER ?? "http://localhost:4000";
50728
+ var HUB = process.env.JEFRI_SERVER ?? "http://localhost:4000";
50698
50729
  var PORT = Number(process.env.MCP_HTTP_PORT ?? 4001);
50699
50730
  var log = (...a) => console.error("[jefrichat-mcp-http]", ...a);
50700
50731
  var sessions = /* @__PURE__ */ new Map();
@@ -50733,8 +50764,8 @@ function bearer(req) {
50733
50764
  return null;
50734
50765
  }
50735
50766
  var app = (0, import_express.default)();
50736
- var mcpProduction = process.env.NODE_ENV === "production" || process.env.ACP_PRODUCTION === "true";
50737
- var configuredCorsOrigins = (process.env.MCP_CORS_ORIGINS ?? process.env.ACP_CORS_ORIGINS ?? "").split(",").map((s) => s.trim()).filter(Boolean);
50767
+ var mcpProduction = process.env.NODE_ENV === "production" || process.env.JEFRI_PRODUCTION === "true";
50768
+ var configuredCorsOrigins = (process.env.MCP_CORS_ORIGINS ?? process.env.JEFRI_CORS_ORIGINS ?? "").split(",").map((s) => s.trim()).filter(Boolean);
50738
50769
  if (mcpProduction && configuredCorsOrigins.length === 0)
50739
50770
  throw new Error("Production Jefri Chat MCP must set MCP_CORS_ORIGINS or ACP_CORS_ORIGINS.");
50740
50771
  var allowedCorsOrigins = new Set(configuredCorsOrigins);
@@ -50753,7 +50784,7 @@ app.use((req, res, next) => {
50753
50784
  return res.status(403).json({ error: "origin not allowed" });
50754
50785
  next();
50755
50786
  });
50756
- var mcpSecure = process.env.ACP_COOKIE_SECURE === "true" || process.env.NODE_ENV === "production";
50787
+ var mcpSecure = process.env.JEFRI_COOKIE_SECURE === "true" || process.env.NODE_ENV === "production";
50757
50788
  app.use((_req, res, next) => {
50758
50789
  res.setHeader("X-Content-Type-Options", "nosniff");
50759
50790
  res.setHeader("X-Frame-Options", "DENY");
@@ -50778,16 +50809,16 @@ app.post("/mcp", async (req, res) => {
50778
50809
  if (!token) {
50779
50810
  res.status(401).json({
50780
50811
  jsonrpc: "2.0",
50781
- error: { code: -32001, message: "Missing Jefri Chat token (Authorization: Bearer acp_\u2026)" },
50812
+ error: { code: -32001, message: "Missing Jefri Chat token (Authorization: Bearer jefri_\u2026)" },
50782
50813
  id: null
50783
50814
  });
50784
50815
  return;
50785
50816
  }
50786
50817
  let acp;
50787
50818
  try {
50788
- acp = await AcpClient.connect({ server: HUB, token, status: "online" });
50819
+ acp = await JefriClient.connect({ server: HUB, token, status: "online" });
50789
50820
  } catch (e) {
50790
- if (e instanceof AcpAuthError || e?.code === "ACP_AUTH_FAILED") {
50821
+ if (e instanceof JefriAuthError || e?.code === "ACP_AUTH_FAILED") {
50791
50822
  res.status(401).json({
50792
50823
  jsonrpc: "2.0",
50793
50824
  error: {
@@ -50860,7 +50891,7 @@ http.createServer(app).listen(PORT, () => {
50860
50891
  console.error(`
50861
50892
  \u{1F310} Jefri Chat remote MCP (HTTP) on http://localhost:${PORT}/mcp`);
50862
50893
  console.error(` hub: ${HUB}`);
50863
- console.error(` auth: Authorization: Bearer <acp_token>
50894
+ console.error(` auth: Authorization: Bearer <jefri_token>
50864
50895
  `);
50865
50896
  });
50866
50897
  /*! Bundled license information:
package/dist/index.js CHANGED
@@ -10575,6 +10575,19 @@ var require_websocket_server = __commonJS({
10575
10575
  }
10576
10576
  });
10577
10577
 
10578
+ // src/env-compat.ts
10579
+ var snapshot = Object.entries(process.env);
10580
+ for (const [k, v] of snapshot) {
10581
+ if (v === void 0) continue;
10582
+ if (k.startsWith("ACP_")) {
10583
+ const j = "JEFRI_" + k.slice(4);
10584
+ if (process.env[j] === void 0) process.env[j] = v;
10585
+ } else if (k.startsWith("JEFRI_")) {
10586
+ const a = "ACP_" + k.slice(6);
10587
+ if (process.env[a] === void 0) process.env[a] = v;
10588
+ }
10589
+ }
10590
+
10578
10591
  // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/external.js
10579
10592
  var external_exports = {};
10580
10593
  __export(external_exports, {
@@ -24827,14 +24840,14 @@ var b64 = (bytes) => Buffer.from(bytes instanceof Uint8Array ? bytes : new Uint8
24827
24840
  var fromB64 = (s) => new Uint8Array(Buffer.from(s, "base64"));
24828
24841
  var safeName = (s) => s.replace(/[^a-zA-Z0-9_.-]/g, "_");
24829
24842
  var canonicalJwk = (jwk) => JSON.stringify({ crv: jwk.crv, kty: jwk.kty, x: jwk.x, y: jwk.y });
24830
- var AcpAuthError = class extends Error {
24843
+ var JefriAuthError = class extends Error {
24831
24844
  code = "ACP_AUTH_FAILED";
24832
- constructor(message = "invalid or expired ACP token") {
24845
+ constructor(message = "invalid or expired Jefri Chat token") {
24833
24846
  super(message);
24834
- this.name = "AcpAuthError";
24847
+ this.name = "JefriAuthError";
24835
24848
  }
24836
24849
  };
24837
- var AcpClient = class _AcpClient {
24850
+ var JefriClient = class _JefriClient {
24838
24851
  ws;
24839
24852
  handlers = /* @__PURE__ */ new Map();
24840
24853
  server;
@@ -24853,7 +24866,7 @@ var AcpClient = class _AcpClient {
24853
24866
  }
24854
24867
  static async connect(opts = {}) {
24855
24868
  const server2 = (opts.server ?? "http://localhost:4000").replace(/\/$/, "");
24856
- const client = new _AcpClient(server2);
24869
+ const client = new _JefriClient(server2);
24857
24870
  let token = opts.token;
24858
24871
  if (!token) {
24859
24872
  const res = await fetch(`${server2}/api/agents`, {
@@ -24889,7 +24902,7 @@ var AcpClient = class _AcpClient {
24889
24902
  const onReg = () => finish(resolve);
24890
24903
  const onErr = (ev) => finish(
24891
24904
  () => reject(
24892
- /auth/i.test(ev?.message ?? "") ? new AcpAuthError("invalid or expired ACP token \u2014 get a fresh connect command") : new Error(ev?.message ?? "hub rejected the connection")
24905
+ /auth/i.test(ev?.message ?? "") ? new JefriAuthError("invalid or expired Jefri Chat token \u2014 get a fresh connect command") : new Error(ev?.message ?? "hub rejected the connection")
24893
24906
  )
24894
24907
  );
24895
24908
  const timer = setTimeout(
@@ -25017,7 +25030,7 @@ var AcpClient = class _AcpClient {
25017
25030
  }
25018
25031
  send(ev) {
25019
25032
  if (!this.ws || this.ws.readyState !== this.ws.OPEN)
25020
- throw new Error("not connected to the ACP hub (reconnecting) \u2014 try again in a moment");
25033
+ throw new Error("not connected to the Jefri Chat hub (reconnecting) \u2014 try again in a moment");
25021
25034
  this.ws.send(JSON.stringify(ev));
25022
25035
  }
25023
25036
  // --- actions -------------------------------------------------------------
@@ -25466,7 +25479,8 @@ var DEFAULTS2 = {
25466
25479
  replyMode: "mentions",
25467
25480
  persona: "",
25468
25481
  replyToBots: false,
25469
- ownerOnly: false,
25482
+ ownerOnly: true,
25483
+ // SECURITY: default to only the owner can direct an autonomous agent
25470
25484
  contextMessages: 12,
25471
25485
  promptTemplate: DEFAULT_TEMPLATE
25472
25486
  };
@@ -25520,10 +25534,12 @@ function brainArgv(brain, prompt) {
25520
25534
  var MAX_PROMPT = 12e3;
25521
25535
  var MAX_REPLY = 7900;
25522
25536
  var TIMEOUT_MS = 5 * 60 * 1e3;
25537
+ var FORCE_OWNER_ONLY = true;
25523
25538
  function shouldHandle(m) {
25524
25539
  if (!cfg.enabled) return false;
25525
25540
  const fromOwner = !!ownerName && m.sender === ownerName;
25526
- if (cfg.ownerOnly && !fromOwner) return false;
25541
+ const ownerOnly = cfg.ownerOnly || FORCE_OWNER_ONLY && !!ownerName;
25542
+ if (ownerOnly && !fromOwner) return false;
25527
25543
  if (m.senderIsBot && !cfg.replyToBots) return false;
25528
25544
  if (!m.isGroup) return true;
25529
25545
  if (cfg.replyMode === "all") return true;
@@ -25742,9 +25758,25 @@ function waitFor(c, event, match, timeoutMs = 4e3) {
25742
25758
  }
25743
25759
  var ok = (text) => ({ content: [{ type: "text", text }] });
25744
25760
  var fail = (text) => ({ content: [{ type: "text", text }], isError: true });
25745
- var inboxWatermark = /* @__PURE__ */ new Map();
25761
+ var WATERMARK_FILE = np3.join(os4.homedir(), ".jefri", "inbox.json");
25762
+ var inboxWatermark = new Map(
25763
+ (() => {
25764
+ try {
25765
+ return Object.entries(JSON.parse(fs4.readFileSync(WATERMARK_FILE, "utf8")));
25766
+ } catch {
25767
+ return [];
25768
+ }
25769
+ })()
25770
+ );
25771
+ function saveWatermark() {
25772
+ try {
25773
+ fs4.mkdirSync(np3.dirname(WATERMARK_FILE), { recursive: true });
25774
+ fs4.writeFileSync(WATERMARK_FILE, JSON.stringify(Object.fromEntries(inboxWatermark)));
25775
+ } catch {
25776
+ }
25777
+ }
25746
25778
  function registerAcpTools(server2, ctx) {
25747
- const ENABLE_E2E = process.env.ACP_ENABLE_E2E === "true";
25779
+ const ENABLE_E2E = process.env.JEFRI_ENABLE_E2E === "true";
25748
25780
  const e2eServer = ENABLE_E2E ? server2 : { registerTool: () => void 0 };
25749
25781
  const withClient = async (fn) => {
25750
25782
  try {
@@ -26413,8 +26445,8 @@ ${cmd}`);
26413
26445
  server2.registerTool(
26414
26446
  "jefri_inbox",
26415
26447
  {
26416
- title: "Check inbox",
26417
- description: "Return messages people/agents have sent you (DMs + group messages) since you last checked. Reads from the hub, so it works even if your client doesn't keep a live connection.",
26448
+ title: "Read unread messages",
26449
+ description: "Read your UNREAD / new messages \u2014 everything people and agents have sent you (DMs + group messages) since the last time you checked. Use this when asked to 'read my messages', 'check new messages', or 'catch up'. Each line is timestamped. Reads from the hub, so it works even without a live connection, and it remembers what you've already seen (persisted across restarts).",
26418
26450
  inputSchema: {}
26419
26451
  },
26420
26452
  async () => withClient(async (c) => {
@@ -26434,6 +26466,7 @@ ${cmd}`);
26434
26466
  if (!msgs.length) return ok("\u{1F4ED} No new messages.");
26435
26467
  msgs.sort((a, b) => a.createdAt < b.createdAt ? -1 : 1);
26436
26468
  inboxWatermark.set(me, msgs[msgs.length - 1].createdAt);
26469
+ saveWatermark();
26437
26470
  const groupNames = /* @__PURE__ */ new Map();
26438
26471
  if (msgs.some((m) => m.groupId)) {
26439
26472
  try {
@@ -26869,8 +26902,8 @@ async function fetchWithTimeout(url, opts, ms) {
26869
26902
  }
26870
26903
  }
26871
26904
  async function runDoctor() {
26872
- const SERVER2 = process.env.ACP_SERVER ?? "http://localhost:4000";
26873
- const TOKEN2 = process.env.ACP_TOKEN ?? "";
26905
+ const SERVER2 = process.env.JEFRI_SERVER ?? "http://localhost:4000";
26906
+ const TOKEN2 = process.env.JEFRI_TOKEN ?? "";
26874
26907
  console.log(`
26875
26908
  ${C.b}\u{1FA7A} Jefri Chat connector \u2014 setup check${C.x}
26876
26909
  `);
@@ -26880,9 +26913,9 @@ ${C.b}\u{1FA7A} Jefri Chat connector \u2014 setup check${C.x}
26880
26913
  pass(`Connector jefrichat-mcp v${connectorVersion()}`, "npm i -g jefrichat-mcp@latest to update");
26881
26914
  pass(`Hub URL ${SERVER2}`);
26882
26915
  if (!TOKEN2)
26883
- fail2("No ACP_TOKEN set", "Get your token from jefrichat.com \u2192 Connect, then re-add the connector");
26884
- else if (!TOKEN2.startsWith("acp_"))
26885
- warn(`Token doesn't look right (${mask(TOKEN2)})`, "Tokens start with acp_ \u2014 check you copied the whole thing");
26916
+ fail2("No JEFRI_TOKEN set", "Get your token from jefrichat.com \u2192 Connect, then re-add the connector");
26917
+ else if (!TOKEN2.startsWith("jefri_") && !TOKEN2.startsWith("acp_"))
26918
+ warn(`Token doesn't look right (${mask(TOKEN2)})`, "Tokens start with jefri_ \u2014 check you copied the whole thing");
26886
26919
  else pass(`Token present (${mask(TOKEN2)})`);
26887
26920
  if (TOKEN2) {
26888
26921
  try {
@@ -26935,20 +26968,25 @@ ${C.b}\u{1FA7A} Jefri Chat connector \u2014 setup check${C.x}
26935
26968
  }
26936
26969
 
26937
26970
  // src/index.ts
26938
- var SERVER = process.env.ACP_SERVER ?? "http://localhost:4000";
26939
- var TOKEN = process.env.ACP_TOKEN;
26940
- var USERNAME = process.env.ACP_AS ?? "claude_agent";
26941
- var NAME = process.env.ACP_NAME ?? USERNAME;
26942
- var TAGS = (process.env.ACP_TAGS ?? "").split(",").map((s) => s.trim()).filter(Boolean);
26943
- var CAPS = (process.env.ACP_CAPABILITIES ?? "coding").split(",").map((s) => s.trim()).filter(Boolean);
26971
+ var SERVER = process.env.JEFRI_SERVER ?? "http://localhost:4000";
26972
+ var TOKEN = process.env.JEFRI_TOKEN;
26973
+ var USERNAME = process.env.JEFRI_AS ?? "claude_agent";
26974
+ var NAME = process.env.JEFRI_NAME ?? USERNAME;
26975
+ var TAGS = (process.env.JEFRI_TAGS ?? "").split(",").map((s) => s.trim()).filter(Boolean);
26976
+ var CAPS = (process.env.JEFRI_CAPABILITIES ?? "coding").split(",").map((s) => s.trim()).filter(Boolean);
26944
26977
  var log = (...a) => console.error("[jefrichat-mcp]", ...a);
26945
- var TOKEN_CACHE = path2.join(os5.homedir(), ".acp", "tokens.json");
26978
+ var TOKEN_CACHE = path2.join(os5.homedir(), ".jefri", "tokens.json");
26979
+ var LEGACY_TOKEN_CACHE = path2.join(os5.homedir(), ".acp", "tokens.json");
26946
26980
  var cacheKey = `${SERVER}::${USERNAME}`;
26947
26981
  function readTokenCache() {
26948
26982
  try {
26949
26983
  return JSON.parse(fs6.readFileSync(TOKEN_CACHE, "utf8"));
26950
26984
  } catch {
26951
- return {};
26985
+ try {
26986
+ return JSON.parse(fs6.readFileSync(LEGACY_TOKEN_CACHE, "utf8"));
26987
+ } catch {
26988
+ return {};
26989
+ }
26952
26990
  }
26953
26991
  }
26954
26992
  function cacheToken(tok) {
@@ -26963,21 +27001,21 @@ function ensureClient() {
26963
27001
  if (!clientPromise) {
26964
27002
  clientPromise = (async () => {
26965
27003
  const known = TOKEN ?? readTokenCache()[cacheKey];
26966
- const provision = () => AcpClient.connect({
27004
+ const provision = () => JefriClient.connect({
26967
27005
  server: SERVER,
26968
27006
  username: USERNAME,
26969
27007
  name: NAME,
26970
27008
  tags: TAGS,
26971
27009
  capabilities: CAPS,
26972
27010
  status: "online",
26973
- ownerToken: process.env.ACP_OWNER_TOKEN
27011
+ ownerToken: process.env.JEFRI_OWNER_TOKEN
26974
27012
  // owned by you → shows in your observability
26975
27013
  });
26976
27014
  let c;
26977
27015
  if (known) {
26978
- c = await AcpClient.connect({ server: SERVER, token: known, status: "online" });
27016
+ c = await JefriClient.connect({ server: SERVER, token: known, status: "online" });
26979
27017
  if (!c.identity) {
26980
- if (TOKEN) throw new Error("ACP_TOKEN was rejected by the server");
27018
+ if (TOKEN) throw new Error("JEFRI_TOKEN was rejected by the server");
26981
27019
  log("cached token rejected, re-provisioning by username");
26982
27020
  c = await provision();
26983
27021
  if (c.identity) cacheToken(c.token);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jefrichat-mcp",
3
- "version": "0.17.0",
3
+ "version": "0.19.0",
4
4
  "description": "Jefri Chat connector — join the Jefri Chat network (WhatsApp for AI agents) from any MCP client (Claude, Codex, Cursor, …).",
5
5
  "type": "module",
6
6
  "bin": {
@@ -36,7 +36,7 @@
36
36
  "@types/cors": "^2.8.17",
37
37
  "@types/express": "^4.17.21",
38
38
  "@types/node": "^22.10.2",
39
- "acp-sdk": "workspace:*",
39
+ "jefri-sdk": "workspace:*",
40
40
  "cors": "^2.8.5",
41
41
  "esbuild": "^0.28.1",
42
42
  "express": "^4.21.2",