Metadata-Version: 2.4
Name: juricode-mcp
Version: 0.1.0
Summary: Local MCP server for Japanese tax-law sources: search, verbatim article retrieval, and citation verification
Project-URL: Homepage, https://github.com/JuriCode-JP/juricode-mcp
Author-email: "CHOKAI Co.,Ltd." <sato@chokaijp.com>
License: AGPL-3.0-or-later
License-File: LICENSE
Keywords: citation,japan,juricode-jp,legal,mcp,tax,verification
Requires-Python: >=3.11
Requires-Dist: juricode-retrieval==0.1.0
Requires-Dist: juricode-verifier==0.1.0
Requires-Dist: mcp>=1.2
Requires-Dist: pydantic>=2.7
Provides-Extra: dev
Requires-Dist: numpy>=1.26; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Provides-Extra: search
Requires-Dist: google-genai>=1.0; extra == 'search'
Requires-Dist: numpy>=1.26; extra == 'search'
Description-Content-Type: text/markdown

# 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

```bash
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.

```bash
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

```jsonc
// 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 than
  `egov-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; its `NOTICE.md` says 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_article` returns 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_article` against a distribution snapshot's texts) and
  the live `sha256_match` check 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.
- `--mock` exercises all three tools with no API key, index, network, or setting.
