jPOS MCP Server について
jPOS MCP Serverは、決済開発者やAIエージェント向けに、ISO 8583とjPOSを扱う決定論的なツールを提供します。検証済みデータによるフィールド参照、メッセージ検証、設定生成に加え、jPOS文書も検索できます。
主な機能
- 01ISO 8583フィールド仕様の参照
- 02MTIのデコード
- 03GenericPackager XMLの生成
- 04Q2デプロイ記述子の検証
- 05ISO 8583メッセージの検証
- 06jPOS文書のセマンティック検索
活用シーン
- 01フィールド形式とjPOSクラス名の確認
- 02決済フロー用packager設定の生成
- 03Q2デプロイ設定の確認やデバッグ
- 04jPOS Programmer's Guideの検索
MCP 対応
MCPクライアントにISO 8583、jPOS、文書検索のツールを公開するMCPサーバーです。ローカルのstdioと、DockerでのStreamable HTTPに対応します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
jPOS MCP サーバー
mcp-name: io.github.mohisyed/jpos-mcp-server
jPOS と ISO 8583 に対応した、初のオープンソース MCP サーバーです。

Claude が決定論的なツールを使って、実際の ISO 8583 金融取引リクエストを検証しています。推測は一切なく、すべての回答は検証済みデータに基づいています。
AI エージェント(Claude、Cursor、VS Code Copilot)に、ISO 8583 フィールド仕様、MTI のデコード、jPOS パッケージャー XML の生成、デプロイ記述子の検証、メッセージの構築、jPOS ドキュメントの検索への決定論的で検証済みのアクセスを提供する MCP サーバーです。
パッケージャークラス名を推測する必要はもうありません。300 ページの PDF をスクロールする必要もありません。ツールを呼び出せば、正しい答えが得られます。
目次
- クイックスタート
- ツール
- アーキテクチャ
- テスト
- ナレッジベース(RAG)
- Docker
- Claude Desktop のセットアップ
- MCP Inspector
- セキュリティ
- トラブルシューティング
- ロードマップ
- コントリビューション
クイックスタート
前提条件: Python 3.11+ と uv パッケージマネージャー。
# 1. Clone and install
git clone https://github.com/mohisyed/JPOS-MCP.git
cd JPOS-MCP
uv sync
# 2. (Optional) Set up the knowledge base for semantic search
mkdir -p knowledge/sources
curl -o knowledge/sources/proguide.pdf https://jpos.org/doc/proguide-draft.pdf
uv run python knowledge/ingest.py
# 3. Add to Claude Desktop (see Claude Desktop Setup below)
ステップ 1 の後、6 つすべてのツールをすぐに使用できます。ステップ 2 を実行すると、実際のドキュメントを使う search_jpos RAG ツールが有効になります。
ツール
| ツール | 名前空間 | 機能 | 入力例 |
|---|---|---|---|
lookup_field | iso | ISO 8583 フィールドの完全な仕様(名前、形式、jPOS クラス、最大長)を返します | field_number: 35 |
decode_mti | iso | MTI をバージョン、クラス、機能、発信元にデコードし、予想される応答も返します | mti: "0200" |
generate_packager | jpos | 平易な英語から完全な GenericPackager XML を生成します | "Visa auth fields 2,3,4,7,11,35,41,42 BCD" |
validate_descriptor | jpos | Q2 デプロイ記述子(チャネル、QMUX、TM ルール)をチェックします | xml_content: "<qmux>..." |
build_message | msg | ISO 8583 フィールド辞書を検証します(必須フィールド、長さ、PAN の安全性) | {"0":"0200", "2":"4111..."} |
search_jpos | docs | jPOS Programmer's Guide をセマンティック検索します(RAG) | "How to configure QMUX" |
LLM の推論ではなく、決定論的なツールを使う理由
LLM はフィールド 35 が IFA_LLVAR を使うと推測できますが、ときには IFA_LLTRACK2(存在しません)のようなクラス名を幻覚することがあります。このツールは data/iso_fields.json の検証済み参照テーブルを読み込むため、常に正しい答えが得られます。AI は呼び出すツールを決め、コードが事実を提供します。
アーキテクチャ
┌─────────────────────────────────────────────────────────────────┐
│ AI AGENT CLIENTS │
│ Claude Desktop · Claude API · Cursor · VS Code Copilot │
└──────────────────────────┬──────────────────────────────────────┘
│ MCP Protocol (JSON-RPC 2.0)
stdio (local) / Streamable HTTP (Docker)
│
┌──────────────────────────▼──────────────────────────────────────┐
│ jpos-mcp-server (Python / FastMCP v3.1.1) │
│ │
│ main.py │
│ ├── iso_server [iso] lookup_field, decode_mti │
│ ├── jpos_server [jpos] generate_packager, validate_descriptor│
│ ├── msg_server [msg] build_message │
│ └── rag_server [docs] search_jpos │
│ │
│ ┌──────────────┐ ┌─────────────────────────────────────────┐ │
│ │ DATA LAYER │ │ KNOWLEDGE LAYER │ │
│ │ iso_fields │ │ ChromaDB + sentence-transformers │ │
│ │ mti_table │ │ Chunked jPOS Programmer's Guide │ │
│ │ mandatory │ │ + project docs (ISO 8583 deep dive) │ │
│ └──────────────┘ └─────────────────────────────────────────┘ │
│ core/ — timeout guardrails, PAN detection, safe logging │
└──────────────────────────────────────────────────────────────────┘
サブサーバーの構成
サーバーは、FastMCP.mount() を介してマウントされた 4 つのドメイン固有のサブサーバーに分割されています。各サブサーバーは個別にテストできます。RAG パイプラインのバグが ISO フィールドの検索を妨げることはありません。新しいドメインの追加は、1 つのファイルと main.py での mount() 呼び出し 1 回で済みます。
タイムアウトのガードレール
すべてのツールは asyncio.wait_for() を使う @with_timeout() でラップされています。ツールがハングした場合(例:ChromaDB のコールドスタート)、MCP サーバー全体をブロックせず、構造化されたエラー辞書を返します。タイムアウトの段階は次のとおりです。
| 段階 | タイムアウト | ツール |
|---|---|---|
| 高速 | 2s | lookup_field、decode_mti |
| 中速 | 5s | build_message、validate_descriptor |
| 低速 | 10s | generate_packager |
| RAG | 15s | search_jpos |
テスト
テストする理由
決済システムでは、誤った回答は一切許されません。パッケージャークラス名の誤り(IFA_LLVAR と IFB_LLHEX の取り違え)は、解読しにくいバイトレベルの解析エラーを引き起こし、デバッグに何時間もかかります。テストでは、すべての入力タイプに対して各ツールが正確で決定論的な結果を返すことを確認します。
テストの実行
# Install dev dependencies (pytest, ruff, black, coverage)
uv sync --dev
# Run all 114 tests (unit + MCP integration + E2E workflows)
uv run pytest tests/ -v
# Run a single test file
uv run pytest tests/test_iso.py -v
# Run a single test function
uv run pytest tests/test_iso.py::test_decode_mti_request -v
# Run with coverage report (target: 80%+, current: 91%)
uv run pytest tests/ --cov=servers --cov=core --cov-report=term-missing
# Lint (must pass with zero errors)
uv run ruff check .
# Format
uv run black .
テスト構成(114 件、3 層)
| ファイル | レイヤー | 対象範囲 |
|---|---|---|
test_iso.py | unit | lookup_field、decode_mti — 有効/無効なフィールド、MTI カテゴリ |
test_jpos_tools.py | unit | generate_packager(BCD/ASCII)、validate_descriptor(QMUX、channel-adaptor、txnmgr、不正な XML) |
test_message.py | unit | build_message — 有効なメッセージ、必須フィールドの欠落、長さの違反、PAN の拒否 |
test_rag.py | unit | クエリ拡張、モックコレクションのレスポンス、空のコレクションの処理 |
test_timeout.py | unit | @with_timeout — ガードレールの作動、高速処理の成功、例外の捕捉 |
test_validators.py | unit | luhn_check、contains_likely_real_pan — Luhn の境界ケース、区切り文字、テスト用 PAN の許可リスト |
test_logging.py | unit | PaymentSafeFormatter による秘匿化、stderr ハンドラーの設定 |
test_mcp_integration.py | integration | ツールの登録、JSON Schema の生成、MCP プロトコル呼び出しのエンドツーエンドテスト |
test_e2e.py | E2E workflow | 複数ステップのワークフロー:Visa 認証パッケージャーの構築、リバーサルのデバッグ、デプロイ記述子の検証、セキュリティ境界、MCP 経由の RAG、システムの健全性、エラー処理 |
新しいテストの作成
ツールを追加する際は、次の 3 つのカテゴリをカバーしてください。
- 正常系 — 有効な入力に対して期待される出力を返す
- 無効な入力 — 不正な型、範囲外の値、不正な形式のデータに対して構造化されたエラーを返す
- 境界ケース — 境界値、空の入力、PCI 機密データ
すべてのツールは async def なので、@pytest.mark.asyncio を使用してください。
@pytest.mark.asyncio
async def test_my_new_tool():
result = await my_tool("valid input")
assert result["expected_key"] == "expected_value"
ナレッジベース(RAG)
search_jpos ツールは、jPOS のドキュメントに対して 2 段階のハイブリッド検索を使用します。高速な候補検索にはバイエンコーダー(mpnet)を使用し、その後、高精度な順序付けのためにクロスエンコーダーで再ランキングします。
仕組み
- 取り込み — PDF と Markdown ファイルをクリーンアップし(定型文、目次の点線、ページヘッダーを削除)、40 語分のオーバーラップを設けて 200 語のチャンクに分割します。シグナルの弱いチャンクは取り込み時に除外します。
- 埋め込み — 各チャンクを
all-mpnet-base-v2を使用して 768 次元ベクトルにエンコードし、ChromaDB に保存します。 - クエリ拡張 — 短いクエリや専門用語の多いクエリ(例:「STAN」、「IFB_LLHEX」)には、埋め込みの前にドメインコンテキストを追加し、モデルが曖昧さを解消するための十分な情報を得られるようにします。
- 第 1 段階の検索 — コサイン類似度を使って上位 25 件の候補を取得します。
- 第 2 段階の再ランキング — クロスエンコーダー(
ms-marco-MiniLM-L-6-v2)が両方の入力を考慮し、各(query, chunk)ペアをスコアリングします。コサイン類似度だけの場合より大幅に高精度です。 - 表示スコア — クロスエンコーダー、コサイン類似度、順位ボーナスを組み合わせ、上位 5 件のチャンクを返します。
クロスエンコーダーは初回の呼び出し時に遅延ロードされます(約 1 秒)。モデルをロードできない場合(オフライン環境など)は、キーワードの重複による再ランキングにフォールバックします。
ナレッジベースのセットアップ
# Download the jPOS Programmer's Guide (5.3MB PDF)
mkdir -p knowledge/sources
curl -o knowledge/sources/proguide.pdf https://jpos.org/doc/proguide-draft.pdf
# Run ingestion (first run downloads ~80MB mpnet + ~80MB cross-encoder)
uv run python knowledge/ingest.py
取り込みスクリプトは次のファイルを処理します。
knowledge/sources/*.pdfの PDF — クリーンアップを行い、ページごとにチャンクに分割docs/*.mdの Markdown — セクションを考慮してチャンクに分割(##見出しで分割)knowledge/sources/*.mdの Markdown — 追加したドキュメントを処理
取り込みは 冪等 です。再実行すると既存のチャンクはスキップされ、新しいチャンクのみが追加されます。
完全に取り込んだ後のデフォルトのナレッジベースは、jPOS Programmer's Guide、ISO 8583-1:2003 仕様書、Wikipedia の参考資料、jPOS チュートリアルページ、プロジェクトドキュメントを含む 約 786 チャンクです。
独自のドキュメントの追加
.pdf または .md ファイルを knowledge/sources/ に配置して、次を再実行してください。
uv run python knowledge/ingest.py
適したドキュメントの例:
- ISO 8583 のリファレンスガイド
- 組織のインターチェンジ仕様ドキュメント
- jPOS チュートリアルページ(Markdown として保存)
- 注釈付き GenericPackager XML の例
検索品質
スコアは、クロスエンコーダー+mpnet パイプライン向けに調整されています。
| スコア | 品質 | 意味 |
|---|---|---|
| 0.55+ | 高い | チャンク内に直接的な回答がある |
| 0.40–0.55 | 良好 | 関連するコンテキストがあり、統合が必要な場合がある |
| 0.25–0.40 | 部分的 | 間接的に関連している |
| <0.25 | (フィルター済み) | ノイズフロア未満のため、返されません |
代表的な25件のクエリでベンチマークを実施:平均スコア0.886、強い結果の割合100%。
Docker
ビルドと実行
# Build and start (HTTP transport)
docker compose -f docker/docker-compose.yml up -d --build
# View logs
docker compose -f docker/docker-compose.yml logs -f
# Re-ingest docs after adding new sources
docker compose -f docker/docker-compose.yml exec jpos-mcp uv run python knowledge/ingest.py
# Check health
docker compose -f docker/docker-compose.yml exec jpos-mcp curl -sf http://localhost:8000/health
Docker のアーキテクチャ
- ベースイメージ:
python:3.11-slim - 埋め込みモデルはビルド時に事前ダウンロードされます(コールドスタート時の30~60秒の待ち時間を回避)
- 非 root ユーザー(
appuser:1001)でセキュリティを確保 - 永続ボリュームに ChromaDB のデータを保存します(コンテナーを再起動してもデータが保持されます)
/healthを30秒ごとに確認するヘルスチェック
Docker を使った Claude Desktop
{
"mcpServers": {
"jpos-expert": {
"url": "http://localhost:8000/mcp"
}
}
}
Claude Desktop のセットアップ
macOS
~/Library/Application Support/Claude/claude_desktop_config.json を編集します。
{
"mcpServers": {
"jpos-expert": {
"command": "uv",
"args": ["run", "python", "main.py"],
"cwd": "/ABSOLUTE/PATH/TO/JPOS-MCP"
}
}
}
Windows
%APPDATA%\Claude\claude_desktop_config.json を編集します。
{
"mcpServers": {
"jpos-expert": {
"command": "uv",
"args": ["run", "python", "main.py"],
"cwd": "C:\\ABSOLUTE\\PATH\\TO\\JPOS-MCP"
}
}
}
保存後、Claude Desktop を再起動します。すべてのツールがハンマー(ツール)メニューに表示されます。
動作確認
Claude に次のように質問します。「フィールド35の jPOS パッケージャークラスは何ですか?」
Claude は lookup_field(35) を呼び出し、推測ではなく正確な仕様(ASCII の場合は IFA_LLVAR、BCD の場合は IFB_LLHEX)を返すはずです。
MCP Inspector
MCP Inspector は、ツールを対話的にテストするためのブラウザベースの UI です。
uv run fastmcp dev inspector main.py:mcp
ブラウザーで http://localhost:6274 が開き、次のことができます。
- 登録済みのすべてのツールとその JSON Schema を確認する
- 任意のツールをカスタム入力で呼び出す
- レスポンスをリアルタイムで調べる
- Claude Desktop を使わずにツールのエラーをデバッグする
セキュリティ
このサーバーは、PCI DSS への準拠を考慮して設計されています。
- 実際の PAN は拒否されます — Luhn アルゴリズムにより、あらゆるツール入力から実際のカード番号を検出します。テスト用 PAN(
4111111111111111、5500005555555559など)のみが受け付けられます。このチェックは、他の処理より先に実行されます。 - 機密フィールドはログから除外されます —
PaymentSafeFormatterは、すべてのログ出力からフィールド2(PAN)、35(Track 2)、45(Track 1)、52(PIN)、55(EMV)、64(MAC)を除去します。 - ログは stderr のみ — stdout は JSON-RPC ストリーム(stdio トランスポート)専用です。
print()を1回実行するだけでもプロトコルが破損します。 - root 以外で Docker を実行 — コンテナーは
appuser:1001として実行されます。 - 認証情報なし — サーバーはキー、トークン、シークレットを保存しません。
- 依存関係を固定 —
fastmcp==3.1.1に正確に固定することで、サプライチェーンに関する予期しない問題を防ぎます。 - ツールの説明をハードコード — ツールの説明は Python のデコレーターに記述され、外部データから読み込まれることはありません(インジェクションを防止します)。
このサーバーを通してはならないデータ
| データ | 理由 |
|---|---|
| 実際の PAN | PCI DSS 要件3 |
| Track 1/2/3 データ | 承認後は使用禁止 |
| CVV/CVV2/CVC2 | PCI DSS 3.2.1 |
| 実際の暗号鍵 | HSM による管理のみ |
| PIN ブロック | 制御されていないレイヤーを通過させてはなりません |
トラブルシューティング
ModuleNotFoundError: No module named 'fastmcp'
依存関係がインストールされていません。次を実行してください。
uv sync
search_jpos が「Knowledge base not initialized」を返す
ChromaDB にデータが投入されていません。次を実行してください。
mkdir -p knowledge/sources
curl -o knowledge/sources/proguide.pdf https://jpos.org/doc/proguide-draft.pdf
uv run python knowledge/ingest.py
Claude Desktop にツールが表示されない
claude_desktop_config.jsonのcwdが絶対パスであることを確認しますuvが PATH に含まれていることを確認します(ターミナルでuv --versionを実行してみてください)- Claude Desktop を完全に再起動します(ウィンドウを閉じるだけでなく、終了してから開き直してください)
テストがインポートエラーで失敗する
開発用の依存関係をインストールしたことを確認してください。
uv sync --dev
print() によって stdio トランスポートが破損した
stdout に出力すると、JSON-RPC が破損します。print() 文を探して削除してください。代わりに logging.getLogger(__name__).info() を使用します。こちらは stderr に出力します。
search_jpos でタイムアウトエラーが発生する
起動後の最初の呼び出しには5~10秒かかることがあります(ChromaDB と埋め込みモデルのコールドスタート)。このため、タイムアウトは15秒に設定されています。問題が続く場合は、knowledge/chroma_db/ が存在し、データが格納されていることを確認してください。
ロードマップ
- V1 — MVP — 6 個のツール、Claude Desktop、Docker、114 件のテスト(カバレッジ 91%)、クロスエンコーダーによる再ランキングを行う RAG、GitHub Actions による CI/セキュリティ、Issue テンプレート、SECURITY.md
- V2 — 拡張 — Java サイドカー(ライブでのパック/アンパック)、カスタムのインターチェンジ仕様、jPOS ログパーサー、OAuth 2.1、PyPI パッケージ、MCP レジストリへの登録申請
- V3 — プラットフォーム — ホステッドデプロイ、複数仕様(Visa/MC/Amex/Discover)、水平スケーリング、トランザクション分析
詳細は、docs/roadmap-and-architecture.md をご覧ください。
コントリビューション
セットアップ手順とガイドラインについては、CONTRIBUTING.md をご覧ください。
ライセンス
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。