kassinao-mcp 1.0.1 → 1.0.2

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
@@ -22,7 +22,7 @@ The connector runs **on your machine** and is a **thin** HTTP client: it does **
22
22
 
23
23
  1. Open `https://YOUR-KASSINAO/app/conectar-ia` and sign in with Discord.
24
24
  2. Click **Generate connection token** and copy the config block shown (it appears **once**).
25
- 3. Paste it into `claude_desktop_config.json` (Claude Desktop) or the Cursor equivalent:
25
+ 3. Paste it into your MCP client's config — `claude_desktop_config.json` (Claude Desktop), `~/.cursor/mcp.json` (Cursor), or wherever your assistant's docs point:
26
26
 
27
27
  ```json
28
28
  {
@@ -39,7 +39,7 @@ The connector runs **on your machine** and is a **thin** HTTP client: it does **
39
39
  }
40
40
  ```
41
41
 
42
- 4. Restart Claude Desktop / Cursor. Done.
42
+ 4. Restart your MCP client (Claude Desktop, Cursor, or any other). Done.
43
43
 
44
44
  ### Option B — no browser (VM/SSH)
45
45
 
package/dist/index.js CHANGED
@@ -50,6 +50,16 @@ function saveStore(s) {
50
50
  let refreshToken = loadStore().refreshToken || process.env.KASSINAO_REFRESH_TOKEN || '';
51
51
  let accessToken = '';
52
52
  let accessExpMs = 0;
53
+ async function tryRefresh(token) {
54
+ const r = await fetch(`${URL_BASE}/api/mcp/refresh`, {
55
+ method: 'POST',
56
+ headers: { 'content-type': 'application/json' },
57
+ body: JSON.stringify({ refresh_token: token }),
58
+ });
59
+ if (!r.ok)
60
+ return null;
61
+ return (await r.json());
62
+ }
53
63
  async function refreshTokens() {
54
64
  if (!URL_BASE)
55
65
  throw new Error('Defina KASSINAO_URL (ex.: https://kassinao.suaempresa.com).');
@@ -57,16 +67,18 @@ async function refreshTokens() {
57
67
  const base = URL_BASE || '<sua URL do Kassinão>';
58
68
  throw new Error(`Sem token. Gere um em ${base}/app/conectar-ia ou rode: kassinao-mcp exchange <codigo>.`);
59
69
  }
60
- const r = await fetch(`${URL_BASE}/api/mcp/refresh`, {
61
- method: 'POST',
62
- headers: { 'content-type': 'application/json' },
63
- body: JSON.stringify({ refresh_token: refreshToken }),
64
- });
65
- if (!r.ok) {
70
+ let data = await tryRefresh(refreshToken);
71
+ // Token salvo morto (ex.: usuário revogou tudo e gerou um NOVO no env):
72
+ // cai de volta pro env uma vez, em vez de só falhar. Se o env funcionar,
73
+ // ele rotaciona e vira o salvo — o fluxo se conserta sozinho.
74
+ const envTok = process.env.KASSINAO_REFRESH_TOKEN || '';
75
+ if (!data && envTok && envTok !== refreshToken) {
76
+ data = await tryRefresh(envTok);
77
+ }
78
+ if (!data) {
66
79
  const base = URL_BASE || '<sua URL do Kassinão>';
67
- throw new Error(`Não consegui renovar o token (HTTP ${r.status}). Gere um novo em ${base}/app/conectar-ia.`);
80
+ throw new Error(`Não consegui renovar o token (revogado ou expirado). Gere um novo em ${base}/app/conectar-ia.`);
68
81
  }
69
- const data = (await r.json());
70
82
  refreshToken = data.refresh_token; // rotação: guarda o novo imediatamente
71
83
  accessToken = data.access_token;
72
84
  accessExpMs = Date.parse(data.access_expires_at) || Date.now() + 10 * 60 * 1000;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kassinao-mcp",
3
- "version": "1.0.1",
4
- "description": "MCP connector for Kassin\u00e3o \u2014 ask your Discord meeting recordings (transcripts, minutes, action items) from Claude Desktop, Cursor and other MCP clients.",
3
+ "version": "1.0.2",
4
+ "description": "MCP connector for Kassinão ask your Discord meeting recordings (transcripts, minutes, action items) from Claude Desktop, Cursor and other MCP clients.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "kassinao-mcp": "dist/index.js"