jefrichat-mcp 0.18.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 -------------------------------------------------------------
@@ -49648,7 +49661,7 @@ function saveWatermark() {
49648
49661
  }
49649
49662
  }
49650
49663
  function registerAcpTools(server, ctx) {
49651
- const ENABLE_E2E = process.env.ACP_ENABLE_E2E === "true";
49664
+ const ENABLE_E2E = process.env.JEFRI_ENABLE_E2E === "true";
49652
49665
  const e2eServer = ENABLE_E2E ? server : { registerTool: () => void 0 };
49653
49666
  const withClient = async (fn) => {
49654
49667
  try {
@@ -50712,7 +50725,7 @@ function attachInbox(c, inbox, self, onIncoming) {
50712
50725
  }
50713
50726
 
50714
50727
  // src/http.ts
50715
- var HUB = process.env.ACP_SERVER ?? "http://localhost:4000";
50728
+ var HUB = process.env.JEFRI_SERVER ?? "http://localhost:4000";
50716
50729
  var PORT = Number(process.env.MCP_HTTP_PORT ?? 4001);
50717
50730
  var log = (...a) => console.error("[jefrichat-mcp-http]", ...a);
50718
50731
  var sessions = /* @__PURE__ */ new Map();
@@ -50751,8 +50764,8 @@ function bearer(req) {
50751
50764
  return null;
50752
50765
  }
50753
50766
  var app = (0, import_express.default)();
50754
- var mcpProduction = process.env.NODE_ENV === "production" || process.env.ACP_PRODUCTION === "true";
50755
- 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);
50756
50769
  if (mcpProduction && configuredCorsOrigins.length === 0)
50757
50770
  throw new Error("Production Jefri Chat MCP must set MCP_CORS_ORIGINS or ACP_CORS_ORIGINS.");
50758
50771
  var allowedCorsOrigins = new Set(configuredCorsOrigins);
@@ -50771,7 +50784,7 @@ app.use((req, res, next) => {
50771
50784
  return res.status(403).json({ error: "origin not allowed" });
50772
50785
  next();
50773
50786
  });
50774
- 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";
50775
50788
  app.use((_req, res, next) => {
50776
50789
  res.setHeader("X-Content-Type-Options", "nosniff");
50777
50790
  res.setHeader("X-Frame-Options", "DENY");
@@ -50796,16 +50809,16 @@ app.post("/mcp", async (req, res) => {
50796
50809
  if (!token) {
50797
50810
  res.status(401).json({
50798
50811
  jsonrpc: "2.0",
50799
- 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)" },
50800
50813
  id: null
50801
50814
  });
50802
50815
  return;
50803
50816
  }
50804
50817
  let acp;
50805
50818
  try {
50806
- acp = await AcpClient.connect({ server: HUB, token, status: "online" });
50819
+ acp = await JefriClient.connect({ server: HUB, token, status: "online" });
50807
50820
  } catch (e) {
50808
- if (e instanceof AcpAuthError || e?.code === "ACP_AUTH_FAILED") {
50821
+ if (e instanceof JefriAuthError || e?.code === "ACP_AUTH_FAILED") {
50809
50822
  res.status(401).json({
50810
50823
  jsonrpc: "2.0",
50811
50824
  error: {
@@ -50878,7 +50891,7 @@ http.createServer(app).listen(PORT, () => {
50878
50891
  console.error(`
50879
50892
  \u{1F310} Jefri Chat remote MCP (HTTP) on http://localhost:${PORT}/mcp`);
50880
50893
  console.error(` hub: ${HUB}`);
50881
- console.error(` auth: Authorization: Bearer <acp_token>
50894
+ console.error(` auth: Authorization: Bearer <jefri_token>
50882
50895
  `);
50883
50896
  });
50884
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 -------------------------------------------------------------
@@ -25763,7 +25776,7 @@ function saveWatermark() {
25763
25776
  }
25764
25777
  }
25765
25778
  function registerAcpTools(server2, ctx) {
25766
- const ENABLE_E2E = process.env.ACP_ENABLE_E2E === "true";
25779
+ const ENABLE_E2E = process.env.JEFRI_ENABLE_E2E === "true";
25767
25780
  const e2eServer = ENABLE_E2E ? server2 : { registerTool: () => void 0 };
25768
25781
  const withClient = async (fn) => {
25769
25782
  try {
@@ -26889,8 +26902,8 @@ async function fetchWithTimeout(url, opts, ms) {
26889
26902
  }
26890
26903
  }
26891
26904
  async function runDoctor() {
26892
- const SERVER2 = process.env.ACP_SERVER ?? "http://localhost:4000";
26893
- const TOKEN2 = process.env.ACP_TOKEN ?? "";
26905
+ const SERVER2 = process.env.JEFRI_SERVER ?? "http://localhost:4000";
26906
+ const TOKEN2 = process.env.JEFRI_TOKEN ?? "";
26894
26907
  console.log(`
26895
26908
  ${C.b}\u{1FA7A} Jefri Chat connector \u2014 setup check${C.x}
26896
26909
  `);
@@ -26900,9 +26913,9 @@ ${C.b}\u{1FA7A} Jefri Chat connector \u2014 setup check${C.x}
26900
26913
  pass(`Connector jefrichat-mcp v${connectorVersion()}`, "npm i -g jefrichat-mcp@latest to update");
26901
26914
  pass(`Hub URL ${SERVER2}`);
26902
26915
  if (!TOKEN2)
26903
- fail2("No ACP_TOKEN set", "Get your token from jefrichat.com \u2192 Connect, then re-add the connector");
26904
- else if (!TOKEN2.startsWith("acp_"))
26905
- 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");
26906
26919
  else pass(`Token present (${mask(TOKEN2)})`);
26907
26920
  if (TOKEN2) {
26908
26921
  try {
@@ -26955,20 +26968,25 @@ ${C.b}\u{1FA7A} Jefri Chat connector \u2014 setup check${C.x}
26955
26968
  }
26956
26969
 
26957
26970
  // src/index.ts
26958
- var SERVER = process.env.ACP_SERVER ?? "http://localhost:4000";
26959
- var TOKEN = process.env.ACP_TOKEN;
26960
- var USERNAME = process.env.ACP_AS ?? "claude_agent";
26961
- var NAME = process.env.ACP_NAME ?? USERNAME;
26962
- var TAGS = (process.env.ACP_TAGS ?? "").split(",").map((s) => s.trim()).filter(Boolean);
26963
- 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);
26964
26977
  var log = (...a) => console.error("[jefrichat-mcp]", ...a);
26965
- 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");
26966
26980
  var cacheKey = `${SERVER}::${USERNAME}`;
26967
26981
  function readTokenCache() {
26968
26982
  try {
26969
26983
  return JSON.parse(fs6.readFileSync(TOKEN_CACHE, "utf8"));
26970
26984
  } catch {
26971
- return {};
26985
+ try {
26986
+ return JSON.parse(fs6.readFileSync(LEGACY_TOKEN_CACHE, "utf8"));
26987
+ } catch {
26988
+ return {};
26989
+ }
26972
26990
  }
26973
26991
  }
26974
26992
  function cacheToken(tok) {
@@ -26983,21 +27001,21 @@ function ensureClient() {
26983
27001
  if (!clientPromise) {
26984
27002
  clientPromise = (async () => {
26985
27003
  const known = TOKEN ?? readTokenCache()[cacheKey];
26986
- const provision = () => AcpClient.connect({
27004
+ const provision = () => JefriClient.connect({
26987
27005
  server: SERVER,
26988
27006
  username: USERNAME,
26989
27007
  name: NAME,
26990
27008
  tags: TAGS,
26991
27009
  capabilities: CAPS,
26992
27010
  status: "online",
26993
- ownerToken: process.env.ACP_OWNER_TOKEN
27011
+ ownerToken: process.env.JEFRI_OWNER_TOKEN
26994
27012
  // owned by you → shows in your observability
26995
27013
  });
26996
27014
  let c;
26997
27015
  if (known) {
26998
- c = await AcpClient.connect({ server: SERVER, token: known, status: "online" });
27016
+ c = await JefriClient.connect({ server: SERVER, token: known, status: "online" });
26999
27017
  if (!c.identity) {
27000
- 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");
27001
27019
  log("cached token rejected, re-provisioning by username");
27002
27020
  c = await provision();
27003
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.18.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",