regen-koi-mcp 1.2.0 → 1.3.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
@@ -4,28 +4,69 @@ Access Regen Network's Knowledge Organization Infrastructure (KOI) through Model
4
4
 
5
5
  ## 🚀 Quick Start
6
6
 
7
- ### One-Line Install (Easiest!)
7
+ **Choose your installation method:**
8
+ - **Native CLI commands** (Recommended) - Most transparent and secure
9
+ - **Automated install script** - Convenient for multiple clients at once
10
+ - **Manual configuration** - Full control over your setup
11
+
12
+ ### Recommended: Native CLI Commands
13
+
14
+ The simplest and most secure way to install for supported clients:
15
+
16
+ **Claude Code CLI:**
17
+ ```bash
18
+ claude mcp add regen-koi npx regen-koi-mcp@latest
19
+ ```
20
+
21
+ **Codex:**
22
+ ```bash
23
+ codex mcp add regen-koi npx "-y regen-koi-mcp@latest"
24
+ ```
25
+
26
+ **Warp:**
27
+ ```bash
28
+ /add-mcp regen-koi npx -y regen-koi-mcp@latest
29
+ ```
30
+
31
+ **Amp:**
32
+ ```bash
33
+ amp mcp add regen-koi -- npx -y regen-koi-mcp@latest
34
+ ```
35
+
36
+ **Factory:**
37
+ ```bash
38
+ droid mcp add regen-koi "npx -y regen-koi-mcp@latest"
39
+ ```
40
+
41
+ Then configure the environment variable (see [client-specific sections](#-supported-clients) below for details).
42
+
43
+ ### Alternative: Automated Install Script
44
+
45
+ **⚠️ Security Note:** This script requires bash access and modifies config files. Review the [install script](https://raw.githubusercontent.com/gaiaaiagent/regen-koi-mcp/main/install.sh) before running.
8
46
 
9
47
  ```bash
10
48
  curl -fsSL https://raw.githubusercontent.com/gaiaaiagent/regen-koi-mcp/main/install.sh | bash
11
49
  ```
12
50
 
13
- This automatically configures Claude Desktop and Claude Code CLI. Just restart and you're done! 🎉
51
+ **What this does:**
52
+ - Automatically configures Claude Desktop and Claude Code CLI
53
+ - Sets up environment variables
54
+ - Works for multiple clients at once
14
55
 
15
- **Quick Test:** After restarting, open Claude and ask: _"What repositories are indexed in KOI?"_ to verify the tools are working.
56
+ **Quick Test:** After installation, restart your client and ask: _"What repositories are indexed in KOI?"_ to verify the tools are working.
16
57
 
17
58
  ---
18
59
 
19
- ### Option 1: NPM (Recommended - Auto-Updates)
60
+ ### Manual Configuration (All Clients)
20
61
 
21
- **No installation needed!** Just configure Claude Desktop with:
62
+ **For clients without a CLI command**, manually add this configuration:
22
63
 
23
64
  ```json
24
65
  {
25
66
  "mcpServers": {
26
67
  "regen-koi": {
27
68
  "command": "npx",
28
- "args": ["-y", "regen-koi-mcp@latest"],
69
+ "args": ["regen-koi-mcp@latest"],
29
70
  "env": {
30
71
  "KOI_API_ENDPOINT": "https://regen.gaiaai.xyz/api/koi"
31
72
  }
@@ -55,7 +96,9 @@ Then restart Claude Desktop and you're done! 🎉
55
96
 
56
97
  ### 🔄 Migrating from Git Installation
57
98
 
58
- If you previously installed via `git clone`, switch to npx for automatic updates:
99
+ If you previously installed via `git clone`, switch to npx for automatic updates.
100
+
101
+ ⚠️ **Security Note:** Review the [migrate script](https://raw.githubusercontent.com/gaiaaiagent/regen-koi-mcp/main/migrate.sh) before running.
59
102
 
60
103
  ```bash
61
104
  curl -fsSL https://raw.githubusercontent.com/gaiaaiagent/regen-koi-mcp/main/migrate.sh | bash
@@ -123,20 +166,31 @@ Regen Network team members with `@regen.network` emails can optionally authentic
123
166
  ```
124
167
  User: "Please use the regen_koi_authenticate tool"
125
168
 
126
- MCP: Opening browser for authentication...
127
- [Browser opens to Google OAuth]
169
+ MCP: ## Authentication Required
170
+
171
+ 🌐 Your browser should open automatically. If not, click:
172
+ [Open Activation Page](https://regen.gaiaai.xyz/activate)
173
+
174
+ Enter this code: NWDV-FCFC
175
+
176
+ Sign in with your @regen.network email.
128
177
 
129
- User: [Log in with yourname@regen.network]
130
- [Grant permissions: email, profile]
178
+ After completing, run this tool again to retrieve your session token.
179
+
180
+ User: [Completes authentication in browser]
181
+ "Please use the regen_koi_authenticate tool again"
182
+
183
+ MCP: ✅ Authentication Successful!
184
+ You now have access to internal Regen Network documentation.
131
185
 
132
- MCP: ✅ Authentication successful!
133
186
  Authenticated as: yourname@regen.network
134
187
  ```
135
188
 
136
189
  **After authentication:**
137
190
  - Queries automatically include internal documentation
138
- - Token is saved on the server (not your machine)
139
- - No need to re-authenticate unless token expires (~7 days)
191
+ - Token is saved locally in `~/.koi-auth.json` and cached in memory
192
+ - Session expires after ~1 hour
193
+ - Browser auto-opens to activation page for convenience
140
194
 
141
195
  ### What Permissions Are Requested
142
196
 
@@ -174,10 +228,20 @@ MCP: Found 23 results from multiple sources:
174
228
  ### Token Security
175
229
 
176
230
  Your authentication tokens are:
177
- - 🔒 Stored server-side only (never on your machine)
178
- - 🔒 Encrypted in PostgreSQL database
179
- - 🔒 User-specific (never shared between users)
180
- - 🔒 Automatically refreshed when needed
231
+ - 🔒 **Local Storage**: Saved in `~/.koi-auth.json` with `0o600` permissions (owner read/write only)
232
+ - 🔒 **Database**: SHA-256 hashed when stored in PostgreSQL (no plain tokens stored)
233
+ - 🔒 **User-Specific**: Never shared between users; each session is isolated
234
+ - 🔒 **Short-Lived**: Sessions expire after 1 hour; tokens are revocable
235
+ - 🔒 **Domain Enforcement**: Only `@regen.network` emails are permitted (verified in JWT claims)
236
+ - 🔒 **Phishing Prevention**: RFC 8628 Device Authorization Grant with user-typed codes
237
+ - 🔒 **Rate Limited**: 5 attempts/min on activation, 60 req/min on token endpoint
238
+ - 🔒 **No Secrets in URLs**: All authentication flows use POST requests to prevent logging
239
+ - 🔒 **Hardcoded URLs**: Activation page URL is hardcoded in the client (not from server)
240
+ - 🔒 **JWT Validation**: Google ID tokens validated locally with signature verification
241
+
242
+ **Production-Ready:** This authentication system follows RFC 8628 and industry best practices.
243
+
244
+ See [docs/AUTHENTICATION.md](docs/AUTHENTICATION.md) for complete security documentation and threat model.
181
245
 
182
246
  ### Troubleshooting
183
247
 
@@ -268,8 +332,7 @@ Once you've installed the MCP server, try these queries in Claude to explore wha
268
332
  ### Knowledge Base Search
269
333
  | Tool | Description | Key Inputs |
270
334
  |------|-------------|-----------|
271
- | `search_knowledge` | Hybrid search (vectors + graph with RRF) | `query` (string), `limit` (1–20, default 5), `published_from` (YYYY‑MM‑DD), `published_to` (YYYY‑MM‑DD), `include_undated` (bool, default false) |
272
- | `hybrid_search` | Intelligent search routing (auto-detects entity vs conceptual queries) | `query` (string), `limit` (1–50, default 10) |
335
+ | `search` | Hybrid search (vectors + graph with RRF) | `query` (string), `limit` (1–50, default 10), `published_from` (YYYY‑MM‑DD), `published_to` (YYYY‑MM‑DD), `include_undated` (bool, default false) |
273
336
  | `get_stats` | Knowledge base statistics | `detailed` (boolean) |
274
337
  | `generate_weekly_digest` | Generate weekly digest SUMMARY of Regen Network activity | `start_date` (YYYY-MM-DD, default: 7 days ago), `end_date` (YYYY-MM-DD, default: today), `save_to_file` (bool, default false), `output_path` (string), `format` ('markdown' or 'json', default: 'markdown') |
275
338
  | `get_notebooklm_export` | Get FULL NotebookLM export with complete forum posts, Notion pages, and source material | `save_to_file` (bool, default false), `output_path` (string) |
@@ -286,6 +349,11 @@ Once you've installed the MCP server, try these queries in Claude to explore wha
286
349
  | `get_repo_overview` | Get structured overview of a Regen repository | `repository` (enum: regen-ledger, regen-web, regen-data-standards, regenie-corpus) |
287
350
  | `get_tech_stack` | Get technical stack information for Regen repositories | `repository` (optional, omit to show all repos) |
288
351
 
352
+ ### Authentication (Team Members Only)
353
+ | Tool | Description | Key Inputs |
354
+ |------|-------------|-----------|
355
+ | `regen_koi_authenticate` | Authenticate with @regen.network email to access internal documentation | None (opens browser for OAuth login) |
356
+
289
357
  ---
290
358
 
291
359
  ## 🤔 What Can I Ask? User Guide
@@ -317,8 +385,8 @@ This table helps you understand which tool to use for different tasks. Just ask
317
385
  | Get repository overview | "Give me an overview of regen-web" | `get_repo_overview` |
318
386
  | Understand tech stack | "What's the tech stack for regen-ledger?" | `get_tech_stack` |
319
387
  | **Search everything (hybrid)** | | |
320
- | Semantic search across code and docs | "How does credit retirement work?" | `hybrid_search` |
321
- | Advanced filtering by date | "Find discussions about tokens from last week" | `search_knowledge` |
388
+ | Semantic search across code and docs | "How does credit retirement work?" | `search` |
389
+ | Advanced filtering by date | "Find discussions about tokens from last week" | `search` |
322
390
  | **Get activity summaries** | | |
323
391
  | Generate weekly digest summary | "Create a weekly digest of Regen activity" | `generate_weekly_digest` |
324
392
  | Get full content for NotebookLM | "Get the full NotebookLM export with all forum posts" | `get_notebooklm_export` |
@@ -394,18 +462,19 @@ regen-koi-mcp/
394
462
 
395
463
  ### Claude Desktop
396
464
 
397
- **One-line install:**
398
- ```bash
399
- curl -fsSL https://raw.githubusercontent.com/gaiaaiagent/regen-koi-mcp/main/install.sh | bash
400
- ```
465
+ **Recommended: Manual configuration**
466
+
467
+ Add to your config file:
468
+ - **Mac:** `~/Library/Application Support/Claude/claude_desktop_config.json`
469
+ - **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
470
+ - **Linux:** `~/.config/Claude/claude_desktop_config.json`
401
471
 
402
- Or manually add to config (`~/Library/Application Support/Claude/claude_desktop_config.json` on Mac, `~/.config/Claude/claude_desktop_config.json` on Linux):
403
472
  ```json
404
473
  {
405
474
  "mcpServers": {
406
475
  "regen-koi": {
407
476
  "command": "npx",
408
- "args": ["-y", "regen-koi-mcp@latest"],
477
+ "args": ["regen-koi-mcp@latest"],
409
478
  "env": {
410
479
  "KOI_API_ENDPOINT": "https://regen.gaiaai.xyz/api/koi"
411
480
  }
@@ -414,29 +483,34 @@ Or manually add to config (`~/Library/Application Support/Claude/claude_desktop_
414
483
  }
415
484
  ```
416
485
 
417
- ---
486
+ **Alternative: Automated installer**
418
487
 
419
- ### Claude Code CLI
488
+ ⚠️ **Security Note:** Review the [install script](https://raw.githubusercontent.com/gaiaaiagent/regen-koi-mcp/main/install.sh) before running.
420
489
 
421
- **Option 1: Use the automated installer (recommended)**
422
490
  ```bash
423
491
  curl -fsSL https://raw.githubusercontent.com/gaiaaiagent/regen-koi-mcp/main/install.sh | bash
424
492
  ```
425
- This configures both Claude Desktop and Claude Code CLI with the correct environment variables.
426
493
 
427
- **Option 2: Manual installation**
428
- 1. Add the MCP server:
494
+ ---
495
+
496
+ ### Claude Code CLI
497
+
498
+ **Recommended: One-line command**
429
499
  ```bash
430
- claude mcp add regen-koi npx -y regen-koi-mcp@latest
500
+ claude mcp add regen-koi npx regen-koi-mcp@latest
431
501
  ```
432
502
 
433
- 2. Configure the environment variable in your Claude Code settings file (`~/.claude/settings.json` or similar):
503
+ Then manually add the environment variable to your Claude Code settings file:
504
+
505
+ **Mac/Linux:** `~/.config/claude/claude_code_config.json`
506
+ **Windows:** `%APPDATA%\claude\claude_code_config.json`
507
+
434
508
  ```json
435
509
  {
436
510
  "mcpServers": {
437
511
  "regen-koi": {
438
512
  "command": "npx",
439
- "args": ["-y", "regen-koi-mcp@latest"],
513
+ "args": ["regen-koi-mcp@latest"],
440
514
  "env": {
441
515
  "KOI_API_ENDPOINT": "https://regen.gaiaai.xyz/api/koi"
442
516
  }
@@ -445,22 +519,38 @@ claude mcp add regen-koi npx -y regen-koi-mcp@latest
445
519
  }
446
520
  ```
447
521
 
522
+ **Alternative: Use the automated installer**
523
+
524
+ ⚠️ **Security Note:** Review the [install script](https://raw.githubusercontent.com/gaiaaiagent/regen-koi-mcp/main/install.sh) before running.
525
+
526
+ ```bash
527
+ curl -fsSL https://raw.githubusercontent.com/gaiaaiagent/regen-koi-mcp/main/install.sh | bash
528
+ ```
529
+
530
+ This configures both Claude Desktop and Claude Code CLI with the correct environment variables.
531
+
448
532
  **Verification:** After installation, restart Claude Code and ask: "What repositories are indexed?" to verify the tools are working.
449
533
 
450
534
  ---
451
535
 
452
536
  ### VS Code / VS Code Insiders
453
537
 
454
- **One-line install:**
538
+ **Recommended: CLI command**
539
+
540
+ For VS Code:
455
541
  ```bash
456
- code --add-mcp '{"name":"regen-koi","command":"npx","args":["-y","regen-koi-mcp@latest"],"env":{"KOI_API_ENDPOINT":"https://regen.gaiaai.xyz/api/koi"}}'
542
+ code --add-mcp '{"name":"regen-koi","command":"npx","args":["regen-koi-mcp@latest"],"env":{"KOI_API_ENDPOINT":"https://regen.gaiaai.xyz/api/koi"}}'
457
543
  ```
458
544
 
459
- Or for VS Code Insiders:
545
+ For VS Code Insiders:
460
546
  ```bash
461
- code-insiders --add-mcp '{"name":"regen-koi","command":"npx","args":["-y","regen-koi-mcp@latest"],"env":{"KOI_API_ENDPOINT":"https://regen.gaiaai.xyz/api/koi"}}'
547
+ code-insiders --add-mcp '{"name":"regen-koi","command":"npx","args":["regen-koi-mcp@latest"],"env":{"KOI_API_ENDPOINT":"https://regen.gaiaai.xyz/api/koi"}}'
462
548
  ```
463
549
 
550
+ **Alternative: Manual configuration**
551
+
552
+ Add to your VS Code MCP settings with the command, args, and env values shown above.
553
+
464
554
  ---
465
555
 
466
556
  ### Cursor
@@ -472,7 +562,7 @@ code-insiders --add-mcp '{"name":"regen-koi","command":"npx","args":["-y","regen
472
562
  4. Enter:
473
563
  - Name: `regen-koi`
474
564
  - Command: `npx`
475
- - Args: `-y regen-koi-mcp@latest`
565
+ - Args: `regen-koi-mcp@latest`
476
566
  - Env: `KOI_API_ENDPOINT=https://regen.gaiaai.xyz/api/koi`
477
567
 
478
568
  ---
@@ -485,7 +575,7 @@ Add to your Windsurf MCP config:
485
575
  "mcpServers": {
486
576
  "regen-koi": {
487
577
  "command": "npx",
488
- "args": ["-y", "regen-koi-mcp@latest"],
578
+ "args": ["regen-koi-mcp@latest"],
489
579
  "env": {
490
580
  "KOI_API_ENDPOINT": "https://regen.gaiaai.xyz/api/koi"
491
581
  }
@@ -504,7 +594,7 @@ Install [Cline from VS Code Marketplace](https://marketplace.visualstudio.com/it
504
594
  "mcpServers": {
505
595
  "regen-koi": {
506
596
  "command": "npx",
507
- "args": ["-y", "regen-koi-mcp@latest"],
597
+ "args": ["regen-koi-mcp@latest"],
508
598
  "env": {
509
599
  "KOI_API_ENDPOINT": "https://regen.gaiaai.xyz/api/koi"
510
600
  }
@@ -523,7 +613,7 @@ Install [Continue from VS Code Marketplace](https://marketplace.visualstudio.com
523
613
  "mcpServers": {
524
614
  "regen-koi": {
525
615
  "command": "npx",
526
- "args": ["-y", "regen-koi-mcp@latest"],
616
+ "args": ["regen-koi-mcp@latest"],
527
617
  "env": {
528
618
  "KOI_API_ENDPOINT": "https://regen.gaiaai.xyz/api/koi"
529
619
  }
@@ -541,61 +631,77 @@ Install [Continue from VS Code Marketplace](https://marketplace.visualstudio.com
541
631
  2. Go to Extensions
542
632
  3. Add MCP server with:
543
633
  - Command: `npx`
544
- - Args: `-y regen-koi-mcp@latest`
634
+ - Args: `regen-koi-mcp@latest`
545
635
  - Env: `KOI_API_ENDPOINT=https://regen.gaiaai.xyz/api/koi`
546
636
 
547
637
  ---
548
638
 
549
639
  ### Warp
550
640
 
551
- **Via Settings:**
552
- 1. Open Settings → AI → Manage MCP Servers
553
- 2. Add new server
554
-
555
- Or use slash command:
641
+ **Recommended: Slash command**
556
642
  ```bash
557
643
  /add-mcp regen-koi npx -y regen-koi-mcp@latest
558
644
  ```
559
645
 
646
+ Then add the environment variable `KOI_API_ENDPOINT=https://regen.gaiaai.xyz/api/koi` in the server settings.
647
+
648
+ **Alternative: Manual configuration via Settings**
649
+ 1. Open Settings → AI → Manage MCP Servers
650
+ 2. Add new server
651
+ 3. Configure:
652
+ - Command: `npx`
653
+ - Args: `regen-koi-mcp@latest`
654
+ - Env: `KOI_API_ENDPOINT=https://regen.gaiaai.xyz/api/koi`
655
+
560
656
  ---
561
657
 
562
658
  ### Amp
563
659
 
564
- **One-line install:**
660
+ **Recommended: One-line command**
565
661
  ```bash
566
662
  amp mcp add regen-koi -- npx -y regen-koi-mcp@latest
567
663
  ```
568
664
 
665
+ Then manually add the environment variable `KOI_API_ENDPOINT=https://regen.gaiaai.xyz/api/koi` to the server configuration.
666
+
569
667
  ---
570
668
 
571
669
  ### Factory
572
670
 
573
- **One-line install:**
671
+ **Recommended: One-line command**
574
672
  ```bash
575
673
  droid mcp add regen-koi "npx -y regen-koi-mcp@latest"
576
674
  ```
577
675
 
578
- Or use interactive UI with `/mcp` command.
676
+ Then manually add the environment variable `KOI_API_ENDPOINT=https://regen.gaiaai.xyz/api/koi` to the server configuration.
677
+
678
+ **Alternative: Interactive UI**
679
+
680
+ Use the `/mcp` command in Factory to add the server interactively.
579
681
 
580
682
  ---
581
683
 
582
684
  ### Codex
583
685
 
584
- **One-line install:**
686
+ **Recommended: One-line command**
585
687
  ```bash
586
688
  codex mcp add regen-koi npx "-y regen-koi-mcp@latest"
587
689
  ```
588
690
 
589
- Or manually edit `~/.codex/config.toml`:
691
+ Then manually add the environment variable to `~/.codex/config.toml`:
590
692
  ```toml
591
693
  [[mcp.servers]]
592
694
  name = "regen-koi"
593
695
  command = "npx"
594
- args = ["-y", "regen-koi-mcp@latest"]
696
+ args = ["regen-koi-mcp@latest"]
595
697
  [mcp.servers.env]
596
698
  KOI_API_ENDPOINT = "https://regen.gaiaai.xyz/api/koi"
597
699
  ```
598
700
 
701
+ **Alternative: Manual configuration**
702
+
703
+ Edit `~/.codex/config.toml` directly with the complete config above.
704
+
599
705
  ---
600
706
 
601
707
  ### Opencode
@@ -606,7 +712,7 @@ Add to `~/.config/opencode/opencode.json`:
606
712
  "mcpServers": {
607
713
  "regen-koi": {
608
714
  "command": "npx",
609
- "args": ["-y", "regen-koi-mcp@latest"],
715
+ "args": ["regen-koi-mcp@latest"],
610
716
  "env": {
611
717
  "KOI_API_ENDPOINT": "https://regen.gaiaai.xyz/api/koi"
612
718
  }
@@ -625,7 +731,7 @@ Add to `.kiro/settings/mcp.json`:
625
731
  "mcpServers": {
626
732
  "regen-koi": {
627
733
  "command": "npx",
628
- "args": ["-y", "regen-koi-mcp@latest"],
734
+ "args": ["regen-koi-mcp@latest"],
629
735
  "env": {
630
736
  "KOI_API_ENDPOINT": "https://regen.gaiaai.xyz/api/koi"
631
737
  }
@@ -641,7 +747,7 @@ Add to `.kiro/settings/mcp.json`:
641
747
  **Via Settings:**
642
748
  1. Open Program sidebar
643
749
  2. Go to MCP configuration
644
- 3. Add server with npx command: `npx -y regen-koi-mcp@latest`
750
+ 3. Add server with npx command: `npx regen-koi-mcp@latest`
645
751
 
646
752
  ---
647
753
 
@@ -652,7 +758,7 @@ Add to `.kiro/settings/mcp.json`:
652
758
  2. Click "Connect more tools"
653
759
  3. Add MCP server:
654
760
  - Command: `npx`
655
- - Args: `-y regen-koi-mcp@latest`
761
+ - Args: `regen-koi-mcp@latest`
656
762
  - Env: `KOI_API_ENDPOINT=https://regen.gaiaai.xyz/api/koi`
657
763
 
658
764
  ---
@@ -665,7 +771,7 @@ Add to Gemini CLI MCP config:
665
771
  "mcpServers": {
666
772
  "regen-koi": {
667
773
  "command": "npx",
668
- "args": ["-y", "regen-koi-mcp@latest"],
774
+ "args": ["regen-koi-mcp@latest"],
669
775
  "env": {
670
776
  "KOI_API_ENDPOINT": "https://regen.gaiaai.xyz/api/koi"
671
777
  }
@@ -683,7 +789,7 @@ Any MCP-compatible client can use this server with:
683
789
  ```json
684
790
  {
685
791
  "command": "npx",
686
- "args": ["-y", "regen-koi-mcp@latest"],
792
+ "args": ["regen-koi-mcp@latest"],
687
793
  "env": {
688
794
  "KOI_API_ENDPOINT": "https://regen.gaiaai.xyz/api/koi"
689
795
  }
@@ -762,7 +868,7 @@ curl -s http://localhost:8301/api/koi/query \
762
868
  }' | jq '.results[0:3]'
763
869
  ```
764
870
 
765
- Within MCP, the `search_knowledge` tool accepts:
871
+ Within MCP, the `search` tool accepts:
766
872
 
767
873
  - `published_from` / `published_to` (YYYY-MM-DD)
768
874
  - `include_undated` (boolean)
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Auth State Persistence
3
+ *
4
+ * Stores authentication state to .koi-auth.json to enable
5
+ * the "One Tool, Two Calls" pattern (no polling loop).
6
+ *
7
+ * State Flow:
8
+ * 1. No state -> Request device code, save to file
9
+ * 2. Has device_code -> Check status with server
10
+ * 3. Has access_token -> Already authenticated
11
+ */
12
+ export interface AuthState {
13
+ deviceCode?: string;
14
+ userCode?: string;
15
+ verificationUri?: string;
16
+ deviceCodeExpiresAt?: number;
17
+ accessToken?: string;
18
+ accessTokenExpiresAt?: number;
19
+ userEmail?: string;
20
+ }
21
+ /**
22
+ * Load auth state from disk.
23
+ * Returns empty object if file doesn't exist or is invalid.
24
+ */
25
+ export declare function loadAuthState(): AuthState;
26
+ /**
27
+ * Save auth state to disk with secure file permissions.
28
+ * File is set to 0o600 (owner read/write only) for security on shared machines.
29
+ */
30
+ export declare function saveAuthState(state: AuthState): void;
31
+ /**
32
+ * Clear auth state (logout).
33
+ */
34
+ export declare function clearAuthState(): void;
35
+ /**
36
+ * Check if access token is still valid.
37
+ */
38
+ export declare function hasValidAccessToken(state: AuthState): boolean;
39
+ /**
40
+ * Check if device code is still valid.
41
+ */
42
+ export declare function hasValidDeviceCode(state: AuthState): boolean;
43
+ /**
44
+ * Clear device code from state (after successful auth or expiry).
45
+ */
46
+ export declare function clearDeviceCode(state: AuthState): AuthState;
47
+ //# sourceMappingURL=auth-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-store.d.ts","sourceRoot":"","sources":["../src/auth-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AASH,MAAM,WAAW,SAAS;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,SAAS,CAUzC;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI,CASpD;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAQrC;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAK7D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAK5D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,CAG3D"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Auth State Persistence
3
+ *
4
+ * Stores authentication state to .koi-auth.json to enable
5
+ * the "One Tool, Two Calls" pattern (no polling loop).
6
+ *
7
+ * State Flow:
8
+ * 1. No state -> Request device code, save to file
9
+ * 2. Has device_code -> Check status with server
10
+ * 3. Has access_token -> Already authenticated
11
+ */
12
+ import fs from 'fs';
13
+ import path from 'path';
14
+ import os from 'os';
15
+ // Store auth state in user's home directory
16
+ const AUTH_FILE = path.join(os.homedir(), '.koi-auth.json');
17
+ /**
18
+ * Load auth state from disk.
19
+ * Returns empty object if file doesn't exist or is invalid.
20
+ */
21
+ export function loadAuthState() {
22
+ try {
23
+ if (fs.existsSync(AUTH_FILE)) {
24
+ const data = fs.readFileSync(AUTH_FILE, 'utf8');
25
+ return JSON.parse(data);
26
+ }
27
+ }
28
+ catch (err) {
29
+ console.error('[Auth] Failed to load auth state:', err);
30
+ }
31
+ return {};
32
+ }
33
+ /**
34
+ * Save auth state to disk with secure file permissions.
35
+ * File is set to 0o600 (owner read/write only) for security on shared machines.
36
+ */
37
+ export function saveAuthState(state) {
38
+ try {
39
+ fs.writeFileSync(AUTH_FILE, JSON.stringify(state, null, 2), {
40
+ encoding: 'utf8',
41
+ mode: 0o600 // Owner read/write only
42
+ });
43
+ }
44
+ catch (err) {
45
+ console.error('[Auth] Failed to save auth state:', err);
46
+ }
47
+ }
48
+ /**
49
+ * Clear auth state (logout).
50
+ */
51
+ export function clearAuthState() {
52
+ try {
53
+ if (fs.existsSync(AUTH_FILE)) {
54
+ fs.unlinkSync(AUTH_FILE);
55
+ }
56
+ }
57
+ catch (err) {
58
+ console.error('[Auth] Failed to clear auth state:', err);
59
+ }
60
+ }
61
+ /**
62
+ * Check if access token is still valid.
63
+ */
64
+ export function hasValidAccessToken(state) {
65
+ if (!state.accessToken || !state.accessTokenExpiresAt) {
66
+ return false;
67
+ }
68
+ return Date.now() < state.accessTokenExpiresAt;
69
+ }
70
+ /**
71
+ * Check if device code is still valid.
72
+ */
73
+ export function hasValidDeviceCode(state) {
74
+ if (!state.deviceCode || !state.deviceCodeExpiresAt) {
75
+ return false;
76
+ }
77
+ return Date.now() < state.deviceCodeExpiresAt;
78
+ }
79
+ /**
80
+ * Clear device code from state (after successful auth or expiry).
81
+ */
82
+ export function clearDeviceCode(state) {
83
+ const { deviceCode, userCode, verificationUri, deviceCodeExpiresAt, ...rest } = state;
84
+ return rest;
85
+ }
86
+ //# sourceMappingURL=auth-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-store.js","sourceRoot":"","sources":["../src/auth-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,4CAA4C;AAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,gBAAgB,CAAC,CAAC;AAY5D;;;GAGG;AACH,MAAM,UAAU,aAAa;IAC3B,IAAI,CAAC;QACH,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;YAChD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,GAAG,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAgB;IAC5C,IAAI,CAAC;QACH,EAAE,CAAC,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;YAC1D,QAAQ,EAAE,MAAM;YAChB,IAAI,EAAE,KAAK,CAAE,wBAAwB;SACtC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,mCAAmC,EAAE,GAAG,CAAC,CAAC;IAC1D,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc;IAC5B,IAAI,CAAC;QACH,IAAI,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,oCAAoC,EAAE,GAAG,CAAC,CAAC;IAC3D,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAgB;IAClD,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,CAAC,KAAK,CAAC,oBAAoB,EAAE,CAAC;QACtD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,oBAAoB,CAAC;AACjD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAgB;IACjD,IAAI,CAAC,KAAK,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,mBAAmB,EAAE,CAAC;QACpD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,mBAAmB,CAAC;AAChD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,KAAgB;IAC9C,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,eAAe,EAAE,mBAAmB,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC;IACtF,OAAO,IAAI,CAAC;AACd,CAAC"}
package/dist/auth.d.ts ADDED
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Authentication Module
3
+ * Manages session tokens for authenticated API calls
4
+ *
5
+ * SECURITY: This module stores session tokens (NOT Google OAuth tokens).
6
+ * Session tokens are generated by our server and only work with our API.
7
+ * They are safe to store locally - even if leaked, they can't be used
8
+ * to access Google APIs or impersonate the user elsewhere.
9
+ */
10
+ export declare const USER_EMAIL: string;
11
+ /**
12
+ * Get the current session token (if any)
13
+ * Returns null if no token is stored or if expired
14
+ */
15
+ export declare function getSessionToken(): string | null;
16
+ export declare const getAccessToken: typeof getSessionToken;
17
+ /**
18
+ * Store session token after successful OAuth
19
+ * @param token - The session token from our server (NOT Google OAuth token)
20
+ * @param expiresAt - Expiry timestamp
21
+ */
22
+ export declare function setSessionToken(token: string, expiresAt?: number): void;
23
+ export declare const setAccessToken: typeof setSessionToken;
24
+ /**
25
+ * Clear session token (called when token is invalid or on logout)
26
+ */
27
+ export declare function clearAuthCache(): void;
28
+ /**
29
+ * Check if we have a valid session token
30
+ */
31
+ export declare function hasSessionToken(): boolean;
32
+ export declare const hasAccessToken: typeof hasSessionToken;
33
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAuBH,eAAO,MAAM,UAAU,QAAuB,CAAC;AAc/C;;;GAGG;AACH,wBAAgB,eAAe,IAAI,MAAM,GAAG,IAAI,CAS/C;AAGD,eAAO,MAAM,cAAc,wBAAkB,CAAC;AAE9C;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAQvE;AAGD,eAAO,MAAM,cAAc,wBAAkB,CAAC;AAE9C;;GAEG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAKrC;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAGD,eAAO,MAAM,cAAc,wBAAkB,CAAC"}