zenn-rag 0.1.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.
Files changed (79) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +221 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +68 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/commands/index.d.ts +6 -0
  8. package/dist/commands/index.d.ts.map +1 -0
  9. package/dist/commands/index.js +11 -0
  10. package/dist/commands/index.js.map +1 -0
  11. package/dist/commands/mcp.d.ts +2 -0
  12. package/dist/commands/mcp.d.ts.map +1 -0
  13. package/dist/commands/mcp.js +245 -0
  14. package/dist/commands/mcp.js.map +1 -0
  15. package/dist/commands/search.d.ts +10 -0
  16. package/dist/commands/search.d.ts.map +1 -0
  17. package/dist/commands/search.js +37 -0
  18. package/dist/commands/search.js.map +1 -0
  19. package/dist/commands/status.d.ts +2 -0
  20. package/dist/commands/status.d.ts.map +1 -0
  21. package/dist/commands/status.js +111 -0
  22. package/dist/commands/status.js.map +1 -0
  23. package/dist/config.d.ts +28 -0
  24. package/dist/config.d.ts.map +1 -0
  25. package/dist/config.js +88 -0
  26. package/dist/config.js.map +1 -0
  27. package/dist/embedder.d.ts +17 -0
  28. package/dist/embedder.d.ts.map +1 -0
  29. package/dist/embedder.js +31 -0
  30. package/dist/embedder.js.map +1 -0
  31. package/dist/index.d.ts +12 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +12 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/logger.d.ts +31 -0
  36. package/dist/logger.d.ts.map +1 -0
  37. package/dist/logger.js +56 -0
  38. package/dist/logger.js.map +1 -0
  39. package/dist/parser.d.ts +56 -0
  40. package/dist/parser.d.ts.map +1 -0
  41. package/dist/parser.js +214 -0
  42. package/dist/parser.js.map +1 -0
  43. package/dist/providers/base.d.ts +2 -0
  44. package/dist/providers/base.d.ts.map +1 -0
  45. package/dist/providers/base.js +4 -0
  46. package/dist/providers/base.js.map +1 -0
  47. package/dist/providers/factory.d.ts +4 -0
  48. package/dist/providers/factory.d.ts.map +1 -0
  49. package/dist/providers/factory.js +27 -0
  50. package/dist/providers/factory.js.map +1 -0
  51. package/dist/providers/gemini.d.ts +20 -0
  52. package/dist/providers/gemini.d.ts.map +1 -0
  53. package/dist/providers/gemini.js +79 -0
  54. package/dist/providers/gemini.js.map +1 -0
  55. package/dist/providers/ollama.d.ts +14 -0
  56. package/dist/providers/ollama.d.ts.map +1 -0
  57. package/dist/providers/ollama.js +38 -0
  58. package/dist/providers/ollama.js.map +1 -0
  59. package/dist/providers/openai.d.ts +18 -0
  60. package/dist/providers/openai.d.ts.map +1 -0
  61. package/dist/providers/openai.js +65 -0
  62. package/dist/providers/openai.js.map +1 -0
  63. package/dist/providers/types.d.ts +7 -0
  64. package/dist/providers/types.d.ts.map +1 -0
  65. package/dist/providers/types.js +2 -0
  66. package/dist/providers/types.js.map +1 -0
  67. package/dist/services/sync-service.d.ts +28 -0
  68. package/dist/services/sync-service.d.ts.map +1 -0
  69. package/dist/services/sync-service.js +310 -0
  70. package/dist/services/sync-service.js.map +1 -0
  71. package/dist/store.d.ts +35 -0
  72. package/dist/store.d.ts.map +1 -0
  73. package/dist/store.js +180 -0
  74. package/dist/store.js.map +1 -0
  75. package/dist/types.d.ts +49 -0
  76. package/dist/types.d.ts.map +1 -0
  77. package/dist/types.js +2 -0
  78. package/dist/types.js.map +1 -0
  79. package/package.json +61 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 SoraKumo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the \"Software\"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,221 @@
