Sap Ai agent Python MC p

SAP透過MCP開立請購單POC概念驗證

1. 系統概述

1.1 目標

將既有 Python 3.8 + pyrfc 的 SAP 請購單 FastAPI 服務,以 Python 3.11 + FastMCP 框架封裝為 MCP Server,讓 Claude Desktop、Cherry Studio 等 MCP 客戶端能以自然語言呼叫 SAP 功能。

1.2 整體架構

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 專案虛擬環境中管理。


2. MCP Tools 清單

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

3. 三種操作情境

情境一:參考工號歷史資料建立請購單

使用者僅提供員工姓名,系統自動查詢申請人工號與歷史請購單範例,再以範例值建立新的請購單。

使用者輸入員工姓名
    → 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 單號

4. 核心程式碼片段

4.1 MCP Server 入口

# 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

4.2 pr_create_pr Tool

# 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()

4.3 Parquet 歷史查詢

# 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()
    )

5. 環境建置重點

5.1 Python 版本分工

環境 Python 版本 用途
venv311 3.11 FastMCP MCP Server
pyrfc38 3.8 FastAPI + pyrfc SAP 連線

5.2 pyrfc 安裝注意事項

pyrfc 已從 PyPI yanked,需手動從 SAP GitHub 下載 wheel 安裝,並將 sapnwrfc.dll 複製至 System32。詳見 python rfc Connector 一文。

5.3 MCP Client客戶端設定

{
  "mcpServers": {
    "sap-mcp": {
      "command": "C:/path/to/venv311/Scripts/python.exe",
      "args": ["C:/path/to/mcp_server.py"]
    }
  }
}

6. 小結

  • 自然語言 → SAP 操作:透過 MCP 工具鏈,使用者無需了解 SAP 欄位命名,直接以中文描述需求即可開立請購單。
  • 架構解耦:pyrfc 相依性隔離在 Python 3.8 虛擬環境,MCP Server 以 httpx 呼叫,互不干擾。
  • 三種情境覆蓋:從完全依賴歷史資料、逐欄位互動填寫到直接貼入 JSON,滿足不同使用者習慣。