Foundry-VTT-MCP Exposure Model + Phase 1 Checklist

Chosen Model (Best Fit)

Cloudflare Tunnel + Cloudflare Access (Zero Trust) in front of foundry-vtt-mcp bound to localhost.

Why this model

  • No router port-forwarding needed.
  • Fastest path for a GM running Foundry locally on a home server.
  • Strong identity gate (Access) before any request reaches MCP.
  • Easy revocation and audit trail.
  • Fits your note: you can provide tunnel capability if needed.

Security posture summary

  • foundry-vtt-mcp stays private (127.0.0.1 or LAN only).
  • Public entrypoint is Cloudflare edge only.
  • Access policy enforces allowlisted users and/or service token.
  • Party app uses read-only allowlisted tool calls.

Phase 1 Goal

Stand up a secure, testable path from the existing Pathfinder stack (pathfinder-experience / P2E_Buddy / Quartz pipeline) Foundry MCP for read-only queries only.

Success looks like:

  1. Endpoint reachable only through Cloudflare Access.
  2. Unauthenticated requests blocked.
  3. Authenticated request succeeds.
  4. Tool surface inventoried and classified for safety.

Prerequisites

  1. GM host can run cloudflared.
  2. Domain in Cloudflare (or subdomain under your existing setup).
  3. Foundry + foundry-vtt-mcp already running locally.
  4. Agreement that Phase 1 is read-only discovery/testing.

Phase 1 Checklist (Operator Runbook)

1) Verify local MCP bind (must be private)

  • Confirm current listening socket:
    • ss -ltnp | grep -E 'foundry|mcp|8787|3000'
  • Requirement:
    • Service binds to 127.0.0.1:<port> (preferred), not 0.0.0.0.

If needed, reconfigure foundry-vtt-mcp to localhost bind before continuing.


2) Install and authenticate Cloudflare Tunnel client

(Commands vary slightly by distro; example flow)

  • Install cloudflared
  • Login once:
    • cloudflared tunnel login

This opens browser auth to the GM’s Cloudflare account/team.


3) Create tunnel + DNS route

Example:

  • cloudflared tunnel create foundry-mcp
  • cloudflared tunnel route dns foundry-mcp mcp-foundry.<your-domain>

Record tunnel UUID and generated credentials file path.


4) Configure ingress to localhost MCP

Create/update config (typical path /etc/cloudflared/config.yml):

tunnel: foundry-mcp
credentials-file: /etc/cloudflared/<TUNNEL-UUID>.json
 
ingress:
  - hostname: mcp-foundry.<your-domain>
    service: http://127.0.0.1:<MCP_PORT>
  - service: http_status:404

Start/enable:

  • sudo systemctl enable --now cloudflared

5) Add Cloudflare Access policy (hard gate)

In Cloudflare Zero Trust:

  1. Create Access application for mcp-foundry.<your-domain>.
  2. Default action: deny.
  3. Allow only:
    • specific emails (GM + you), and/or
    • service token for app backend.
  4. Set short session duration and require re-auth.

Recommended: use service token for machine-to-machine app adapter.


6) Validate edge protection

Checks:

  1. From incognito/no auth, hit endpoint should be blocked by Access.
  2. From authorized identity, endpoint should respond.
  3. Check Cloudflare Access logs show allow/deny events.

If unauthenticated access works, stop and fix before proceeding.


7) Tool surface inventory (read-only recon)

From authorized client:

  1. List available MCP tools/resources.
  2. Export list into a local note.
  3. Classify each item:
    • SAFE_READ
    • SENSITIVE_READ
    • PROHIBITED (write/mutate/admin/spoiler-heavy)

Output artifact to create in ideas folder:

  • 01_P2E_MCP/Foundry_MCP_Tool_Allowlist_Draft.md

8) Define temporary allowlist for Phase 1 app tests

Allow only minimal read endpoints needed for validation, e.g.:

  • system/world metadata
  • actor read
  • encounter/initiative read

Block everything else at adapter layer (even if server exposes more).


9) Smoke test from app adapter

Run three test prompts through adapter:

  1. “What is current initiative order?”
  2. “What conditions are on party members?”
  3. “Summarize current encounter state (player-safe).”

Acceptance:

  • Responses return quickly.
  • No GM-only notes/spoilers leak.
  • Source tags added (foundry-live).

10) Phase 1 exit criteria

All must pass:

  1. No direct public access to localhost MCP.
  2. Access policy enforced and logged.
  3. Tool inventory completed.
  4. Draft allowlist written.
  5. Smoke tests pass with no spoiler leak.

If any fail, do not advance to wider pilot.


Risk Notes (Phase 1)

  • Biggest risk is exposing overly broad read scope, not just write scope.
  • Journals/scenes can contain GM-only content; default to blocked until verified.
  • Keep adapter as policy enforcement point; do not trust client behavior.

Create after Phase 1 completion:

  • 01_P2E_MCP/Phase_2_Spoiler_Safety_and_Adapter_Policy.md

Include:

  • final tool allowlist
  • spoiler test cases
  • credential rotation + incident steps