mcpField
L
llm-wiki

llm-wiki

github.com/nashsu生産性1521.8k 回インストール23 週間前に更新
リポジトリ

llm-wiki について

llm-wiki は、ローカル HTTP API 経由で LLM Wiki を利用するスキルです。ユーザーのナレッジベースを扱うエージェント向けに、プロジェクト選択、検索、ページ閲覧、グラフ照会、ソース再スキャンを案内し、プロジェクト境界とトークンの扱いにも触れます。

主な機能

  1. 01ローカル HTTP API でアクセス
  2. 02Wiki ページの検索と閲覧
  3. 03Wikilinks グラフの照会
  4. 04ソースファイルの再スキャン
  5. 05複数プロジェクトの解決

活用シーン

  1. 01Wiki 内のトピックを検索
  2. 02ページを読みパスを引用
  3. 03Wiki グラフの構造を確認
  4. 04追加ソースを再スキャン

MCP 対応

入力には MCP との関係が記載されていません。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/nashsu/llm_wiki_skill --skill llm-wiki

インストール後、Claude Code で/llm-wikiを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

README.md
examples.md
api-reference.md

詳細

LLM Wiki ローカル API スキル

組み込み HTTP API を使って、ユーザーがローカルで実行している LLM Wiki アプリとやり取りします。これは標準的な JSON APIです。環境にすでにある HTTP ツール(curl、fetch、requests、http ミドルウェアなど)から直接呼び出してください。インストールが必要なクライアントライブラリも、習得が必要な SDK もありません。

この Wiki は、ユーザーがキュレーションしてきたプライベートで構造化されたナレッジベースとして扱います。ページは wiki/**.md にあり、未加工のドキュメントは raw/sources/ に保存され、Wiki リンクがグラフを形成しています。

呼び出すタイミング

ユーザーがアプリ名、「wiki」という文脈、または「知識庫」という文脈で、明確に LLM Wiki を指している場合にのみ呼び出してください。具体的には、次のような場合です。

  • 「自分のwiki/ナレッジベース/我的知識庫/LLM Wikiには X について何と書かれていますか」のように尋ねる
  • 「X について自分の wiki/LLM Wikiプロジェクト/我的知識庫を検索して」と依頼する
  • wiki ページをファイル名のベース名/タイトルで指定し、内容の確認や相互リンクを求める
  • wiki グラフ/知識グラフ/wiki の概要/wiki の構造について尋ねる
  • LLM Wiki のソースフォルダー内のファイルを追加または編集した直後に、再取り込み/再インデックスを求める
  • 「文脈として自分の wikiを使って」/「回答の根拠を自分の wikiにして」/「自分の LLM Wikiを確認して」と言う
  • wiki プロジェクトを(ID、絶対パス、または current で)指定する

次のような場合は呼び出さないでください。

  • 追加の説明なしに「自分のノートを検索して」と言う場合。Obsidian/Apple Notes/Notion/Logseq/Bear などを指している可能性があります
  • 「自分のノートブックで探して」と言う場合。Jupyter/OneNote/Notability を指している可能性があります
  • 「自分の Obsidian/Notion/Roam/Logseq の保管庫を確認して」と言う場合。別のツールを明示的に指しています
  • 「自分の Anki/Readwise/Pocketを調べて」と言う場合。別のツールです
  • 「自分のファイル/Documents フォルダーを検索して」と言う場合。一般的なファイルシステムを指しており、Wiki ではありません
  • 一般的な知識、時事問題、またはユーザーが明らかにオープンウェブからの情報を求めている場合

ユーザーがどのナレッジツールを指しているか不明な場合は、「LLM Wiki のことですか。それとも別のツールですか?」と尋ねてください。Obsidian の保管庫かもしれないのに、黙って LLM Wiki API を呼び出してはいけません。

クイックスタート

API はすべてプレーンな HTTP + JSON です。最短の手順は次のとおりです。

BASE=http://127.0.0.1:19828
TOKEN="${LLM_WIKI_API_TOKEN:-<paste-from-Settings>}"

# 1. probe state — no auth needed
curl -s $BASE/api/v1/health

# 2. list projects
curl -s -H "Authorization: Bearer $TOKEN" $BASE/api/v1/projects

# 3. search
curl -s -H "Authorization: Bearer $TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"query":"rope embedding","topK":5}' \
  $BASE/api/v1/projects/current/search

# 4. read a page
curl -s -H "Authorization: Bearer $TOKEN" \
  "$BASE/api/v1/projects/current/files/content?path=wiki/concepts/rope.md"

TypeScript/JavaScript を書く場合:

const res = await fetch("http://127.0.0.1:19828/api/v1/projects/current/search", {
  method: "POST",
  headers: { "Authorization": `Bearer ${process.env.LLM_WIKI_API_TOKEN}`, "Content-Type": "application/json" },
  body: JSON.stringify({ query: "rope embedding", topK: 5 }),
})
const { results } = await res.json()

Python も同じ形式です。urllib.request、requests、httpx など、すでに使っているものを利用できます。新しいものはインストールしないでください。

認証モデル

API はローカルホストからのみ利用できます。トークンは次のいずれかです。

  1. LLM_WIKI_API_TOKEN 環境変数(設定されている場合、UI の設定より優先されます)
  2. Settings → API Server で保存されたユーザーの apiConfig.token
  3. allowUnauthenticated: true モード(トークン不要。まれなケースで、ユーザーが明示的に選んだ場合に限ります)

必ず最初に /api/v1/health を確認してください。ここでは { enabled, authConfigured, allowUnauthenticated, tokenSource } が返されます。authConfigured: false && allowUnauthenticated: false の場合は、ユーザーに Settings → API Server → Generate new token を開くよう依頼してください。認証を設定せずに先へ進んではいけません。

トークンを送信する方法は、同等のものが 3 通りあります。

Authorization: Bearer <token>          # preferred
X-LLM-Wiki-Token: <token>              # alternative header
?token=<urlencoded-token>              # query param — last resort, leaks into logs

トークンをログに記録したり、応答に含めたりしてはいけません。ユーザーに見える出力内の URL にも決して含めないでください(Referer、シェル履歴、ログなどから漏えいする可能性があります)。

標準的なワークフロー

ユーザーから「自分の wiki で調べて」と頼まれた場合:

  1. プロジェクトを解決します(下記のプロジェクトの解決を参照)。
  2. 検索します。POST /api/v1/projects/{id}/search に { query, topK: 5..10 } を指定すると、ランキングされたヒット(path、title、snippet、score、titleMatch、任意の vectorScore、images)が返されます。ハイブリッド検索が使われたかどうかを確認するため、response.mode を調べてください。
  3. 上位のヒットを読み込みます。有望なヒットごとに、GET /api/v1/projects/{id}/files/content?path=... を呼び出して Markdown 全文を取得します。または、検索へのラウンドトリップを省略するため、検索リクエストに includeContent: true を渡します。
  4. 出典を示して回答します。読み込んだページに基づいて回答をまとめます。ユーザーが確認してアプリ内で該当ページを開けるよう、使用した各ページの path を引用してください。
スコアの読み方

score フィールドの尺度は mode によって異なります。

  • mode: "keyword" — キーワードの加算スコアです。ファイル名が完全一致する場合は約200、タイトル内のフレーズ一致は約50以上、トークンの集合による一致は1桁台になります。最上位の結果の約5%未満のスコアは、信頼度が低いものとして扱ってください。
  • mode: "hybrid" または "vector" — RRF(Reciprocal Rank Fusion)スコアで、通常は 0.015~0.035 の範囲です。絶対値は小さいため、重要なのは相対的な順位です。「埋め込みがどの程度強く一致したか」を確認する必要がある場合は、結果ごとの vectorScore(生のコサイン類似度、0~1)を使ってください。

モードをまたいで固定のスコアしきい値を適用しないでください。score の降順で並べ、相対的な差に基づいて判断してください。

プロジェクトの解決

プロジェクトを指定する各エンドポイントの {id} は、次の4つの形式を受け付けます。

形式使用する場合例
current(文字列そのまま)「自分の wiki/自分のナレッジベース/このプロジェクト/この wiki」のデフォルトです。ユーザーはデスクトップ UI で開いているプロジェクトを指しています。/api/v1/projects/current/search
UUIDユーザーがプロジェクト ID を貼り付けた場合、または名前を ID に解決済みで再利用する場合です。/api/v1/projects/a0e90b29-fcf3-4364-9502-8bd1272de820/files
絶対ファイルシステムパス(URL エンコード済み)ユーザーがパス(例:~/notes/research)を指定した場合です。名前が似ている複数のプロジェクトがユーザーにある場合に便利です。/api/v1/projects/%2FUsers%2Fme%2Fwiki%2Fresearch/files
プロジェクト名直接はサポートされていません。 まず GET /api/v1/projects を実行し、name で一致するプロジェクトを見つけてから、そのプロジェクトの id を使う必要があります。

ユーザーの発言に応じた判断フロー:

"my wiki" / "my 知识库" / "this wiki" / "this project" / unspecified
    → use `current`

"my Research project" / "in Reading"
    → GET /api/v1/projects
    → name-match (case-insensitive substring on `name`)
    → use the resulting `id`
    → if 0 matches: tell the user, list available names, fall back to `current` only if they confirm
    → if 2+ matches: ask the user to disambiguate, quoting both names + paths

"the project at /Users/me/foo"
    → URL-encode the path, use directly
    → if the API returns 404, the project isn't registered — list and let user pick

"project a0e90b29-…"
    → use the UUID literally

解決した id は会話の残りの間キャッシュしてください。呼び出しごとに /projects を再度 GET する必要はありません。ただし、ユーザーが会話の途中でコンテキストを切り替えた場合(「次は Reading プロジェクトを見て」など)は、再度解決してください。

ユーザーがプロジェクトを指定しない場合は、デフォルトで current を使い、その旨を一度伝えてください。「アクティブなプロジェクト(Research Notes)を検索しています……」。これにより、意図しない別プロジェクトの参照を防げます。

グラフや相互参照に関する質問の場合:

  • GET /api/v1/projects/{id}/graph?limit=200 → { nodes: [{id, label, nodeType, path, linkCount}], edges: [{source, target, weight}] }
  • ?q=term(id/label の部分一致、大文字と小文字は区別しません)および ?nodeType=entity|concept|... でフィルターします。

「新しいドキュメントを追加した」という依頼の場合:

  • POST /api/v1/projects/{id}/sources/rescan → { queue: { tasks }, changedTasks: [...] } を返します。変更されたファイル数をユーザーに伝えてください。実際の取り込みはデスクトップキューを通じて非同期で実行されます。
エンドポイントの仕様(v1)
メソッドパス説明
GET/api/v1/health認証不要。{ ok, status, version, enabled, authRequired, authConfigured, allowUnauthenticated, tokenSource } を返します。
GET/api/v1/projectsプロジェクトの一覧です。各項目は { id, name, path, current } です。
GET/api/v1/projects/{id}/files?root=wiki|sources|all&recursive=true&maxFiles=2000{ name, path, isDir, size, children } のツリーです。ノード数は10000件に制限されます(413)。
GET/api/v1/projects/{id}/files/content?path=wiki/foo.mdテキストファイルのみ(md/mdx/txt/json/yaml/yml/csv/html/htm/xml/rtf/log)。最大2 MB。バイナリファイルは415、サイズ超過は413、対象範囲外のパスは403を返します。
POST/api/v1/projects/{id}/search本文:{ "query": "...", "topK": 10, "includeContent": false }。ユーザーが Settings で埋め込みを設定している場合は ハイブリッド(キーワード+ベクトル) で検索し、それ以外の場合はキーワードのみの検索にフォールバックします。レスポンスには mode: "keyword" | "vector" | "hybrid"、tokenHits/vectorHits、および結果ごとの vectorScore が含まれます。空のクエリは400を返します。
GET/api/v1/projects/{id}/graph?q=&nodeType=&limit=200wiki/*.md の Wikilinks グラフです。上限は1000に制限されます。
POST/api/v1/projects/{id}/sources/rescanユーザーの Source Watch 設定を使って、バックエンドの再スキャンを開始します。再スキャン後のキューと、実際に変更されたタスクを返します。
POST/api/v1/projects/{id}/chat501 — v1 では実装されていません。呼び出さないでください。

{id} は UUID、絶対ファイルシステムパス(URL エンコード済み)、または文字列そのままの current を受け付けます。

エラー処理

ステータスコードを常に契約として扱ってください。

ステータス意味対応
200OK念のため body.ok === true を確認してください。ペイロードは同じオブジェクト内にあります。
400不正なリクエストbody.error を表示してください。よくある原因:空の query、無効な ?root=、リクエスト本文のサイズ超過。
401認証されていませんトークンがないか、正しくありません。Settings → API Server でトークンを設定するか、再生成するようユーザーに伝えてください。
403禁止されていますパストラバーサル、または許可範囲外です(例:../app-state.json)。同じパスで再試行しないでください。
404見つかりません不明なプロジェクト ID、または不明なルートです。プロジェクトが不明な場合は、復旧のため最初にプロジェクト一覧を取得してください。
405許可されていないメソッドHTTP メソッドが誤っています。
413ペイロードが大きすぎますファイルが 2 MB を超えている、ファイルツリーが maxFiles を超えている、またはリクエスト本文が 1 MB を超えています。対象範囲を絞るよう提案してください。
415サポートされていないメディア形式バイナリ、または UTF-8 以外のファイル内容です。API はテキストのみを扱います。
429リクエストが多すぎますレート制限(全体で 120 リクエスト/秒)です。1 秒以上待ってから再試行してください。
500内部エラーログに記録して報告してください。繰り返し処理しないでください。
501未実装/chat のスタブです。再試行しないでください。
503サービスを利用できません2 つの原因があります:API が無効になっている(error に "disabled" が含まれる)、または処理中リクエスト数の上限(64)に達している("busy")。2 秒以上待ってから再試行してください。

HTTP 呼び出し自体が失敗した場合(connection refused/ENOTFOUND)、デスクトップアプリは起動していません。ユーザーに「LLM Wiki を起動してから、もう一度お試しください」と伝えてください。

エチケット

  • パスを明記してください。 Wiki の内容を使って回答するときは、ページ名を記載してください:(wiki/concepts/rope.md から)。ユーザーはこれを使って内容を確認し、アプリ内でページを開きます。
  • デフォルトでは読み取り専用で対応してください。 状態を変更するのは sources/rescan だけです。それ以外はすべて読み取りです。書き込み用エンドポイントを作り出さないでください。v1 には存在しません。
  • 求められない限り、ページ全体を出力しないでください。 通常はスニペットとパスがあれば十分です。推論に本当に必要な場合に限り、全内容を取得してください。
  • プロジェクトの境界を尊重してください。 現在のプロジェクトはユーザーがアクティブに使用しているコンテキストです。黙ってプロジェクトを切り替えないでください。
  • レート制限を守ってください。 120 リクエスト/秒あれば順次処理には十分ですが、ページの読み取りを並列で行うと上限に近づくことがあります。API で可能な場合はまとめて処理してください(検索時に includeContent: true を指定すると、N+1 回の読み取りを避けられます)。
  • トークンを決して漏らさないでください。 ヘッダーは安全ですが、クエリパラメーターと自身の出力テキストは安全ではありません。

関連項目

  • api-reference.md — リクエスト/レスポンスの例を含む、すべてのエンドポイントの形式
  • examples.md — 一般的な会話パターンと、それに対応する直接的な curl/fetch の実行例
  • README.md — 人間向けのセットアップ手順(トークン生成、ポート競合、トラブルシューティング)

コメント