將既有 Python 3.8 + pyrfc 的 SAP 請購單 FastAPI 服務,以 Python 3.11 + FastMCP 框架封裝為 MCP Server,讓 Claude Desktop、Cherry Studio 等 MCP 客戶端能以自然語言呼叫 SAP 功能。
MCP Client(Claude Desktop / Cherry Studio)
↓ stdio(本機)或 SSE(區域網路)
mcp_server.py(FastMCP 3.x,Python 3.11,port 8080)
↓ httpx POST
FastAPI main.py(pyrfc38 專案,Python 3.8,localhost:8000)
↓ pyrfc
SAP ECC 6.0(192.168.8.14 / 8.15,sysnr=01,client=200/570)
設計原則:MCP Server 不直接連 SAP,SAP 連線由 FastAPI 服務(pyrfc38 專案)統一負責。請注意pyrfc 已從 PyPI yanked,僅在 pyrfc38 專案虛擬環境中管理。
| Tool 名稱 | 說明 | 呼叫對象 |
|---|---|---|
search_requester |
以姓名查詢申請人工號 | Parquet |
get_pr_history |
取得歷史請購單範例值 | Parquet |
search_cost_center |
確認成本中心代碼 | Parquet |
search_pur_group |
確認採購組代碼 | Parquet |
search_matl_group |
確認物料群組代碼 | Parquet |
pr_create_pr |
建立請購單,呼叫 BAPI_PR_CREATE | FastAPI → SAP |
使用者僅提供員工姓名,系統自動查詢申請人工號與歷史請購單範例,再以範例值建立新的請購單。
使用者輸入員工姓名
→ search_requester(確認申請人工號)
→ get_pr_history(取得歷史請購單範例值)
→ pr_create_pr(以範例值建立請購單)
→ 回傳 PR 單號
使用者依本文逐步填入各欄位(廠商 / 申請人 / 交貨日 / 金額 / 成本中心 …),系統同步查詢各主檔代碼後合併建立請購單。
使用者依本文填寫
→ search_cost_center (確認成本中心代碼)
→ search_pur_group (確認採購組代碼)
→ search_matl_group (確認物料群組代碼)
→ pr_create_pr(帶入完整本文建立請購單)
→ 回傳 PR 單號
使用者貼入 JSON 或表格範例值,系統直接呼叫 FastAPI 建立請購單。
使用者貼入 JSON / 表格範例值
→ pr_create_pr(直接呼叫 FastAPI)
→ SAP RFC
→ 建立請購單 → PR 單號
# mcp_server.py
from fastmcp import FastMCP
from tools.pr import create_pr
from tools.material import search_material
mcp = FastMCP("SAP MCP Server")
mcp.add_tool(create_pr)
mcp.add_tool(search_material)
if __name__ == "__main__":
mcp.run(transport="stdio") # 測試環境若為本機 Claude Desktop
# mcp.run(transport="sse", port=8080) # 區域網路 Cherry Studio
# tools/pr.py
import httpx
from fastmcp import tool
FASTAPI_BASE = "http://localhost:8000"
@tool
async def create_pr(payload: dict) -> dict:
"""建立 SAP 請購單,回傳 PR 單號。"""
async with httpx.AsyncClient(timeout=30) as client:
resp = await client.post(f"{FASTAPI_BASE}/pr/create", json=payload)
resp.raise_for_status()
return resp.json()
# tools/parquet_query.py
import polars as pl
from pathlib import Path
PR_FILE = Path(__file__).parent.parent / "data" / "PR_20250701_20250710.parquet"
def get_pr_history(requester: str, n: int = 3) -> list[dict]:
"""以申請人工號查詢最近 n 筆歷史請購單。"""
lf = pl.scan_parquet(PR_FILE)
return (
lf.filter(pl.col("AFNAM") == requester)
.sort("BADAT", descending=True)
.limit(n)
.collect()
.to_dicts()
)
| 環境 | Python 版本 | 用途 |
|---|---|---|
venv311 |
3.11 | FastMCP MCP Server |
pyrfc38 |
3.8 | FastAPI + pyrfc SAP 連線 |
pyrfc 已從 PyPI yanked,需手動從 SAP GitHub 下載 wheel 安裝,並將 sapnwrfc.dll 複製至 System32。詳見 python rfc Connector 一文。
{
"mcpServers": {
"sap-mcp": {
"command": "C:/path/to/venv311/Scripts/python.exe",
"args": ["C:/path/to/mcp_server.py"]
}
}
}