MindRoom Chat

July 18, 2026 ยท View on GitHub

MindRoom Chat is a Matrix client focused on AI-agent workflows. It is built on Cinny, with substantial product and UX changes for MindRoom use cases.

What MindRoom Chat Is

MindRoom Chat is designed for teams that use Matrix as the execution and collaboration layer for AI-assisted work. The app prioritizes:

  • reliable streaming/edit rendering,
  • thread-first workflows,
  • tool-call and run-metadata visibility,
  • predictable deployment under root and subpath hosting,
  • iOS distribution readiness.

What Is Different From Upstream Cinny

MindRoom Chat began as a Cinny fork, but it is now developed as an independent product for Matrix-based AI-agent workflows. It retains Cinny's Matrix foundation while owning its product direction, release cadence, native apps, deployment model, and MindRoom integrations.

AreaMindRoom Chat direction
ProductIndependent MindRoom branding, roadmap, defaults, onboarding, CI, and releases
Agent workflowsStreaming edit resolution, response cancellation, model/run metadata, collapsible tool traces, long-text sidecars, and ! command autocomplete
Threads and navigationThread-aware composition, deep links, search, unread state, and timeline recovery tuned for long-running agent conversations
Calls and voiceAgent-call flows built on MatrixRTC and embedded Element Call, including encrypted call-key handling and native microphone preflight
Native iOSCapacitor packaging, Apple-oriented authentication, APNs/Sygnal push support, voice recording behavior, and App Store release tooling
DeploymentRuntime configuration and base-path support for root or subpath hosting, plus fork-owned Docker and release workflows
EngineeringA large regression suite and a maintained compatibility ledger for product, Matrix SDK, deployment, and native-app changes

Cinny remains the upstream foundation and is credited in Upstream Attribution. Compatible upstream improvements continue to be evaluated for incorporation, while MindRoom Chat's product behavior and release decisions are owned here.

For the implementation history and rationale behind individual changes, see FORK_CHANGES.md.

App Store / iOS Submission Docs

TestFlight via Xcode Cloud

The Xcode Cloud workflow should archive the iOS app with the Archive - iOS action. Set that action's Distribution Preparation to TestFlight (Internal Testing Only) so successful archives are prepared for TestFlight. If that setting changes after a successful archive, rerun the workflow because existing archives are not prepared for TestFlight retroactively. The source release tag can stay tied to upstream Cinny, for example v4.11.1-mindroom.80, while the App Store marketing version advances independently. For the current iOS train, Xcode Cloud publishes Apple version 4.11.2; release tags ending in -mindroom.<n> provide the App Store build number, so v4.11.1-mindroom.80 uploads as 4.11.2 (80). Branch-triggered builds fall back to the checked-in Xcode build number, currently 80. Set IOS_MARKETING_VERSION or IOS_BUILD_NUMBER in Xcode Cloud only when overriding those defaults is intentional.

Quick Start

npm ci
npm run test
npm run build

Runtime Configuration

Main runtime config file:

Notable options:

  • homeserver defaults and allowed-server policy,
  • auth behavior (including allowRegistration, support/privacy/terms links),
  • splash loading copy via splash.loadingMessages,
  • MindRoom placeholder copy via mindroom.thinkingPlaceholderMessages,
  • additional application-link schemes via messageRendering.additionalAllowedUriSchemes,
  • sidebar entry points including sidebar.showThreads,
  • welcome-page behavior.

Formatted message links can allow additional desktop application URI schemes:

{
  "messageRendering": {
    "additionalAllowedUriSchemes": ["obsidian"]
  }
}

Use scheme names without ://. Trailing : or :// delimiters are normalized if supplied. The configured list is additive to the built-in safe schemes. Browser-sensitive schemes including javascript, data, file, blob, vbscript, about, chrome, chrome-extension, filesystem, resource, and view-source are always ignored.

Self-Hosting

Standard static hosting

Build and serve dist/ with your preferred web server.

Runtime base-path (single build artifact)

  • Build once with relative assets: npm run build
  • At runtime set APP_BASE_PATH to / or /mindroom
  • Example: APP_BASE_PATH=/mindroom ./your-server

Containerized runtime also supports:

  • APP_ENABLE_SERVICE_WORKER (enabled by default in container runtime config)

When the client shares an origin with sibling applications, add their root-relative path prefixes to the runtime config so the PWA app-shell fallback leaves those navigations to the network:

window.__SERVICE_WORKER_NAVIGATION_FALLBACK_EXCLUDE_PATHS__ = ['/other-app'];