1
+ # zenn-rag
2
+
3
+ Zenn 記事リポジトリのための **Vector DB & RAG(検索・執筆支援)ツールキット**。
4
+ Markdown記事を見出し単位でベクトル化し、CLI検索および **Model Context Protocol (MCP)** サーバー経由でエディタやAIアシスタント(Cursor、Claude、Antigravityなど)と連携できます。
5
+
6
+ ---
7
+
8
+ ## 主な機能
9
+
10
+ - **コードブロック保護付き階層チャンキング**: Frontmatterメタデータ(タイトル・トピック)と見出し(H1〜H3)の階層構造を保持し、コードブロックを途中で切断せずにベクトル化
11
+ - **Zenn 記事(Articles)& 本(Books)の双方に対応**: `articles/*.md` に加え、`books/<book-slug>/*.md` の各チャプターも自動認識してインデックス
12
+ - **自動同期(ウォッチモード)**: `index --watch` でファイル保存時にバックグラウンドで即時差分同期
13
+ - **マルチプロバイダー対応**:
14
+ - **OpenAI / LM Studio / LocalAI**: 高速バッチEmbedding(`text-embedding-bge-m3`, `text-embedding-3-small` など)
15
+ - **Google Gemini**: レートリミット制御・自動リトライ付き(`gemini-embedding-001`)
16
+ - **Ollama**: ローカルオフライン実行(`bge-m3` など)
17
+ - **高速・サーバーレスVector DB**: Apache Arrowベースの **LanceDB** を採用し、コサイン類似度で高精度検索
18
+ - **スマート差分同期**: ファイルのMD5ハッシュで変更を検知し、新規・更新された記事・本チャプターのみを数秒で同期
19
+ - **モデル変更の自動検知**: モデルや次元数が変わった場合は自動でテーブルをリセット&再構築
20
+ - **MCP サーバー標準搭載**: `zenn-rag mcp` でAIエディタから過去記事を参照・引用・リンク推薦・インデックス更新が可能
21
+
22
+ ---
23
+
24
+ ## インストール
25
+
26
+ ```bash
27
+ # グローバルインストール
28
+ pnpm add -g zenn-rag
29
+ # またはプロジェクトに追加
30
+ pnpm add -D zenn-rag
31
+ ```
32
+
33
+ または `npx` で即座に実行できます:
34
+
35
+ ```bash
36
+ npx zenn-rag --help
37
+ ```
38
+
39
+ ---
40
+
41
+ ## 設定(.env)
42
+
43
+ Zenn プロジェクトのルートディレクトリに `.env` を配置します(`.env.example` 参照)。
44
+ 本ツールではプロバイダを切り替えても同じ環境変数名(`BASE_URL`, `EMBEDDING_MODEL`, `API_KEY`)で直感的に設定できます。
45
+
46
+ ### 共通環境変数一覧
47
+
48
+ | 環境変数名 | 必須 | デフォルト値 | 説明 |
49
+ | :------------------- | :----: | :------------------------------------ | :---------------------------------------------------------------------- |
50
+ | `EMBEDDING_PROVIDER` | 任意 | `gemini` または APIキー等から自動判別 | 使用するプロバイダ (`openai` \| `ollama` \| `gemini`) |
51
+ | `BASE_URL` | 任意 | プロバイダ依存 | エンドポイントURL(LM Studio や Ollama 利用時に指定) |
52
+ | `EMBEDDING_MODEL` | 任意 | プロバイダ依存 | 使用する埋め込みモデル名 |
53
+ | `API_KEY` | 条件付 | - | APIキー(Gemini, OpenAI利用時に必須。LM Studio等は任意文字列で可) |
54
+ | `ZENN_USERNAME` | 任意 | - | 記事URL生成用ユーザー名 (`https://zenn.dev/[username]/articles/[slug]`) |
55
+ | `VECTOR_DB_DIR` | 任意 | `.vectordb` | Vector DB (LanceDB) のデータ保存ディレクトリ |
56
+
57
+ > 💡 **Tip**: 従来の `OPENAI_BASE_URL` や `GEMINI_API_KEY`, `OLLAMA_EMBEDDING_MODEL` などのプロバイダ別環境変数もそのまま利用可能です(個別設定がある場合はそちらが優先されます)。
58
+
59
+ ---
60
+
61
+ ### 代表的なプロバイダ設定例
62
+
63
+ #### 1. LM Studio(OpenAI 互換ローカルサーバー / 推奨)
64
+
65
+ 完全ローカルで高速・無料にベクトル化できます。
66
+
67
+ ```env
68
+ EMBEDDING_PROVIDER=openai
69
+ BASE_URL=http://localhost:1234/v1
70
+ EMBEDDING_MODEL=text-embedding-bge-m3
71
+ API_KEY=lm-studio
72
+
73
+ ZENN_USERNAME=your_zenn_id
74
+ VECTOR_DB_DIR=.vectordb
75
+ ```
76
+
77
+ #### 2. Ollama(完全ローカル・オフライン)
78
+
79
+ ```env
80
+ EMBEDDING_PROVIDER=ollama
81
+ BASE_URL=http://localhost:11434
82
+ EMBEDDING_MODEL=bge-m3
83
+
84
+ ZENN_USERNAME=your_zenn_id
85
+ VECTOR_DB_DIR=.vectordb
86
+ ```
87
+
88
+ #### 3. Google Gemini(クラウド)
89
+
90
+ Google AI Studio で取得した無料〜従量課金の API キーを使用します。
91
+
92
+ ```env
93
+ EMBEDDING_PROVIDER=gemini
94
+ API_KEY=AIzaSy...
95
+ EMBEDDING_MODEL=gemini-embedding-001
96
+
97
+ ZENN_USERNAME=your_zenn_id
98
+ ```
99
+
100
+ #### 4. OpenAI API(クラウド)
101
+
102
+ ```env
103
+ EMBEDDING_PROVIDER=openai
104
+ API_KEY=sk-...
105
+ EMBEDDING_MODEL=text-embedding-3-small
106
+
107
+ ZENN_USERNAME=your_zenn_id
108
+ ```
109
+
110
+ ---
111
+
112
+ ## コマンド一覧
113
+
114
+ ### 1. インデックス同期(差分更新・自動同期)
115
+
116
+ ```bash
117
+ # 変更・新規コンテンツのみ差分同期
118
+ npx zenn-rag index
119
+
120
+ # ファイルを監視し、保存時に自動で差分同期(ウォッチモード)
121
+ npx zenn-rag index --watch
122
+
123
+ # 全記事・本を強制再同期
124
+ npx zenn-rag index --force
125
+
126
+ # 対象ディレクトリを指定する場合
127
+ npx zenn-rag index --dir /path/to/zenn-repo
128
+ ```
129
+
130
+ ### 2. 過去記事・本の検索(CLI)
131
+
132
+ ```bash
133
+ # 基本検索
134
+ npx zenn-rag search "Cloudflare Workers WASM"
135
+
136
+ # 取得件数とトピック絞り込み
137
+ npx zenn-rag search "App Router キャッシュ" --limit 3 --topic nextjs
138
+ ```
139
+
140
+ ### 3. 進捗・トピック統計の確認
141
+
142
+ ```bash
143
+ npx zenn-rag status
144
+ ```
145
+
146
+ ### 4. MCPサーバー起動
147
+
148
+ ```bash
149
+ npx zenn-rag mcp
150
+ ```
151
+
152
+ ---
153
+
154
+ ## MCP(AIエディタ連携)設定
155
+
156
+ Antigravity、Claude Desktop、Cursor などのMCP設定ファイルに以下を追加します:
157
+
158
+ ```json
159
+ {
160
+ "mcpServers": {
161
+ "zenn-rag": {
162
+ "command": "npx",
163
+ "args": ["-y", "zenn-rag", "mcp"],
164
+ "cwd": "/path/to/your/zenn-repo"
165
+ }
166
+ }
167
+ }
168
+ ```
169
+
170
+ ### 提供ツール
171
+
172
+ - **`search_articles`**: 自然言語でクエリに類似する過去記事・本チャプターのセクション・スコア・URLを検索
173
+ - **`suggest_related_links`**: 執筆中の文章やメモから、引用・内部リンクすべき関連記事や本をMarkdownリンク形式で推薦
174
+ - **`get_article`**: スラッグを指定して記事・チャプター全体の構成や内容を取得
175
+ - **`list_topics`**: 蓄積されたコンテンツの全トピックと件数を集計
176
+ - **`sync_index`**: AIエディタ内から直接インデックスの差分更新を実行
177
+
178
+ ---
179
+
180
+ ## ライブラリとしての利用
181
+
182
+ ```typescript
183
+ import {
184
+ searchArticles,
185
+ syncIndex,
186
+ ArticleVectorStore,
187
+ initContext,
188
+ } from "zenn-rag";
189
+
190
+ // コンテキストの初期化
191
+ initContext("/path/to/zenn-repo");
192
+
193
+ // 検索実行
194
+ const results = await searchArticles("React Server Actions", { limit: 3 });
195
+ console.log(results);
196
+ ```
197
+
198
+ ---
199
+
200
+ ## 開発
201
+
202
+ ```bash
203
+ # 依存パッケージのインストール
204
+ pnpm install
205
+
206
+ # ビルド(TypeScript 公式コンパイラ tsc で dist/ に出力)
207
+ pnpm run build
208
+
209
+ # テスト実行
210
+ pnpm test
211
+
212
+ # ウォッチモード(ビルド / テスト)
213
+ pnpm run dev
214
+ pnpm run test:watch
215
+ ```
216
+
217
+ ---
218
+
219
+ ## ライセンス
220
+
221
+ MIT
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import { initContext } from "./config.js";
4
+ import { syncIndex } from "./commands/index.js";
5
+ import { searchCli } from "./commands/search.js";
6
+ import { showStatus } from "./commands/status.js";
7
+ import { runMcpServer } from "./commands/mcp.js";
8
+ import { getLogger } from "./logger.js";
9
+ const program = new Command();
10
+ const logger = getLogger();
11
+ function handleCliAction(action) {
12
+ return async () => {
13
+ try {
14
+ await action();
15
+ }
16
+ catch (err) {
17
+ const message = err instanceof Error ? err.message : String(err);
18
+ logger.error(`\n[エラー発生]: ${message}`);
19
+ process.exit(1);
20
+ }
21
+ };
22
+ }
23
+ program
24
+ .name("zenn-rag")
25
+ .description("Zenn articles Vector DB & RAG toolkit with MCP server")
26
+ .version("0.1.0");
27
+ // 1. index
28
+ program
29
+ .command("index")
30
+ .description("Zenn記事をベクトル化してVector DBに同期します(差分更新対応)")
31
+ .option("-f, --force", "既存のインデックスを破棄して全件再同期する")
32
+ .option("-w, --watch", "ファイルを監視して変更時に自動で差分同期する")
33
+ .option("-d, --dir <path>", "Zennプロジェクトのルートディレクトリ(デフォルト: カレントディレクトリ)")
34
+ .action((options) => handleCliAction(async () => {
35
+ initContext(options.dir);
36
+ await syncIndex({ force: options.force, watch: options.watch });
37
+ })());
38
+ // 2. search
39
+ program
40
+ .command("search <query>")
41
+ .description("過去記事から類似セクションをベクトル検索します")
42
+ .option("-l, --limit <number>", "取得件数", (val) => parseInt(val, 10), 5)
43
+ .option("-t, --topic <topic>", "特定のトピック(タグ)で絞り込み")
44
+ .option("-d, --dir <path>", "Zennプロジェクトのルートディレクトリ")
45
+ .action((query, options) => handleCliAction(async () => {
46
+ initContext(options.dir);
47
+ await searchCli(query, { limit: options.limit, topic: options.topic });
48
+ })());
49
+ // 3. status
50
+ program
51
+ .command("status")
52
+ .description("現在のインデックス状況や登録済みトピック統計を表示します")
53
+ .option("-d, --dir <path>", "Zennプロジェクトのルートディレクトリ")
54
+ .action((options) => handleCliAction(async () => {
55
+ initContext(options.dir);
56
+ await showStatus();
57
+ })());
58
+ // 4. mcp
59
+ program
60
+ .command("mcp")
61
+ .description("Model Context Protocol (MCP) サーバーを起動します(Stdio通信)")
62
+ .option("-d, --dir <path>", "Zennプロジェクトのルートディレクトリ")
63
+ .action((options) => handleCliAction(async () => {
64
+ initContext(options.dir);
65
+ await runMcpServer();
66
+ })());
67
+ program.parse(process.argv);
68
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { type SyncOptions } from "../services/sync-service.js";
2
+ export interface CliSyncOptions extends SyncOptions {
3
+ watch?: boolean;
4
+ }
5
+ export declare function syncIndex(options?: CliSyncOptions): Promise<void>;
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAE5E,MAAM,WAAW,cAAe,SAAQ,WAAW;IACjD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wBAAsB,SAAS,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAO3E"}
@@ -0,0 +1,11 @@
1
+ import { SyncService } from "../services/sync-service.js";
2
+ export async function syncIndex(options = {}) {
3
+ const service = new SyncService(options.logger);
4
+ if (options.watch) {
5
+ await service.watch(options);
6
+ }
7
+ else {
8
+ await service.sync(options);
9
+ }
10
+ }
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAoB,MAAM,6BAA6B,CAAC;AAM5E,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAO,GAAmB,EAAE;IAC1D,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,MAAM,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;SAAM,CAAC;QACN,MAAM,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function runMcpServer(): Promise<void>;
2
+ //# sourceMappingURL=mcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"AAOA,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAuRlD"}
@@ -0,0 +1,245 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { z } from "zod";
4
+ import { getEmbedding } from "../embedder.js";
5
+ import { McpLogger, setLogger } from "../logger.js";
6
+ import { ArticleVectorStore } from "../store.js";
7
+ export async function runMcpServer() {
8
+ setLogger(new McpLogger());
9
+ const server = new McpServer({
10
+ name: "zenn-rag",
11
+ version: "0.1.0",
12
+ });
13
+ const store = new ArticleVectorStore();
14
+ // 1. 過去記事の類似セクション検索ツール
15
+ server.tool("search_articles", "Zennの過去記事からクエリに関連するセクションをベクトル検索します。新しい記事の執筆時に、過去の知見やコード例、関連記事のURLを探すために使用します。", {
16
+ query: z
17
+ .string()
18
+ .describe("検索したい内容(例: 'Next.js App RouterのServer Actions実装例', 'Cloudflare Workers WASM')"),
19
+ limit: z
20
+ .number()
21
+ .optional()
22
+ .default(5)
23
+ .describe("取得件数(デフォルト: 5)"),
24
+ topic: z
25
+ .string()
26
+ .optional()
27
+ .describe("トピック名による絞り込み(例: 'nextjs', 'cloudflare')"),
28
+ }, async ({ query, limit, topic }) => {
29
+ try {
30
+ const queryVector = await getEmbedding(query);
31
+ const results = await store.search(queryVector, { limit, topic });
32
+ if (results.length === 0) {
33
+ return {
34
+ content: [
35
+ {
36
+ type: "text",
37
+ text: "関連する記事は見つかりませんでした。まだインデックスを作成していない場合は `zenn-rag index` を実行してください。",
38
+ },
39
+ ],
40
+ };
41
+ }
42
+ const formatted = results
43
+ .map((r, i) => {
44
+ const score = (r.score * 100).toFixed(1);
45
+ return [
46
+ `### [${i + 1}] ${r.title} (類似度: ${score}%)`,
47
+ `- **見出し**: ${r.heading}`,
48
+ `- **URL**: ${r.url}`,
49
+ `- **トピック**: ${r.topics.join(", ") || "なし"}`,
50
+ "",
51
+ "```markdown",
52
+ r.text,
53
+ "```",
54
+ ].join("\n");
55
+ })
56
+ .join("\n\n---\n\n");
57
+ return {
58
+ content: [
59
+ {
60
+ type: "text",
61
+ text: `# 過去記事の検索結果 (クエリ: "${query}")\n\n${formatted}`,
62
+ },
63
+ ],
64
+ };
65
+ }
66
+ catch (err) {
67
+ const msg = err instanceof Error ? err.message : String(err);
68
+ return {
69
+ content: [
70
+ { type: "text", text: `検索中にエラーが発生しました: ${msg}` },
71
+ ],
72
+ isError: true,
73
+ };
74
+ }
75
+ });
76
+ // 2. 指定スラッグの記事セクション一覧取得ツール
77
+ server.tool("get_article", "指定したスラッグ(ファイル名)の記事の全セクションと内容を取得します。", {
78
+ slug: z.string().describe("記事のスラッグ(例: 'cloudflare-scale-up')"),
79
+ }, async ({ slug }) => {
80
+ try {
81
+ const chunks = await store.getArticleChunks(slug);
82
+ if (chunks.length === 0) {
83
+ return {
84
+ content: [
85
+ {
86
+ type: "text",
87
+ text: `記事 '${slug}' のデータが見つかりませんでした。`,
88
+ },
89
+ ],
90
+ };
91
+ }
92
+ const title = chunks[0].title;
93
+ const url = chunks[0].url;
94
+ const topics = chunks[0].topics.join(", ");
95
+ const body = chunks
96
+ .map((c) => `## ${c.heading}\n\n${c.text}`)
97
+ .join("\n\n---\n\n");
98
+ return {
99
+ content: [
100
+ {
101
+ type: "text",
102
+ text: `# ${title}\n- URL: ${url}\n- トピック: ${topics}\n\n${body}`,
103
+ },
104
+ ],
105
+ };
106
+ }
107
+ catch (err) {
108
+ const msg = err instanceof Error ? err.message : String(err);
109
+ return {
110
+ content: [
111
+ {
112
+ type: "text",
113
+ text: `記事の取得中にエラーが発生しました: ${msg}`,
114
+ },
115
+ ],
116
+ isError: true,
117
+ };
118
+ }
119
+ });
120
+ // 3. 登録済みトピック一覧取得ツール
121
+ server.tool("list_topics", "蓄積されている過去記事の全トピック(タグ)と各トピックの記事数を取得します。", {}, async () => {
122
+ try {
123
+ const topicCounts = await store.getAllTopics();
124
+ const sorted = Object.entries(topicCounts).sort((a, b) => b[1] - a[1]);
125
+ if (sorted.length === 0) {
126
+ return {
127
+ content: [
128
+ { type: "text", text: "登録されているトピックがありません。" },
129
+ ],
130
+ };
131
+ }
132
+ const list = sorted
133
+ .map(([topic, count]) => `- **${topic}**: ${count} 記事`)
134
+ .join("\n");
135
+ return {
136
+ content: [
137
+ {
138
+ type: "text",
139
+ text: `# 過去記事のトピック一覧 (全 ${sorted.length} 種類)\n\n${list}`,
140
+ },
141
+ ],
142
+ };
143
+ }
144
+ catch (err) {
145
+ const msg = err instanceof Error ? err.message : String(err);
146
+ return {
147
+ content: [
148
+ {
149
+ type: "text",
150
+ text: `トピック取得中にエラーが発生しました: ${msg}`,
151
+ },
152
+ ],
153
+ isError: true,
154
+ };
155
+ }
156
+ });
157
+ // 4. 執筆支援: 関連記事・本の推薦リンク生成ツール
158
+ server.tool("suggest_related_links", "執筆中の記事テキストや構想メモから、関連記事や本チャプターを推薦し、Markdownリンク形式で提示します。記事の内部リンクや引用の作成に便利です。", {
159
+ text: z.string().describe("執筆中の文章、段落、または構想メモ"),
160
+ limit: z
161
+ .number()
162
+ .optional()
163
+ .default(3)
164
+ .describe("提案するリンクの最大件数(デフォルト: 3)"),
165
+ }, async ({ text, limit }) => {
166
+ try {
167
+ const queryVector = await getEmbedding(text);
168
+ const results = await store.search(queryVector, { limit });
169
+ if (results.length === 0) {
170
+ return {
171
+ content: [
172
+ {
173
+ type: "text",
174
+ text: "関連する過去記事または本が見つかりませんでした。",
175
+ },
176
+ ],
177
+ };
178
+ }
179
+ const links = results
180
+ .map((r) => {
181
+ const score = (r.score * 100).toFixed(1);
182
+ const excerpt = r.text.slice(0, 120).replace(/\n+/g, " ");
183
+ return `- [${r.title} - ${r.heading}](${r.url}) (類似度: ${score}%)\n > 関連箇所: ${excerpt}...`;
184
+ })
185
+ .join("\n\n");
186
+ return {
187
+ content: [
188
+ {
189
+ type: "text",
190
+ text: `### 執筆支援: 推薦リンク一覧\n\n${links}`,
191
+ },
192
+ ],
193
+ };
194
+ }
195
+ catch (err) {
196
+ const msg = err instanceof Error ? err.message : String(err);
197
+ return {
198
+ content: [
199
+ {
200
+ type: "text",
201
+ text: `リンク提案中にエラーが発生しました: ${msg}`,
202
+ },
203
+ ],
204
+ isError: true,
205
+ };
206
+ }
207
+ });
208
+ // 5. インデックス同期実行ツール
209
+ server.tool("sync_index", "Zenn記事および本のインデックスを差分同期(再ベクトル化)します。執筆直後の記事を即座にAIエディタの検索対象に反映させるために使用します。", {
210
+ force: z
211
+ .boolean()
212
+ .optional()
213
+ .default(false)
214
+ .describe("trueを指定すると全件強制再同期"),
215
+ }, async ({ force }) => {
216
+ try {
217
+ const { SyncService } = await import("../services/sync-service.js");
218
+ const syncService = new SyncService(new McpLogger());
219
+ const result = await syncService.sync({ force });
220
+ return {
221
+ content: [
222
+ {
223
+ type: "text",
224
+ text: `インデックス同期が正常に完了しました。\n- 全体ファイル数: ${result.totalFiles}\n- 更新ファイル数: ${result.processedArticles}\n- 総チャンク数: ${result.totalChunks}`,
225
+ },
226
+ ],
227
+ };
228
+ }
229
+ catch (err) {
230
+ const msg = err instanceof Error ? err.message : String(err);
231
+ return {
232
+ content: [
233
+ {
234
+ type: "text",
235
+ text: `インデックス同期中にエラーが発生しました: ${msg}`,
236
+ },
237
+ ],
238
+ isError: true,
239
+ };
240
+ }
241
+ });
242
+ const transport = new StdioServerTransport();
243
+ await server.connect(transport);
244
+ }
245
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { SearchResult } from "../types.js";
2
+ export declare function searchArticles(query: string, options?: {
3
+ limit?: number;
4
+ topic?: string;
5
+ }): Promise<SearchResult[]>;
6
+ export declare function searchCli(query: string, options?: {
7
+ limit?: number;
8
+ topic?: string;
9
+ }): Promise<void>;
10
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,wBAAsB,cAAc,CAClC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC/C,OAAO,CAAC,YAAY,EAAE,CAAC,CAIzB;AAED,wBAAsB,SAAS,CAC7B,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC/C,OAAO,CAAC,IAAI,CAAC,CAqCf"}