ukagaka-doc-mcp 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 (70) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE.md +24 -0
  3. package/README.md +109 -0
  4. package/SPEC.md +356 -0
  5. package/data/index.json +22046 -0
  6. package/dist/bootstrap.d.ts +17 -0
  7. package/dist/bootstrap.d.ts.map +1 -0
  8. package/dist/bootstrap.js +57 -0
  9. package/dist/bootstrap.js.map +1 -0
  10. package/dist/build-index.d.ts +12 -0
  11. package/dist/build-index.d.ts.map +1 -0
  12. package/dist/build-index.js +51 -0
  13. package/dist/build-index.js.map +1 -0
  14. package/dist/constants.d.ts +77 -0
  15. package/dist/constants.d.ts.map +1 -0
  16. package/dist/constants.js +86 -0
  17. package/dist/constants.js.map +1 -0
  18. package/dist/index-builder.d.ts +5 -0
  19. package/dist/index-builder.d.ts.map +1 -0
  20. package/dist/index-builder.js +53 -0
  21. package/dist/index-builder.js.map +1 -0
  22. package/dist/index-validation.d.ts +9 -0
  23. package/dist/index-validation.d.ts.map +1 -0
  24. package/dist/index-validation.js +75 -0
  25. package/dist/index-validation.js.map +1 -0
  26. package/dist/index.d.ts +11 -0
  27. package/dist/index.d.ts.map +1 -0
  28. package/dist/index.js +27 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/parser/satori-scraper.d.ts +35 -0
  31. package/dist/parser/satori-scraper.d.ts.map +1 -0
  32. package/dist/parser/satori-scraper.js +272 -0
  33. package/dist/parser/satori-scraper.js.map +1 -0
  34. package/dist/parser/ukadoc-parser.d.ts +21 -0
  35. package/dist/parser/ukadoc-parser.d.ts.map +1 -0
  36. package/dist/parser/ukadoc-parser.js +231 -0
  37. package/dist/parser/ukadoc-parser.js.map +1 -0
  38. package/dist/parser/yaya-scraper.d.ts +46 -0
  39. package/dist/parser/yaya-scraper.d.ts.map +1 -0
  40. package/dist/parser/yaya-scraper.js +308 -0
  41. package/dist/parser/yaya-scraper.js.map +1 -0
  42. package/dist/search/engine.d.ts +41 -0
  43. package/dist/search/engine.d.ts.map +1 -0
  44. package/dist/search/engine.js +114 -0
  45. package/dist/search/engine.js.map +1 -0
  46. package/dist/server.d.ts +12 -0
  47. package/dist/server.d.ts.map +1 -0
  48. package/dist/server.js +36 -0
  49. package/dist/server.js.map +1 -0
  50. package/dist/text.d.ts +2 -0
  51. package/dist/text.d.ts.map +1 -0
  52. package/dist/text.js +8 -0
  53. package/dist/text.js.map +1 -0
  54. package/dist/tools/get-doc.d.ts +4 -0
  55. package/dist/tools/get-doc.d.ts.map +1 -0
  56. package/dist/tools/get-doc.js +29 -0
  57. package/dist/tools/get-doc.js.map +1 -0
  58. package/dist/tools/list-categories.d.ts +3 -0
  59. package/dist/tools/list-categories.d.ts.map +1 -0
  60. package/dist/tools/list-categories.js +21 -0
  61. package/dist/tools/list-categories.js.map +1 -0
  62. package/dist/tools/search-docs.d.ts +4 -0
  63. package/dist/tools/search-docs.d.ts.map +1 -0
  64. package/dist/tools/search-docs.js +45 -0
  65. package/dist/tools/search-docs.js.map +1 -0
  66. package/dist/types.d.ts +59 -0
  67. package/dist/types.d.ts.map +1 -0
  68. package/dist/types.js +5 -0
  69. package/dist/types.js.map +1 -0
  70. package/package.json +64 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 finelagusaz
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/NOTICE.md ADDED
@@ -0,0 +1,24 @@
1
+ # Notice
2
+
3
+ This package contains two different kinds of material with different handling.
4
+
5
+ ## 1. Code in this repository
6
+
7
+ The implementation code authored for this repository is licensed under the MIT
8
+ License. See `LICENSE`.
9
+
10
+ ## 2. Bundled documentation snapshot data
11
+
12
+ `data/index.json` is a generated snapshot derived from third-party technical
13
+ documentation sources, including:
14
+
15
+ - UKADOC
16
+ - YAYA Wiki
17
+ - 里々Wiki
18
+
19
+ This generated data is not re-licensed under the MIT License by this
20
+ repository. It remains subject to the terms, permissions, and restrictions of
21
+ the original source materials and their respective rights holders.
22
+
23
+ If you intend to reuse, redistribute, or republish the bundled data, verify the
24
+ applicable upstream terms yourself.
package/README.md ADDED
@@ -0,0 +1,109 @@
1
+ # ukagaka-doc-mcp
2
+
3
+ 伺か(Ukagaka)の技術ドキュメントを検索する MCP サーバーです。
4
+
5
+ 以下の3ソースをビルド時に収集したスナップショットを検索対象にします。
6
+
7
+ - UKADOC
8
+ - YAYA Wiki
9
+ - 里々Wiki
10
+
11
+ ランタイムでは外部ネットワークにアクセスせず、同梱された `data/index.json` を読み込んで動作します。
12
+
13
+ ## 提供ツール
14
+
15
+ - `list_categories`
16
+ - `search_docs`
17
+ - `get_doc`
18
+
19
+ ## 必要環境
20
+
21
+ - Node.js 20 以上
22
+
23
+ ## インストール
24
+
25
+ ```bash
26
+ npm install -g ukagaka-doc-mcp
27
+ ```
28
+
29
+ ## 使い方
30
+
31
+ 標準入出力で MCP サーバーとして起動します。
32
+
33
+ ```bash
34
+ ukagaka-doc-mcp
35
+ ```
36
+
37
+ ## Claude Desktop 設定例
38
+
39
+ ```json
40
+ {
41
+ "mcpServers": {
42
+ "ukagaka-doc": {
43
+ "command": "ukagaka-doc-mcp"
44
+ }
45
+ }
46
+ }
47
+ ```
48
+
49
+ ## 開発
50
+
51
+ 依存関係を入れたあと、インデックスを生成してからサーバーを起動します。
52
+
53
+ ```bash
54
+ npm install
55
+ npm run refresh:index
56
+ npm run build
57
+ npm start
58
+ ```
59
+
60
+ テスト:
61
+
62
+ ```bash
63
+ npm test
64
+ ```
65
+
66
+ ## インデックス更新
67
+
68
+ `data/index.json` は静的スナップショットです。ランタイムでは自動更新しません。
69
+
70
+ - ローカル手動更新: `npm run refresh:index`
71
+ - 自動更新 PR: `.github/workflows/refresh-index-pr.yml`
72
+ - CI: `.github/workflows/ci.yml`
73
+ - release: `.github/workflows/release.yml`
74
+
75
+ 自動更新は以下の流れです。
76
+
77
+ 1. `refresh-index-pr.yml` が毎週 1 回または手動実行で動く
78
+ 2. `docs/ukadoc` submodule を最新化し、`data/index.json` を再生成する
79
+ 3. 変更があれば patch version を 1 つ進めて自動 PR を作成する
80
+ 4. `ci.yml` が PR を検証し、成功したら auto-merge で `main` に取り込む
81
+ 5. `release.yml` が merge 後に npm publish、git tag、GitHub Release を行う
82
+
83
+ 必要な GitHub / npm 側設定:
84
+
85
+ - `AUTOMATION_GITHUB_TOKEN` secret
86
+ - fine-grained PAT 推奨
87
+ - repository contents: write
88
+ - pull requests: write
89
+ - repository setting の auto-merge 有効化
90
+ - npm Trusted Publishing でこの GitHub repository を publisher 登録
91
+
92
+ ## パッケージ内容
93
+
94
+ npm パッケージには公開実行に必要なファイルだけを含めます。
95
+
96
+ - `dist/`
97
+ - `data/index.json`
98
+ - `LICENSE`
99
+ - `NOTICE.md`
100
+ - `README.md`
101
+ - `SPEC.md`
102
+
103
+ `docs/ukadoc/` や `src/`、`tests/` は npm tarball に含めません。
104
+
105
+ ## ライセンス
106
+
107
+ このリポジトリの実装コードは MIT License です。詳細は `LICENSE` を参照してください。
108
+
109
+ ただし、同梱している `data/index.json` は UKADOC、YAYA Wiki、里々Wiki を元に生成した外部由来データです。この生成物は MIT License では再ライセンスしていません。利用・再配布時は上流の権利関係を別途確認してください。詳細は `NOTICE.md` を参照してください。
package/SPEC.md ADDED
@@ -0,0 +1,356 @@
1
+ # 伺か技術ドキュメント検索 MCPサーバー仕様
2
+
3
+ ## 1. 目的
4
+
5
+ このリポジトリは、伺か(Ukagaka)の技術ドキュメントをビルド時に収集・正規化し、MCPサーバー経由で検索・参照可能にする。
6
+
7
+ 本仕様は、実装計画ではなく、外部契約と不変条件を定義する。
8
+
9
+ ## 2. 用語
10
+
11
+ - **MUST**: 必須要件
12
+ - **SHOULD**: 強く推奨される要件
13
+ - **MAY**: 任意要件
14
+ - **インデックス**: `data/index.json`
15
+ - **canonical_id**: 各ドキュメントエントリを一意に識別するID
16
+
17
+ ## 3. スコープ
18
+
19
+ ### 3.1 対象ソース
20
+
21
+ 本サーバーは以下の3ソースのみを対象とする。
22
+
23
+ 1. UKADOC (`docs/ukadoc/manual/`)
24
+ 2. YAYA Wiki (`https://emily.shillest.net/ayaya/`)
25
+ 3. 里々Wiki (`https://soliton.sub.jp/satori/`)
26
+
27
+ ### 3.2 非スコープ
28
+
29
+ 以下は本仕様の対象外とする。
30
+
31
+ - ランタイムでの外部サイト再取得
32
+ - 差分同期やRSS更新
33
+ - 書き込み系MCPツール
34
+ - 歴史的参考資料の横断検索
35
+
36
+ ## 4. アーキテクチャ
37
+
38
+ ### 4.1 ビルド時
39
+
40
+ `npm run build:index` は以下を行う。
41
+
42
+ 1. UKADOC をローカルHTMLからパースする
43
+ 2. YAYA Wiki をHTTP取得してパースする
44
+ 3. 里々Wiki をHTTP取得してパースする
45
+ 4. 3ソースを統合して `data/index.json` を生成する
46
+
47
+ ### 4.2 ランタイム
48
+
49
+ ランタイムは以下を満たさなければならない。
50
+
51
+ - 起動時ネットワーク通信ゼロであること
52
+ - `data/index.json` の読み込みだけで起動できること
53
+ - `generatedAt` が 7 日を超えて古い場合、警告を出すことが望ましい
54
+ - `data/index.json` が存在しない場合、起動失敗すること
55
+
56
+ ## 5. データモデル
57
+
58
+ ### 5.1 Source
59
+
60
+ ```ts
61
+ type Source = 'ukadoc' | 'yaya_wiki' | 'satori_wiki';
62
+ ```
63
+
64
+ ### 5.2 Category
65
+
66
+ カテゴリは単一ソースの定数定義を正とし、少なくとも以下を含む。
67
+
68
+ ```ts
69
+ type Category =
70
+ | 'sakurascript'
71
+ | 'shiori_event'
72
+ | 'descript'
73
+ | 'protocol'
74
+ | 'file_structure'
75
+ | 'dev_guide'
76
+ | 'yaya_grammar'
77
+ | 'yaya_basic'
78
+ | 'yaya_function'
79
+ | 'yaya_system'
80
+ | 'yaya_tips'
81
+ | 'yaya_startup'
82
+ | 'satori_reference'
83
+ | 'satori_event'
84
+ | 'satori_tips'
85
+ | 'satori_saori';
86
+ ```
87
+
88
+ ### 5.3 DocEntry
89
+
90
+ `DocEntry` はインデックスに保存される基本単位であり、以下を満たさなければならない。
91
+
92
+ ```ts
93
+ type DocEntry = {
94
+ id: string;
95
+ title: string;
96
+ source: Source;
97
+ category: Category;
98
+ content: string;
99
+ url: string;
100
+ };
101
+ ```
102
+
103
+ #### 要件
104
+
105
+ - `id` は全エントリで一意でなければならない
106
+ - `title` は空文字であってはならない
107
+ - `content` は全文でなければならない
108
+ - `content` は保存時に要約化してはならない
109
+ - `url` はそのエントリの元ページまたは元セクションを指さなければならない
110
+
111
+ ### 5.4 SearchEntry
112
+
113
+ `SearchEntry` は `search_docs` の返却用派生型である。
114
+
115
+ ```ts
116
+ type SearchEntry = {
117
+ id: string;
118
+ title: string;
119
+ source: Source;
120
+ category: Category;
121
+ summary: string;
122
+ url: string;
123
+ };
124
+ ```
125
+
126
+ #### 要件
127
+
128
+ - `summary` は `content` から導出される表示用テキストであること
129
+ - `summary` は `content` の先頭 500 文字であること
130
+ - `content` が 500 文字を超える場合に限り、`summary` の末尾に明示的な省略記号 `...` を付与すること
131
+ - 省略時の `summary` は `content.slice(0, 500) + "..."` と等価でなければならない
132
+ - `summary` 生成時に改行や空白の追加正規化を行ってはならない
133
+ - `summary` はインデックスの正規データではなく派生値であること
134
+
135
+ ### 5.5 IndexFile
136
+
137
+ ```ts
138
+ type IndexFile = {
139
+ version: number;
140
+ generatedAt: string;
141
+ entries: DocEntry[];
142
+ };
143
+ ```
144
+
145
+ #### 要件
146
+
147
+ - `generatedAt` は ISO 8601 文字列でなければならない
148
+ - `entries` に重複 `id` が存在してはならない
149
+ - `entries` に無効ページやエラーページが含まれてはならない
150
+
151
+ ## 6. canonical_id
152
+
153
+ ### 6.1 共通原則
154
+
155
+ - `canonical_id` は安定かつ一意でなければならない
156
+ - 同じ文書断片は、ビルドのたびに同じ `id` を持つべきである
157
+ - 別の文書断片が同じ `id` を持ってはならない
158
+ - `id` の重複が発生した場合、ビルドは失敗しなければならない
159
+
160
+ ### 6.2 ソース別ルール
161
+
162
+ #### UKADOC
163
+
164
+ - 形式は `ukadoc:{filename}:{anchor}` を基本とする
165
+ - `anchor` には、ソースHTMLに存在する `id` または `name` を優先的に使用しなければならない
166
+ - 優先順位は `id` → `name` → フォールバックでなければならない
167
+ - フォールバック形式は `ukadoc:{filename}:{normalized_raw_title}:{occurrence_index}` とする
168
+ - `occurrence_index` は、同一ページ内で同じ `normalized_raw_title` が出現した順の 1 始まり整数とする
169
+ - `normalized_raw_title` は安定した正規化文字列でなければならない
170
+ - フォールバックは、記号除去や小文字化だけに依存してはならない
171
+
172
+ #### YAYA Wiki
173
+
174
+ - 関数ページは `yaya:{page_path}` とする
175
+ - セクション分割ページは `yaya:{page_path}#{anchor}` とする
176
+ - `page_path` はURLデコード済みの論理ページパスとする
177
+
178
+ #### 里々Wiki
179
+
180
+ - ページ単位は `satori:{page_name}` とする
181
+ - セクション分割ページは `satori:{page_name}#{anchor}` とする
182
+ - `page_name` はURLデコード済みの論理ページ名とする
183
+
184
+ ## 7. 収集・正規化仕様
185
+
186
+ ### 7.1 リンク正規化
187
+
188
+ Wikiリンクは取得前に正規化しなければならない。
189
+
190
+ #### 必須ルール
191
+
192
+ - `./?foo` は `?foo` に正規化する
193
+ - `#fragment` はページ取得対象から除去する
194
+ - ページ内アンカーは別ページとしてクロールしてはならない
195
+ - 外部リンクはクロール対象に含めてはならない
196
+ - `cmd=` または `plugin=` を含むメタ操作リンクは除外しなければならない
197
+
198
+ ### 7.2 エラーページ除外
199
+
200
+ 以下のようなページはインデックスに含めてはならない。
201
+
202
+ - `有効なWikiNameではありません`
203
+ - ログイン要求ページ
204
+ - 差分、履歴、凍結、編集、添付などのメタページ
205
+ - 実コンテンツではなくナビゲーションのみのページ
206
+
207
+ ### 7.3 テキスト抽出
208
+
209
+ - ナビゲーション、フッター、編集UIは本文抽出前に除去すること
210
+ - セクション単位で分割するページでは、見出しと本文の対応が保たれなければならない
211
+ - 関数ページのように1ページ1エントリと定義された対象は、セクション分割してはならない
212
+
213
+ ## 8. 検索仕様
214
+
215
+ ### 8.1 `search_docs`
216
+
217
+ #### 入力
218
+
219
+ - `query: string` MUST
220
+ - `category?: Category`
221
+ - `source?: Source`
222
+ - `limit?: number`
223
+
224
+ #### 動作
225
+
226
+ - 大文字小文字を無視する
227
+ - 日本語・英語とも部分一致を許可する
228
+ - バックスラッシュは `\\s` → `\s` のように正規化して比較する
229
+ - スコアリング優先度は以下とする
230
+ 1. タイトル完全一致
231
+ 2. タイトル部分一致
232
+ 3. 本文部分一致
233
+
234
+ #### 出力
235
+
236
+ - ヒット時は `status: "ok"` を返す
237
+ - ヒット0件時は `status: "not_found"` を返す
238
+ - `data` は `SearchEntry[]` とする
239
+ - `summary` は本仕様 5.4 の規則に従って `content` から導出する
240
+ - デフォルト件数は 10、最大件数は 50 とする
241
+
242
+ ### 8.2 `get_doc`
243
+
244
+ #### 入力
245
+
246
+ - `id: string` MUST
247
+
248
+ #### 動作
249
+
250
+ - 指定された `id` に一致する `DocEntry` を1件だけ返す
251
+ - 一致が0件なら `not_found`
252
+ - 一致が2件以上存在する状態は仕様違反であり、インデックス生成時点で防止されていなければならない
253
+
254
+ #### 出力
255
+
256
+ - `content` は全文でなければならない
257
+ - `summary` は返さない
258
+
259
+ ### 8.3 `list_categories`
260
+
261
+ - カテゴリ一覧を返す
262
+ - 各カテゴリは `id`, `source`, `label` を持つ
263
+ - 実装はカテゴリ定数を単一ソースとして利用しなければならない
264
+
265
+ ## 9. ビルド仕様
266
+
267
+ ### 9.1 成功条件
268
+
269
+ `npm run build:index` は、以下をすべて満たしたときのみ成功してよい。
270
+
271
+ - 必須3ソースの取得・パースが完了している
272
+ - 重複 `id` が存在しない
273
+ - 無効ページが含まれていない
274
+ - 各ソースが空でない
275
+ - 各ソースについて少なくとも1カテゴリ以上のエントリが存在する
276
+
277
+ ### 9.2 失敗条件
278
+
279
+ 以下のいずれかに該当した場合、ビルドは失敗しなければならない。
280
+
281
+ - ソース取得失敗
282
+ - パース失敗
283
+ - 重複 `id`
284
+ - 無効ページ混入
285
+ - 各ソースについて少なくとも1カテゴリ以上のエントリが存在しない
286
+
287
+ ### 9.3 出力の原子性
288
+
289
+ - ビルド中は既存 `data/index.json` を直接上書きしてはならない
290
+ - 一時ファイルに出力し、検証成功後にのみ置き換えなければならない
291
+ - 失敗時は前回の正常な `data/index.json` を保持しなければならない
292
+
293
+ ### 9.4 部分成功の禁止
294
+
295
+ - UKADOC だけ成功、YAYA/里々失敗のような部分成功を正規成果物として出力してはならない
296
+ - ビルドは fail-open ではなく fail-closed でなければならない
297
+
298
+ ## 10. ランタイム仕様
299
+
300
+ ### 10.1 起動
301
+
302
+ - サーバー起動時は `data/index.json` を読み込む
303
+ - 読み込みに成功したらインメモリ検索エンジンへロードする
304
+ - 読み込み失敗時はプロセスを正常起動してはならない
305
+
306
+ ### 10.2 freshness 警告
307
+
308
+ - `generatedAt` が 7 日より古い場合、警告を出すことが望ましい
309
+ - 警告は起動失敗条件ではない
310
+
311
+ ### 10.3 不正インデックスの扱い
312
+
313
+ ランタイムは `data/index.json` の不正を検出した場合、種類に応じて以下のように扱わなければならない。
314
+
315
+ #### 起動失敗とすべきもの
316
+
317
+ - JSON パース失敗
318
+ - 必須フィールド欠落
319
+ - `id` 重複
320
+ - `content` 空
321
+ - `entries` が空
322
+
323
+ #### 警告付き起動でよいもの
324
+
325
+ - `generatedAt` 不正
326
+ - `version` 不一致
327
+ - 未知カテゴリの混入
328
+
329
+ ### 10.4 ランタイムでの外部通信
330
+
331
+ - ランタイムは外部HTTPアクセスを行ってはならない
332
+ - 検索・全文取得・カテゴリ列挙は、すべてローカルインデックスだけで完結しなければならない
333
+
334
+ ## 11. 受け入れ条件
335
+
336
+ 少なくとも以下を自動テストで担保すること。
337
+
338
+ - `DocEntry.content` が全文保存されること
339
+ - `search_docs` が 500 文字要約を返すこと
340
+ - `search_docs` の省略時 `summary` が `content.slice(0, 500) + "..."` と一致すること
341
+ - `get_doc` が全文を返すこと
342
+ - 重複 `id` がビルド失敗になること
343
+ - `#fragment` 付きWikiリンクが別ページとしてクロールされないこと
344
+ - エラーページがインデックスに入らないこと
345
+ - バックスラッシュ正規化検索が正しく動作すること
346
+ - `data/index.json` 不在時に起動失敗すること
347
+ - `generatedAt` の stale 判定が動作すること
348
+ - `id` 重複を含む不正インデックスで起動失敗すること
349
+ - `version` 不一致を含むインデックスで警告付き起動すること
350
+ - ビルド失敗時に既存 `data/index.json` が保持されること
351
+
352
+ ## 12. 実装計画との関係
353
+
354
+ - `implementation_plan.md` は実装順序と作業計画を扱う
355
+ - `SPEC.md` は不変条件と外部契約を扱う
356
+ - 実装と計画が衝突した場合、外部契約に関しては本仕様を優先する