feat: Update .env.example and server.py to clarify Frappe credentials handling for different deployment modes
This commit is contained in:
parent
c051804170
commit
7289a91b66
36
.env.example
36
.env.example
@ -1,25 +1,37 @@
|
||||
# ══════════════════════════════════════════════════════════════════════════════
|
||||
# DEPLOYMENT MODE
|
||||
# THREE SUPPORTED MODES
|
||||
# ══════════════════════════════════════════════════════════════════════════════
|
||||
#
|
||||
# SSE / VPS mode (hosted server — recommended):
|
||||
# Frappe credentials are NOT stored here. Each user passes their own
|
||||
# X-Frappe-URL, X-Frappe-API-Key, X-Frappe-API-Secret headers when connecting.
|
||||
# Only set MCP_HOST, MCP_PORT, MCP_BEARER_TOKEN below.
|
||||
# MODE 1 — Local / stdio (single user, your machine)
|
||||
# Run: frappe-mcp
|
||||
# Config: Set FRAPPE_URL + credentials below.
|
||||
# Claude Desktop spawns the process directly via stdio.
|
||||
#
|
||||
# Local / stdio mode:
|
||||
# Credentials are read from this file. Run: frappe-mcp (no --sse flag).
|
||||
# Uncomment the Frappe Connection block below.
|
||||
# MODE 2 — VPS / SSE, multi-tenant (public hosted server)
|
||||
# Run: frappe-mcp --sse
|
||||
# Config: Set only MCP_HOST, MCP_PORT, MCP_BEARER_TOKEN here.
|
||||
# Each connecting user supplies their own Frappe credentials as
|
||||
# request headers: X-Frappe-URL, X-Frappe-API-Key, X-Frappe-API-Secret
|
||||
# No Frappe credentials are stored on the server.
|
||||
#
|
||||
# ── SSE Server Settings (VPS hosting) ────────────────────────────────────────
|
||||
# MODE 3 — VPS / SSE, single-tenant (you host it for yourself)
|
||||
# Run: frappe-mcp --sse
|
||||
# Config: Set BOTH the MCP server settings AND Frappe credentials here.
|
||||
# Users connect without sending credential headers — the server's
|
||||
# .env credentials are used for everyone.
|
||||
#
|
||||
# ── SSE Server Settings (modes 2 & 3) ────────────────────────────────────────
|
||||
MCP_HOST=0.0.0.0
|
||||
MCP_PORT=8001
|
||||
|
||||
# Shared access token — all users must send this as: Authorization: Bearer <token>
|
||||
# Generate with: python -c "import secrets; print(secrets.token_hex(32))"
|
||||
# Shared access token — clients must send: Authorization: Bearer <token>
|
||||
# Generate: python -c "import secrets; print(secrets.token_hex(32))"
|
||||
MCP_BEARER_TOKEN=change_this_to_a_strong_random_token
|
||||
|
||||
# ── Frappe Connection (local/stdio mode only) ─────────────────────────────────
|
||||
# ── Frappe Connection (modes 1 & 3) ──────────────────────────────────────────
|
||||
# Required for local stdio mode (mode 1).
|
||||
# Optional for SSE mode — set these only if you want a single fixed Frappe
|
||||
# instance for all connections (mode 3). Leave commented for multi-tenant (mode 2).
|
||||
# FRAPPE_URL=http://YOUR_VPS_IP:8000
|
||||
# FRAPPE_API_KEY=your_api_key_here
|
||||
# FRAPPE_API_SECRET=your_api_secret_here
|
||||
|
||||
@ -83,25 +83,30 @@ def _run_sse():
|
||||
if auth != f"Bearer {bearer_token}":
|
||||
return Response("Unauthorized", status_code=401)
|
||||
|
||||
# Extract per-user Frappe credentials from request headers
|
||||
# Per-user Frappe credentials via request headers (optional).
|
||||
# If omitted, FrappeClient falls back to .env values — useful when the
|
||||
# server owner is the only user, or for a single-tenant VPS deployment.
|
||||
frappe_url = request.headers.get("X-Frappe-URL", "")
|
||||
api_key = request.headers.get("X-Frappe-API-Key", "")
|
||||
api_secret = request.headers.get("X-Frappe-API-Secret", "")
|
||||
site_name = request.headers.get("X-Frappe-Site-Name", "")
|
||||
|
||||
if not frappe_url or not api_key or not api_secret:
|
||||
return Response(
|
||||
"Missing required headers: X-Frappe-URL, X-Frappe-API-Key, X-Frappe-API-Secret",
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
from frappe_mcp.session import SessionConfig, set_session
|
||||
set_session(SessionConfig(
|
||||
frappe_url=frappe_url,
|
||||
api_key=api_key,
|
||||
api_secret=api_secret,
|
||||
site_name=site_name,
|
||||
))
|
||||
if frappe_url or api_key or api_secret:
|
||||
# At least one header present — require all three to be explicit
|
||||
if not (frappe_url and api_key and api_secret):
|
||||
return Response(
|
||||
"Partial credentials: supply all three headers together — "
|
||||
"X-Frappe-URL, X-Frappe-API-Key, X-Frappe-API-Secret",
|
||||
status_code=400,
|
||||
)
|
||||
from frappe_mcp.session import SessionConfig, set_session
|
||||
set_session(SessionConfig(
|
||||
frappe_url=frappe_url,
|
||||
api_key=api_key,
|
||||
api_secret=api_secret,
|
||||
site_name=site_name,
|
||||
))
|
||||
# else: no headers — FrappeClient will use .env credentials
|
||||
|
||||
async with sse.connect_sse(
|
||||
request.scope, request.receive, request._send
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user