PluginWorld
Io

io.github.shuji-bonji/houki-egov-mcp

MCP✓ SPEC VERIFIED

日本の法令(憲法・法律・政令・省令・規則)を e-Gov 法令API v2 から、条・項・号の単位で、法令番号と URL を添えて返す MCP サーバー。税法・労働法・会社法・民法など全分野の条文を LLM から引けます。 Japanese statutes from e-Gov Law API v2 — laws and ordinances per article, with law number and URL.

@shuji-bonji · v0.21.0 · MIT · updated 12d ago

SECURITY

A

SCORE

78

INSTALLS

▲ 5.9K

PLUG IN

claude mcp add io-github-shuji-bonji-houki-egov-mcp -- npx -y @shuji-bonji/houki-egov-mcp

README

[!CAUTION] 旧リポジトリ名 houki-hub-mcp / 旧 npm 名 @shuji-bonji/houki-hub-mcp は使っていません。 現行は @shuji-bonji/houki-egov-mcp です。

Houki e-Gov MCP Server

CI npm version License: MIT Node

日本の法令(憲法・法律・政令・省令・規則)を e-Gov 法令API v2 から、条・項・号の単位で、法令番号と URL を添えて返す MCP サーバーです。税法・労働法・会社法・民法など、分野を問わず条文を LLM から引けます。

通達・質疑応答事例・タックスアンサーは @shuji-bonji/houki-nta-mcp が担当します。2 つを分けているのは、「法律で決まっている」と「通達でそうなっている」を混ぜずに返すためです。

できること

税務・労務・会社の手続きなどを調べるときに、根拠になる条文を一次情報のまま確かめるための機能です。

  • e-Gov に収録されている法令の条文を、条・項・号の単位で返します。応答には法令番号と e-Gov の URL、取得日時が付きます
  • 「消法」「労基法」「電帳法」のような略称でも引けます(略称辞書 174 エントリ・6 分野)
  • 施行令・施行規則と、条文が「政令で定める」と委ねている先をたどれます
  • 日付を指定して、その時点の条文を取れます。改正履歴(公布日・施行日)も引けます
  • 民法の「契約」の章のように、章・節の単位でまとめて読めます
  • LLM が書いた引用(「所得税法第 121 条第 1 項」など)が実在するかを、まとめて確かめられます

相談の形の問いでの使い方

「会社員で、副業の所得が 20 万円以下なら確定申告はしなくてよいか」と尋ねると、LLM が get_law(law_name="所得税法", article="121", paragraph=1) を呼び、「確定所得申告を要しない場合」の条文が返ります。

条文には、答えを分ける条件が並んでいます。給与の支払者が 1 か所か 2 か所以上か、給与の全部が源泉徴収または年末調整の対象か、給与等の金額が 2,000 万円以下か、給与所得と退職所得以外の所得の合計が 20 万円以下か、ただし書きの「政令で定める場合」に当たらないか、です。利用者は、自分の事実がどの条件に当たるかを条文で確かめられます。

国税庁の解説(タックスアンサー「給与所得者で確定申告が必要な人」など)もあわせて引くには、houki-nta-mcp を併用してください。個別の事案に条文を当てはめた結論(「あなたは申告が不要です」)は返しません。理由は業法との関係に書いています。

まず試す(ローカル DB なし)

登録するだけで、14 ツールのうち 13 はそのまま動きます。e-Gov 法令 API v2 をその場で呼ぶためで、事前の取り込みは要りません。

// claude_desktop_config.json
{
  "mcpServers": {
    "houki-egov": {
      "command": "npx",
      "args": ["-y", "@shuji-bonji/houki-egov-mcp@latest"]
    }
  }
}

再起動して「消費税法第 30 条第 1 項を見せて」「インボイス制度の登録要件は」のように尋ねると、search_law → get_law の順に呼ばれ、法令番号と e-Gov の URL 付きで本文が返ります。

ローカル DB が要るのは search_fulltext(条文本文の横断検索)だけです。DB が無いときは search_law(法令名の検索)に切り替わり、応答の source が "api-fallback" になります。本文の全文検索が要ると分かったら、そのとき一度だけ下記の「CLI(ローカル DB の構築)」を実行してください。全法令 zip(約 290 MB)の取得と取り込みが走ります。

ローカル DB なし ローカル DB あり
search_law get_law get_toc get_law_range get_law_revisions resolve_abbreviation explain_law_type get_related_laws get_article_references verify_citations list_attachments get_attachment get_law_file 動く(e-Gov API をその場で呼ぶ) 同じ
search_fulltext search_law に切り替わる(source: "api-fallback") 条文本文を横断検索する(freshness 付き)

提供ツール

Tool 用途
search_law 法令タイトルでキーワード検索(略称→正式名解決済み)。total_count は e-Gov で一致した総数で、0 件のときは search_fulltext と resolve_abbreviation を案内する(v0.18.0)
get_law 条/項/号レベルで本文取得(Markdown / JSON / TOC)。条は本則から探し、附則の条は suppl_index で附則を指して取る(v0.18.0)
get_toc 目次のみ取得(トークン節約)。本則と附則を分け、附則は改正法ごとにまとめる(v0.13.0)
get_law_range 編・章・節・款・目のいずれか、または附則 1 本を範囲にして条を本文ごと取得。上限を超える範囲は条の単位で打ち切り、続きの条番号を返す(v0.14.0)
get_law_revisions 改正履歴を取得(公布日・施行日・状態)
search_fulltext 条文本文の横断全文検索(ローカル SQLite FTS5。bulk DB 未構築時は search_law にフォールバック)。通達などの管轄外の略称だけを渡すと OUT_OF_SCOPE(v0.18.0)
resolve_abbreviation 略称→正式名解決の診断。全角英数字・全角空白は揃えて照合し、辞書のエントリはどの管轄でも返して in_scope と hint で管轄を示す(v0.16.0)
explain_law_type 法令種別(憲法・法律・政令・省令・通達 等)の解説。e-Gov の法令種別コード(Act・Constitution・Rule など)でも引ける
get_related_laws 法令名の規則で施行令・施行規則(施行令からは親の法律)を引き、e-Gov に実在するものだけを law_id 付きで返す(v0.10.0)。法律でも施行令・施行規則でもない法令からは候補を作らない(v0.18.0)
get_article_references 本則の条の本文が引用している他法令の条(law_id 付き)・同一法令内の条項号・「附則第N条」・「政令で定める」の委任先を取り出し、get_law(条の無い他法令の参照は get_toc)の引数を next_actions で付ける(v0.10.0。附則と委任先の扱いは v0.18.0)
verify_citations 引用のリストをまとめて実在確認し、件ごとに found / not_found / ambiguous を返す(v0.11.0)。条は本則で確かめ、附則の条は suppl_index で指す(v0.18.0)
list_attachments 法令に付いた添付ファイル(別表・様式・別記の図。jpg / pdf)の一覧。各ファイルに認証なしで開ける URL と、法令の中の置き場所(「別表第一(第一条関係)」など。附則の別表・様式は v0.18.0 から)を付ける(v0.15.0)
get_attachment 添付ファイル 1 件(または zip)。既定は URL とメタ情報だけ、save: true でサーバー側の保存先に書いて絶対パスを返す(v0.15.0)
get_law_file 法令本文を xml / json / html / rtf / docx のファイルで。既定は URL だけ、save: true で保存(v0.15.0)

search_fulltext は、2 文字の語(「相殺」「時効」)を渡されたときに何をして結果を出したかを short_tokens で返します(v0.12.0)。索引が trigram で 3 文字以上の語しか載せないため、既定では条の本文を引かず、法令名を添える形と scan_body: true で走査する形を next_actions で示します。詳しくは2 文字の語の検索をご覧ください。

