关于 jPOS MCP Server
jPOS MCP Server 为支付开发者和 AI Agent 提供 ISO 8583 与 jPOS 的确定性查询和校验工具。它基于已验证的数据处理字段规格、消息构建及部署描述符,并可搜索 jPOS 文档。
主要功能
- 01查询 ISO 8583 字段规格
- 02解码 MTI
- 03生成 GenericPackager XML
- 04验证 Q2 部署描述符
- 05校验 ISO 8583 消息
- 06语义搜索 jPOS 文档
适用场景
- 01查找字段格式与 jPOS 类名
- 02为支付场景生成 packager 配置
- 03排查或校验 Q2 部署配置
- 04搜索 jPOS 编程指南
MCP 相关
该项目是供 MCP 客户端调用的 MCP 服务,提供 ISO 8583、jPOS 及文档检索工具。支持本地 stdio 和 Docker 中的 Streamable HTTP 传输。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
jPOS MCP 服务
mcp-name: io.github.mohisyed/jpos-mcp-server
首个面向 jPOS 和 ISO 8583 的开源 MCP 服务。

Claude 使用确定性工具验证真实的 ISO 8583 金融交易请求。不靠猜测——每个答案都来自经过验证的数据。
一个 MCP 服务,为 AI Agent(Claude、Cursor、VS Code Copilot)提供对 ISO 8583 字段规范、MTI 解码、jPOS packager XML 生成、部署描述符验证、消息构建和 jPOS 文档搜索的确定性、经过验证的访问能力。
不再需要猜测 packager 类名,也不必再翻阅 300 页的 PDF。调用工具,即可获得正确答案。
目录
快速开始
前置条件: 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 部署描述符(channel、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" |
为什么使用确定性工具,而不是让大模型推断?
大模型可能会猜测字段 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 │
└──────────────────────────────────────────────────────────────────┘
子服务组合
此服务拆分为 4 个特定领域的子服务,通过 FastMCP.mount() 挂载。每个子服务都可以独立测试——RAG 流水线中的错误不会影响 ISO 字段查询。添加新领域只需一个文件,以及在 main.py 中调用一次 mount()。
超时保护
每个工具都通过 asyncio.wait_for() 使用 @with_timeout() 包装。如果某个工具卡住(例如 ChromaDB 冷启动),它会返回结构化错误字典,而不会阻塞整个 MCP 服务。超时级别:
| 级别 | 超时 | 工具 |
|---|---|---|
| 快速 | 2s | lookup_field、decode_mti |
| 中等 | 5s | build_message、validate_descriptor |
| 慢速 | 10s | generate_packager |
| RAG | 15s | search_jpos |
测试
为什么要测试
支付系统对错误答案零容忍。错误的 packager 类名(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 | 单元测试 | lookup_field、decode_mti——有效/无效字段、MTI 类别 |
test_jpos_tools.py | 单元测试 | generate_packager(BCD/ASCII)、validate_descriptor(QMUX、channel-adaptor、txnmgr、格式错误的 XML) |
test_message.py | 单元测试 | build_message——有效消息、缺失字段、长度违规、拒绝 PAN |
test_rag.py | 单元测试 | 查询扩展、模拟集合响应、空集合处理 |
test_timeout.py | 单元测试 | @with_timeout——触发保护机制、快速通过、捕获异常 |
test_validators.py | 单元测试 | luhn_check、contains_likely_real_pan——Luhn 边缘情况、分隔符、测试 PAN 白名单 |
test_logging.py | 单元测试 | PaymentSafeFormatter 脱敏、stderr 处理器配置 |
test_mcp_integration.py | 集成测试 | 工具注册、JSON Schema 生成、端到端 MCP 协议调用 |
test_e2e.py | 端到端工作流 | 多步骤工作流:Visa 授权打包器构建、冲正调试、部署描述符验证、安全边界、通过 MCP 使用 RAG、系统健康状况、错误处理 |
编写新测试
添加工具时,请覆盖以下三类:
- 正常路径——有效输入返回预期输出
- 无效输入——错误类型、超出范围的值、格式错误的数据返回结构化错误
- 边缘情况——边界值、空输入、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 文档的两阶段混合检索:先通过双编码器(mpnet)快速检索候选内容,再使用交叉编码器重排器按高精度排序。
工作原理
- 摄取——清理 PDF 和 Markdown 文件(去除模板文本、目录点线、页眉),并切分为每块 200 个词、重叠 40 个词的文本块。摄取时会过滤掉低信息量文本块。
- 嵌入——使用
all-mpnet-base-v2将每个文本块编码为 768 维向量,并存储在 ChromaDB 中。 - 查询扩展——为简短或包含大量术语的查询(例如 “STAN”、“IFB_LLHEX”)添加领域背景后再进行嵌入,以便模型获得足够的信息来消除歧义。
- 第一阶段检索——通过余弦相似度获取排名前 25 的候选内容。
- 第二阶段重排——交叉编码器(
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 示例
搜索质量
分数针对 cross-encoder + 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-60s)
- 非 root 用户(
appuser:1001),用于安全防护 - 持久化卷用于存储 ChromaDB 数据(容器重启后数据仍保留)
- 每 30s 对
/health执行一次健康检查
使用 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 packager 类是什么?”
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、5500005555559等)。此检测会在任何其他处理之前运行。 - 日志中会脱敏敏感字段 —
PaymentSafeFormatter会从所有日志输出中移除字段 2(PAN)、35(Track 2)、45(Track 1)、52(PIN)、55(EMV)和 64(MAC)。 - 日志仅写入 stderr — stdout 保留用于 JSON-RPC 流(stdio 传输)。单个
print()都会破坏协议。 - Docker 中不以 root 身份运行 — 容器以
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-10s(ChromaDB + 嵌入模型冷启动)。15s 超时已考虑到这一点。如果问题仍然存在,请检查 knowledge/chroma_db/ 是否存在且包含数据。
路线图
- V1 — MVP — 6 个工具、Claude Desktop、Docker、114 项测试(覆盖率为 91%)、经交叉编码器重排的 RAG、GitHub Actions CI/安全、Issue 模板、SECURITY.md
- V2 — 增强版 — Java sidecar(实时打包/解包)、自定义交换规范、jPOS 日志解析器、OAuth 2.1、PyPI 包、提交至 MCP 注册表
- V3 — 平台 — 托管部署、多规范(Visa/MC/Amex/Discover)、水平扩展、交易分析
完整详情请参阅 docs/roadmap-and-architecture.md。
贡献
有关设置说明和指南,请参阅 CONTRIBUTING.md。
许可证
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。