Skip to content

Feature/self hosted server mcp - #33

Merged
pavlicekdominik merged 5 commits into
Mountea-Framework:devfrom
thundertone:feature/self-hosted-server-mcp
Oct 19, 2026
Merged

pavlicekdominik merged 5 commits into
Mountea-Framework:devfrom
thundertone:feature/self-hosted-server-mcp

Conversation

@thundertone

Copy link
Copy Markdown

Stacked on the "Copy/paste/duplicate nodes, preview from a node, and an idempotent canonicalizer" PR: the MCP server needs the canonicalization fix from there. Until that one is merged, this diff also shows its three commits.

Summary

An optional way to run Mountea Dialoguer as a web app on your own machine and use it from every device, plus an MCP server so an LLM can author projects. Nothing is active unless the app is built with VITE_SYNC_SERVER=true; the desktop app and the Google Drive and Steam providers are untouched. Details and a quick start are in SELF_HOSTED.md.

The app side is small

  • New server sync provider in the provider registry and storage providers: it talks to /api/sync/files and stores the same immutable revisions as the other providers, in plain text and without a login. revisionProtocol.js asks isPlaintextProvider() instead of comparing with 'steam'.
  • With VITE_SYNC_SERVER=true, loadAccount connects to the server and sets sync mode to full, __root.jsx pulls once before the first paint (8 s cap), and the Google login prompt is not shown. That is about 25 lines outside the new provider.

server/ (no dependencies)

Serves the built app and is the file store: create-if-absent files in DATA_DIR/sync, never rewritten, plus /api/health. Access control is left to whatever sits in front (reverse proxy, Cloudflare Access, VPN).

mcp/ (no dependencies) and the skill

  • Streamable HTTP MCP server, 39 tools: projects, dialogues, nodes and connections, participants, categories, decorators, conditions, row timing (executionBehaviour, durationMode, durationOverride), translations, validation, and .mnteadlg / .mnteadlgproj v3 export.
  • It reads a project's head revision from the store, changes a copy, validates it with the app's own canonicalProject code and writes a new revision. The revision history is the backup, and it refuses to write when a project has divergent heads.
  • No tool deletes a project or a dialogue itself. Content inside a dialogue can be deleted.
  • Bearer token (or token in the URL path for clients that cannot send headers), rate limiting, audit log. An MCP_TOKEN of at least 24 characters is required.
  • .claude/skills/mountea-dialoguer/ teaches an LLM the workflow and the plugin's limits (name rules, property types, import format).

Docker

Dockerfile and docker-compose.yml: app on :8080, MCP on :8081, data in ./data.

Tests

  • npm run test:mcp: 20 Vitest tests (protocol, auth, authoring rules, export, revision-history linearity). This adds vitest as a dev dependency, used only for these tests.
  • Playwright against a running server: autosave.spec.js (a project is pushed and restored in a fresh browser) and mcp.spec.js (a dialogue built through MCP opens, previews and exports in the app; competing saves end in the conflict panel). Both skip unless the servers are running.
  • Upstream's sync, auth, repository and smoke specs still pass (42 tests).

Notes

  • The unencrypted store is as private as the network in front of it.
  • Every save adds a revision file and each page load downloads each revision once; a compaction step would be a good follow-up.
  • Not covered: building the Docker image in CI.

🤖 Generated with Claude Code

thundertone and others added 4 commits October 17, 2026 18:24
Canonicalizing an already canonical snapshot re-stamped the timestamps of localized entries and
added keyType only on the second pass, and legacy property types (bool, int, float) were
normalized only while validating. A revision's payload hash therefore differed after a round
trip and other devices reported it as CORRUPT_REMOTE.

Unchanged entries keep their timestamps, entries go through normalizeLocalizedStringEntry, and
decorator/condition property types are normalized before hashing.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U2LYX8SVLgzrkJt4GiVG1P
… options

- Ctrl/Cmd+C, V and D copy, paste and duplicate the selected nodes and the edges between them.
  Pasted nodes and rows get new ids and localization keys. Pasting into another project clears
  speakers and decorators, which belong to the source project.
- Right-click a node, "Preview from here" starts the preview at that node.
- Preview options show the action label and the line the player then says; options that end
  the conversation are listed last.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U2LYX8SVLgzrkJt4GiVG1P
The project has no unit test runner; use the module harness like the other regression specs.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U2LYX8SVLgzrkJt4GiVG1P
- server/: dependency-free Node server; serves the built app and is the file store behind a new
  'server' sync provider (plaintext immutable revisions, no login).
- Activated only by VITE_SYNC_SERVER=true: the app connects to the server at start, pulls before
  the first paint, pushes after each change.
- mcp/: dependency-free MCP server that authors projects through the same revision store,
  validated with the app's canonicalProject code. It cannot delete projects or dialogues.
- Dockerfile, docker-compose.yml, SELF_HOSTED.md, a Claude skill, tests.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U2LYX8SVLgzrkJt4GiVG1P
@netlify

netlify Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for mountea-dialoguer ready!

Name Link
🔨 Latest commit 992d16b
🔍 Latest deploy log https://app.netlify.com/projects/mountea-dialoguer/deploys/6ad3c88f1eb720d6f9640e10
😎 Deploy Preview https://deploy-preview-33--mountea-dialoguer.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@codacy-production

codacy-production Bot commented Oct 17, 2026 •

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 3 critical

Results:
3 new issues

Category Results
Security 3 critical

View in Codacy

🟢 Metrics 976 complexity · 7 duplication

Metric Results
Complexity 976
Duplication 7

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

They run on Node, so process and Buffer are defined. Add them to the Node override of the ESLint
config and to the lint script. Note on the Dockerfile why the image runs as root.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U2LYX8SVLgzrkJt4GiVG1P
@pavlicekdominik
pavlicekdominik merged commit fcedcc4 into Mountea-Framework:dev Oct 19, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants