👋

Vibe Coding で法令検索MCPサーバーを作ってみた

に公開

なにこれ?

私はGovTech東京の職員として、日々行政のデジタル化、特に生成AIの業務活用に取り組んでいます。これまでコードを書く経験もほぼなかったり、法制業務に携わったりすることもないのですが、昨年度はデジタル庁の法令×デジタルワークショップにも参加するなど、技術と行政の接点には積極的に関わりたいと思っています。

そんな私が最近、ありもののMCPサーバー×Claude Desktopを使っていたんですが、どうもMCPのことがよく分からないなーと思っていました。新しい技術トレンド好きなのでMCP×Claude Desktopはすぐ試したし、Brave SearchやMemoryやFile、GitHubなどの既存MCPサーバーをプライベート環境に立てて色々使い勝手を見ていました。とはいえ、よりちゃんとMCPを理解するために、何か自分でもMCPサーバーを作って動かしてみたいと思っていたんです。

そこで、行政デジタル化の現場にいる立場として、そっち方面でのネタを探していたところ、法令検索APIがあることを思い出しました。ワークショップでも注目していた取り組みで、ちょうど法令検索APIもバージョンが1から2になっていて使い勝手が向上していたので、こちらを活用してMCPサーバーをローカルに立てて利用することにしました。

今回やりたかったのは、

  • 法律に関する調査内容を割とざっくり自然言語で入力
  • 推論モデルが検索戦略を考える
  • 法令検索APIを実行し情報を集める
  • レポートにまとめる

というものです。

Claude 3.7 SonnetのThinkモードで多段階検索することで網羅的に情報を集めてもらい、集めた情報を元にレポートを作ってもらうという仕組みで、MCPクライアントはClaude Desktopにする予定です。Claude Codeを使ったVibe Codingをじっくり体験するのも目的の一つです!
※試しに作ってみただけなので、API利用に関する制限やセキュリティについては考慮していません。

開発プロセス

今回の開発は以下のような流れで進めました:

  1. リソース収集と理解
    • 法令検索API Version2の仕様を調査
    • MCP Python SDKの概要を把握
    • 参考となるMCPサーバーの実装例を確認
  2. Claude Codeとの対話
    • やりたいことをClaudeに説明
    • APIの仕様を理解してもらう
    • MCPサーバーの設計方針を決める
  3. 実装とテスト
    • Claude Codeに必要なコードを書いてもらう
    • ローカルでの動作テスト
    • Claude Desktopへの統合

今回は、Claude 3.7 sonnetのthinkモードを活用してやりたいと思っていることの実装をお願いしました。Claudeが期待するMCPサーバーを作ってくれるように十分なコンテキストを与えることに注力しました。ポイントは3つで、①法令検索API、②MCP Python SDK、③リファレンスMCPサーバーの仕様を理解してもらうことからはじめてみました。

プロジェクト構成

最終的に、今回作成したプロジェクトの構成は以下のようになりました:

mcp-law-search/
├── README.md                  # プロジェクトの説明
├── mcp_law_search/
│   ├── __init__.py            # パッケージ初期化
│   ├── __main__.py            # コマンドライン実行用エントリーポイント
│   └── server.py              # MCPサーバーの本体実装
├── pyproject.toml             # パッケージ設定と依存関係
└── run_server.py              # 開発用の起動スクリプト

主要ファイルの役割

  • server.py: MCPサーバーのメイン実装。FastMCPを使って法令検索APIへの接続とデータ処理
  • __main__.py: python -m mcp_law_search で直接実行できるようにするためのスクリプト
  • run_server.py: 開発中に便利な起動スクリプト

法令検索MCPサーバーの機能

今回作成したMCPサーバーでは、以下の3つの主要機能を実装しました:

  1. キーワードによる法令検索 (search_law)
    • 例: search_law("著作権")
    • 関連する法令と条文をハイライト表示
    • ページネーション対応(例: search_law("著作権", 10, 10) で2ページ目)
  2. 法令IDによる全文取得 (get_law)
    • 例: get_law("345AC0000000048")
    • 法令の全文を構造化して取得
  3. 法令名からの取得 (get_law_by_name)
    • 例: get_law_by_name("著作権法")
    • 一般的な法令は直接名前で検索可能

これらの機能により、Claudeに「著作権法の最新改正内容は?」といった質問をすると、APIから最新情報を取得して回答してくれるようになりました!

技術的な実装のポイント

使用技術

  • Python 3.11+
  • MCP SDK (mcp >= 1.1.3)
  • httpx: 非同期HTTPクライアント
  • e-Gov法令API Version2

コードの工夫ポイント

1. 階層的な法令データの処理

法令データは複雑な階層構造になっているので、いろんなパターンに対応できるよう工夫しました(工夫してくれたのはClaudeさんです。エライ。):

def format_law_results(result: Dict[str, Any]) -> str:
    """法令データを整形します。"""
    try:
        # メタデータの抽出・表示
        law = result["laws"][0]

        # さまざまな階層構造に対応
        if "parts" in law and law["parts"]:
            # 部・章・節構造の処理
            ...
        elif "articles" in law and law["articles"]:
            # 直接条文がある場合
            ...
        elif "topics" in law and law["topics"]:
            # トピック構造の場合
            ...

        return output
    except Exception as e:
        return f"結果の整形中にエラーが発生しました: {str(e)}"

2. エラーハンドリングと安全なロギング

MCPプロトコルではJSON通信を使うため、標準出力にログを出すとJSON解析エラーが発生してしまいます。標準エラー出力を使ってこの問題を解決しました(ここがちょっとハマったところ):

def safe_log(message):
    """標準エラーにログを出力する安全な方法"""
    print(message, file=sys.stderr)

使用例と結果

自然言語で「著作権法のことについて理解したいので、関連法案調べてまとめて」みたいなことをClaudeに投げたとすると、、、

キーワード検索の例

まず、クエリ選定を行って検索を実行してくれます。

search_law("著作権")

結果:

検索結果: 3件 (表示: 2件)

## 1. 著作権法
法令ID: 345AC0000000048
法令番号: 昭和四十五年法律第四十八号
法令種別: Act

### 検索キーワードを含む条文:
amendsupplprovision: 国及び地方公共団体は、国民が、著作権法第三十条第一項(同法第百二条第一項において準用する場合を含む。)に定める私的使用の目的をもって、有償著作物等特...

---

## 2. 映画の盗撮の防止に関する法律
...

法令全文取得の例

レポートを作るために法令の文章も取得してコンテキストに入れてくれます。Thinkモードで動かすといわゆるDeep Researchぽい挙動になります。

get_law_by_name("著作権法")

結果(一部抜粋):

# 著作権法

法令ID: 345AC0000000048
法令番号: 昭和四十五年法律第四十八号
法令種別: Act
公布日: 1970-05-06
改正公布日: 2023-06-07

## 法令本文

### 第一章 総則

#### 第一節 通則

**第1条 目的**

この法律は、著作物並びに実演、レコード、放送及び有線放送に関し著作者の権利及びこれに隣接する権利を定め、これらの文化的所産の公正な利用に留意しつつ、著作者等の権利の保護を図り、もつて文化の発展に寄与することを目的とする。
...

Vibe Codingの感想

Claude Codeを使ったVibe Codingは、コードを書く経験がほとんどない私にとって、とても新鮮な体験でした。

  • 自然言語で「こういうことがしたい」と伝えるだけでコードを書いてくれる
  • エラーが出ても原因と修正方法を教えてくれる
  • 技術的な背景も含めて説明してくれるので学びながら進められる

Claude CodeはCLIで操作しているからなのか分からないですが、何とも言えない気持ちよさがあります(わかります?)。例えば、CursorやReplitなどのツールを使った開発体験と違うんですよね。技術がわからないなりに楽しい開発が出来ました。

まとめ

今回のプロジェクトでは、MCPという新しい技術とVibe Codingという開発手法を組み合わせて、実用的な法令検索ツールを作ることができました。コードを書く経験がなくても、AIに技術解説してもらいながら実装を進めることで以前よりはMCPサーバーについて理解が深まったと思います。

今回はローカルMCPサーバーで検証をしましたが、仕事で使うとなると安全な環境にリモートMCPサーバーを立てたり、職員の人が使いやすいMCPホストなどの利用環境の整備もしていく必要があるなーと思いました。

このように、私は行政分野でこそ必要になる生成AI技術の検証や環境整備に取り組んでいきたいと考えています。同じような関心を持つ方、一緒に挑戦してみたい方がいらっしゃいましたら、ぜひお声がけください。よろしくお願いします!

参考情報

GovTech東京

Discussion