Local MCP server for Japanese tax-law sources: search, verbatim article retrieval, and citation verification
Project description
juricode-mcp
Status: v0.1 under development. Live text wiring is not enabled yet, and sections marked
<TBD>are filled in at release; see "Development status".
A local MCP server (stdio) that lets tax professionals search Japanese tax-law sources -- statutes, cabinet/ministerial orders, NTA interpretive circulars (通達), NTA Tax Answers, and NTA tribunal rulings (裁決) -- and verify quotations against the original texts, from Claude, ChatGPT, or any MCP client.
Search and verification only. This server does not generate text, does not compute tax amounts, and does not give legal advice.
ローカルで動く MCP サーバー(stdio)です。条文・政省令・通達・タックスアンサー・裁決を 検索し、引用文が原文と一字一句一致しているかを機械で検証できます。検索と検証のみ を行い、文章の生成・税額等の数値の算出・法的助言は行いません。
Tools
| tool | purpose |
|---|---|
search_law |
Dense semantic search over the corpus. Returns document-level hits with source metadata (no body text). |
get_article |
Returns the verbatim text of a document as stored in this corpus (see hash_basis for provenance) plus its source metadata (source_url / version_date / decision_date / text_sha256 / hash_basis / license). decision_date is populated only for rulings (裁決); it is null for every other layer. |
verify_citation |
Checks a quoted string against the original text: byte-exact match, stored-hash match, difference class, and a suggested verbatim quote when locatable. |
Every response carries a meta block naming which snapshot answered it
(index_name, registry_snapshot), so the version you are running is always
explicit. 応答には必ず meta(どの版が答えたか)が付きます。
Setup
0. Try it in one second -- no key, no index, no download
uvx juricode-mcp --mock
--mock runs on a small demo snapshot bundled with the package: 30 real
documents (income tax act, orders, circulars, Tax Answers, tribunal rulings) on
employment income and withholding. All three tools answer. Nothing is
configured, nothing is downloaded, and nothing leaves your machine.
The demo ships no retrieval index, so search_law returns documents in a
fixed order rather than by relevance -- it shows you the shape of an answer, not
a search result. Sources and licences are listed in the snapshot's NOTICE.md.
--mock は同梱のデモ・スナップショット(実在の公開資料 30 文書)で動きます。API キー・
索引・ダウンロード・設定のいずれも不要です。デモには索引が入っていないため、
search_law は関連度順ではなく固定順で返します(ツールの応答形式を見るためのものです)。
1. Get a snapshot
The server ships no corpus. A snapshot is a directory that declares its own version and carries everything the server reads:
juricode-snapshot-<id>/
├── snapshot.json the version of record: id, counts, and a digest per file
├── index/ the retrieval index
├── corpus/ row-aligned corpus
└── registry/ documents.jsonl / chunks.jsonl / texts.jsonl
- Download:
<TBD: snapshot URL>-- size<TBD>, snapshot date<TBD> - Extract it somewhere stable, e.g.
~/juricode/.
2. Set the environment
Two settings for the data, and that is deliberate: the index name, the
corpus and the registry are read from snapshot.json, never typed in. An index
paired with a registry from another build resolves every id and answers every
query -- while scoring against the stale index and serving the fresh text. That
mismatch is unreachable if there is nothing to mis-set.
JURICODE_SNAPSHOT_DIR=/path/to/juricode-snapshot-<id>
GEMINI_API_KEY=<your key> # used only to embed your search query
The retrieval code is not a setting: it is a declared, pinned dependency
(juricode-retrieval), installed with this package. --mock needs neither of
the two settings above.
There are no built-in defaults. Anything missing is reported at startup, with the names to set -- never at the first query.
On startup the server checks the snapshot against its own declaration: every
file it declares is present and digests to the value declared for it, the loaded
document, chunk and text counts are the counts declared, and the index was built
with the embedding model the snapshot names. Any mismatch is a refusal to start,
not a warning. --verify-snapshot additionally digests the vector matrix, which
is skipped by default because it is large; run it once after downloading.
設定はデータについて 2 つだけです(索引名・コーパス・レジストリは snapshot.json
から読むため、利用者が打つ必要はありません)。検索コードは設定ではなく、宣言済みで
バージョン固定した依存(juricode-retrieval)として本パッケージと共にインストール
されます。既定値は持ちません。起動時にスナップショットを自身の宣言(sha256・件数・
埋め込みモデル)と照合し、1 つでも違えば起動を拒否します(警告ではなく拒否)。
3. Point your MCP client at it
// Claude Desktop (claude_desktop_config.json)
{
"mcpServers": {
"juricode": {
"command": "uvx",
"args": ["juricode-mcp"],
"env": {
"JURICODE_SNAPSHOT_DIR": "/path/to/juricode-snapshot-<id>",
"GEMINI_API_KEY": "<your key>"
}
}
}
}
To try it first, use "args": ["juricode-mcp", "--mock"] and no env at all.
juricode-mcp --help runs with no snapshot, no index and no API key.
Disclaimer / 免責
This software does not provide legal or tax advice. Its output is source material and mechanical verification results only. Use of this software does not constitute tax agent services, tax document preparation, or tax consultation under the Certified Public Tax Accountant Act of Japan. The professional judgement remains with the tax accountant.
本ソフトウェアは法的助言・税務上の助言を提供するものではありません。出力は原典資料と 機械的な検証結果のみです。本ソフトウェアの利用は、税理士法に定める税務代理・税務書類の 作成・税務相談のいずれにも該当しません。個別の判断は税理士が行ってください。
Privacy and network access / 守秘と外部通信
The only external communication this server performs is one embedding API call
(Google Gemini) per search query, using your own GEMINI_API_KEY. There is
no telemetry, no background communication, and no automatic update check.
Document texts, verification inputs, and results never leave your machine.
--mock makes no network call at all.
外部に出る通信は、検索クエリを埋め込みに変換する Gemini API 呼び出し 1 回のみです
(鍵はユーザー自身のもので、当方は預かりません)。テレメトリ・バックグラウンド通信・
自動更新チェックのいずれも行いません。本文・検証の入力・結果が外部に出ることは
ありません。--mock は一切の外部通信を行いません。
About verify_citation / 逐語検証の注意
verbatim is a byte-exact substring check against the original text. Even
when the difference is whitespace only (diff_class: "whitespace_only"),
verbatim stays false -- the classification never relaxes the check. If you
quote the text returned by get_article as-is, or re-use the returned
suggested_quote as-is, the result is always verbatim: true.
verbatim は正規化なしの byte 一致判定です。空白・改行のみの差
(diff_class: "whitespace_only")でも verbatim は false のままです。空白差を許容する
という意味ではありません。get_article の本文、または suggested_quote をそのまま
引用すれば必ず true になります。
sha256_match is a property of the document, not of your quote: it says the
text this server holds hashes to the value its registry records for it.
When a document's hash_basis is not egov-xml-canonical, verify_citation
attaches a caveat to the response so that verbatim: true is not read as a
match against the issuing authority's original -- only as a match against the
text this server stores. verify_citation の応答には hash_basis が入り、それが
egov-xml-canonical でないときは caveat が機械付与されます(verbatim: true を
「発行元の原典と一致」と誤読させないためで、意味は「本サーバーの格納テキストと一致」です)。
About text_sha256 and hash_basis / ハッシュの意味(正直な表記)
Each document carries a text_sha256 and a hash_basis that states what the
hash actually proves. They are not all the same strength -- do not read them
as "everything has been verified against the issuing source":
egov-xml-canonical-- statute main-provision texts, produced by a deterministic parser from the e-Gov statute XML and hash-pinned so that any later modification is detectable.egov-xml-derived-- supplementary provisions (附則): derived from the same e-Gov XML by the same deterministic parser, but they are not part of the canonical article corpus and are therefore not covered by the fidelity gate that checks statute text against the source XML. There is no per-article manifest anchor either. Treat this guarantee as weaker thanegov-xml-canonical.juricode-stored-text-- circulars (通達), Tax Answers and tribunal rulings (裁決): a fingerprint of the text as ingested into this corpus, not a cross-check against the issuing body's original. The bundled demo hashes every document on this basis, including statutes; itsNOTICE.mdsays so.
法令(本則)は e-Gov の XML から決定論的なパーサで生成し、以後の改変を検知できる形で
ハッシュ固定しています(egov-xml-canonical)。附則は同じ XML から同じパーサで生成して
いますが、正本(条文)に含まれないため、原典 XML との忠実性ゲートの対象外です(条単位の
アンカーもありません)。本則より弱い保証として扱ってください(egov-xml-derived)。
通達・タックスアンサー・裁決は取込テキストの指紋(juricode-stored-text)であり、
発行元の原典と突合したものではありません。
The set of hash_basis values is defined by the data registry and passed
through exactly as stored; the list above explains the values published so far,
not a closed enum. hash_basis の値の集合はデータレジストリ側で定義され、本サーバーは
格納値をそのまま返します(固定の列挙ではありません)。
Coverage and known gaps / 収録範囲と、含まれないもの
Included: statutes, cabinet and ministerial orders, NTA circulars, NTA Tax Answers, and NTA tribunal ruling summaries.
Not included (stated plainly rather than omitted):
- Appended tables (別表 / Appdx) are not part of the canonical corpus yet.
- Case law (判例) and English translations are not part of v0.1.
収録: 法令本文・政省令・通達・タックスアンサー・裁決要旨。含まれないもの(省かずに 書きます): 別表(Appdx)は現時点で正本に含まれません/判例・英訳は v0.1 の対象外です。
Snapshots / 索引の更新
Snapshots are published on a best-effort basis. There is no fixed release schedule and no release date is promised. Every snapshot declares its own version and file digests, and every tool response reports which snapshot answered it, so the version you are running is always explicit.
索引スナップショットは**不定期(ベストエフォート)**で公開します。更新時期は約束しません。
各スナップショットは自身の版とファイルの sha256 を宣言し、応答の meta が「どの版が
答えたか」を返すため、利用中の版は常に明示されます。
License and data terms / ライセンスと出典
- Code: AGPL-3.0-or-later (see
LICENSE). Copyright (c) 2026 CHOKAI Co.,Ltd. - Data: each source's own terms apply. Every document carries the licence
recorded for it in the registry, and
get_articlereturns it, so the terms travel with the text rather than living only here.- e-Gov statute data (statutes, orders)
- NTA circulars, Tax Answers, and tribunal rulings
Development status
- The live text path (
get_articleagainst a distribution snapshot's texts) and the livesha256_matchcheck against real registry hashes are pending the upstream data refresh; the tools run today against the bundled demo snapshot and against test fixtures. - Live search reuses the upstream retrieval service, now consumed as a pinned
dependency (
juricode-retrieval) installed with this package. --mockexercises all three tools with no API key, index, network, or setting.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file juricode_mcp-0.1.0.tar.gz.
File metadata
- Download URL: juricode_mcp-0.1.0.tar.gz
- Upload date:
- Size: 103.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ee37e4f19e9cca35c843a93b886b9f7b7caae33de6e1d9a31865e29931768852
|
|
| MD5 |
319e62bc1708be03f5eee26718e750c9
|
|
| BLAKE2b-256 |
61971dc18a2bb5cd73676583d31e131c33a3ded1002be0055aff6f2f97f034b0
|
Provenance
The following attestation bundles were made for juricode_mcp-0.1.0.tar.gz:
Publisher:
publish-juricode-mcp.yml on JuriCode-JP/juricode-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
juricode_mcp-0.1.0.tar.gz -
Subject digest:
ee37e4f19e9cca35c843a93b886b9f7b7caae33de6e1d9a31865e29931768852 - Sigstore transparency entry: 2195668637
- Sigstore integration time:
-
Permalink:
JuriCode-JP/juricode-mcp@eb63a80b1f325d2a4609cfee2803d02dc1a70c73 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/JuriCode-JP
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-juricode-mcp.yml@eb63a80b1f325d2a4609cfee2803d02dc1a70c73 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file juricode_mcp-0.1.0-py3-none-any.whl.
File metadata
- Download URL: juricode_mcp-0.1.0-py3-none-any.whl
- Upload date:
- Size: 73.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d6f1af3f6aa1211271958b3e1ae0061a996943f230242678f59b8d63dca8752f
|
|
| MD5 |
e5801847bf36f5ea580e5c100a9267af
|
|
| BLAKE2b-256 |
c63696e098926b5e43b228bf2a54dee834d4a3e77f935e87484892c75925f0b2
|
Provenance
The following attestation bundles were made for juricode_mcp-0.1.0-py3-none-any.whl:
Publisher:
publish-juricode-mcp.yml on JuriCode-JP/juricode-mcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
juricode_mcp-0.1.0-py3-none-any.whl -
Subject digest:
d6f1af3f6aa1211271958b3e1ae0061a996943f230242678f59b8d63dca8752f - Sigstore transparency entry: 2195668643
- Sigstore integration time:
-
Permalink:
JuriCode-JP/juricode-mcp@eb63a80b1f325d2a4609cfee2803d02dc1a70c73 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/JuriCode-JP
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-juricode-mcp.yml@eb63a80b1f325d2a4609cfee2803d02dc1a70c73 -
Trigger Event:
workflow_dispatch
-
Statement type: