Skip to main content
Glama
crashzero9
by crashzero9

OHMS - 订单中心管理系统

Flauraly Flowers and Plants - 托管在 Replit 预留虚拟机上的 Python FastMCP 服务器。

目的

OHMS 通过模型上下文协议 (MCP) 向 Violet(以及任何其他授权的 MCP 客户端)公开了一组精简且经过加固的订单和库存相关工具。它将 Shopify Admin REST 访问集中在 Bearer 身份验证网关之后,确保代理永远不会接触到原始的 Shopify 凭据。

架构

+-----------------+      Bearer       +------------------------------+
|  MCP Client     |  ---------------> |  OHMS (Replit Reserved VM)   |
|  (Violet, etc.) |   /mcp or /sse    |                              |
+-----------------+                   |  Starlette parent app        |
                                      |  +-- /health (open)          |
                                      |  +-- /mcp   (Streamable HTTP)|
                                      |  +-- /sse   (SSE fallback)   |
                                      |  +-- BearerAuthMiddleware    |
                                      +--------------+---------------+
                                                     |
                                                     v
                                      +------------------------------+
                                      |  Shopify Admin REST API      |
                                      +------------------------------+

/mcp (可流式传输 HTTP) 和 /sse (服务器发送事件回退) 同时挂载,因此任何 MCP 客户端传输配置文件均可工作。

环境变量

OHMS 通过 OAuth 2.0 client_credentials 授权方式向 Shopify 进行身份验证。服务器从不持有长期有效的 SHOPIFY_ACCESS_TOKEN;相反,它持有一对 SHOPIFY_CLIENT_ID + SHOPIFY_CLIENT_SECRET,并根据需要向 https://{shop}.myshopify.com/admin/oauth/access_token 请求获取短期访问令牌。生成的令牌会缓存在内存中,并带有 5 分钟的时钟偏移缓冲,并在需要时(或在后续调用返回 401/403 时)自动重新生成。所有值均通过 os.environ.get(...) 读取。没有任何硬编码内容。

变量

目的

PORT

绑定的 TCP 端口(Replit 会注入此值;默认为 8080)。

OHMS_API_TOKEN

每个非 /health 请求所需的静态 Bearer 令牌(客户端到 OHMS 的身份验证 - 与 Shopify 分开)。

SHOPIFY_STORE_URL

商店域名,例如 flauraly.myshopify.com。

SHOPIFY_CLIENT_ID

Shopify 应用客户端 ID(用于 OAuth client_credentials 授权)。

SHOPIFY_CLIENT_SECRET

Shopify 应用客户端密钥(用于 OAuth client_credentials 授权)。请按 Secrets_Registry.md 计划轮换。

SHOPIFY_API_VERSION

固定的 Shopify API 版本,例如 2025-01。

PRINTER_IP

收据打印机的本地网络 IP(存根使用此值)。

请参阅 .env.example 获取占位符模板。

本地开发 (Windows)

OHMS 仅在本地运行时读取 .env(通过 python-dotenv)。请从 Windows DPAPI 保护的密钥存储中引导您的 .env,而不是以明文形式输入密钥:

# 1. Pull each secret from DPAPI into the local .env (PowerShell pseudocode)
$secrets = @("OHMS_API_TOKEN","SHOPIFY_STORE_URL","SHOPIFY_CLIENT_ID","SHOPIFY_CLIENT_SECRET","SHOPIFY_API_VERSION","PRINTER_IP")
foreach ($k in $secrets) {
    $v = Unprotect-DpapiSecret -Name $k    # your local helper
    Add-Content .env "$k=$v"
}

# 2. Run the server
python -m venv .venv
.venv\Scripts\Activate.ps1
pip install -r requirements.txt
python main.py

服务器默认监听 http://0.0.0.0:8080。使用以下命令探测:

curl http://localhost:8080/health
# => OHMS OK

Replit 部署

  1. 创建一个 Replit 项目并导入此文件夹。

  2. 在 Secrets 面板中,设置 .env.example 中的所有变量(使用真实值 - 切勿将其粘贴到任何已提交的文件中)。

  3. 确认 .replit 显示 deploymentTarget = "reserved_vm" 且端口为 8080 -> 80。

  4. 部署。公共 URL 为 https://ohms-server.crashzero9.replit.app。

  5. 验证两种传输方式:

curl https://ohms-server.crashzero9.replit.app/health
curl -H "Authorization: Bearer $OHMS_API_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"jsonrpc":"2.0","method":"tools/list","id":1}' \
     https://ohms-server.crashzero9.replit.app/mcp

工具注册表

工具

来源

说明

get_order(order_id)

Shopify Admin REST

GET /orders/{id}.json

list_pending_orders()

Shopify Admin REST

GET /orders.json?status=open&limit=50

update_order_status(order_id, status)

Shopify Admin REST

PUT /orders/{id}.json (设置标签)

get_inventory_snapshot()

Shopify Admin REST

GET /inventory_levels.json?limit=50

get_doordash_orders_via_browser()

存根

返回用于浏览器自动化切换的路由字典。

print_order_ticket(order_id)

存根

读取 PRINTER_IP;返回排队状态。驱动程序待开发。

阶段状态

  • 阶段 1 (当前): MVP 脚手架、Bearer 身份验证、六个工具(4 个实时 + 2 个存根)、Replit 预留虚拟机部署、基础 pytest 套件。

  • 阶段 2 (计划中): 用 OAuth 2.1 替换静态 Bearer、完整的 DoorDash 驱动程序、真实的网路打印机驱动程序、带密钥脱敏的结构化日志记录、速率限制。

安全说明

  • 任何已提交的文件中均不出现密钥值。

  • 永远不会记录 Authorization 标头和完整的 Shopify 响应正文。

  • /health 仅返回字面字符串 OHMS OK - 不包含版本、环境或路径信息。

  • 所有 httpx 调用均有明确的 30 秒超时限制。

Related MCP Connectors