kiku-agent 1.0.6 → 1.0.8

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,8 +1,30 @@
1
1
  # 🌸 Ju Jingyi (鞠婧祎) Portal & Kiku AI Agent
2
2
 
3
- > **New CLI capabilities:** `/subagent <task>` runs a bounded Ju Jingyi research worker, while `/skill learn <instruction>` teaches Kiku persistent response preferences.
3
+ ![npm](https://img.shields.io/badge/Node-%3E%3D20-brightgreen) ![ESM](https://img.shields.io/badge/ESM-only-4a90d9)
4
4
 
5
- > Full-stack fan archive, REST API Suite v1.0, autonomous AI Agent CLI, and MCP server powered by **LM Studio** (`google/gemma-4-e4b` / Gemma models).
5
+ > Full-stack fan archive, REST API Suite v1.0, autonomous AI Agent CLI, and MCP server powered by **LM Studio** (`google/gemma-4-e4b` / Gemma models) or any major cloud provider.
6
+
7
+ ---
8
+
9
+ ## 📦 What's in the box
10
+
11
+ This monorepo ships three deliverables in a single `kiku-agent` npm package:
12
+
13
+ | Deliverable | Location | What it does |
14
+ |---|---|---|
15
+ | **Fan portal (SPA)** | `src/` (+ `api/` for Vercel) | Vite + React 19 + Tailwind 4 fan site served & deployed to Vercel |
16
+ | **REST API v1** | `server/apiRouter.js` | Framework-free Node `http` router with all `/api/v1/*` routes, `/api-docs`, and `/openapi.json` |
17
+ | **AI agent CLI + MCP server** | `server/agent/cli.js`, `server/mcp/stdio.js` | ReAct agent over local LM Studio or cloud providers, plus a stdio/HTTP MCP server — published as `kiku-agent` |
18
+
19
+ **Core CLI highlights** (kept up to date — see each section below for details):
20
+
21
+ - **Autonomous ReAct agent** with **38+ validated tools** across catalog, web, media, filesystem, and music.
22
+ - **Multi-provider support**: LM Studio (local, free) plus OpenAI, Google Gemini, Groq, DeepSeek, OpenRouter, and custom OpenAI-compatible gateways.
23
+ - **Bounded research workers**: `/subagent`, `/research`, and `/verify` run coordinated, capacity-limited workers with source-backed answers.
24
+ - **Persistent fan collection**: `/favorites` builds a reusable personal archive, `/news` surfaces dated coverage, `/jobs` tracks background work.
25
+ - **Multilingual**: automatically detects and responds in Thai, Chinese, or English.
26
+ - **Career knowledge dashboard**: 15-question `/quiz`, giftable Developer VIP keys, terminal image `/gallery`, GPU/VRAM `/gpu`, and system `/system` monitors.
27
+ - **Interactive TUI** with rich panels, themes, thinking/reasoning panels, and markdown rendering.
6
28
 
7
29
  ---
8
30
 
@@ -65,7 +87,7 @@ Automatic installation is available for global npm installs. Source checkouts, l
65
87
 
66
88
  After an update or rollback, restart `kiku-agent` and any application hosting `kiku-mcp`. Update settings and rollback history are stored in the normal Kiku user data directory as `update-state.json`; sessions, memory, `.env`, and YouTube cookies are not modified.
67
89
 
68
- For a local checkout before the package is published, use `npm pack` followed by `npm install -g ./kiku-agent-1.0.6.tgz`.
90
+ For a local checkout before the package is published, use `npm pack` followed by `npm install -g ./kiku-agent-1.0.8.tgz`.
69
91
 
70
92
  ### ✨ Features
71
93
  - **LM Studio Integration**: Connects seamlessly to LM Studio's OpenAI-compatible server at `http://127.0.0.1:1234/v1` (default model `google/gemma-4-e4b`, with auto-detection of loaded models).
@@ -76,6 +98,10 @@ For a local checkout before the package is published, use `npm pack` followed by
76
98
  - **Resilient ReAct Loop**: Supports OpenAI function calling as well as structured JSON tool parsing optimized for Gemma models.
77
99
  - **Graceful Diagnostics**: Displays real-time connection status, loaded model names, and fallback search modes if LM Studio is offline.
78
100
  - **Interactive TUI**: Optional Ink-based terminal UI (`npm run kiku-ink`) with themes, thinking panels, and tool result rendering.
101
+ - **Sourced Research**: `/research`, `/verify`, and `/subagent` run bounded workers that cite source URLs; `/sources` lists them and `/suggestion` auto-generates research prompts.
102
+ - **Fan Collection & Discovery**: `/favorites` persists a reusable collection (JSON/Markdown export); `/discover` recommends items by type, year, and mood; `/quiz` awards Developer VIP keys.
103
+ - **Background Jobs**: `/jobs` tracks research, verification, subagent, and suggestion runs with show/cancel/clear controls.
104
+ - **Learned Response Skills**: `/skill learn <instruction>` persists reusable response preferences across sessions.
79
105
 
80
106
  ---
81
107
 
@@ -101,10 +127,11 @@ npm run kiku-agent
101
127
 
102
128
  ### Launch with Specific Cloud Provider & Model
103
129
  ```bash
104
- npm run kiku-agent -- --provider openai --model gpt-4o-mini
105
- npm run kiku-agent -- --provider gemini --model gemini-2.5-flash
106
- npm run kiku-agent -- --provider groq --model llama-3.1-8b-instant
107
- npm run kiku-agent -- --provider openrouter --model google/gemini-2.5-flash
130
+ npm run kiku-agent -- --provider openai --model gpt-5.6-luna
131
+ npm run kiku-agent -- --provider gemini --model gemini-3.7-flash
132
+ npm run kiku-agent -- --provider groq --model openai/gpt-oss-120b
133
+ npm run kiku-agent -- --provider deepseek --model deepseek-v4-flash
134
+ npm run kiku-agent -- --provider openrouter --model openrouter/auto
108
135
  ```
109
136
 
110
137
  ### One-shot Question Query
@@ -124,7 +151,7 @@ npm run kiku-agent -- --model google/gemma-4-e4b-Q4_K_M --url http://127.0.0.1:1
124
151
  | `-V`, `--version` | Print the installed package version and exit |
125
152
  | `-P`, `--provider <name>` | Select active provider (`lmstudio`, `openai`, `gemini`, `groq`, `deepseek`, `openrouter`, `custom`) |
126
153
  | `-k`, `--api-key <key>` | Specify API key for cloud provider |
127
- | `-m`, `--model <id>` | Override model ID (e.g. `gpt-4o-mini`, `google/gemma-4-e4b-Q4_K_M`) |
154
+ | `-m`, `--model <id>` | Override model ID (e.g. `gpt-5.6-luna`, `google/gemma-4-e4b-Q4_K_M`) |
128
155
  | `-u`, `--url <url>` | Override provider base URL |
129
156
  | `-t`, `--tools` | List all registered tools |
130
157
  | `-s`, `--stats` | Print catalog overview statistics |
@@ -150,11 +177,17 @@ Run `/help` inside a session for the full list. Commonly used:
150
177
  - `/model reconnect` — Recheck server and leave catalog-only mode after a chat model is loaded
151
178
  - `/doctor` — Check Node, writable app data, LM Studio, model availability, FFmpeg, speaker, and yt-dlp
152
179
  - `/update [check|install|channel|rollback]` — Manage npm-backed CLI and MCP package updates
153
- - `/tools` — View all tool names and parameter descriptions
180
+ - `/tools` — View all tool names and parameter descriptions
181
+ - `/find <query> [--type <type>] [--year YYYY]` — Search works, songs, roles, brands, awards, photos, and stages without a chat model; when an LLM is available it adds a short explanation of why the top results match your query
182
+ - `/compare <item-a> -- <item-b>` — Compare two catalog entries or two career years side by side; when an LLM is available it adds a natural-language summary of the differences
183
+ - `/favorites [list|add|remove|export|suggest]` — Build a persistent personal collection and export it as JSON or Markdown; `suggest` uses an LLM (when available) to recommend items that fit your saved taste
184
+ - `/news [topic] [--days N] [--official-only]` — Find recent source-backed coverage with available dates and URLs; when an LLM is available it adds a short desk-style summary of the results
185
+ - `/jobs [list|show|cancel|clear]` — Inspect and control research, verification, subagent, and suggestion jobs
186
+ - `/discover [drama|song|stage|photo]` — Pick a catalog recommendation with optional year and mood filters; when an LLM is available it also adds a short AI rationale for the pick (falls back to catalog-only offline)
154
187
  - `/details [Qn]` — Open a compact diagnostic overview for the latest or selected question (F2 opens latest)
155
188
  - `/details [Qn] answer|thinking|tools` — Inspect one diagnostic section without dumping every raw result
156
189
  - `/details [Qn] tool <n>` — Inspect bounded raw arguments and result for one tool call
157
- - `/stats` — Print summary counts of dramas, songs, brands, and awards
190
+ - `/stats` — Print summary counts of dramas, songs, brands, and awards; when an LLM is available it adds a one-line insight about the snapshot
158
191
  - `/thinking [show|hide]` — Toggle reasoning process visibility
159
192
  - `/save` — Export session transcript to Markdown file
160
193
  - `/history` — Review conversation history
@@ -169,7 +202,72 @@ Run `/help` inside a session for the full list. Commonly used:
169
202
  - `/clear` — Reset conversation history
170
203
  - `/exit` — Exit the agent
171
204
 
172
- ---
205
+ ##### AI-compatible commands
206
+ `/find`, `/compare`, `/favorites suggest`, `/news`, `/discover`, and `/stats` are **catalog-native + AI-enhanced**: they run fully in catalog-only mode with no model, and layer a short, bounded AI narration on top whenever a chat model is available. All AI output is sanitized (ANSI-injection-safe), length-capped, respects `/lang`, and **always** falls back silently to the plain result if the model is missing or errors — so the commands never crash or block in offline mode. Deliberately **not** AI-driven are commands that execute side effects or mutate config/credentials (`/tool`, `/mcp`, `/provider`, `/model`, `/key`, `/login`, `/play` & music controls, `/update`, `/copy`, `/exit`).
207
+
208
+ #### Memory & Session commands
209
+ - `/mem add <fact>` / `/mem search <query>` — Add to or search long-term memory
210
+ - `/mem list`, `/mem topics`, `/mem del <id>` — Review, summarize, or delete stored facts
211
+ - `/mem import <path>` / `/mem export` / `/mem clear` — Back up, restore, or reset memory
212
+ - `/session info|list|export|clear` — Manage the current session and its transcript
213
+ - `/history [n|search|clear]` — View or search prior conversation turns
214
+ - `/save` — Export the session transcript to a Markdown file
215
+ - `/copy [Qn] [answer|thinking|tools|all|markdown]` — Copy untruncated model output or diagnostics to the clipboard
216
+
217
+ #### Language & Appearance
218
+ - `/lang [th|zh|en|auto]` — Set the response language
219
+ - `/theme [name|list|current|reset]` — Switch or inspect the terminal color theme
220
+ - `/thinking [show|hide|toggle]` — Control reasoning-visibility
221
+
222
+ #### Diagnostics & System
223
+ - `/details [Qn] [overview|answer|thinking|tools|tool n]` — Inspect query diagnostics (F2 opens the latest)
224
+ - `/stats` — Print summary counts of the catalog database
225
+ - `/system` — Show OS, CPU, RAM, and heap information
226
+ - `/gpu [status]` — Show GPU & VRAM resource metrics (NVIDIA)
227
+ - `/ping` — Check active model server latency
228
+ - `/config` — Show runtime configuration
229
+ - `/prompt` — Preview the active system persona
230
+ - `/doctor` — Check first-run environment and optional features
231
+ - `/about` / `/version` — Show info and installed package version
232
+
233
+ #### Extras & Engagement
234
+ - `/gallery` — Render the next Ju Jingyi image directly in the terminal
235
+ - `/quiz [lang]` — Take the 15-question quiz; correctly completing it claims a Developer VIP Key
236
+ - `/key [show|apply <key>|clear]` — Manage your Developer VIP API Key
237
+ - `/ads` — Show the next sponsor card
238
+ - `/retry` — Retry the previous query
239
+ - `/cancel` — Abort the running query, tool, or subagent task
240
+
241
+ #### Research & Collection (advanced)
242
+ - `/suggestion [list|run <id|all>|auto|refresh|topic <name>]` — Auto-generate research prompts and execute them with concurrent subagents
243
+ - `/subagent <task>` — Run a single bounded Ju Jingyi research worker
244
+ - `/research <question|status|last|sources|cancel>` — Coordinate parallel catalog/web/verification workers and synthesize a sourced answer
245
+ - `/verify <claim>` — Classify a claim as verified, unverified, conflicting, or false
246
+ - `/sources` — Show source URLs captured by the latest research run
247
+ - `/jobs [list|show|cancel|clear]` — Inspect and control research, verification, subagent, and suggestion jobs
248
+
249
+ Examples:
250
+
251
+ ```text
252
+ /find "In Blossom" --type work
253
+ /compare "In Blossom" -- "Beauty of Resilience"
254
+ /compare 2024 -- 2025
255
+ /favorites add song "Rain Love"
256
+ /favorites list --type song
257
+ /favorites export markdown
258
+ /news ซีรีส์ใหม่ --days 14 --official-only
259
+ /jobs list
260
+ /discover song --mood calm
261
+ /research "Ju Jingyi 2026 upcoming dramas"
262
+ /verify "Ju Jingyi is a Versace brand ambassador"
263
+ /suggestion auto
264
+ /subagent "List Ju Jingyi's fashion brand partnerships"
265
+ /skill learn "ตอบภาษาไทยแบบสั้น กระชับ"
266
+ /quiz lang th
267
+ /mem add "Ju Jingyi debuted with SNH48 in 2013"
268
+ ```
269
+
270
+ ---
173
271
 
174
272
  ## 📚 Available API Tools in Kiku Agent (38)
175
273
 
@@ -227,30 +325,33 @@ Run `/help` inside a session for the full list. Commonly used:
227
325
  | Provider | Recommended Active Models | Pricing / Cost Tier | Doc & API Reference | Required ENV Variable |
228
326
  |---|---|---|---|---|
229
327
  | **LM Studio** (Local) | `google/gemma-4-e4b` *(Q4_K_M, Q6_K, Q8_0)* | **100% Free / Local** (Zero token cost) | [Docs](https://lmstudio.ai/docs) • [API Ref](https://lmstudio.ai/docs/api/local-server) | `LMSTUDIO_BASE_URL` (default: `http://127.0.0.1:1234/v1`) |
230
- | **OpenAI** | `gpt-4o-mini` *(default)*, `gpt-4o`, `o3-mini` | **Ultra-Cheap** (~$0.15 / 1M input) | [Docs](https://platform.openai.com/docs) • [API Ref](https://platform.openai.com/docs/api-reference) | `OPENAI_API_KEY` |
231
- | **Google Gemini** | `gemini-2.5-flash` *(default)*, `gemini-2.5-flash-lite`, `gemini-2.5-pro`, `gemini-3.1-pro` | **Ultra-Cheap** ($0.10 / 1M in, 1M-2M context) | [Docs](https://ai.google.dev/docs) • [API Ref](https://ai.google.dev/api) | `GEMINI_API_KEY` |
232
- | **Groq** | `llama-3.3-70b-versatile` *(default)*, `llama-3.1-8b-instant`, `gpt-oss-120b` | **LPU Ultra-Fast** ($0.05 - $0.59 / 1M in) | [Docs](https://console.groq.com/docs/quickstart) • [API Ref](https://console.groq.com/docs/api-reference) | `GROQ_API_KEY` |
233
- | **DeepSeek** | `deepseek-chat` *(default, V3)*, `deepseek-reasoner` *(R1 CoT)* | **Ultra-Low Cost** ($0.14 - $0.27 / 1M in) | [Docs](https://api-docs.deepseek.com) • [API Ref](https://api-docs.deepseek.com/api/create-chat-completion) | `DEEPSEEK_API_KEY` |
234
- | **OpenRouter** | `google/gemini-2.5-flash`, `deepseek/deepseek-chat`, `deepseek/deepseek-r1`, `meta-llama/llama-3.3-70b-instruct`, `qwen/qwen-2.5-72b-instruct`, `:free` | **Flexible Aggregator** (Free & Paid) | [Docs](https://openrouter.ai/docs/quick-start) • [API Ref](https://openrouter.ai/docs/api_reference/overview) | `OPENROUTER_API_KEY` |
328
+ | **OpenAI** | `gpt-5.6-luna` *(default)*, `gpt-5.6-terra`, `gpt-5.6-sol` | **Cost-sensitive → Flagship** ($0.20 - $4.00 / 1M input) | [Docs](https://developers.openai.com/api/docs/models) • [API Ref](https://developers.openai.com/api/reference) | `OPENAI_API_KEY` |
329
+ | **Google Gemini** | `gemini-3.7-flash` *(default)*, `gemini-3.5-flash-lite`, `gemini-3.6-flash` | **Free tier / Stable Flash** ($0.30 - $0.75 / 1M input) | [Docs](https://ai.google.dev/gemini-api/docs/models) • [API Ref](https://ai.google.dev/api/generate-content) | `GEMINI_API_KEY` |
330
+ | **Groq** | `openai/gpt-oss-120b` *(default)*, `openai/gpt-oss-20b` | **LPU Ultra-Fast** ($0.075 - $0.15 / 1M input) | [Docs](https://console.groq.com/docs/quickstart) • [API Ref](https://console.groq.com/docs/api-reference) | `GROQ_API_KEY` |
331
+ | **DeepSeek** | `deepseek-v4-flash` *(default)*, `deepseek-v4-pro` | **V4 / 1M context** ($0.22 - $1.32 / 1M uncached input) | [Docs](https://api-docs.deepseek.com/quick_start/pricing/) • [API Ref](https://api-docs.deepseek.com/api/create-chat-completion) | `DEEPSEEK_API_KEY` |
332
+ | **OpenRouter** | `openrouter/auto` *(default, dynamic catalog)* | **Automatic routing** (billed at routed model rate) | [Docs](https://openrouter.ai/docs/guides/routing/routers/auto-router) • [API Ref](https://openrouter.ai/docs/api/reference/overview) | `OPENROUTER_API_KEY` |
235
333
  | **Custom Gateway** | Any OpenAI-compatible server (vLLM, Ollama, TGI, Azure) | **Custom** | [OpenAI Spec](https://platform.openai.com/docs/api-reference) | `LLM_BASE_URL`, `LLM_API_KEY` |
236
334
 
237
335
  ```bash
238
336
  # Launch with a specific cloud provider and model
239
- npm run kiku-agent -- --provider openai --model gpt-4o-mini
240
- npm run kiku-agent -- --provider gemini --model gemini-2.5-flash
241
- npm run kiku-agent -- --provider groq --model llama-3.1-8b-instant
242
- npm run kiku-agent -- --provider openrouter --model google/gemini-2.5-flash
337
+ npm run kiku-agent -- --provider openai --model gpt-5.6-luna
338
+ npm run kiku-agent -- --provider gemini --model gemini-3.7-flash
339
+ npm run kiku-agent -- --provider groq --model openai/gpt-oss-120b
340
+ npm run kiku-agent -- --provider deepseek --model deepseek-v4-flash
341
+ npm run kiku-agent -- --provider openrouter --model openrouter/auto
243
342
 
244
343
  # Manage providers interactively within the agent CLI
245
344
  /provider list # View all 7 providers and key status
246
- /provider use groq llama-3.1-8b-instant # Switch provider and model in one command
345
+ /provider use groq openai/gpt-oss-120b # Switch provider and model in one command
247
346
  /provider models gemini # List curated cost-effective models with pricing & context
248
347
  /provider info openai # Show developer documentation & API details
249
348
  /provider test groq # Test live endpoint connection and measure latency
250
349
  /provider setkey groq gsk-... # Set or update API key dynamically at runtime
251
350
  /model recommend # View recommended models for active provider
252
- /model use gpt-4o-mini # Switch active model on current provider
253
- ```
351
+ /model use gpt-5.6-luna # Switch active model on current provider
352
+ ```
353
+
354
+ At interactive startup, provider switches, and before a one-shot query, the CLI checks the provider's live `/models` catalog. If a configured model has been retired, it selects the first available model from that provider's maintained recommendation list and reports the fallback. Legacy IDs for Groq, DeepSeek, and selected renamed models are normalized automatically.
254
355
 
255
356
  ---
256
357
 
@@ -262,7 +363,19 @@ The package ships a Model Context Protocol server exposing the catalog as tools,
262
363
  # stdio transport (Claude Desktop, Cursor, ...)
263
364
  npm run kiku-mcp
264
365
  ```
265
- The production deployment exposes a stateless Streamable HTTP endpoint at `https://jujingyi-kikuuu.vercel.app/mcp` (`POST /mcp`).
366
+ The production deployment exposes a stateless Streamable HTTP endpoint at `https://jujingyi-kikuuu.vercel.app/mcp` (`POST /mcp`). The server offers catalog tools (`search_works`, `get_work_detail`, `search_discography`, `get_brand_endorsements`, `get_awards`, `get_career_timeline`, `global_search`, …), resources, and prompts — see `server/mcp/`.
367
+
368
+ **HTTP security** — the remote MCP endpoint is guarded by a bearer token and CORS allow-list:
369
+ - Set `MCP_API_KEY` to require `Authorization: Bearer <MCP_API_KEY>` on `POST /mcp`.
370
+ - Set `MCP_CORS_ORIGINS` to a comma-separated list of allowed browser origins (empty = no CORS).
371
+
372
+ ```bash
373
+ # Example: curl the Streamable HTTP endpoint
374
+ curl -X POST https://jujingyi-kikuuu.vercel.app/mcp \
375
+ -H "Authorization: Bearer $MCP_API_KEY" \
376
+ -H "Content-Type: application/json" \
377
+ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}'
378
+ ```
266
379
 
267
380
  ### 2. MCP Client in `kiku-agent`
268
381
  `kiku-agent` can connect to external MCP servers (Streamable HTTP, Stdio) and dynamically load their tools:
@@ -273,7 +386,9 @@ The production deployment exposes a stateless Streamable HTTP endpoint at `https
273
386
  /mcp tools
274
387
  ```
275
388
 
276
- `/mcp` shows the connection summary plus every available MCP tool command in a compact list. `/mcp tools` expands the same list with parameters and descriptions. Long command panels open at their first page in the classic TUI; use Page Down or End to continue through the result.
389
+ `/mcp` shows the connection summary plus every available MCP tool command in a compact list. `/mcp tools` expands the same list with parameters and descriptions. Long command panels open at their first page in the classic TUI; use Page Down or End to continue through the result. Manage persistent connections with `/mcp status|list|disconnect <name>|remove <name>|reconnect [all]|save|reload`.
390
+
391
+ > **Note on web tools:** MCP web tools are gated behind `KIKU_MCP_ENABLE_WEB_TOOLS=true`.
277
392
 
278
393
  ---
279
394
 
@@ -294,23 +409,194 @@ Copy `.env.example` → `.env` (parsed automatically when the CLI runs; only uns
294
409
  | `KIKU_YT_BROWSER` | Import cookies from a browser (`chrome`, `edge`, `firefox`) |
295
410
  | `KIKU_YTDLP` | Path/command for yt-dlp binary (default `yt-dlp`) |
296
411
  | `KIKU_YTDLP_CLIENT` | YouTube player client override (`tv`, `ios`, `web`) |
412
+ | `MCP_API_KEY` | Bearer token required by the HTTP MCP endpoint (`POST /mcp`) |
413
+ | `MCP_CORS_ORIGINS` | Comma-separated allowed origins for browser MCP calls |
414
+ | `KIKU_MCP_ENABLE_WEB_TOOLS` | Set `true` to enable web tools in the MCP server |
415
+ | `KIKU_API_KEYS` | Pre-seeded REST API keys (higher rate limits) |
416
+ | `KIKU_VIP_KEYS` | Pre-seeded Developer VIP API keys (highest rate limits) |
297
417
 
298
418
  > `.env` is gitignored — never commit it. The checked-in `.env.example` contains placeholders only.
419
+ > Likewise, `cookies.txt` at the repo root contains real YouTube session cookies and must never be staged.
299
420
 
300
421
  ---
301
422
 
302
- ## 🌐 Web App & API Development
423
+ ## 🧭 Web App & API Development
303
424
 
425
+ ### Frontend (Vite + React 19 + Tailwind 4)
304
426
  ```bash
305
427
  # Start frontend dev server (API v1 works in-process)
306
428
  npm run dev
307
429
 
308
430
  # Production build
309
431
  npm run build
432
+ ```
433
+ The SPA lives in `src/` (entry `src/App.jsx`) and is state-navigated via `NavigationContext` (no react-router). All non-API paths rewrite to `/` in `vercel.json`.
310
434
 
311
- # Run unit tests (agent + MCP, no LM Studio required)
312
- npm test
435
+ ### REST API v1
436
+ The API is a single framework-free Node handler in `server/apiRouter.js` (~2000 lines) serving every `/api/v1/*` route plus interactive docs and an OpenAPI spec.
313
437
 
314
- # Run API verification tests against localhost:3000
315
- powershell -ExecutionPolicy Bypass -File test_api.ps1 -BaseHost localhost:3000
316
- ```
438
+ - **Base URL (prod):** `https://jujingyi-kikuuu.vercel.app/api/v1`
439
+ - **Base URL (dev):** `http://localhost:3000/api/v1`
440
+ - **Interactive docs:** `https://jujingyi-kikuuu.vercel.app/api-docs`
441
+ - **OpenAPI 3.0 JSON:** `https://jujingyi-kikuuu.vercel.app/api/v1/openapi.json`
442
+ - **Health check:** `GET /api/v1/health`
443
+
444
+ ```bash
445
+
446
+ ---
447
+
448
+ ## 🔌 Model Context Protocol (MCP)
449
+
450
+ ### 1. MCP Server (`kiku-mcp`)
451
+ The package ships a Model Context Protocol server exposing the catalog as tools, resources, and prompts:
452
+ ```bash
453
+ # stdio transport (Claude Desktop, Cursor, ...)
454
+ npm run kiku-mcp
455
+ ```
456
+ The production deployment exposes a stateless Streamable HTTP endpoint at `https://jujingyi-kikuuu.vercel.app/mcp` (`POST /mcp`). The server offers catalog tools (`search_works`, `get_work_detail`, `search_discography`, `get_brand_endorsements`, `get_awards`, `get_career_timeline`, `global_search`, …), resources, and prompts — see `server/mcp/`.
457
+
458
+ **HTTP security** — the remote MCP endpoint is guarded by a bearer token and CORS allow-list:
459
+ - Set `MCP_API_KEY` to require `Authorization: Bearer <MCP_API_KEY>` on `POST /mcp`.
460
+ - Set `MCP_CORS_ORIGINS` to a comma-separated list of allowed browser origins (empty = no CORS).
461
+
462
+ ```bash
463
+ # Example: curl the Streamable HTTP endpoint
464
+ curl -X POST https://jujingyi-kikuuu.vercel.app/mcp \
465
+ -H "Authorization: Bearer $MCP_API_KEY" \
466
+ -H "Content-Type: application/json" \
467
+ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}'
468
+ ```
469
+
470
+ ### 2. MCP Client in `kiku-agent`
471
+ `kiku-agent` can connect to external MCP servers (Streamable HTTP, Stdio) and dynamically load their tools:
472
+ ```bash
473
+ # Connect to an MCP server from CLI:
474
+ /mcp connect kiku-remote https://jujingyi-kikuuu.vercel.app/mcp
475
+ /mcp connect filesystem stdio npx -y @modelcontextprotocol/server-filesystem ./
476
+ /mcp tools
477
+ ```
478
+
479
+ `/mcp` shows the connection summary plus every available MCP tool command in a compact list. `/mcp tools` expands the same list with parameters and descriptions. Long command panels open at their first page in the classic TUI; use Page Down or End to continue through the result. Manage persistent connections with `/mcp status|list|disconnect <name>|remove <name>|reconnect [all]|save|reload`.
480
+
481
+ > **Note on web tools:** MCP web tools are gated behind `KIKU_MCP_ENABLE_WEB_TOOLS=true`.
482
+
483
+ ---
484
+
485
+ ## ⚙️ Environment Variables
486
+
487
+ Copy `.env.example` → `.env` (parsed automatically when the CLI runs; only unset variables are filled):
488
+
489
+ | Variable | Purpose |
490
+ |---|---|
491
+ | `LLM_PROVIDER` | Active provider override (`openai`, `openrouter`, `groq`, `deepseek`, `gemini`, `lmstudio`, `custom`) |
492
+ | `OPENAI_API_KEY` | OpenAI API Key |
493
+ | `OPENROUTER_API_KEY` | OpenRouter API Key |
494
+ | `GROQ_API_KEY` | Groq Cloud API Key |
495
+ | `DEEPSEEK_API_KEY` | DeepSeek API Key |
496
+ | `GEMINI_API_KEY` | Google Gemini API Key |
497
+ | `LMSTUDIO_BASE_URL` | LM Studio endpoint (default `http://127.0.0.1:1234/v1`) |
498
+ | `KIKU_YT_COOKIES` | Path to a `cookies.txt` file for YouTube playback |
499
+ | `KIKU_YT_BROWSER` | Import cookies from a browser (`chrome`, `edge`, `firefox`) |
500
+ | `KIKU_YTDLP` | Path/command for yt-dlp binary (default `yt-dlp`) |
501
+ | `KIKU_YTDLP_CLIENT` | YouTube player client override (`tv`, `ios`, `web`) |
502
+ | `MCP_API_KEY` | Bearer token required by the HTTP MCP endpoint (`POST /mcp`) |
503
+ | `MCP_CORS_ORIGINS` | Comma-separated allowed origins for browser MCP calls |
504
+ | `KIKU_MCP_ENABLE_WEB_TOOLS` | Set `true` to enable web tools in the MCP server |
505
+ | `KIKU_API_KEYS` | Pre-seeded REST API keys (higher rate limits) |
506
+ | `KIKU_VIP_KEYS` | Pre-seeded Developer VIP API keys (highest rate limits) |
507
+
508
+ > `.env` is gitignored — never commit it. The checked-in `.env.example` contains placeholders only.
509
+ > Likewise, `cookies.txt` at the repo root contains real YouTube session cookies and must never be staged.
510
+
511
+ ---
512
+
513
+ ## 🧭 Web App & API Development
514
+
515
+ ### Frontend (Vite + React 19 + Tailwind 4)
516
+ ```bash
517
+ # Start frontend dev server (API v1 works in-process)
518
+ npm run dev
519
+
520
+ # Production build
521
+ npm run build
522
+ ```
523
+ The SPA lives in `src/` (entry `src/App.jsx`) and is state-navigated via `NavigationContext` (no react-router). All non-API paths rewrite to `/` in `vercel.json`.
524
+
525
+ ### REST API v1
526
+ The API is a single framework-free Node handler in `server/apiRouter.js` (~2000 lines) serving every `/api/v1/*` route plus interactive docs and an OpenAPI spec.
527
+
528
+ - **Base URL (prod):** `https://jujingyi-kikuuu.vercel.app/api/v1`
529
+ - **Base URL (dev):** `http://localhost:3000/api/v1`
530
+ - **Interactive docs:** `https://jujingyi-kikuuu.vercel.app/api-docs`
531
+ - **OpenAPI 3.0 JSON:** `https://jujingyi-kikuuu.vercel.app/api/v1/openapi.json`
532
+ - **Health check:** `GET /api/v1/health`
533
+
534
+ ```bash
535
+ curl https://jujingyi-kikuuu.vercel.app/api/v1/health
536
+ ```
537
+
538
+ Endpoint groups include catalog (works, discography, brands, awards, timeline, profile, gallery), stats, quiz challenges and Developer VIP key claiming (`/api/v1/quiz/challenge`, `/api/v1/keys/claim`), plus agent/REST integration. `?key=` or bearer auth with a `KIKU_API_KEYS` / `KIKU_VIP_KEYS` value unlocks higher rate limits.
539
+
540
+ In production `/api/*` is served by the Vercel serverless wrapper.
541
+
542
+ ## 🗃️ Data architecture & gotchas
543
+
544
+ - **The catalog exists twice** — `src/data/*.js` (used by the SPA, REST API, and agent tools) and `server/mcp/data/*.js` (used by the MCP server) are two independent copies with the same export names but different content (the site copy is richer and Thai-heavy; the MCP copy is compact English). **Any catalog change must be applied to both trees**, or MCP answers will drift from the site/API.
545
+ - **Packaging**: `package.json` `"files"` ships `src/data/**/*.js` because the agent imports them — don't move that directory without updating both `"files"` and every importer. Bins are `kiku-agent` and `kiku-mcp`; package exports map `.` → `server/agent/agentCore.js`.
546
+ - **Path aliases**: the `@/*` alias in `jsconfig.json` is unused — use relative imports everywhere (no matching alias in `vite.config.js`).
547
+ - **No linter/formatter/typecheck**: verification is `npm test` plus a successful build. CI (GitHub Actions) only runs Snyk + secret scanning.
548
+
549
+ ---
550
+
551
+ ## 🧱 Project structure
552
+
553
+ ```
554
+ ├── src/ # Vite + React 19 + Tailwind 4 fan portal (SPA)
555
+ │ ├── App.jsx # Entry (state-based navigation)
556
+ │ ├── components/ # Navbar, Hero, MusicPlayer, ApiDocsModal, …
557
+ │ ├── pages/ # Biography, Dramas, Music, Gallery, …
558
+ │ ├── data/ # Rich, Thai-heavy catalog (shared with API + agent)
559
+ │ └── context/ # NavigationContext, i18n, …
560
+ ├── server/
561
+ │ ├── apiRouter.js # All /api/v1/* routes, /api-docs, /openapi.json
562
+ │ ├── agent/ # Agent CLI core, tools, commands, TUI (ui.js), memory,
563
+ │ │ # research/subagent/verify, suggestions, job manager,
564
+ │ │ # audio player, MCP client, model/provider manager, …
565
+ │ ├── mcp/ # MCP server (stdio.js) + compact English catalog data
566
+ │ └── supabase_schema.sql # Optional SQL for a hosted database
567
+ ├── api/ # Vercel serverless wrappers (delegate to apiRouter)
568
+ ├── test_api.ps1 # API verification suite
569
+ └── .env.example # Environment variable template
570
+ ```
571
+
572
+ ---
573
+
574
+ ## 🧰 Troubleshooting
575
+
576
+ **Agent won't start or stays in catalog-only mode**
577
+ - Ensure LM Studio is running with a Gemma model loaded and the local server on `127.0.0.1:1234`, or pass a cloud provider + key.
578
+ - Run `/doctor` inside the session to diagnose Node, app data, LM Studio, model, FFmpeg, speaker, and yt-dlp availability. If no chat model is available, Kiku deliberately starts in catalog-only mode instead of crashing.
579
+
580
+ **Windows install fails with `EBUSY` on `ffmpeg-static`**
581
+ - Close every Kiku/Node terminal, then in a fresh PowerShell: `npm uninstall -g kiku-agent`, remove the stale `kiku-agent` folder under `npm root -g`, `npm cache verify`, then reinstall.
582
+
583
+ **Kiku tries to write to a protected folder**
584
+ - Remove any old `KIKU_DATA_DIR` user override and upgrade to ≥ 1.0.2. Sessions live in `%APPDATA%\kiku-agent` on Windows; no Administrator rights are needed.
585
+
586
+ **YouTube playback fails**
587
+ - Re-authenticate with `/login`, or point `KIKU_YT_COOKIES` / `KIKU_YT_BROWSER` at a valid session and `KIKU_YTDLP` at a working yt-dlp binary. Some regions/clients need `KIKU_YTDLP_CLIENT` set to `tv` or `ios`.
588
+
589
+ **Remote MCP returns 401**
590
+ - Set `MCP_API_KEY` on the server and send `Authorization: Bearer <MCP_API_KEY>`; for browser clients, set `MCP_CORS_ORIGINS` to the allowed origins.
591
+
592
+ **MCP answers disagree with the site/API**
593
+ - The catalog lives in two copies (`src/data` vs `server/mcp/data`). Update both trees whenever a fact changes.
594
+
595
+ **Reports of missing or stale model after switching providers**
596
+ - The CLI re-checks the live `/models` catalog at startup, on provider switches, and before one-shot queries, auto-falling back to that provider's recommendation list if a configured model was retired.
597
+
598
+ ---
599
+
600
+ ## 📄 License
601
+
602
+ This project is licensed under the [GNU General Public License v3.0 (GPL-3.0)](LICENSE).