get_toc は、本則を toc、附則を改正法ごとに suppl_provisions へ分けて返します(v0.13.0)。既定では附則は見出しと条数だけで、suppl: "full" で附則の中の条まで返します。depth で階層を刈ったときは truncated: true と truncated_by: "depth" が返ります(v0.21.0)。この truncated は depth で刈ったときだけ true になり、get_law_range の truncated(文字数の上限で条を打ち切った印)とは意味が違うので、続きを取る操作はありません。詳しくは本則と附則の分け方をご覧ください。

list_attachments / get_attachment / get_law_file は、条文の文字列に入らないもの(別表・様式の図、Word や HTML の本文ファイル)を取る道です(v0.15.0)。ファイルの中身は応答に入れず、認証なしで開ける URL と、save: true のときだけ保存先の絶対パスを返します。詳しくは添付ファイルと法令本文ファイルをご覧ください。

get_law_range は、get_law(1 条ずつ)と get_toc(目次だけ)の間を埋めます(v0.14.0)。民法の「第三編第二章 契約」のように章・節を指定すると、その中の条を本文ごと返し、長い範囲は条の単位で打ち切って続きの条番号を返します。詳しくは章・節単位の取得をご覧ください。

略称辞書(174 エントリ・6 分野)は @shuji-bonji/houki-abbreviations を内部で利用しています。

施行令・施行規則と条文内の参照(v0.10.0)

