Pathfinder-Experience: Foundry MCP Env Vars + Adapter Policy Skeleton
1) Environment variable block
Use this as a starter .env block for the ingestion adapter.
# Foundry MCP endpoint (Cloudflare Tunnel hostname)
FOUNDRY_MCP_URL="https://mcp-foundry.example.com"
# Cloudflare Access service token (recommended)
# Leave blank only if you intentionally run without Access (not recommended)
CF_ACCESS_CLIENT_ID=""
CF_ACCESS_CLIENT_SECRET=""
# Adapter behavior
FOUNDRY_MCP_TIMEOUT_MS="12000"
FOUNDRY_MCP_RETRIES="2"
FOUNDRY_MCP_POLL_INTERVAL_SEC="120"
FOUNDRY_MCP_ENABLED="true"
# Safety controls
FOUNDRY_MCP_FAIL_CLOSED="true"
FOUNDRY_MCP_ALLOWLIST_PATH="./config/foundry-mcp-allowlist.yaml"
FOUNDRY_MCP_AUDIT_LOG="./logs/foundry-mcp-audit.log"Notes
- Keep
FOUNDRY_MCP_FAIL_CLOSED=true. - If Access is enabled, requests must include both
CF_ACCESS_CLIENT_ID+CF_ACCESS_CLIENT_SECRETheaders. - Keep polling conservative during live sessions.
2) Adapter policy skeleton (YAML)
Create: config/foundry-mcp-allowlist.yaml
version: 1
mode: deny_by_default
sourceTag: foundry-live
transport:
baseUrlEnv: FOUNDRY_MCP_URL
timeoutMsEnv: FOUNDRY_MCP_TIMEOUT_MS
retriesEnv: FOUNDRY_MCP_RETRIES
cloudflareAccessHeaders:
clientIdEnv: CF_ACCESS_CLIENT_ID
clientSecretEnv: CF_ACCESS_CLIENT_SECRET
# Only these tool/resource names are allowed.
# Replace example names with real names from recon.
allow:
- name: foundry.getWorldInfo
class: SAFE_READ
cacheTtlSec: 300
- name: foundry.getInitiative
class: SAFE_READ
cacheTtlSec: 10
- name: foundry.getPartyStatus
class: SAFE_READ
cacheTtlSec: 15
# Sensitive reads may be allowed only with explicit filters.
sensitive:
- name: foundry.listActors
class: SENSITIVE_READ
requireFilters:
- hideGmOnly
- hideHiddenNpc
- hidePrivateNotes
# Always blocked, regardless of caller intent.
# Use wildcard/prefix patterns your adapter supports.
deny:
- pattern: "*.create*"
- pattern: "*.update*"
- pattern: "*.delete*"
- pattern: "*.set*"
- pattern: "*.execute*"
- pattern: "*.eval*"
- pattern: "*.admin*"
responsePolicy:
includeSourceTag: true
includeToolName: true
includeFetchedAt: true
redactFields:
- gmNotes
- privateNotes
- hidden
- secret
- ownership
observability:
auditLogPathEnv: FOUNDRY_MCP_AUDIT_LOG
logDeniedCalls: true
logAllowedCalls: true
metrics:
enabled: true
failurePolicy:
failClosedEnv: FOUNDRY_MCP_FAIL_CLOSED
onPolicyMismatch: deny
onMissingAuth: deny
onTimeout: fail3) Minimal request header contract (if Access enabled)
CF-Access-Client-Id: <CF_ACCESS_CLIENT_ID>
CF-Access-Client-Secret: <CF_ACCESS_CLIENT_SECRET>4) Quick adapter pseudo-flow
incoming query
-> resolve required tool
-> check allowlist (deny by default)
-> attach Access headers (if configured)
-> call MCP with timeout + retries
-> apply field redaction policy
-> stamp metadata (source/tool/fetchedAt)
-> return sanitized payload5) Acceptance checks
- Denied tool call returns policy error.
- Allowed read call returns payload with
source=foundry-live. - Sensitive call removes redacted fields.
- Missing Access headers (when configured) fails closed.