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.
| Area | MindRoom Chat direction |
|---|---|
| Product | Independent MindRoom branding, roadmap, defaults, onboarding, CI, and releases |
| Agent workflows | Streaming edit resolution, response cancellation, model/run metadata, collapsible tool traces, long-text sidecars, and ! command autocomplete |
| Threads and navigation | Thread-aware composition, deep links, search, unread state, and timeline recovery tuned for long-running agent conversations |
| Calls and voice | Agent-call flows built on MatrixRTC and embedded Element Call, including encrypted call-key handling and native microphone preflight |
| Native iOS | Capacitor packaging, Apple-oriented authentication, APNs/Sygnal push support, voice recording behavior, and App Store release tooling |
| Deployment | Runtime configuration and base-path support for root or subpath hosting, plus fork-owned Docker and release workflows |
| Engineering | A 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
- Checklist:
APP_STORE_COMPLIANCE.md - Submission metadata/review notes packet:
APP_STORE_SUBMISSION_PACKET.md - Build guide:
ios-build.md
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_PATHto/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
- Netlify:
netlify.toml - Nginx:
contrib/nginx/mindroom-chat.domain.tld.conf - Caddy:
contrib/caddy/caddyfile
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:
- 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"
}
}
}
- Sync iOS project artifacts after config/dependency changes:
npx cap sync ios. - In Xcode, confirm
Signing & CapabilitiesincludesPush Notifications. - Run the app on a physical iPhone and enable
Settings -> Notifications -> iOS Push Notificationsinside MindRoom Chat. - 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:28090for 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) unlessE2E_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
devcreates an automated GitHub release tag in the formatv<base_version>-mindroom.<n>. base_versionis read frompackage.jsonby default (orBASE_VERSIONif 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
devpush release workflow builds a signed Android App Bundle and publishes it to the Google Playinternaltrack 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, andGOOGLE_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.
- MindRoom Chat: https://github.com/mindroom-ai/mindroom-chat
- Original Cinny project: https://cinny.in
- Matrix: https://matrix.org
License
Licensed under AGPL-3.0-only (same as upstream project).
See LICENSE.