building-standards-act-mcp 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -21
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/article-analyzer.d.ts +5 -0
- package/dist/lib/article-analyzer.js +106 -0
- package/dist/lib/article-analyzer.js.map +1 -0
- package/dist/lib/cache.d.ts +40 -1
- package/dist/lib/cache.js +127 -0
- package/dist/lib/cache.js.map +1 -1
- package/dist/lib/citation-verifier.d.ts +14 -0
- package/dist/lib/citation-verifier.js +139 -0
- package/dist/lib/citation-verifier.js.map +1 -0
- package/dist/lib/egov-client.d.ts +4 -0
- package/dist/lib/egov-client.js +48 -5
- package/dist/lib/egov-client.js.map +1 -1
- package/dist/lib/logger.d.ts +10 -0
- package/dist/lib/logger.js +41 -0
- package/dist/lib/logger.js.map +1 -0
- package/dist/lib/metrics.d.ts +14 -0
- package/dist/lib/metrics.js +100 -0
- package/dist/lib/metrics.js.map +1 -0
- package/dist/lib/mlit-client.js +3 -3
- package/dist/lib/mlit-client.js.map +1 -1
- package/dist/lib/pdf-extractor.js +2 -2
- package/dist/lib/pdf-extractor.js.map +1 -1
- package/dist/lib/related-law-finder.d.ts +5 -0
- package/dist/lib/related-law-finder.js +103 -0
- package/dist/lib/related-law-finder.js.map +1 -0
- package/dist/lib/resilience.d.ts +34 -0
- package/dist/lib/resilience.js +110 -0
- package/dist/lib/resilience.js.map +1 -0
- package/dist/lib/types.d.ts +72 -0
- package/dist/server.js +16 -1
- package/dist/server.js.map +1 -1
- package/dist/tools/analyze-article.d.ts +2 -0
- package/dist/tools/analyze-article.js +31 -0
- package/dist/tools/analyze-article.js.map +1 -0
- package/dist/tools/get-laws-batch.d.ts +2 -0
- package/dist/tools/get-laws-batch.js +165 -0
- package/dist/tools/get-laws-batch.js.map +1 -0
- package/dist/tools/get-metrics.d.ts +2 -0
- package/dist/tools/get-metrics.js +15 -0
- package/dist/tools/get-metrics.js.map +1 -0
- package/dist/tools/suggest-related.d.ts +2 -0
- package/dist/tools/suggest-related.js +62 -0
- package/dist/tools/suggest-related.js.map +1 -0
- package/dist/tools/validate-presets.js +2 -2
- package/dist/tools/validate-presets.js.map +1 -1
- package/dist/tools/verify-citation.d.ts +2 -0
- package/dist/tools/verify-citation.js +98 -0
- package/dist/tools/verify-citation.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,10 +15,12 @@ AI の建築法規回答に含まれるハルシネーションを、条文原
|
|
|
15
15
|
- **法令検索** — キーワードで法令を横断検索
|
|
16
16
|
- **法令全文取得** — 法令全体のテキストを取得
|
|
17
17
|
- **告示取得** — 建築基準法が技術基準を委任している告示を国土交通省の告示データベース(PDF)から取得
|
|
18
|
-
- **主要法令プリセット** — 建築基準法・消防法・都市計画法ほか 115 法令の law_id
|
|
18
|
+
- **主要法令プリセット** — 建築基準法・消防法・都市計画法ほか 115 法令の law_id をプリセット登録済み
|
|
19
19
|
- **プリセット検証** — `validate_presets` ツールでプリセットの有効性をランタイム検証
|
|
20
20
|
- **略称対応** — 「建基法」「都計法」「消防法」等の略称で指定可能
|
|
21
|
-
- **キャッシュ** — 検索 30 分・法令データ 24 時間の TTL
|
|
21
|
+
- **キャッシュ** — 検索 30 分・法令データ 24 時間の TTL キャッシュ(永続化オプションあり)
|
|
22
|
+
- **API 耐障害性** — 自動リトライ(exponential backoff)+ サーキットブレーカー
|
|
23
|
+
- **運用可視化** — 構造化 JSON ログ + 使用量メトリクス(`get_metrics` ツール)
|
|
22
24
|
|
|
23
25
|
## セットアップ
|
|
24
26
|
|
|
@@ -73,14 +75,19 @@ npm run build
|
|
|
73
75
|
|
|
74
76
|
## MCP ツール
|
|
75
77
|
|
|
76
|
-
| ツール | 説明
|
|
77
|
-
| ------------------- |
|
|
78
|
-
| `get_law` | 条番号を指定して法令の条文を取得する。略称・正式名称のいずれでも指定可能
|
|
79
|
-
| `get_full_law` | 法令の全文を取得する。条番号を指定せず法令全体のテキストを返す
|
|
80
|
-
| `search_law` | キーワードで建築関連法令を横断検索する。プリセット法令と e-Gov API の両方を検索
|
|
81
|
-
| `get_kokuji` | 建築基準法が技術基準を委任している告示の全文を取得する
|
|
82
|
-
| `validate_presets` | プリセット法令の law_id が e-Gov API で有効かを一括検証する
|
|
83
|
-
| `check_law_updates` | 法令の改正状況を e-Gov API で確認する(単体/バッチ/改正履歴表示に対応)
|
|
78
|
+
| ツール | 説明 |
|
|
79
|
+
| ------------------- | ------------------------------------------------------------------------------------------- |
|
|
80
|
+
| `get_law` | 条番号を指定して法令の条文を取得する。略称・正式名称のいずれでも指定可能 |
|
|
81
|
+
| `get_full_law` | 法令の全文を取得する。条番号を指定せず法令全体のテキストを返す |
|
|
82
|
+
| `search_law` | キーワードで建築関連法令を横断検索する。プリセット法令と e-Gov API の両方を検索 |
|
|
83
|
+
| `get_kokuji` | 建築基準法が技術基準を委任している告示の全文を取得する |
|
|
84
|
+
| `validate_presets` | プリセット法令の law_id が e-Gov API で有効かを一括検証する |
|
|
85
|
+
| `check_law_updates` | 法令の改正状況を e-Gov API で確認する(単体/バッチ/改正履歴表示に対応) |
|
|
86
|
+
| `get_laws_batch` | 複数の法令・条文を一括取得する(最大20件、同一法令は1回のAPI呼び出しで効率処理) |
|
|
87
|
+
| `verify_citation` | AIの回答に含まれる法令引用を検証する(条文存在確認・テキスト照合、最大10件) |
|
|
88
|
+
| `suggest_related` | 指定した条文の関連法令・委任先・同法令内参照を自動抽出して提案する |
|
|
89
|
+
| `analyze_article` | 条文の構造解析メタデータ(項数・号数・参照統計・プレビュー)をJSON形式で返す |
|
|
90
|
+
| `get_metrics` | サーバーの使用量メトリクスを返す(ツール呼び出し回数・APIリクエスト数・キャッシュヒット率) |
|
|
84
91
|
|
|
85
92
|
### パラメータ
|
|
86
93
|
|
|
@@ -124,6 +131,36 @@ npm run build
|
|
|
124
131
|
| `group` | 章グループ(バッチチェック、省略時は全章) | `1章` |
|
|
125
132
|
| `show_history` | 改正履歴の詳細を表示(`law_name` 指定時) | `true` |
|
|
126
133
|
|
|
134
|
+
#### `get_laws_batch`
|
|
135
|
+
|
|
136
|
+
| パラメータ | 説明 | 例 |
|
|
137
|
+
| ---------- | ---------------------------------------------------------------------- | --- |
|
|
138
|
+
| `requests` | 取得対象の配列。各要素に `law_name`, `article_number`, `format` を指定 | — |
|
|
139
|
+
|
|
140
|
+
#### `verify_citation`
|
|
141
|
+
|
|
142
|
+
| パラメータ | 説明 | 例 |
|
|
143
|
+
| ----------- | ------------------------------------------------------------------------------- | --- |
|
|
144
|
+
| `citations` | 検証対象の配列。各要素に `law_name`, `article_number`, `claimed_text`(省略可) | — |
|
|
145
|
+
|
|
146
|
+
#### `suggest_related`
|
|
147
|
+
|
|
148
|
+
| パラメータ | 説明 | 例 |
|
|
149
|
+
| ---------------- | ---------------------------- | ------------ |
|
|
150
|
+
| `law_name` | 法令名(正式名称または略称) | `建築基準法` |
|
|
151
|
+
| `article_number` | 条文番号 | `第20条` |
|
|
152
|
+
|
|
153
|
+
#### `analyze_article`
|
|
154
|
+
|
|
155
|
+
| パラメータ | 説明 | 例 |
|
|
156
|
+
| ---------------- | ---------------------------- | ------------ |
|
|
157
|
+
| `law_name` | 法令名(正式名称または略称) | `建築基準法` |
|
|
158
|
+
| `article_number` | 条文番号 | `第20条` |
|
|
159
|
+
|
|
160
|
+
#### `get_metrics`
|
|
161
|
+
|
|
162
|
+
パラメータなし。サーバー起動後の稼働時間・ツール呼び出し回数・API リクエスト数・キャッシュヒット率を返す。
|
|
163
|
+
|
|
127
164
|
## 使用例
|
|
128
165
|
|
|
129
166
|
### 条文取得
|
|
@@ -172,7 +209,7 @@ npm run build
|
|
|
172
209
|
|
|
173
210
|
## 対応法令一覧(115 法令)
|
|
174
211
|
|
|
175
|
-
###
|
|
212
|
+
### 総則(4 法令)
|
|
176
213
|
|
|
177
214
|
| 法令名 | 略称 |
|
|
178
215
|
| ------------------ | -------------------- |
|
|
@@ -181,7 +218,7 @@ npm run build
|
|
|
181
218
|
| 建築基準法施行規則 | 建基規則 |
|
|
182
219
|
| 民法 | — |
|
|
183
220
|
|
|
184
|
-
###
|
|
221
|
+
### 手続関連規定(6 法令)
|
|
185
222
|
|
|
186
223
|
| 法令名 | 略称 |
|
|
187
224
|
| ---------------- | ------------ |
|
|
@@ -192,7 +229,7 @@ npm run build
|
|
|
192
229
|
| 建設業法施行令 | — |
|
|
193
230
|
| 建設業法施行規則 | — |
|
|
194
231
|
|
|
195
|
-
###
|
|
232
|
+
### 集団規定・街づくり(13 法令)
|
|
196
233
|
|
|
197
234
|
| 法令名 | 略称 |
|
|
198
235
|
| -------------------------------------------------- | ---------------------- |
|
|
@@ -210,7 +247,7 @@ npm run build
|
|
|
210
247
|
| 国土利用計画法 | 国土利用計画法, 国土法 |
|
|
211
248
|
| 都市計画法施行規則 | 都計規則 |
|
|
212
249
|
|
|
213
|
-
###
|
|
250
|
+
### 防火・耐火規定(4 法令)
|
|
214
251
|
|
|
215
252
|
| 法令名 | 略称 |
|
|
216
253
|
| ------------------------ | ---------- |
|
|
@@ -219,7 +256,7 @@ npm run build
|
|
|
219
256
|
| 消防法施行規則 | 消防規則 |
|
|
220
257
|
| 危険物の規制に関する規則 | 危険物規則 |
|
|
221
258
|
|
|
222
|
-
###
|
|
259
|
+
### 構造規定(7 法令)
|
|
223
260
|
|
|
224
261
|
| 法令名 | 略称 |
|
|
225
262
|
| ------------------------------------------ | ---------------------- |
|
|
@@ -231,7 +268,7 @@ npm run build
|
|
|
231
268
|
| 建築物の耐震改修の促進に関する法律施行令 | 耐震改修促進法施行令 |
|
|
232
269
|
| 建築物の耐震改修の促進に関する法律施行規則 | 耐震改修促進法施行規則 |
|
|
233
270
|
|
|
234
|
-
###
|
|
271
|
+
### 建築材料(3 法令)
|
|
235
272
|
|
|
236
273
|
| 法令名 | 略称 |
|
|
237
274
|
| ---------------- | ---------------------- |
|
|
@@ -239,7 +276,7 @@ npm run build
|
|
|
239
276
|
| 製造物責任法 | PL法, 製造物責任法 |
|
|
240
277
|
| 石綿障害予防規則 | 石綿則, アスベスト規則 |
|
|
241
278
|
|
|
242
|
-
###
|
|
279
|
+
### 設備関連規定(5 法令)
|
|
243
280
|
|
|
244
281
|
| 法令名 | 略称 |
|
|
245
282
|
| -------------------------- | ---------------- |
|
|
@@ -249,7 +286,7 @@ npm run build
|
|
|
249
286
|
| 浄化槽法施行令 | — |
|
|
250
287
|
| 環境省関係浄化槽法施行規則 | 浄化槽法施行規則 |
|
|
251
288
|
|
|
252
|
-
###
|
|
289
|
+
### その他(5 法令)
|
|
253
290
|
|
|
254
291
|
| 法令名 | 略称 |
|
|
255
292
|
| ---------------------------------------------- | ------------------ |
|
|
@@ -259,7 +296,7 @@ npm run build
|
|
|
259
296
|
| 不動産の鑑定評価に関する法律 | 不動産鑑定法 |
|
|
260
297
|
| 住宅宿泊事業法 | 民泊新法 |
|
|
261
298
|
|
|
262
|
-
###
|
|
299
|
+
### 建築基準関係規定・建築関連法令(52 法令)
|
|
263
300
|
|
|
264
301
|
<details>
|
|
265
302
|
<summary>法令一覧を表示</summary>
|
|
@@ -321,7 +358,7 @@ npm run build
|
|
|
321
358
|
|
|
322
359
|
</details>
|
|
323
360
|
|
|
324
|
-
###
|
|
361
|
+
### 省エネ・住宅関連法(13 法令)
|
|
325
362
|
|
|
326
363
|
| 法令名 | 略称 |
|
|
327
364
|
| ------------------------------------------------------------------ | ---------------------- |
|
|
@@ -339,7 +376,7 @@ npm run build
|
|
|
339
376
|
| 長期優良住宅の普及の促進に関する法律施行規則 | 長期優良住宅法施行規則 |
|
|
340
377
|
| 建築物のエネルギー消費性能の向上等に関する法律施行規則 | 建築物省エネ法施行規則 |
|
|
341
378
|
|
|
342
|
-
###
|
|
379
|
+
### 既存建築物関連(3 法令)
|
|
343
380
|
|
|
344
381
|
| 法令名 | 略称 |
|
|
345
382
|
| ------------------------------------------ | ---------------- |
|
|
@@ -368,6 +405,30 @@ e-Gov API は告示を収録していないため、`get_kokuji` は国土交通
|
|
|
368
405
|
- `check_law_updates` ツールで法令の改正状況を確認できます(e-Gov API のリビジョン履歴を参照)
|
|
369
406
|
- 法令改正による `law_id` の無効化リスクは低い(`law_id` は法令番号ベースの固有識別子)
|
|
370
407
|
|
|
408
|
+
## 環境変数
|
|
409
|
+
|
|
410
|
+
| 変数 | 説明 | デフォルト |
|
|
411
|
+
| ------------------------ | ------------------------------------------------- | ---------------------------- |
|
|
412
|
+
| `BUILDING_LAW_CACHE` | キャッシュモード(`memory` / `file`) | `memory` |
|
|
413
|
+
| `BUILDING_LAW_CACHE_DIR` | ファイルキャッシュの保存先ディレクトリ | `~/.cache/building-law-mcp/` |
|
|
414
|
+
| `BUILDING_LAW_LOG_LEVEL` | ログレベル(`debug` / `info` / `warn` / `error`) | `info` |
|
|
415
|
+
|
|
416
|
+
### 永続キャッシュの有効化
|
|
417
|
+
|
|
418
|
+
```json
|
|
419
|
+
{
|
|
420
|
+
"mcpServers": {
|
|
421
|
+
"building-law": {
|
|
422
|
+
"command": "npx",
|
|
423
|
+
"args": ["-y", "building-law-mcp"],
|
|
424
|
+
"env": {
|
|
425
|
+
"BUILDING_LAW_CACHE": "file"
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
```
|
|
431
|
+
|
|
371
432
|
## 技術仕様
|
|
372
433
|
|
|
373
434
|
| 項目 | 値 |
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
3
|
import { createServer } from "./server.js";
|
|
4
|
+
import { logger } from "./lib/logger.js";
|
|
4
5
|
const server = createServer();
|
|
5
6
|
async function main() {
|
|
6
7
|
const transport = new StdioServerTransport();
|
|
7
8
|
await server.connect(transport);
|
|
8
|
-
|
|
9
|
+
logger.info("server started", { transport: "stdio" });
|
|
9
10
|
}
|
|
10
11
|
main().catch((error) => {
|
|
11
12
|
console.error("Fatal error:", error);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAEzC,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;AAE9B,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;AACxD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { getLawData } from "./egov-client.js";
|
|
2
|
+
import { parseArticleStructured } from "./egov-parser.js";
|
|
3
|
+
import { LawRegistry } from "./law-registry.js";
|
|
4
|
+
const registry = new LawRegistry();
|
|
5
|
+
const PREVIEW_LENGTH = 100;
|
|
6
|
+
/**
|
|
7
|
+
* Remove parentheses from caption text.
|
|
8
|
+
* "(構造耐力)" → "構造耐力"
|
|
9
|
+
*/
|
|
10
|
+
function stripParentheses(caption) {
|
|
11
|
+
return caption.replace(/^[((]/, "").replace(/[))]$/, "");
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Count total characters in a structured article.
|
|
15
|
+
*/
|
|
16
|
+
function countCharacters(article) {
|
|
17
|
+
let count = 0;
|
|
18
|
+
for (const para of article.paragraphs) {
|
|
19
|
+
count += para.paragraph_sentence.length;
|
|
20
|
+
for (const item of para.items) {
|
|
21
|
+
count += item.item_sentence.length;
|
|
22
|
+
for (const sub of item.subitems) {
|
|
23
|
+
count += countSubitemChars(sub);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return count;
|
|
28
|
+
}
|
|
29
|
+
function countSubitemChars(sub) {
|
|
30
|
+
let count = sub.subitem_sentence.length;
|
|
31
|
+
for (const child of sub.subitems) {
|
|
32
|
+
count += countSubitemChars(child);
|
|
33
|
+
}
|
|
34
|
+
return count;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Count total subitems recursively.
|
|
38
|
+
*/
|
|
39
|
+
function countSubitems(article) {
|
|
40
|
+
let count = 0;
|
|
41
|
+
for (const para of article.paragraphs) {
|
|
42
|
+
for (const item of para.items) {
|
|
43
|
+
count += countSubitemsRecursive(item.subitems);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return count;
|
|
47
|
+
}
|
|
48
|
+
function countSubitemsRecursive(subs) {
|
|
49
|
+
let count = subs.length;
|
|
50
|
+
for (const sub of subs) {
|
|
51
|
+
count += countSubitemsRecursive(sub.subitems);
|
|
52
|
+
}
|
|
53
|
+
return count;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Analyze a single article and return structured metadata.
|
|
57
|
+
*/
|
|
58
|
+
export async function analyzeArticle(lawName, articleNumber) {
|
|
59
|
+
const preset = registry.findByName(lawName);
|
|
60
|
+
if (!preset) {
|
|
61
|
+
throw new Error(`法令「${lawName}」がプリセットに見つかりませんでした。`);
|
|
62
|
+
}
|
|
63
|
+
const lawData = await getLawData(preset.law_id);
|
|
64
|
+
const article = parseArticleStructured(lawData.law_full_text, articleNumber);
|
|
65
|
+
if (!article) {
|
|
66
|
+
throw new Error(`${preset.title}に第${articleNumber}条が見つかりませんでした。`);
|
|
67
|
+
}
|
|
68
|
+
const itemCount = article.paragraphs.reduce((sum, p) => sum + p.items.length, 0);
|
|
69
|
+
const refs = article.references ?? [];
|
|
70
|
+
const crossLawRefs = refs.filter((r) => r.ref_type === "cross_law");
|
|
71
|
+
const referencedLaws = [
|
|
72
|
+
...new Set(crossLawRefs
|
|
73
|
+
.map((r) => r.target_law)
|
|
74
|
+
.filter((l) => l !== undefined)),
|
|
75
|
+
];
|
|
76
|
+
return {
|
|
77
|
+
law_name: preset.title,
|
|
78
|
+
law_num: preset.law_num,
|
|
79
|
+
article_num: article.article_num,
|
|
80
|
+
article_title: article.article_title,
|
|
81
|
+
caption: stripParentheses(article.article_caption),
|
|
82
|
+
structure: {
|
|
83
|
+
paragraph_count: article.paragraphs.length,
|
|
84
|
+
item_count: itemCount,
|
|
85
|
+
subitem_count: countSubitems(article),
|
|
86
|
+
total_characters: countCharacters(article),
|
|
87
|
+
},
|
|
88
|
+
paragraph_summaries: article.paragraphs.map((p) => ({
|
|
89
|
+
paragraph_num: p.paragraph_num,
|
|
90
|
+
preview: p.paragraph_sentence.length > PREVIEW_LENGTH
|
|
91
|
+
? p.paragraph_sentence.slice(0, PREVIEW_LENGTH) + "…"
|
|
92
|
+
: p.paragraph_sentence,
|
|
93
|
+
item_count: p.items.length,
|
|
94
|
+
})),
|
|
95
|
+
reference_summary: {
|
|
96
|
+
total: refs.length,
|
|
97
|
+
cross_law: crossLawRefs.length,
|
|
98
|
+
same_law: refs.filter((r) => r.ref_type === "same_law").length,
|
|
99
|
+
relative: refs.filter((r) => r.ref_type === "relative").length,
|
|
100
|
+
delegation: refs.filter((r) => r.ref_type === "delegation").length,
|
|
101
|
+
referenced_laws: referencedLaws,
|
|
102
|
+
},
|
|
103
|
+
structured_data: article,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=article-analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"article-analyzer.js","sourceRoot":"","sources":["../../src/lib/article-analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD,MAAM,QAAQ,GAAG,IAAI,WAAW,EAAE,CAAC;AAEnC,MAAM,cAAc,GAAG,GAAG,CAAC;AAE3B;;;GAGG;AACH,SAAS,gBAAgB,CAAC,OAAe;IACvC,OAAO,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;AAC3D,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,OAA0B;IACjD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACtC,KAAK,IAAI,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC;QACxC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,KAAK,IAAI,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;YACnC,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAChC,KAAK,IAAI,iBAAiB,CAAC,GAAG,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,iBAAiB,CACxB,GAAkE;IAElE,IAAI,KAAK,GAAG,GAAG,CAAC,gBAAgB,CAAC,MAAM,CAAC;IACxC,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QACjC,KAAK,IAAI,iBAAiB,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAS,aAAa,CAAC,OAA0B;IAC/C,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACtC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,KAAK,IAAI,sBAAsB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,sBAAsB,CAC7B,IAAgE;IAEhE,IAAI,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;IACxB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,KAAK,IAAI,sBAAsB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAChD,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,OAAe,EACf,aAAqB;IAErB,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,MAAM,OAAO,qBAAqB,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAChD,MAAM,OAAO,GAAG,sBAAsB,CAAC,OAAO,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;IAE7E,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,GAAG,MAAM,CAAC,KAAK,KAAK,aAAa,eAAe,CACjD,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,MAAM,CACzC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,EAChC,CAAC,CACF,CAAC;IAEF,MAAM,IAAI,GAAG,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC;IACtC,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,WAAW,CAAC,CAAC;IACpE,MAAM,cAAc,GAAG;QACrB,GAAG,IAAI,GAAG,CACR,YAAY;aACT,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC;aACxB,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAC/C;KACF,CAAC;IAEF,OAAO;QACL,QAAQ,EAAE,MAAM,CAAC,KAAK;QACtB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,aAAa,EAAE,OAAO,CAAC,aAAa;QACpC,OAAO,EAAE,gBAAgB,CAAC,OAAO,CAAC,eAAe,CAAC;QAClD,SAAS,EAAE;YACT,eAAe,EAAE,OAAO,CAAC,UAAU,CAAC,MAAM;YAC1C,UAAU,EAAE,SAAS;YACrB,aAAa,EAAE,aAAa,CAAC,OAAO,CAAC;YACrC,gBAAgB,EAAE,eAAe,CAAC,OAAO,CAAC;SAC3C;QACD,mBAAmB,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAClD,aAAa,EAAE,CAAC,CAAC,aAAa;YAC9B,OAAO,EACL,CAAC,CAAC,kBAAkB,CAAC,MAAM,GAAG,cAAc;gBAC1C,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,EAAE,cAAc,CAAC,GAAG,GAAG;gBACrD,CAAC,CAAC,CAAC,CAAC,kBAAkB;YAC1B,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM;SAC3B,CAAC,CAAC;QACH,iBAAiB,EAAE;YACjB,KAAK,EAAE,IAAI,CAAC,MAAM;YAClB,SAAS,EAAE,YAAY,CAAC,MAAM;YAC9B,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,UAAU,CAAC,CAAC,MAAM;YAC9D,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,UAAU,CAAC,CAAC,MAAM;YAC9D,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,YAAY,CAAC,CAAC,MAAM;YAClE,eAAe,EAAE,cAAc;SAChC;QACD,eAAe,EAAE,OAAO;KACzB,CAAC;AACJ,CAAC"}
|
package/dist/lib/cache.d.ts
CHANGED
|
@@ -1,4 +1,18 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Common cache interface shared by all cache implementations.
|
|
3
|
+
*/
|
|
4
|
+
export interface ICache<T> {
|
|
5
|
+
get(key: string): T | undefined;
|
|
6
|
+
set(key: string, value: T, ttl_ms?: number): void;
|
|
7
|
+
has(key: string): boolean;
|
|
8
|
+
delete(key: string): boolean;
|
|
9
|
+
clear(): void;
|
|
10
|
+
readonly size: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* In-memory TTL cache. Entries expire after a configurable duration.
|
|
14
|
+
*/
|
|
15
|
+
export declare class TTLCache<T> implements ICache<T> {
|
|
2
16
|
private readonly store;
|
|
3
17
|
private readonly default_ttl_ms;
|
|
4
18
|
constructor(default_ttl_ms?: number);
|
|
@@ -9,3 +23,28 @@ export declare class TTLCache<T> {
|
|
|
9
23
|
clear(): void;
|
|
10
24
|
get size(): number;
|
|
11
25
|
}
|
|
26
|
+
/**
|
|
27
|
+
* File-based TTL cache. Entries persist across server restarts.
|
|
28
|
+
* Each key is stored as an individual JSON file under
|
|
29
|
+
* `~/.cache/building-law-mcp/{name}/{hash}.json`.
|
|
30
|
+
*/
|
|
31
|
+
export declare class FileCache<T> implements ICache<T> {
|
|
32
|
+
private readonly dir;
|
|
33
|
+
private readonly default_ttl_ms;
|
|
34
|
+
constructor(name: string, default_ttl_ms?: number);
|
|
35
|
+
private keyToPath;
|
|
36
|
+
get(key: string): T | undefined;
|
|
37
|
+
set(key: string, value: T, ttl_ms?: number): void;
|
|
38
|
+
has(key: string): boolean;
|
|
39
|
+
delete(key: string): boolean;
|
|
40
|
+
clear(): void;
|
|
41
|
+
get size(): number;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Factory function to create a cache instance based on the
|
|
45
|
+
* `BUILDING_LAW_CACHE` environment variable.
|
|
46
|
+
*
|
|
47
|
+
* - `"memory"` (default): in-memory TTLCache
|
|
48
|
+
* - `"file"`: file-based FileCache that persists across restarts
|
|
49
|
+
*/
|
|
50
|
+
export declare function createCache<T>(name: string, ttl_ms: number): ICache<T>;
|
package/dist/lib/cache.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import * as os from "node:os";
|
|
4
|
+
import * as crypto from "node:crypto";
|
|
5
|
+
/**
|
|
6
|
+
* In-memory TTL cache. Entries expire after a configurable duration.
|
|
7
|
+
*/
|
|
1
8
|
export class TTLCache {
|
|
2
9
|
store = new Map();
|
|
3
10
|
default_ttl_ms;
|
|
@@ -41,4 +48,124 @@ export class TTLCache {
|
|
|
41
48
|
return this.store.size;
|
|
42
49
|
}
|
|
43
50
|
}
|
|
51
|
+
const DEFAULT_CACHE_DIR = path.join(os.homedir(), ".cache", "building-law-mcp");
|
|
52
|
+
/**
|
|
53
|
+
* File-based TTL cache. Entries persist across server restarts.
|
|
54
|
+
* Each key is stored as an individual JSON file under
|
|
55
|
+
* `~/.cache/building-law-mcp/{name}/{hash}.json`.
|
|
56
|
+
*/
|
|
57
|
+
export class FileCache {
|
|
58
|
+
dir;
|
|
59
|
+
default_ttl_ms;
|
|
60
|
+
constructor(name, default_ttl_ms = 30 * 60 * 1000) {
|
|
61
|
+
this.default_ttl_ms = default_ttl_ms;
|
|
62
|
+
const cacheBase = process.env.BUILDING_LAW_CACHE_DIR ?? DEFAULT_CACHE_DIR;
|
|
63
|
+
this.dir = path.join(cacheBase, name);
|
|
64
|
+
fs.mkdirSync(this.dir, { recursive: true });
|
|
65
|
+
}
|
|
66
|
+
keyToPath(key) {
|
|
67
|
+
const hash = crypto.createHash("md5").update(key).digest("hex");
|
|
68
|
+
return path.join(this.dir, `${hash}.json`);
|
|
69
|
+
}
|
|
70
|
+
get(key) {
|
|
71
|
+
const filePath = this.keyToPath(key);
|
|
72
|
+
try {
|
|
73
|
+
const raw = fs.readFileSync(filePath, "utf-8");
|
|
74
|
+
const entry = JSON.parse(raw);
|
|
75
|
+
if (Date.now() > entry.expires_at) {
|
|
76
|
+
try {
|
|
77
|
+
fs.unlinkSync(filePath);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
// ignore cleanup failure
|
|
81
|
+
}
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
return entry.value;
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
set(key, value, ttl_ms) {
|
|
91
|
+
const ttl = ttl_ms ?? this.default_ttl_ms;
|
|
92
|
+
const entry = { value, expires_at: Date.now() + ttl };
|
|
93
|
+
fs.writeFileSync(this.keyToPath(key), JSON.stringify(entry), "utf-8");
|
|
94
|
+
}
|
|
95
|
+
has(key) {
|
|
96
|
+
return this.get(key) !== undefined;
|
|
97
|
+
}
|
|
98
|
+
delete(key) {
|
|
99
|
+
try {
|
|
100
|
+
fs.unlinkSync(this.keyToPath(key));
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
clear() {
|
|
108
|
+
try {
|
|
109
|
+
const files = fs.readdirSync(this.dir);
|
|
110
|
+
for (const file of files) {
|
|
111
|
+
if (file.endsWith(".json")) {
|
|
112
|
+
try {
|
|
113
|
+
fs.unlinkSync(path.join(this.dir, file));
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
// ignore individual file cleanup failure
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
// directory might not exist
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
get size() {
|
|
126
|
+
try {
|
|
127
|
+
const files = fs.readdirSync(this.dir).filter((f) => f.endsWith(".json"));
|
|
128
|
+
let count = 0;
|
|
129
|
+
for (const file of files) {
|
|
130
|
+
const filePath = path.join(this.dir, file);
|
|
131
|
+
try {
|
|
132
|
+
const raw = fs.readFileSync(filePath, "utf-8");
|
|
133
|
+
const entry = JSON.parse(raw);
|
|
134
|
+
if (Date.now() <= entry.expires_at) {
|
|
135
|
+
count++;
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
try {
|
|
139
|
+
fs.unlinkSync(filePath);
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
// ignore cleanup failure
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
// corrupted file, skip
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return count;
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
return 0;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Factory function to create a cache instance based on the
|
|
159
|
+
* `BUILDING_LAW_CACHE` environment variable.
|
|
160
|
+
*
|
|
161
|
+
* - `"memory"` (default): in-memory TTLCache
|
|
162
|
+
* - `"file"`: file-based FileCache that persists across restarts
|
|
163
|
+
*/
|
|
164
|
+
export function createCache(name, ttl_ms) {
|
|
165
|
+
const mode = process.env.BUILDING_LAW_CACHE ?? "memory";
|
|
166
|
+
if (mode === "file") {
|
|
167
|
+
return new FileCache(name, ttl_ms);
|
|
168
|
+
}
|
|
169
|
+
return new TTLCache(ttl_ms);
|
|
170
|
+
}
|
|
44
171
|
//# sourceMappingURL=cache.js.map
|
package/dist/lib/cache.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/lib/cache.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/lib/cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { CitationVerification } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Normalize text for comparison: collapse whitespace, remove formatting artifacts.
|
|
4
|
+
*/
|
|
5
|
+
export declare function normalizeText(text: string): string;
|
|
6
|
+
/**
|
|
7
|
+
* Calculate match score between claimed text and actual text.
|
|
8
|
+
* Returns a value between 0.0 and 1.0.
|
|
9
|
+
*/
|
|
10
|
+
export declare function calculateMatchScore(claimed: string, actual: string): number;
|
|
11
|
+
/**
|
|
12
|
+
* Verify a single citation against the actual law text.
|
|
13
|
+
*/
|
|
14
|
+
export declare function verifyCitation(lawName: string, articleNumber: string, claimedText?: string): Promise<CitationVerification>;
|