Only root-relative paths without a query or fragment are accepted. Each prefix excludes its exact path and descendants without excluding similarly named client routes.

Optional build-time base path

  • APP_BUILD_BASE_PATH=/mindroom npm run build

Reverse-proxy examples

iOS Build / Archive

npm run build
npm run ios:icons
npm run appstore:preflight
npx cap sync ios
npx cap open ios

Then archive from Xcode (App scheme, Any iOS Device (arm64)).

iOS Push Notifications (APNs + Matrix)

Native iOS push plumbing is included in this fork (@capacitor/push-notifications + Matrix pusher registration). To turn it on for a deployment:

  1. Configure config.json:
{
  "push": {
    "ios": {
      "enabled": true,
      "appId": "chat.mindroom.app",
      "gatewayUrl": "https://YOUR-PUSH-GATEWAY/_matrix/push/v1/notify",
      "appDisplayName": "MindRoom Chat iOS",
      "deviceDisplayName": "MindRoom Chat iOS",
      "append": true,
      "format": "full"
    }
  }
}
  1. Sync iOS project artifacts after config/dependency changes: npx cap sync ios.
  2. In Xcode, confirm Signing & Capabilities includes Push Notifications.
  3. Run the app on a physical iPhone and enable Settings -> Notifications -> iOS Push Notifications inside MindRoom Chat.
  4. Ensure your Matrix push gateway is configured server-side to accept APNs tokens for your app.

format: "full" is an explicit opt-in that lets a Sygnal-compatible gateway receive the sender and message preview for unencrypted rooms. Omitting it uses the privacy-preserving event_id_only fallback. Encrypted rooms use a generic notification because the homeserver cannot read their message content.

Local Development

npm ci
npm start

Docker

docker build -t mindroom-chat:latest .
docker run -p 8080:80 mindroom-chat:latest

Dockerized Matrix E2E

The Docker boundary for local e2e is the Matrix stack, not the MindRoom Chat app itself. MindRoom Chat and Playwright stay on the host. Docker only runs a disposable Tuwunel homeserver.

Start or stop the local Matrix stack:

npm run e2e:matrix:up
npm run e2e:matrix:down

Run the e2e suite against that Docker-backed homeserver:

npm run test:e2e:docker-matrix

Pass extra Playwright arguments after --:

npm run test:e2e:docker-matrix -- e2e/live/smoke.spec.ts
npm run test:e2e:docker-matrix -- --grep "three stored accounts"

Notes:

  • The stack is defined in e2e/docker-compose.matrix.yaml.
  • The wrapper provisions three local e2e accounts, seeds the shared fixture room, and starts a static built preview on http://127.0.0.1:28090 for the deployed clear-cache spec.
  • The main app under test still runs from the host via Playwright's normal webServer (npm run start -- --host 127.0.0.1 --port 4173 --strictPort) unless E2E_NO_WEB_SERVER=1.
  • Useful overrides: E2E_MATRIX_PORT, E2E_MATRIX_SERVER_NAME, E2E_MATRIX_AUTO_DOWN=1, E2E_ENABLE_DEPLOYED_FIXTURE=0, E2E_SERVER_COMMAND, MINDROOM_TUWUNEL_IMAGE.

Releases

  • Every push to dev creates an automated GitHub release tag in the format v<base_version>-mindroom.<n>.
  • base_version is read from package.json by default (or BASE_VERSION if set), with upstream-style semver tags as fallback; <n> increments from existing fork tags for that base version.
  • The Python helper is reusable across forks via env vars: RELEASE_TAG_PREFIX, RELEASE_TAG_SUFFIX, BASE_TAG_PREFIX, BASE_VERSION.
  • Local preview of the next tag:
npm run release:next-tag

Android Play internal releases

  • The same dev push release workflow builds a signed Android App Bundle and publishes it to the Google Play internal track when it creates a new MindRoom GitHub release.
  • Required GitHub secrets: ANDROID_UPLOAD_KEYSTORE_BASE64, ANDROID_UPLOAD_KEYSTORE_PASSWORD, ANDROID_UPLOAD_KEY_ALIAS, ANDROID_UPLOAD_KEY_PASSWORD, and GOOGLE_PLAY_SERVICE_ACCOUNT_JSON.
  • The keystore secret should be the base64-encoded upload keystore file. The Play service account must have permission to release com.mindroom_ai.app.

Upstream Attribution

This project is built on top of Cinny and Matrix ecosystem libraries.

License

Licensed under AGPL-3.0-only (same as upstream project). See LICENSE.