Skip to main content
Glama
crashzero9
by crashzero9

OHMS - Order Hub Management System

Flauraly Flowers and Plants - Replit Reserved VM上でホストされるPython FastMCPサーバー。

目的

OHMSは、注文および在庫関連のツールを、Model Context Protocol(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(Server-Sent Eventsフォールバック)の両方が同時にマウントされているため、あらゆる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はローカル実行時のみ(python-dotenv を介して).env を読み取ります。シークレットをプレーンテキストで入力するのではなく、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認証、6つのツール(ライブ4つ + スタブ2つ)、Replit Reserved VMデプロイ、基本的なpytestスイート。

  • フェーズ2 (計画中): 静的Bearerを置き換えるOAuth 2.1、完全なDoorDashドライバー、実際のネットワークプリンタードライバー、シークレットを秘匿化した構造化ログ、レート制限。

セキュリティに関する注意

  • コミットされたファイルにはシークレット値は一切含まれません。

  • Authorization ヘッダーおよびShopifyの完全なレスポンスボディはログに記録されません。

  • /health はリテラル文字列 OHMS OK のみを返します(バージョン、環境、パス情報は含まれません)。

  • すべての httpx 呼び出しには30秒の明示的なタイムアウトが設定されています。

Related MCP Connectors