Deadzone について
Deadzoneは、ライブラリ文書を検索するローカル中心のMCPサーバーです。ベクトル検索で関連するスニペットを返し、インデックスはローカルのTursoファイルに保存します。
主な機能
- 01自然言語によるライブラリ検索
- 02文書スニペットの意味検索
- 03ライブラリとバージョンでの絞り込み
- 04応答のトークン予算設定
- 05インデックスのローカル保存
活用シーン
- 01ライブラリ機能の説明を探す
- 02特定バージョンの文書を検索
- 03コーディングエージェントに文書断片を提供
MCP 対応
stdioで通信し、`search_libraries`と`search_docs`の2つのツールをMCPクライアントに提供します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
docker run -i --rm ghcr.io/laradji/deadzone:v0.7.4ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ghcr.io/laradji/deadzone:v0.7.4stdioツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
_ _
__| | ___ __ _ __| |_______ _ __ ___
/ _` |/ _ \/ _` |/ _` |_ / _ \| '_ \ / _ \
| (_| | __/ (_| | (_| |/ / (_) | | | | __/
\__,_|\___|\__,_|\__,_/___\___/|_| |_|\___|
> semantic doc search. local file. no cloud. no key.
> you ask in english. it answers in snippets.
ステータス。 ベクトル検索をエンドツーエンドで接続済みです。stdio 経由の MCP。Linux と macOS に対応した単一バイナリで、テレメトリーはゼロです。最新のタグはリリース、進行中の作業はロードマップをご覧ください。 スクレイパーはまだ課題の多い部分です。#64で現状を率直に説明しています。
ひとことで言うと
AI クライアントが「"how do I register a tool?"」と尋ねます。ドキュメントには AddTool と書かれています。grep ベースのインデックスはお手上げですが、ベクトルインデックスなら対応できます。Deadzone はそのベクトルインデックスです。Turso のネイティブなコサイン距離を使って nomic-embed-text-v1.5 を実行し、stdio 経由で MCP を話し、すべてのバイトをノート PC 内に保つ Go バイナリでラップしています。おおまかに言えば、インターネットを切った Context7 です。
deadzone の原則
- バイナリはひとつ。
deadzoneです。すべての操作にサブコマンドを使います。pip installもnpm iもdocker compose upも不要です。 - インデックスは外に出ません。 ローカルの Turso ファイルです。アカウントも API キーも不要です。通常の処理経路で外部への通信はありません。
- 自然言語を最優先。 コサイン距離による埋め込みを使います。
FTS5の出番はありません。 - バイナリがバージョンです。 DB のバージョンはバイナリに固定されています。バイナリをアップグレードすると DB も追随します。アップグレードしなければ、そのままです。
- 失敗は明確に。さもなくば何もしません。
DEADZONE_DB_OFFLINE=1は推測を拒否します。スクレイパーで検証に失敗した場合、実行全体ではなくそのドキュメントを破棄します。
インストール(どれかひとつを選択。いずれも同じバイナリに行き着きます)
# macOS Apple Silicon — the one-liner
brew install laradji/deadzone/deadzone
# Linux — resolve the latest tag once, then pick a flavor
VERSION=$(curl -fsSL https://api.github.com/repos/laradji/deadzone/releases/latest | grep '"tag_name"' | cut -d'"' -f4)
ARCH=amd64 # or arm64
# self-mounting AppImage
curl -L -O "https://github.com/laradji/deadzone/releases/download/${VERSION}/deadzone_${VERSION}_linux_${ARCH}.AppImage"
chmod +x "deadzone_${VERSION}_linux_${ARCH}.AppImage"
mv "deadzone_${VERSION}_linux_${ARCH}.AppImage" deadzone
# or plain tarball (no FUSE needed)
curl -L "https://github.com/laradji/deadzone/releases/download/${VERSION}/deadzone_${VERSION}_linux_${ARCH}.tar.gz" \
| tar xz --strip-components=1
どちらの方法でも、現在のディレクトリに deadzone 実行可能ファイルが配置されるため、以下の ./deadzone server の例をそのまま実行できます。
# Container — multi-arch (linux/amd64 + linux/arm64), ships with the DB baked, runs offline by default
docker pull ghcr.io/laradji/deadzone:latest
docker run --rm -i ghcr.io/laradji/deadzone:latest server
イメージにはバイナリ、libonnxruntime、deadzone.db、nomic-embed-text-v1.5 の ONNX 重み(合計約 230 MB)が組み込まれており、distroless ベースで非 root ユーザーとして実行されます(シェルもパッケージマネージャーもありません)。イメージでは DEADZONE_DB_OFFLINE=1 が設定されているため、初回起動も即座に完了します。ダウンロード、ボリュームのマウント、--network アクセスは不要です。インデックスを更新するには、新しいタグをプルしてください。
Windows は上流で未対応です。libtokenizers.a がありません。WSL を使用してください。
チェックサムを検証する(任意ですが簡単です):
curl -L -O "https://github.com/laradji/deadzone/releases/download/${VERSION}/deadzone_${VERSION}_checksums.txt"
sha256sum --ignore-missing -c "deadzone_${VERSION}_checksums.txt" # Linux
shasum -a 256 --ignore-missing -c "deadzone_${VERSION}_checksums.txt" # macOS
AppImage には FUSE v2 が必要です。 ほとんどのデスクトップ環境には含まれていますが、最小構成のサーバーにはありません。dlopen(): libfuse.so.2 が表示される場合は、apt-get install libfuse2(または dnf install fuse-libs)を実行するか、--appimage-extract-and-run を渡して FUSE を完全に回避してください。
実行
./deadzone server
これでクイックスタートは完了です。初回起動時は、このバイナリのバージョンに一致する deadzone.db を取得し、SHA256 を検証して、プラットフォームのデータディレクトリにキャッシュした後、サービスを開始します。2 回目以降はネットワーク通信が発生しません。バイナリをアップグレードすると、次回起動時に DB が再取得されます。アップグレードしなければ、キャッシュがそのまま使われ続けます。
MCP クライアントの接続設定 — ネイティブバイナリ(Brew tap、tarball、AppImage):
{
"mcpServers": {
"deadzone": {
"type": "stdio",
"command": "/path/to/deadzone",
"args": ["server"]
}
}
}
MCP クライアントの接続設定 — コンテナ(ghcr.io 上のマルチアーキテクチャ対応)。イメージには deadzone.db が組み込まれているため、ボリュームのマウントは不要で、コンテナを起動するたびにオフラインで即座に利用できます。
{
"mcpServers": {
"deadzone": {
"type": "stdio",
"command": "docker",
"args": ["run", "--rm", "-i", "ghcr.io/laradji/deadzone:latest", "server"]
}
}
}
次に、クライアントから:
search_libraries("terraform aws") → ranked (lib_id, version) pairs
search_docs("creating an s3 bucket", lib_id=...) → snippets, token-budgeted
2 つのツール
┌─────────────────────────────────────────────────────────────────────┐
│ search_libraries(name, limit?) → []LibraryHit │
│ ───────────────────────────────────────────── │
│ free text ──► vector match against the `libs` table │
│ ──► [{lib_id, version, doc_count, match_score}] │
├─────────────────────────────────────────────────────────────────────┤
│ search_docs(query, lib_id?, version?, tokens?) → []Snippet │
│ ────────────────────────────────────────────────── │
│ natural ──► 768-dim embed ──► cosine over docs │
│ language ──► token-budgeted snippets back │
└─────────────────────────────────────────────────────────────────────┘
| 引数 | 形式 | 説明 |
|---|---|---|
query | 文字列 | 意味的にマッチします。キーワードではなく、知りたいことを書いてください。 |
lib_id | /org/project | 任意のフィルターです。search_libraries から取得できます。 |
version | "1.14" など | 任意の固定指定です。lib_id が必須です。 version のみの指定は拒否されます。 |
tokens | 整数 | レスポンスの予算です。デフォルトは 5000、最小値は 1000、1 トークンあたり約 4 文字です。 |
limit | 整数 | search_libraries での最大結果数です。デフォルトは 10、最大値は 50 です。 |
name | 文字列 | search_libraries での自由入力テキストです。空の場合、インデックス登録数が最も多いライブラリを返します。 |
内部の仕組み
deadzone server
│
▼
┌──────────────┐ stdio JSON-RPC ┌───────────────┐
│ MCP client │ ─────────────────────► │ handler │
└──────────────┘ └──────┬────────┘
│
┌──────────────────┴──────────────────┐
▼ ▼
┌────────────────┐ ┌──────────────────┐
│ embedder │ │ Turso (local) │
│ hugot + ORT │ │ F32_BLOB(768) │
│ nomic v1.5 │ │ vector_distance │
└────────┬───────┘ └──────────────────┘
│ 768-dim ▲
└────────────── query vector ────────┘
| レイヤー | 選択内容 |
|---|---|
| 言語 | Go 1.26.2。バージョンは mise で固定しています |
| ストレージ | Turso のローカルファイル — ネイティブの F32_BLOB(N) と vector_distance_cos |
| ドライバー | tursogo — purego により CGO 不使用 |
| 埋め込みモデル | hugot → nomic-ai/nomic-embed-text-v1.5、768 次元、8192 トークンのコンテキスト(int8 量子化) |
| ランタイム | ONNX Runtime — バイナリはビルド時に CGO とリンクされます。libonnxruntime は初回起動時に自動取得され、SHA256 で検証されます |
| プロトコル | stdio 経由の modelcontextprotocol/go-sdk |
バイナリ自体は CGO とリンクされています(hugot ORT バックエンド + 静的リンクされた libtokenizers.a)。ランタイムで使用される唯一のネイティブ要素は libonnxruntime で、SHA256 検証済みの自動ダウンロード後に dlopen 経由で読み込まれます。それ以外はすべて、Go 標準ライブラリ、tursogo、モデルの重みのいずれかが静的にリンクされるか、固定されたハッシュを照合して初回起動時に取得されます。システムへのインストールは不要です。sudo も不要です。ダウンロードしたファイルのハッシュが固定値と異なる場合、実行は中止されます。未検証のファイルを取得するフォールバックはありません。
エアギャップ環境向けの回避策:
| 環境変数 | 効果 |
|---|---|
DEADZONE_ORT_LIB_PATH | libonnxruntime のパスを手動で指定します。ダウンロードはスキップされます。 |
DEADZONE_ORT_CACHE | ORT ライブラリのキャッシュディレクトリを上書きします。 |
DEADZONE_HUGOT_CACHE | モデルの重みのキャッシュディレクトリを上書きします。 |
DEADZONE_DB_CACHE | deadzone.db のキャッシュディレクトリを上書きします。 |
DEADZONE_DB_OFFLINE=1 | ネットワーク呼び出しをすべて拒否します。キャッシュに何もない場合は、エラーを明示して失敗します。deadzone.db が組み込み済みのコンテナイメージでは、デフォルトで設定されています。 |
DEADZONE_DB_AUTOUPDATE=0 | 起動時の DB 鮮度プローブを無効にします(デフォルトではプローブを実行します。このフラグに関係なく、fetch-db は常にプローブを実行します)。 |
プラットフォームごとのデフォルトのキャッシュパス:
| プラットフォーム | deadzone.db の保存場所 |
|---|---|
| macOS | ~/Library/Application Support/deadzone/deadzone.db |
| Linux | $XDG_DATA_HOME/deadzone/deadzone.db(未設定の場合は ~/.local/share/...) |
| Windows | %LOCALAPPDATA%\deadzone\deadzone.db |
同じディレクトリにある deadzone.db.release JSON マニフェストには、{tag, sha256, fetched_at} が記録されます。起動時に、キャッシュされたタグとバイナリにコンパイル時に埋め込まれたバージョンを比較します。一致する場合は、一致する GitHub Release の deadzone.db.sha256 に対して 3 秒間の鮮度プローブを実行し、リモートの sha が異なる場合はアトミックに入れ替えます(ネットワークエラーが発生した場合は、キャッシュを使って処理を続行します)。異なる場合は、新しいタグのリリースを取得してアトミックに入れ替えます。開発ビルドの場合は、server.db_version_dev_fallback WARN を伴って /releases/latest にフォールバックします。#197 より前のバイナリはタグだけを含む単一行のサイドカーファイルを書き込んでいましたが、JSON リーダーは引き続きその形式を受け入れ、最初のプローブ時に v1 形式に書き換えます。
ライブラリを追加する
コントリビューター向けの手順です。エンドユーザーはここを編集しません。deadzone.db に含まれるものをそのまま利用します。
自分で YAML を編集しませんか? New issue ページから課題を作成し、Add a library または Refresh a library を選択してください。テンプレートには、レジストリエントリーに必要な情報がすべて含まれています。
自分で YAML を編集しますか? libraries_sources.yaml に追記します。
libraries:
# Single-version lib — no `versions` key, urls used as-is.
- lib_id: /modelcontextprotocol/go-sdk
kind: github-md
urls:
- https://raw.githubusercontent.com/modelcontextprotocol/go-sdk/main/README.md
- https://raw.githubusercontent.com/modelcontextprotocol/go-sdk/main/docs/quick_start.md
# Multi-version lib — `versions` expands into one effective lib_id
# per version (/org/project/1.4, /org/project/1.5, …). {ref} is
# substituted from each version's ref: field.
- lib_id: /modelcontextprotocol/go-sdk
kind: github-md
versions:
"1.4": { ref: v1.4.1 }
"1.5": { ref: v1.5.0 }
urls:
- https://raw.githubusercontent.com/modelcontextprotocol/go-sdk/{ref}/README.md
- https://raw.githubusercontent.com/modelcontextprotocol/go-sdk/{ref}/docs/getting-started.md
| フィールド | 必須 | 目的 |
|---|---|---|
lib_id | はい | 正規の /org/project 識別子(db.docs.lib_id と一致します)。 |
kind | はい | github-md(raw markdown)、github-rst(raw reStructuredText)、または scrape-via-agent(LLM 経由の HTML/テキスト)。 |
urls | はい | 任意の {ref} プレースホルダーを含むドキュメント URL のリストです。 |
versions | いいえ | {"1.4": {ref: v1.4.1, urls: [...]}, "1.5": {ref: v1.5.0}, …} — ユーザー向け識別子には major.minor を推奨します。 |
ref | いいえ | {ref} に代入される Git タグまたはコミット SHA です。バージョンごとの ref: はトップレベルの値を上書きします。 |
versions[v].urls | いいえ | バージョンごとの URL リストです。既存のリスト全体を置き換えます。構造が大きく異なるバージョンに使用してください。 |
1.0 より前は、Go の編集も再コンパイルも不要です。YAML を編集して再スクレイプするだけです。
Scrape-via-agent(実験的)
⚠️ 厄介な部分です。 現在、Markdown 以外のソース(Terraform プロバイダー、mkdocs、GitBook など)で動作しますが、LLM→検証のループは入力の切り詰め(48 KiB 上限)、HTML→Markdown のスキル、コードの逐語的一致に影響されやすいです。情報量の多い実際のドキュメントサイトでの成功率は URL あたり約 50% です。#64 を参照してください。プロジェクトにコミット済みの Markdown が含まれている場合は、
github-mdを優先してください。
任意の LLM ランタイムを使用できます。Ollama、llama.cpp、vLLM、LocalAI、LM Studio、Groq、OpenAI など、POST /v1/chat/completions に対応しているものなら何でも利用できます。
export DEADZONE_AGENT_ENDPOINT=http://localhost:11434/v1
export DEADZONE_AGENT_ENDPOINT_MODEL=qwen2.5:7b
export DEADZONE_AGENT_ENDPOINT_API_KEY=sk-... # optional
次に、ページ URL のリストを指定して、libraries_sources.yaml に kind: scrape-via-agent のエントリーを追加します。後続のパイプライン(parse → chunk → embed → store)は github-md と同一で、Markdown のソースだけが変わります。
ガードレール。 LLM の出力に含まれるすべてのフェンス付きコードブロックは、ソースと逐語的に照合して検証されます。作り出された例があった場合は、実行全体ではなく、そのドキュメントが除外されます(scraper.agent_verification_failed)。エンドポイントが存在しない場合や到達できない場合は起動時に中断し、サイレントフォールバックは行いません。
ローカルパイプライン(コントリビューター向け)
2 段階でブートストラップします。まずツールチェーンを導入し、次に CGO のネイティブ依存関係を導入します。これらは別々の手順になっているため、libtokenizers.a をベンダー管理しているネットワーク分離環境/CI ランナーでは、DEADZONE_TOKENIZERS_LIB を上書きして手順 2 を省略できます。
just bootstrap # Go 1.26.2 + just toolchain (mise install)
just fetch-tokenizers # libtokenizers.a — one-shot CGO setup
just build # CGO + ORT, all packages
just scrape # all libs — one artifact folder per lib
just scrape /hashicorp/terraform # one base lib, every version
just scrape /hashicorp/terraform/1.14 # one exact version
just consolidate # merge artifacts/*/artifact.db → deadzone.db
just serve # MCP server against deadzone.db
引数なしで just を実行すると、すべてのレシピが一覧表示されます。各スクレイプは artifacts/<slug>/artifact.db と state.yaml をその場で書き換えます。consolidate はすべてのアーティファクト DB を deadzone.db にアトミックに統合します。ライブラリごとのフォルダーは Git の対象外です。コミット済みの artifacts/manifest.yaml には、リリース履歴のみが記録されます。
CI でレジストリー全体を処理します。 gh workflow run scrape-pack.yml -f tag=vX.Y.Z を実行すると、マトリックス処理、統合、タグ付きリリースへの deadzone.db のアップロードが行われます。統合済み DB のキャッシュで停止するには、-f tag=… を省略します。
リリースフロー
#101以降は2段階です。CIがバイナリを公開し、運用担当者がDBを公開します。
# 1. Regenerate deadzone.db from the committed scraper config.
just scrape && just consolidate
# 2. Tag + push. CI's release.yml builds tarballs + AppImages, creates the release,
# and auto-bumps the Homebrew tap on release.published.
git tag v0.X.0 && git push --tags
# 3. Ship deadzone.db + deadzone.db.sha256 to the same release.
just dbrelease v0.X.0
# 4. Commit artifacts/manifest.yaml so the release-history trace lands in git.
git add artifacts/manifest.yaml && git commit -m "release v0.X.0" && git push
安定版タグをプッシュすると、CIですべてが連鎖して実行されます。release.yml -> chain-release.yml が scrape-pack.yml をディスパッチし、さらに chain-image.yml が docker-publish.yml をディスパッチします(関心ごとごとにワークフローを分け、workflow_run で連鎖させています)。
Homebrewの手動フォールバック。 tapの自動更新は release.published で実行されます(#148)。RELEASE_PUBLISH_TOKEN の有効期限が切れて連鎖が止まった場合は、手動で実行してください。
gh workflow run update-package-channels.yml -f tag=v0.X.0
ログ
log/slog を介して、構造化されたJSONをstderrに出力します。deadzone server では、stdoutはMCP JSON-RPC用に確保されています。
| サブコマンド | 主なイベント |
|---|---|
scrape | scraper.start、scraper.lib_start、scraper.fetch(URLごと)、scraper.indexed、scraper.lib_done、scraper.done。エラー:scraper.fetch_failed、scraper.insert_failed。エージェント経由の実行では、scraper.agent_configured、scraper.agent_ping_ok、scraper.agent_verification_failed、agent.input_truncated も追加されます。 |
consolidate | consolidate.start、consolidate.done。artifacts、docs_merged、libs_merged、duration_ms を含みます。 |
dbrelease | dbrelease.start、packs.dbrelease.uploaded(アセットごと)、dbrelease.done。sha256、size、lib_count、doc_count を含みます。 |
server | server.start(埋め込みモデルと doc_count)、呼び出しごとに1件の search_docs(lib_id、tokens、results、latency_ms)。起動時には、server.db_upgraded、server.db_version_dev_fallback WARN、server.db_tag_sidecar_write_failed WARN が出力される場合があります。 |
任意のサブコマンドで --verbose を指定すると、デバッグレベルの詳細が追加されます。server では生の query がログに記録されます(デフォルトでは無効です。クエリにはユーザーデータが含まれる場合があります)。scrape では、ドキュメントごとの scraper.doc_indexed が追加されます。
MCP クライアントのログ出力先:macOSのClaude Codeでは ~/Library/Logs/Claude/mcp-server-deadzone.log に書き込まれます。他のクライアントでは異なります。
ロードマップとコントリビューション
Issue: laradji/deadzone/issues。範囲はマイルストーンで確認できます。カテゴリは feature / research ラベルで、優先度は P1 / P2 / P3 で示されます。
新しいライブラリの追加や更新には、新しいIssueページを使い、該当するフォームを選択してください。
なぜベクトルを使うのか
"how to register a tool" で AddTool と書かれたドキュメントを見つけられるべきだからです。答えを人があらかじめ知っていない限り、FTS5のクエリでは見つけられません。埋め込みを優先した検索こそが目的で、それ以外はすべてそのための仕組みです。
詳細: docs/research/context7-analysis.md。
ライセンス
Apache License, Version 2.0。サードパーティの帰属表示は NOTICE を参照してください。
重要な但し書きが1つあります。 Apache 2.0が適用されるのはDeadzoneのソースコードだけです。スクレイパーがインデックス化するサードパーティのドキュメントには適用されません。これらのドキュメントは、それぞれのライセンスに基づき、元の著者に帰属します。deadzone scrape の実行には、各情報源の利用規約が適用されます。ビルド済みパックにはApache 2.0ではなく、元のコンテンツのライセンスが適用されます。個人的なローカルでのインデックス化は問題ありません。公開で再配布する場合は、まず十分に確認してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。