get_related_laws と get_article_references は、法令名の文字列規則と条文本文の正規表現で 決定論的に引ける参照だけ を返します。同じ入力には同じ出力になり、LLM の判断は挟みません。

  • get_related_laws({ law_name: "所得税法" }) → related[] に所得税法施行令(340CO0000000096)と所得税法施行規則(340M50000040011)。名前の末尾に「施行令」「施行規則」を付けた候補を e-Gov に問い合わせ、law_title が完全一致した 1 件だけを採用します。無かった候補は not_found[] に残します
  • get_article_references({ law_name: "所得税法", article: "57の2", paragraph: 2 }) → references[] に「雇用保険法(昭和四十九年法律第百十六号)第十条第五項第一号」が law_id と条・項・号付きで入り、delegations[] に「政令で定める」×N と委任先(所得税法施行令)が入ります。「前項」「同法」は kind: "relative" で解決しません
  • 確かでないときは推定しません(v0.18.0)。get_article_references は本則の条だけを対象にし、本文の「附則第N条」は kind: "suppl"・resolved: false で返します。省令・府令の委任先は、施行規則を定めた命令の名前(法令番号の 大蔵省令 など。省の改称は同じ省として扱います)が委任の文言と合うときだけ付け、合わないときと 主務省令 は target_law: null にします。施行規則の本文の「令第N条」は、兄弟の施行令が実在すれば external に解決します。get_related_laws は、法律でも施行令・施行規則でもない法令(省令・政令・規則など)からは候補を作らず、related を空にして note に理由を書きます
  • どちらの応答にも note / coverage.note が付き、抽出できた範囲だけを返していること、網羅性を保証しないことを書いています。委任の趣旨の解釈や意味的に近い条の推薦は行いません(houki-hub#8 の法令グラフの担当)

インストール

Claude Desktop で使う

上の「まず試す」の claude_desktop_config.json の例をそのまま使います。ローカル DB は無くても動きます。

Claude Code plugin で使う

リポジトリ同梱の .claude-plugin/plugin.json が MCP server として npx -y @shuji-bonji/houki-egov-mcp@latest を登録します。plugin として入れた場合も、下の「Claude Desktop で使う」も、起動されるのは npm に公開された同じパッケージです。

ローカル開発

git clone git@github.com:shuji-bonji/houki-egov-mcp.git
cd houki-egov-mcp
npm install
npm run build
npm test
// 開発中の動作確認 (.mcp.json)
{
  "mcpServers": {
    "houki-egov-local": {
      "command": "node",
      "args": ["/absolute/path/to/houki-egov-mcp/dist/index.js"]
    }
  }
}

手元のビルドも、HOUKI_EGOV_DB_PATH が無ければ plugin と同じ ~/.cache/houki-egov-mcp/laws.db を開きます。古いコミットや DB の版を上げる変更を試すときは、別のファイルに向けてください(CONTRIBUTING.md の「ローカル DB を使う開発」)。

使用例

# LLM への問いかけ → MCP ツール呼び出し

「消費税法30条1項を見せて」
  → get_law(law_name="消法", article="30", paragraph=1)

「消費税法第三十条第一項を見せて」(判決文や通達からの引き写し)
  → get_law(law_name="消法", article="第三十条", paragraph=1)   # 漢数字は v0.7.0 から。項は数値で

「消費税法2条1項8号の2(特定資産の譲渡等)を見せて」
  → get_law(law_name="消法", article="2", paragraph=1, item="8の2")

「労働基準法の目次を取得」
  → get_toc(law_name="労基法")

「民法の契約の章をまとめて読みたい」
  → get_law_range(law_name="民法", part=3, chapter=2)
  → 第三編 債権 第二章 契約(198 条)を上限(既定 30,000 文字)まで返し、続きは from_article で取る

「会社法の設立の章を見せて」
  → get_law_range(law_name="会社法", path="Part2/Chapter1")   # get_toc の toc[].path をそのまま渡せる

「個人情報保護法の改正履歴を最新5件」
  → get_law_revisions(law_name="個情法", latest=5)

「電帳法って正式名称なに?」
  → resolve_abbreviation(abbr="電帳法")
  → 電子計算機を使用して作成する国税関係帳簿書類の保存方法等の特例に関する法律

「政令と省令の違いは?」
  → explain_law_type(name="政令")

「民法で不法行為について定めている条文は?」(bulk DB 構築後)
  → search_fulltext(keyword="民法 不法行為")
  → law_scope=[民法] に絞って本文検索。724 条・719 条・509 条 などが snippet 付きで返る

「民法 第709条」(法令名 + 条番号だけ)
  → search_fulltext(keyword="民法 第709条")
  → 本文検索をせず、民法 709 条を直接返す

CLI(ローカル DB の構築 — v0.3.1+)

ローカル DB が要るのは search_fulltext だけです。それ以外の 13 ツールは DB が無くても動くので、条文本文の横断検索が要ると分かってから作れば足ります(上の「まず試す」)。

全文検索用のローカル DB(SQLite FTS5)は、e-Gov の bulk ダウンロード zip から構築します。MCP server として常駐する通常起動とは別に、フラグ付きで起動すると CLI モードで動作します。

# 全法令 zip (約 290 MB) を DL して DB に取り込む (初回)
npx -y @shuji-bonji/houki-egov-mcp@latest --bulk-download-everything

# 最終同期日から今日までの日次差分を取り込む (2 回目以降。v0.8.0+)
npx -y @shuji-bonji/houki-egov-mcp@latest --sync

# DB の件数と鮮度 (freshness) を表示
npx -y @shuji-bonji/houki-egov-mcp@latest --status

コマンドは、どのフォルダーからでも動く npx -y @shuji-bonji/houki-egov-mcp@latest <フラグ> の形で書いています。

  • npm install -g @shuji-bonji/houki-egov-mcp でグローバルにインストールしたときは、houki-egov-mcp <フラグ> でも動きます。インストールしていないと command not found になります
  • npx houki-egov-mcp <フラグ> は、npm に houki-egov-mcp という名前のパッケージが無いので 404 になります(このリポジトリのフォルダーの中でだけ動きます)
  • @latest を付けると、npx が以前に取得した古い版を使わずに、公開中の最新版で実行します。plugin と同じ版で DB を作り、更新するために付けています(0.18.x 以前の版で版 3 の DB を開くと全テーブルが消えるので、古い版を使わないことが大切です)

search_fulltext の応答(next_actions と note)と CLI の出力で案内するコマンドも、この npx -y @shuji-bonji/houki-egov-mcp@latest <フラグ> の形です(0.20.0 から)。HOUKI_EGOV_DB_PATH か XDG_CACHE_HOME で DB の場所を決めて起動・実行したときは、同じ変数を前に付けた形(例: HOUKI_EGOV_DB_PATH="$HOME/.cache/houki-egov-mcp/laws.dev.db" npx -y @shuji-bonji/houki-egov-mcp@latest --bulk-download-everything)になるので、そのまま実行すれば同じ DB を作り、更新します。--help の使い方だけは houki-egov-mcp <フラグ> の形で書いています。

--sync は、差分が無い日(土日など)を飛ばし、途中で失敗しても成功した日までを記録して終わります。最終同期から 90 日(HOUKI_EGOV_INCREMENTAL_LIMIT_DAYS)を超えて空いているときは、e-Gov の日次差分の公開範囲を超えるので、何もせずに --bulk-download-everything を促します。1 日分は数百 KB〜30 MB、13 日分でおよそ 1〜2 分です。

DB は既定で ~/.cache/houki-egov-mcp/laws.db に作られます。場所を変えるときは、下の「DB の場所を変える(HOUKI_EGOV_DB_PATH)」を見てください。

--status は、1 行目に版、2 行目に DB:(開く DB のファイル)、3 行目に DB の場所の設定:(HOUKI_EGOV_DB_PATH・XDG_CACHE_HOME・既定 のどれでその場所に決まったか)を出します(3 行目は 0.20.0 から)。同じフォルダーに、名前が laws で始まり .db で終わるファイルがほかにあるときは、その次の行の [WARN] 同じフォルダーに、この DB のほかに laws*.db のファイルがあります: … で、名前・大きさ・最終更新を挙げます。MCP サーバーと CLI が別のファイルを開いていないかを確かめるための行で、終了コードは変わりません。

MCP サーバー(plugin を含む)が開くファイルは、起動時のログ(標準エラー出力)の [server] DB: <絶対パス>(DB の場所の設定: <名前>) の行と、search_fulltext の応答の freshness.db_path(ホームディレクトリの部分は ~)で確かめられます(0.20.0 から)。起動時のログは、MCP クライアントが保存する MCP サーバーのログに出ます。

--bulk-download-by-date YYYYMMDD は 1 日分の差分だけを取り込む確認用のコマンドです。同期の状態(last_sync_date)は変えないので、最新化には --sync を使ってください。差分の無い日を指定したときは 差分なし を出して終了コード 0 で終わります。

引数を打ち間違えたとき(houki-egov-mcp status のような - の無い引数、--sync --status のようにフラグの後に続く引数)は、何もせずにエラーと使い方を出して終了コード 2 で終わります(0.19.0 から。それまでは MCP サーバーとして起動するか、最初のフラグだけを実行していました)。

日々の更新と作り直し

ふだんの更新は --sync だけで足ります。--bulk-download-everything を使うのは、表の 2〜5 行目の 4 つのときです。

場面 使うコマンド すること
ふだんの更新(毎日・毎週など) --sync 最後に同期した日から今日までの日次差分を取り込みます。差分の無い日は 差分なし で飛ばします
初めて DB を作るとき --bulk-download-everything 全件の zip(約 290 MB)を取得して DB を作ります
最後の同期から 90 日(HOUKI_EGOV_INCREMENTAL_LIMIT_DAYS)を超えたとき --bulk-download-everything --sync は何もせずに、このコマンドを促して終了コード 1 で終わります
houki-egov-mcp を上げて DB の版が変わったとき(0.19.0 で版 2 → 3) --bulk-download-everything 版の古い DB を作り直して取り込みます(取り込んだ中身は消えます)
--sync・--status が [WARN] 施行日が last_sync_date … を出したとき(0.19.1 から) --bulk-download-everything 施行日を過ぎても未施行のまま残った版の状態を直します(条の本文は入れ直しません)

版が同じ DB に --bulk-download-everything を実行しても、作り直しはしません。全件の zip を取り直して、中身の変わった法令と、施行されて状態が変わった版だけを書き換えます。ふだんの更新に使う必要はありません。

0.19.0 で 2026-10-04 以降に --sync した DB は、0.19.1 で 1 回取り込み直してください

e-Gov は、改正の施行日の当日の差分に、それまで未施行として配っていた版を同じ中身のまま「施行済み」としてもう一度入れます。0.19.0 はこの版を「中身が同じ」として飛ばしていたので、施行日を過ぎても版が未施行のまま残り、search_fulltext が改正前の条文を返し続けることがありました(#107)。0.19.1 は、中身が同じでも状態だけを書き換えます。

0.19.0 で 2026-10-04 以降に --sync した DB は、0.19.1 に上げた後に次のコマンドを 1 回実行してください。施行日を過ぎても未施行のまま残った版の状態を直します(条の本文は入れ直しません。全件の zip 約 290 MB を取得します)。0.19.1 の --sync や --status が [WARN] 施行日が last_sync_date … を出したときも同じです。

npx -y @shuji-bonji/houki-egov-mcp@latest --bulk-download-everything
  • 取り込みで状態だけを書き換えた版があると、 ingest 完了: … の行の後に 状態の更新: <件数> 件 (…) の行が出ます
  • このコマンドが要る DB の正確な範囲(--sync だけで直る場合)は docs/NOTES.md の「施行日の当日に配り直される版(0.19.1)」にあります

0.19.0 に上げたら DB を作り直してください

0.19.0 で DB のスキーマの版を 2 から 3 に上げました。0.18.x 以前に作った DB は 0.19.0 では使えないので、次のコマンドで作り直してください。全件の zip(約 290 MB)を取得し直し、取り込み直します。

npx -y @shuji-bonji/houki-egov-mcp@0.19.0 --bulk-download-everything
  • 作り直すまで、search_fulltext は条文本文を検索せずに search_law(法令名のタイトル一致)の結果を返し、note で作り直しを案内します。--sync・--status・--bulk-download-by-date は DB に触れずにエラー(終了コード 1)で終わります
  • 作り直すのは、zip の取得に成功した後です。取得に失敗したときは古い DB がそのまま残ります
  • 作り直した後に 0.18.x 以前の houki-egov-mcp でこの DB を開くと、版が違うため全テーブルが消えます(0.18.x 以前の動きで、0.19.0 からは直せません)。0.19.0 で作り直した後は 0.18.x に戻さないでください。plugin などで版を固定している場合は、CLI と同じ版にそろえてください
  • 0.18.x の plugin を使い続けたまま 0.19.0 を試すときは、0.19.0 の側だけ HOUKI_EGOV_DB_PATH で別のファイルを指定してください(下の「DB の場所を変える」)。2 つの版が別々の DB を使うので、どちらの DB も消えません

環境変数

環境変数 内容 既定
HOUKI_EGOV_DB_PATH DB ファイルのパス(フォルダーではなく、ファイル名まで書く)。CLI と MCP サーバーの両方に同じ値を設定します(下の「DB の場所を変える」) $XDG_CACHE_HOME/houki-egov-mcp/laws.db(XDG_CACHE_HOME が無ければ ~/.cache/houki-egov-mcp/laws.db)
HOUKI_EGOV_BULK_RETRY 一括ダウンロードの zip の取得に失敗したときに試す回数 3
HOUKI_EGOV_INCREMENTAL_LIMIT_DAYS --sync が差分で追える日数の上限。--status と search_fulltext の警告の日数にも使います 90
HOUKI_EGOV_CONCURRENCY e-Gov 法令 API への同時リクエスト数の上限 4
HOUKI_EGOV_FILES_DIR get_attachment / get_law_file の save: true の保存先 ${XDG_CACHE_HOME:-~/.cache}/houki-egov-mcp/files

数値の 3 つ(HOUKI_EGOV_BULK_RETRY・HOUKI_EGOV_INCREMENTAL_LIMIT_DAYS・HOUKI_EGOV_CONCURRENCY)は 1 以上の整数で指定します。0・負の数・小数・数字以外を指定すると、CLI(取り込み・同期・状態の表示)は何もせずに終了コード 2 で終わり、MCP サーバーは警告を出して既定値で起動します(0.19.0 から。それまでは 0 や数字以外は黙って既定値になり、負の数はそのまま使っていました)。

DB の場所を変える(HOUKI_EGOV_DB_PATH)

DB の場所は、次の順で決まります。

  1. 環境変数 HOUKI_EGOV_DB_PATH があれば、その値のファイル
  2. 無ければ、環境変数 XDG_CACHE_HOME の下の houki-egov-mcp/laws.db
  3. どちらも無ければ、~/.cache/houki-egov-mcp/laws.db

起動のしかたによって、環境変数が渡るかどうかが違います。どのファイルを開くかは次のとおりです。

起動のしかた 環境変数 開く DB
Claude Code plugin(.claude-plugin/plugin.json) plugin は env を持たず、Claude Desktop のような GUI アプリはシェルの環境変数を受け継がない ~/.cache/houki-egov-mcp/laws.db
MCP の設定ファイル(claude_desktop_config.json・.mcp.json)に書いたサーバー 設定の env だけ env に HOUKI_EGOV_DB_PATH があればそのファイル。無ければ ~/.cache/houki-egov-mcp/laws.db
ターミナルの CLI(--bulk-download-everything・--sync・--status) そのシェルの環境変数 HOUKI_EGOV_DB_PATH があればそのファイル。無ければ ${XDG_CACHE_HOME:-~/.cache}/houki-egov-mcp/laws.db

環境変数を付けずに CLI を実行すると、plugin が使う laws.db を作り、更新します。 plugin で使う DB は、環境変数を付けずに CLI で作り、--sync で更新してください。逆に、plugin と別の DB を試したいときは、CLI にだけ HOUKI_EGOV_DB_PATH を付けます。そのときに作った DB を plugin は読みません。シェルの設定(~/.zshrc など)で HOUKI_EGOV_DB_PATH を export しているときは、plugin と同じ DB を扱う CLI の前に env -u HOUKI_EGOV_DB_PATH を付けます(例: env -u HOUKI_EGOV_DB_PATH npx -y @shuji-bonji/houki-egov-mcp@latest --sync)。

HOUKI_EGOV_DB_PATH を使うのは、DB を別のディスクに置きたいとき、版の違う houki-egov-mcp を並べて使うとき(0.18.x の plugin と 0.19.0 など)、試しに別の DB を作りたいときです。設定するときは、次の 3 点に気を付けてください。

  • CLI と MCP サーバーの両方に、同じ値を設定します。 DB を作る CLI(--bulk-download-everything など)と、DB を読む MCP サーバー(search_fulltext)は別々に起動するので、片方だけに設定すると、CLI が作った DB を MCP サーバーが見つけられません(search_fulltext が ローカル DB (<パス>) が無いため か HOUKI_EGOV_DB_PATH が指すファイル (<パス>) が無いため で search_law に切り替わります)
  • フォルダーではなく、ファイル名まで書きます。 例: /Users/you/data/houki-egov/laws.db。途中のフォルダーが無ければ、--bulk-download-everything が作ります
  • MCP の設定ファイル(JSON)では、~ を使わずに絶対パスで書きます。 JSON の env の値はシェルを通らないので、~/… は展開されません。ターミナルで export するときは ~ が使えます

CLI での指定(ターミナル):

export HOUKI_EGOV_DB_PATH=~/data/houki-egov/laws.db
npx -y @shuji-bonji/houki-egov-mcp@latest --bulk-download-everything
npx -y @shuji-bonji/houki-egov-mcp@latest --status   # 2 行目の「DB:」に使っている場所、3 行目に DB の場所の設定が出ます

MCP サーバーでの指定(claude_desktop_config.json や .mcp.json):

{
  "mcpServers": {
    "houki-egov": {
      "command": "npx",
      "args": ["-y", "@shuji-bonji/houki-egov-mcp@latest"],
      "env": {
        "HOUKI_EGOV_DB_PATH": "/Users/you/data/houki-egov/laws.db"
      }
    }
  }
}

設定を変えたら、MCP クライアント(Claude Desktop など)を起動し直してください。MCP サーバーが使っている場所は、起動時のログの [server] DB: … の行か、search_fulltext の応答の freshness.db_path で確かめられます。CLI では、同じ値を付けて --status を実行し、2 行目の DB:、3 行目の DB の場所の設定:、laws: の件数で確かめてください。

search_fulltext が api-fallback になるとき

ローカル DB を作ったはずなのに search_fulltext が source: "api-fallback" を返すときは、note の先頭で原因を見分けます。

note の先頭 考えられる原因 確かめ方・直し方
ローカル DB (<パス>) が無いため <パス> に DB をまだ作っていない(HOUKI_EGOV_DB_PATH を設定していないサーバー) <パス> に DB を作ります。plugin なら環境変数を付けずに --bulk-download-everything を実行します(上の env -u)。別のファイルに作った DB があるなら、下の手順で <パス> に移します
HOUKI_EGOV_DB_PATH が指すファイル (<パス>) が無いため MCP サーバーの HOUKI_EGOV_DB_PATH が、無いファイルを指している(ファイルの名前を変えた・消した、CLI と違う値を設定した、など) HOUKI_EGOV_DB_PATH を作ってある DB のファイルに直すか、そのパスに作ります。note と next_actions のコマンドは同じ変数を付けた形なので、そのまま実行すればそのパスに作ります
ローカル DB (<パス>) にまだ法令が取り込まれていないため ファイルはあるが、法令が取り込まれていない(0 バイトのファイル、取り込みを途中で止めた DB、houki-egov-mcp で作っていない SQLite のファイル) --bulk-download-everything を実行します
ローカル DB (<パス>) の版 (<n>) がこの houki-egov-mcp (3) より古いため 開いた DB が、前の版の houki-egov-mcp で作ったもの --bulk-download-everything で作り直します。新しい版の DB が別のファイルにあるなら、下の手順で移すと取り込み直さずに済みます
ローカル DB (<パス>) の版 (<n>) がこの houki-egov-mcp (3) より新しいため 開いた DB が、新しい版の houki-egov-mcp で作ったもの(plugin の版が CLI より古い、など) plugin と CLI の版をそろえます
ローカル DB (<パス>) の版を読めないため (schema_version: <値>) DB の版の記録が、整数でない値になっている <パス> のファイルを消してから --bulk-download-everything を実行します
ローカル DB (<パス>) を開けなかったため パスがフォルダーを指している、途中が普通のファイル、権限が無い HOUKI_EGOV_DB_PATH の値を直します。この場面では --bulk-download-everything を案内しません(同じパスでは、取り込みも取得の前に止まるためです)

<パス> は MCP サーバーが開こうとしたファイルで、ホームディレクトリの部分を ~ にして書きます(0.20.0 から。0.19.x までは bulk DL 未実行のため などの文で、開こうとしたファイルが分かりませんでした)。CLI の側は、MCP サーバーと同じ環境変数で --status を実行し、2 行目の DB: と 3 行目の DB の場所の設定: で、開くファイルとその場所に決まった理由を確かめます。plugin なら HOUKI_EGOV_DB_PATH を付けずに実行します(上の env -u)。同じフォルダーに別の laws*.db が残っていれば、--status が [WARN] の行で挙げます。

別のファイルで作った DB を laws.db に移す

HOUKI_EGOV_DB_PATH で別のファイル(例: laws.v3.db)に作った DB は、名前を laws.db に変えれば、取り込み直さずに plugin から使えます。

  1. その DB を開いている MCP サーバーを止めます(Claude Desktop などを終了し、--sync などの CLI も動いていないことを確かめます)
  2. WAL の中身を DB ファイルに書き戻します: sqlite3 ~/.cache/houki-egov-mcp/laws.v3.db 'PRAGMA wal_checkpoint(TRUNCATE);'
  3. 今の laws.db を退避します: mv ~/.cache/houki-egov-mcp/laws.db ~/.cache/houki-egov-mcp/laws.v2.bak.db(laws.db-wal・laws.db-shm があれば、同じように名前を変えるか消します)
  4. 名前を変えます: mv ~/.cache/houki-egov-mcp/laws.v3.db ~/.cache/houki-egov-mcp/laws.db(2 で空になった laws.v3.db-wal・laws.v3.db-shm は、laws.db の名前に付け替えずに消すか別の名前にします)
  5. 環境変数を付けずに npx -y @shuji-bonji/houki-egov-mcp@latest --status を実行し、DB: が laws.db で laws: の件数が入っていることを確かめます
  6. HOUKI_EGOV_DB_PATH で古いファイル名を指している設定(MCP の設定ファイルの env、シェルの export)があれば、消すか laws.db に直します。古い名前を指したままのサーバーは、ファイルが無いので HOUKI_EGOV_DB_PATH が指すファイル (…) が無いため を返します

退避した古い DB は、確かめた後に消してかまいません。

SQLite と DB の置き場所(npx / plugin 経由で使う場合)

SQLite は本パッケージが依存する better-sqlite3 に同梱されています(SQLite 3.53 系の amalgamation。OS の sqlite3 は使いません)。npx や plugin で初めて起動したときに npm が better-sqlite3 を取り込み、実行中の Node.js と OS に合ったビルド済みバイナリ(prebuild-install)を GitHub Releases から取得します。対応する prebuilt がない Node.js の場合は node-gyp でその場でコンパイルするため、Python と C++ ビルドツール(macOS なら Xcode Command Line Tools)が必要になります。Node 22 / 24 の LTS では prebuilt が用意されているので、通常はコンパイルは走りません。

DB ファイルはパッケージの中ではなく、上記のユーザーのキャッシュディレクトリに置かれます。したがって次の 3 つは 同じ 1 つの DB を読み書きします。

起動方法 実行されるコード 読む DB
npx -y @shuji-bonji/houki-egov-mcp@latest --bulk-download-everything(CLI) npx のキャッシュ内のパッケージ ~/.cache/houki-egov-mcp/laws.db
Claude Desktop / Claude Code plugin(npx -y …@latest) 同上(@latest 指定なら起動ごとにレジストリを確認) 同上
ローカル開発(node dist/index.js) リポジトリの dist 同上。古いコミットや DB の版を上げる変更を試すときは、HOUKI_EGOV_DB_PATH で別のファイルに向けてください(CONTRIBUTING.md)

どれも環境変数が無いときの場所です。HOUKI_EGOV_DB_PATH を設定した起動だけが別のファイルを開きます(上の「DB の場所を変える」)。

このため、DB の構築は一度 CLI で行えば、plugin 経由の search_fulltext からもそのまま使えます。--bulk-download-everything のあとに MCP server を再起動する必要はありません(search_fulltext は呼び出しごとに DB を開いて閉じます)。書き込みは CLI だけが行い、MCP server は読むだけです(journal は WAL なので、取り込み中に検索しても壊れません)。DB を作るのは --bulk-download-everything だけで、search_fulltext と --status は DB が無くてもファイルやフォルダーを作りません(0.19.0 から)。

DB が存在しない、または条が 1 件も入っていないときは、search_fulltext は source: "api-fallback" で search_law の結果を返し、next_actions に --bulk-download-everything の実行を案内します。パッケージを更新しても DB は消えません。版が古い DB は --bulk-download-everything を実行したときだけ作り直します。新しい版の DB は触りません。

DB の版(DB に記録したスキーマの版)ごとの扱いは次のとおりです(0.19.0 から)。

DB の状態 --bulk-download-everything --sync・--bulk-download-by-date --status search_fulltext
ファイルが無い 作って取り込む 作らない。全件の取り込みを促して終了コード 1 作らない。DB が無いことを出して終了コード 0 作らない。search_law に切り替える
版が同じ(3) 取り込む 取り込む 表示する 検索する
版が古い(1・2) 取得に成功してから作り直して取り込む 書き込まずに終了コード 1 書き込まずに終了コード 1 使わずに search_law に切り替え、作り直しを案内する
版が新しい・版を読めない 取得せずに終了コード 1 書き込まずに終了コード 1 書き込まずに終了コード 1 使わずに search_law に切り替える

全データを消すコマンドはありません。中身を消したいときは DB のファイルを消してください(場所は --status の DB: の行に出ます)。

DB を構築すると search_fulltext が条文本文を SQLite FTS5 で検索します(v0.5.0〜)。略称は正式名称にも展開され(労基法 → 労基法 または 労働基準法)、通称(インボイス など)は元の語で条が当たらないときだけ正式名称で探し直します(v0.18.0)。「民法 不法行為」「労基法 時間外」のように法令名と語を並べるとその法令の条に絞って本文を検索します。各ヒットに条番号・snippet・score・DB の鮮度(freshness)が付きます。DB が未構築のときは従来どおり search_law(法令名のタイトル一致)にフォールバックし、note でその旨を返します。

v0.5.0 以前に構築した DB について: v0.5.0 で本文の正規化を投入時に行うようになり(スキーマバージョン 2)、v0.5.1 で編(Part)を持つ法令の本則が取り込まれていなかった不具合を直しました。0.19.0 からはスキーマの版 3 の DB だけを使うので、どの版で作った DB も --bulk-download-everything で作り直してください。

検索語の制約: 索引が trigram のため、条文本文は 3 文字以上の語で索引から引きます。2 文字の語(「相殺」「時効」等)の扱いは v0.12.0 で変わりました(下記)。「第30条」のような条番号は本文検索には使わず、該当条を上位に寄せる加点にだけ使います(漢数字は未対応)。

添付ファイルと法令本文ファイル(v0.15.0)

法令には、条文の文字列に入らないものが付いています。別表・様式・別記の図(e-Gov では jpg か pdf)と、法令全体を 1 つのファイルにした本文(xml / json / html / rtf / docx)です。get_law の Markdown には図の中身は入らず、様式の図が要る作業(届書の書式、旗の寸法図)は条文だけでは済みません。v0.15.0 の 3 ツールはそのための道です。

「戸籍法施行規則の出生届の様式を見たい」
  → list_attachments(law_name="戸籍法施行規則")
     attachments[] の location.title が「附録第十一号様式」の 1 件(pdf)の url を得る
  → pdf-reader-mcp の read_url(url=…)                          # URL は認証なしで開ける
  (またはディスクに置くなら)
  → get_attachment(law_name="戸籍法施行規則", src="./pict/2FH00000076885.pdf", save=true)
     → saved.path を pdf-reader-mcp の read_text に渡す

「民法の全文を Word で」
  → get_law_file(law_name="民法", file_type="docx", save=true)
     → saved.path(182 KB)。saved.law_revision_id にどの履歴の本文かが入る
  • 中身は返しません。バイナリを base64 にして応答に入れることはせず、URL(https://laws.e-gov.go.jp/api/2/attachment/<law_revision_id>?src=…、…/law_file/<file_type>/<law_id>)を返します。URL は認証なしで開けるので、pdf-reader-mcp の read_url や、利用者のブラウザーにそのまま渡せます
  • 保存先はサーバー側で決めます。save: true のときだけファイルを取得し、${XDG_CACHE_HOME:-~/.cache}/houki-egov-mcp/files/<law_revision_id>/<ファイル名> に書いて saved.path を返します。保存先は環境変数 HOUKI_EGOV_FILES_DIR で変えられますが、ツールの引数にはありません(LLM が渡した文字列をパスに使わないため)。1 ファイル 50 MB を超えるときは保存せず FILE_TOO_LARGE を返します。e-Gov の応答の Content-Length で分かるときは本文を読みません(v0.16.0)
  • 置き場所を付けます。list_attachments は e-Gov の attached_files_info(src と更新日時)と本文の Fig 要素を src で突き合わせ、各ファイルに location(別表・様式の見出しと関係条文、条の中なら条番号、附則の中なら改正法番号)を付けます。一覧にだけあって本文に無いファイルは location: null です
  • 添付ファイルは法令履歴ごとに付くので、at で時点を変えると一覧も変わります。添付が無い法令は list_attachments では count: 0 の成功応答、get_attachment では ATTACHMENT_NOT_FOUND です
  • get_law_file の xml / json は法令全体(民法で 1.6 MB)なので、条文を読むだけなら get_law / get_law_range を使ってください。docx / html / rtf は人が開く版です

章・節単位の取得(v0.14.0)

get_law_range は、編・章・節・款・目のいずれか、または附則 1 本を範囲にして、その中の条を本文ごと返します。get_law で 1 条ずつ引くと手数がかかり、法令全体を返すには長すぎる法令(民法・会社法・消費税法)のためのツールです。

範囲の指定は次の 3 通りで、同時に指定できるのは 1 つだけです。

指定 書き方
編・章・節・款・目の番号 part=3, chapter=2("三"・"第三編"・枝番号の "2の2" も可)
範囲のパス path="Part3/Chapter2"(get_toc の toc[].path をそのまま渡せます)
附則 suppl_index=12(get_toc の suppl_provisions[].index。search_fulltext が「附則(12) 1」と表示する番号と同じ)

章番号は編ごとに振り直されます(民法には第一章が 5 つ、第一節が 19 あります)。chapter だけを指定して複数の範囲に当たったときは、候補のパスを hint と next_actions に入れた INVALID_ARGUMENT を返します。

大きい範囲は max_chars(既定 30,000 文字)で条の単位で打ち切ります。条の途中では切らないため、1 条目だけは上限を超えても返します。2026-09-20 に測った条本文のサイズは次のとおりです(UTF-8 の日本語は 1 文字 3 バイト)。

法令 章の条本文(中央値 / 最大) 既定の上限での回数
民法 6.2 KB / 98.2 KB ほとんどの章は 1 回。第三編第一章(183 条)は 2 回
会社法 17.9 KB / 207.6 KB 大きい章は 2〜3 回
所得税法 10.8 KB / 229.1 KB 大きい章は 2〜3 回
消費税法 59.5 KB / 102.4 KB 章は 2〜4 回(編が無く章が大きい)

打ち切ったときの応答の range は次の形です。

{
  "path": "Part3/Chapter2",
  "titles": ["第三編 債権", "第二章 契約"],
  "tag": "Chapter",
  "article_count": 198,      // 範囲が持つ条の数
  "returned_count": 186,     // 本文を返した条の数
  "skipped_count": 0,        // from_article より前で返さなかった条の数
  "first_article": "第521条",
  "last_article": "第684条",
  "truncated": true,
  "body_chars": 29911,
  "max_chars": 30000,
  "next_from_article": "685",
  "note": "範囲の条 198 件のうち 186 件を返しました(第521条〜第684条)。本文 29,911 文字(上限 30,000 文字)。上限で打ち切りました。続きは from_article: \"685\" を付けて同じ範囲を呼び直してください。"
}

from_article に next_from_article の値を渡すと、同じ範囲の続きから返します。条を立てず項だけで書かれた附則(「1 この法律は、公布の日から施行する。」の形)は、範囲の本文をそのまま返します。

削除された条は、e-Gov の法令データでは複数の条をまとめた範囲表記になっています(民法第534条は Article Num="534:535"、見出しは「第五百三十四条及び第五百三十五条」、本文は「削除」)。応答ではこれを 第534条及び第535条(3 条以上なら 第170条から第174条まで)と表示し、next_from_article にも "534:535" の形を返すので、そのまま from_article に渡せます(v0.14.1)。なお get_law に article: "534" を渡してこの条を引くことは、まだできません。

本則と附則の分け方(v0.13.0)

附則は改正法ごとに 1 本ずつ積み上がります(所得税法は 352 本・条 983 件)。v0.12.1 までの get_toc は、この附則の条を本則の章の後ろにそのまま並べていたため、いま効いている規定と、ある改正法の施行日・経過措置の区別が目次から付きませんでした。

v0.13.0 からは、本則を toc、附則を suppl_provisions に分けて返します。附則 1 本は次の形です。

{
  "index": 2,                                        // LawBody の中での並び順。ローカル DB の Suppl2_1 と同じ番号
  "label": "附則",
  "amend_law_num": "平成元年六月二八日法律第三九号",  // どの改正法の附則か。制定時の附則には付かない
  "extract": true,                                   // 抄(改正法の附則のうち一部だけを載せた形)
  "article_count": 1,
  "paragraph_only": false,                           // 条を立てず項だけで書かれた附則か
  "children": []                                     // suppl: "full" のときだけ中の目次が入る
}

suppl で附則をどこまで返すかを選びます。

suppl 返すもの 所得税法の Markdown
"list"(既定) 改正法ごとの見出しと条数だけ 752 行 / 54.5 KB
"full" 附則の中の条まで 1,735 行 / 114.4 KB
"none" 附則を返さない(本数と条数は suppl.count / suppl.article_count に入る) 395 行 / 24.6 KB

既定を "list" にしているのは、附則の条が目次の大半を占めるためです(所得税法は本則 388 ノードに対し附則の条 983 件)。何を返したかは suppl.note に書きます。

with_amend_titles: true を付けると、改正法の題名も付けます。附則の属性には法令番号しか無いため、改正履歴(get_law_revisions と同じ e-Gov の応答)を 1 回引き、法令番号で照合します。2 つの表記は違うので(附則は 令和七年六月二〇日法律第七四号、改正履歴は 令和七年法律第七十四号)、公布の月日と漢数字の書き方を落とした「元号 + 年 + 種別 + 号数」で突き合わせます。e-Gov の改正履歴は近年の改正が中心なので、それより古い改正法には題名が付きません(消費税法は附則 167 本のうち 28 本に付き、改正履歴は 65 件)。付いた本数と付かなかった本数は suppl.amend_law_titles に入ります。

get_law の format: "toc" でも本則と附則を分け、附則は見出しだけを返します。

2 文字の語の検索(v0.12.0)

「相殺」「時効」「善意」のような 2 文字の法律用語は、条本文の索引 articles_fts(trigram)に載りません。v0.12.0 からは、そのときに何をして結果を出したかを応答の short_tokens で返します。

クエリ body_search 何をするか
適格請求書 保存 fts_then_filter 3 文字以上の語で索引を引き、その条の本文に 2 文字語が含まれるかで絞る
労基法 協定 like_in_law_scope 法令名で対象法令を絞り、その範囲の条の本文を引く
相殺 not_searched 条の本文は引かず、法令名・略称・番号の照合だけを返す(既定)
相殺 + scan_body: true like_all_articles 索引を使わず、全法令の条の本文を端から照合する

short_tokens.hits_by_match_type に article(条本文由来)と law_meta(法令名・略称・番号由来)の件数が入ります。v0.11.0 までは「相殺」で「相殺関税に関する政令」だけが返り、条の本文が引かれなかったことが応答から分かりませんでした。

既定で not_searched にしているのは、全法令の走査に時間がかかるためです。2026-09-20 に実データ(条 1,434,710 件・本文 587,926,852 バイト)で測ったところ、ヒットが多く上限 150 件で打ち切れる語で 5.4 秒、該当が少なく全表を走り切る語で 22 秒かかりました。LIKE を instr や GLOB に変えても、JOIN を外しても同じ時間です。588 MB を読んで照合する分そのものなので、書き方では縮みません。

そのため not_searched の next_actions は 2 つの道を示します。

  1. 「<法令名> 相殺」の形(例: 民法 相殺)— 法令名を添えると、その法令の条に絞って索引で引けます(速く、並び順も関連度順)。語から法令名は決まらないので、この案内には example を付けず、reason に形を書きます(v0.18.0)
  2. { keyword: "相殺", scan_body: true } — 法令名が分からないときの最後の手段です。5〜20 秒かかり、並び順は関連度順になりません。上限(150 件)で打ち切ったときは truncated: true になります

3 文字以上の語を含むクエリでは索引を引くので、scan_body は効きません。

引用の実在確認(v0.11.0)

verify_citations は、回答に添える引用のリストを送り出す前に、その条(指定があれば項・号)が e-Gov の法令にあるか を 1 回の呼び出しでまとめて確かめます。存在しない引用が混ざっていてもツール全体はエラーにならず、件ごとに判定が返ります。

{
  "citations": [
    { "law_name": "所法", "article": "9", "paragraph": 1, "item": 1, "label": "所法9①一" },
    { "law_name": "電子帳簿保存法", "article": "7" },
    { "law_name": "所得税法", "article": "9999" }
  ]
}
  • 上の 3 件は順に found(条見出し「(非課税所得)」付き)、found(resolved_by: "exact_title" で 410AC0000000025)、not_found(code: "ARTICLE_NOT_FOUND")になります
  • summary に件数の内訳と all_found が入るので、「全部実在した」と書いてよいかを 1 つの値で判断できます
  • 法令名が e-Gov の法令名と完全一致しなければ ambiguous にし、部分一致の候補を candidates[] に最大 5 件返します(例: 「所得税法施行」→ 所得税法施行令・所得税法施行規則)。項が複数ある条で項を書かずに号だけを指定した件も ambiguous です
  • 通達など houki-egov の管轄外の引用は OUT_OF_SCOPE にし、next_actions で houki-nta を指します
  • 条は本則の中で確かめます。本則に無く附則にだけある条番号は ARTICLE_NOT_FOUND にし、附則の番号を案内します。附則の条は suppl_index(get_toc の suppl_provisions[].index)で附則を指して確かめます(v0.18.0)
  • 確かめるのは条文が実在するかどうかだけです。引用した条文が主張を支えるかどうかは判定しません
  • e-Gov に問い合わせられなかったときは、件ごとの判定を返さずツール全体を SOURCE_* エラーにします。「聞けなかった」を「存在しない」と書かないためです

状態

v0.15.0 (2026-09-20)

  • e-Gov 法令API v2 クライアント(searchLaws / getLawData / getLawRevisions / getAttachment / getLawFile)
  • 法令ツリー走査(条/項/号、目次抽出)+ LRU cache
  • 14 ツール本実装
  • 略称辞書を @shuji-bonji/houki-abbreviations に分離(v0.15.4 から ^0.6.1)
  • 法令階層ナレッジ(憲法・法律・政令・省令・規則・条例・告示・訓令・通達・通知 の10種別)
  • houki-hub family 共通の error contract(SOURCE_* / OUT_OF_SCOPE)に準拠
  • Phase 2 基盤:bulk DL → SQLite FTS5 の取り込みパイプライン(schema / CSV・XML parser / zip fetcher / ingester / freshness / CLI)
  • Phase 2-7: search_fulltext の FTS5 本実装(略称 OR 展開 / revision 重複排除 / relevance scoring / freshness)
  • MCP SDK v2(@modelcontextprotocol/server)/ Node 22・24 / TypeScript 7 / Biome
  • Trusted Publisher (OIDC) で publish
  • get_law の item で枝番号の号("8の2"・"第8号の2")を指定(v0.6.0)
  • ツールの引数の型を inputSchema から導き(json-schema-to-ts の FromSchema)、未知の引数は INVALID_ARGUMENT(v0.6.0)
  • get_law の article / item で漢数字("第三十条の二"・"八の二")と全角数字を受け付ける(v0.7.0)
  • --sync で最終同期日から今日までの日次差分を取り込む。差分が無い日は飛ばし、途中で失敗しても成功した日までを記録(v0.8.0)
  • get_related_laws / get_article_references: 施行令・施行規則の関連付けと条文内の参照抽出(v0.10.0、Issue #20)
  • verify_citations: 引用リストの実在確認(v0.11.0、Issue #18)
  • search_fulltext の 2 文字語(「相殺」「時効」)の扱いを short_tokens で明示し、scan_body で全走査を選べるようにした(v0.12.0、Issue #23)
  • get_toc で本則と附則を分け、附則を改正法ごとにまとめた(v0.13.0、Issue #24)
  • get_law_range: 編・章・節(または附則 1 本)を範囲にした条文の取得(v0.14.0、Issue #22)
  • list_attachments / get_attachment / get_law_file: 添付ファイル(別表・様式の図)と xml / html / rtf / docx の本文ファイル(v0.15.0、Issue #19)
  • テストスイート(456 tests)

計画中

  • Phase 2-8: 差分同期(--sync)— v0.8.0
  • Phase 2-13: API enrichment(category / 改正履歴 / 廃止ステータスの精緻化)
  • 漢数字対応(「第三十条」を 30 に変換)— v0.7.0 で get_law の article / item に対応。search_fulltext のキーワード中の「第三十条」は未対応
  • 大規模法令の応答サイズ対策(民法・会社法)— v0.14.0 の get_law_range で章・節単位の取得に対応

houki-hub MCP family

houki-egov-mcp は 単体で利用可能ですが、houki-hub MCP family の一員でもあります。同じ family 内の他 MCP と組み合わせると、通達・判例等まで横断的に扱えます。

パッケージ 役割 状態
@shuji-bonji/houki-abbreviations 略称辞書・正規化・freshness 判定(共有ライブラリ) ✅ v0.5.0
@shuji-bonji/houki-egov-mcp e-Gov 法令API クライアント + ローカル全文検索(このリポジトリ) ✅ v0.5.1
@shuji-bonji/houki-nta-mcp 国税庁通達・Q&A・タックスアンサー・文書回答事例 ✅ v0.9.5
houki-research-skill family を横断する Claude Skill(error contract の正典) ✅
@shuji-bonji/houki-mhlw-mcp 厚労省通達・通知 計画中
@shuji-bonji/houki-court-mcp 判例(裁判所サイト) 構想中
@shuji-bonji/houki-saiketsu-mcp 国税不服審判所裁決 構想中

family 全体の設計思想・想定利用シーン・業法との関係は docs/DESIGN.md を参照。

エラー応答 (houki-hub family contract)

v0.3.0 より、本 MCP のエラー応答は houki-hub family 共通契約に完全準拠します。code 文字列は family 全体で統一された語彙を使用するため、複数の MCP を併用しても LLM・Skill 層は一貫したロジックで解釈できます。

houki-egov-mcp の src/errors.ts は family 全体の リファレンス実装として位置付けられています。他 MCP は同じ code 語彙を共有しつつ、共通パッケージへの依存は持たずに独立実装します。

{
  "error": "法令『消費税法』第3000条は存在しません",
  "code": "ARTICLE_NOT_FOUND",
  "hint": "条番号を get_toc で確認してください",
  "next_actions": [
    { "action": "get_toc", "reason": "目次で正しい条番号を特定", "example": { "law_name": "消費税法" } }
  ],
  "retryable": false
}

本 MCP で使用するコード

code 用途 retryable
INVALID_ARGUMENT 引数が tools/list の inputSchema に合わない(型・必須・enum・範囲・形式・inputSchema に無い引数。detail.issues[] に違反 1 件ごとの引数名と日本語の文、tool に呼んだツール名)、必須の文字列が空白だけ、at が暦に無い日付、get_law で項が複数ある条に paragraph なしで item を指定した、get_law_range で範囲の指定が無い・2 通り同時・複数の章に当たった、e-Gov が時点 at を受け付けないと答えた(2017-04-01 より前。detail.issues[0].path: "at"、hint に e-Gov の文。v0.18.0) 等 false
INVALID_ARTICLE_NUM 条番号・号番号のフォーマットが不正 (例: "30-2"、位ごとに並べた "三〇") false
OUT_OF_SCOPE 通達名で get_law を呼んだ、search_fulltext に通達の略称だけを渡した(v0.18.0)等、別 MCP の管轄リソースが要求された false
LAW_NOT_FOUND 略称辞書に無く、e-Gov の法令名の検索で題名の完全一致が無かった(0 件、または部分一致だけ。部分一致のときは候補を hint と next_actions に入れる。v0.18.0)。law_id を決めた後に e-Gov が「その法令が無い」と答えたときも(404・404004 / 改正履歴は 404001。v0.18.0)。検索が通信の失敗で終わったときは SOURCE_*(v0.16.0) false
ARTICLE_NOT_FOUND 指定された条/項/号が見つからない(get_law_range の from_article がその範囲に無い場合を含む)。本則に無く附則にだけある条番号も含み、そのときは附則の番号を案内する(v0.18.0) false
RANGE_NOT_FOUND get_law_range で指定された編・章・節(または附則の番号)が見つからない false
ATTACHMENT_NOT_FOUND get_attachment で指定された src がその法令履歴の添付に無い、添付が 1 件も無い、または e-Gov の /attachment が「存在しない」(code 404003)を返した false
SOURCE_API_ERROR e-Gov API がエラー応答(5xx は再試行できる、429 以外の 4xx は再試行できない。LAW_NOT_FOUND・INVALID_ARGUMENT にする 404・400 を除く)。法令名の検索の失敗も含む 状況による
SOURCE_TIMEOUT e-Gov API がタイムアウト true
SOURCE_RATE_LIMITED e-Gov API がレート制限 (HTTP 429) true
SOURCE_UNAVAILABLE e-Gov に接続できない(ENOTFOUND / EAI_AGAIN / ECONNREFUSED / ECONNRESET / ETIMEDOUT。detail.cause にその code。v0.16.0 から fetch failed の cause.code も見る) true
FILE_TOO_LARGE get_attachment / get_law_file の save: true で、ファイルが上限(50 MB)を超えている(detail.bytes に大きさ。v0.16.0。pdf-reader-mcp と同じ code) false
INTERNAL_ERROR 内部エラー (バグ・予期せぬ例外)。search_fulltext でローカル DB の同期の記録の日付を読めないときも(v0.16.0。全件の取り込みを案内) false
UNKNOWN_TOOL 存在しない tool 名が呼ばれた false

verify_citations の code は件ごとに付きます(v0.11.0)

verify_citations は、存在しない引用が混ざっていてもツール全体を isError にしません。上の表の code は results[] の 1 件ごとに付き、LAW_NOT_FOUND / ARTICLE_NOT_FOUND / INVALID_ARTICLE_NUM / OUT_OF_SCOPE / INVALID_ARGUMENT のいずれかです。法令名が完全一致せず候補が複数あった件は status: "ambiguous" と candidates[] だけを返し、code は付きません。

ツール全体がエラーになるのは、引数の形が壊れているとき(INVALID_ARGUMENT)と、e-Gov が時点 at を受け付けないとき(INVALID_ARGUMENT。at は全件に共通のため。v0.18.0)と、e-Gov に問い合わせられなかったとき(SOURCE_*)と、e-Gov との通信と関係の無い処理中の例外(INTERNAL_ERROR。v0.16.0)だけです。e-Gov に問い合わせられなかったときに件ごとの判定を返さないのは、「聞けなかった」を「存在しない」と書かないためです。

Migration (v0.2.x → v0.3.0)

  • v0.2.x までは EGOV_API_ERROR / EGOV_TIMEOUT / EGOV_RATE_LIMITED を返していました。v0.3.0 からは family 共通の SOURCE_API_ERROR / SOURCE_TIMEOUT / SOURCE_RATE_LIMITED に切替。
  • EGOV_* は v0.15.x まで LawErrorCode の型に残していましたが、v0.16.0 で型からも外しました(返さない ABBREVIATION_NOT_FOUND も同じ)。
  • 構造化エラーの形 ({ error, code, tool?, hint?, next_actions?, retryable?, detail? }) は不変(tool は v0.16.0 で引数の検査の INVALID_ARGUMENT に足した)。クライアント側で code 文字列の比較をしている場合は SOURCE_* を受け付けるよう更新してください。
  • OUT_OF_SCOPE を新たに受け取る可能性があります。例えば「消基通」(消費税法基本通達 / 国税庁の通達) を get_law の law_name に渡すと、next_actions[0].example.mcp = "houki-nta" を含む OUT_OF_SCOPE が返されるので、Skill 層は houki-nta-mcp に切り替えてください。

ドキュメント

  • docs/LAW-HIERARCHY.md — 法令種別の階層リファレンス(専門家でない利用者向け)
  • docs/USE-CASES.md — プロダクト開発の典型ユースケース(電帳法・電子契約・個情法・e-KYC)
  • docs/DESIGN.md — 設計原則・houki-hub family のロードマップ・業法との関係
  • docs/NOTES.md — README の注意書きの詳細(施行日の当日に配り直される版と 0.19.1 の DB の直し方)
  • DISCLAIMER.md — 利用上の注意(業法との関係)
  • CONTRIBUTING.md — 貢献方法
  • CHANGELOG.md — リリースノート

業法との関係

本MCPは 一次情報の取得・提示のみ を担います。分析は LLM、当てはめと結論は事実を見た人(本人か、資格を持つ専門家)が行います。弁護士・税理士・社会保険労務士が自分の業務の調査に使うことは通常の使い方です。想定していないのは、本MCPが個別の事案の結論を返すことと、資格のない者がその出力を他人の事件や税務の判断として業で渡すことの 2 つです — 詳細は DISCLAIMER.md 参照。

デジタル庁公式 MCP との関係

デジタル庁は 2025年12月〜2026年3月の「法令×デジタル」ハッカソンで法令API / MCP のプロトタイプを試行提供した。将来一般公開された場合は、本 MCP のコアを公式 MCP に委譲し、houki-hub family 全体は 公式が手を出さないレイヤ(通達・裁決・判例の横断インデックス、業法対応 Skill 等) に注力する方針。

ライセンス

MIT — フォーク・改変・再配布を自由に許可します。

作者が責任を負わないのは、本MCPの出力をそのまま業務上の正解として扱った結果です。資格のない者が出力を他人の事件や税務の判断として業で渡すこと(弁護士法72条・税理士法52条・社労士法27条が資格者に限定)は想定していません。DISCLAIMER.md を必ずご確認ください。

SIMILAR PLUGINS