Skip to main content
Glama
CaptainCurso

Music and Madness Sync Bridge

by CaptainCurso

Music and Madness Sync Bridge

This project implements Stage 1 of your plan:

  • FoundryVTT -> Notion Story Bible journal mirroring

  • Manual-run sync commands

  • MCP tool surface for Codex/LLM orchestration

  • Full media copy to durable local storage

  • Conflict tracking with manual resolution

  • Non-destructive write scope lock to Music and Madness Story Bible

Project layout

  • /Users/nicholasmcdowell/Documents/Codex Projects/Music and Madness/music-madness-sync-bridge/src

    • Bridge service, CLI, MCP server, Foundry/Notion adapters.

  • /Users/nicholasmcdowell/Documents/Codex Projects/Music and Madness/music-madness-sync-bridge/foundry-module/music-madness-bridge

    • Foundry module scaffold exposing authenticated journal read events.

  • /Users/nicholasmcdowell/Documents/Codex Projects/Music and Madness/music-madness-sync-bridge/data

    • Runtime state (state/bridge.sqlite), media copies (media/), logs (logs/audit.log).

Definitions

  • MCP: Model Context Protocol. Lets Codex call bridge tools like sync.foundry_to_notion.apply.

  • Mirror block: Generated section under ## Foundry Mirror in a Notion page.

  • Conflict: Source and target changed since last sync, requiring manual decision.

Setup

  1. Copy env template.

cd '/Users/nicholasmcdowell/Documents/Codex Projects/Music and Madness/music-madness-sync-bridge' cp .env.example .env
  1. Fill .env values:

  • Foundry URL/tokens

  • Notion key

  • Story Bible scope database IDs

  1. Typecheck.

npm run typecheck

Operator commands

Preview changes (no writes):

npm run sync:preview

Apply mirror updates:

npm run sync:apply -- --include-media

List conflicts:

npm run sync:conflicts

Resolve one conflict:

npm run sync:resolve -- --conflict-id <id> --resolution manual_merge --notes "Reviewed and merged"

Health check:

tsx src/cli.ts health

MCP server

Run stdio MCP server:

npm run mcp:start

Exposed tools:

  • foundry.health_check

  • foundry.list_journals

  • foundry.get_journal

  • foundry.export_journal_media

  • sync.foundry_to_notion.preview

  • sync.foundry_to_notion.apply

  • sync.diff

  • sync.conflicts.list

  • sync.conflicts.resolve

Guardrails enforced

  • Only writes to Notion pages in NOTION_ALLOWED_DATABASE_IDS.

  • Existing prose preserved by appending/updating generated mirror block.

  • Legacy Music and Madness section is untouched by default because database scope is explicit.

Known limitations in this initial implementation

  • Foundry HTTP routes are expected at /health, /journals, /journals/:id, etc.

  • The Foundry module included here is an authenticated socket/event scaffold. If you need direct HTTP routes from Foundry itself, run a small local proxy (or use an API module) that maps those routes to module events.

  • Media is copied to local durable files. To render media directly inside cloud Notion reliably, set MEDIA_PUBLIC_BASE_URL to a reachable static host.

Local test bridge API (optional)

If your Foundry module routes are not live yet, run the mock API that implements:

  • GET /health

  • GET /journals

  • GET /journals/:id

  • GET /journals/:id/media

  • GET /assets/:assetId

  • GET /changes?since=

Command:

npm run foundry:mock-api

Fixture data file:

  • /Users/nicholasmcdowell/Documents/Codex Projects/Music and Madness/music-madness-sync-bridge/fixtures/foundry-fixture.json

Real Foundry proxy (Socket.IO -> HTTP routes)

Use this when your Foundry world and music-madness-bridge module are running.

Why this exists

Your sync client expects HTTP routes (/journals, /health, etc.). The Foundry module communicates via socket events in-world. This proxy translates HTTP calls to socket event calls.

Start order

  1. Start Foundry and open the target world.

  2. Ensure module music-madness-bridge is enabled.

  3. In Foundry world settings, set Bridge Token to the same value as .env FOUNDRY_BRIDGE_TOKEN.

  4. Populate in .env:

    • FOUNDRY_SITE_URL

    • FOUNDRY_WORLD

    • FOUNDRY_SESSION_COOKIE

    • FOUNDRY_BRIDGE_TOKEN

  5. Start proxy:

npm run foundry:proxy
  1. In another terminal, run bridge operations:

npm run sync:preview npm run sync:apply -- --include-media

FOUNDRY_SESSION_COOKIE is the value of the session cookie from a browser already logged into your Foundry world. Treat it like a secret token.

Current limitation

GET /assets/:assetId returns 501 in socket-proxy mode unless your module adds binary asset streaming. Media still syncs from journal-linked sourceUrl values where accessible.

Remote Foundry host (LAN)

If Foundry runs on another machine on your network, set:

FOUNDRY_SITE_URL=http://192.168.1.105:30000/

Keep the sync client pointed at your local proxy:

FOUNDRY_BASE_URL=http://127.0.0.1:8788

So the flow is:

  • this laptop sync client -> local proxy (127.0.0.1:8788)

  • local proxy -> remote Foundry (192.168.1.105:30000)

You still need:

  • FOUNDRY_WORLD for that remote Foundry world

  • FOUNDRY_SESSION_COOKIE from a browser logged into that remote Foundry

  • matching FOUNDRY_BRIDGE_TOKEN in Foundry module world settings

Remote diagnostic command

Run this before sync to verify remote Foundry + proxy health:

npm run health:remote

What it checks:

  • FOUNDRY_SITE_URL HTTP reachability

  • local proxy /health response and socket connection state

  • local proxy /journals route response

Exit code is non-zero if any check fails.

Verbose diagnostics with remediation hints:

npm run health:remote -- --verbose

Doctor command

Validate your .env before running proxy or sync:

npm run doctor

What it validates:

  • required env variables are present

  • URL formats (FOUNDRY_BASE_URL, FOUNDRY_SITE_URL)

  • Notion DB scope consistency (NOTION_DEFAULT_TARGET_DB_ID is in NOTION_ALLOWED_DATABASE_IDS)

  • proxy port sanity

  • basic shape checks for world slug and session cookie

Exit code is non-zero when required checks fail.

Remote module install (manifest URL)

For one-click Foundry install/update via URL, use the release workflow guide:

  • /Users/nicholasmcdowell/Documents/Codex Projects/Music and Madness/music-madness-sync-bridge/docs/foundry_remote_install.md

Quick command (example):

MODULE_VERSION=0.1.0 MODULE_URL=https://github.com/<you>/<repo> MODULE_MANIFEST_URL=https://raw.githubusercontent.com/<you>/<repo>/main/foundry-module/music-madness-bridge/module.json MODULE_DOWNLOAD_URL=https://github.com/<you>/<repo>/releases/download/v0.1.0/music-madness-bridge-v0.1.0.zip node scripts/release/prepare-foundry-module.mjs
-
security - not tested
F
license - not found
-
quality - not tested

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/CaptainCurso/music-madness-sync-bridge'

If you have feedback or need assistance with the MCP directory API, please join our Discord server