Upload audio, transcribe it, and turn it into meeting summaries, diagrams, actions, transcripts, and exports.
The project is meant to be easy to try locally without relying on external services for login and storage. The compose stack starts Keycloak, MinIO, Postgres, and Redis.
The AI backend is configurable. You can use an OpenAI business/API key, or point OPENAI_BASE_URL to a service that is compatible with the OpenAI APIs used by the project. That means a company can keep the app, identity, storage, and database under its own control, then choose the AI backend that fits its policies.
- Direct browser upload to S3-compatible storage with presigned URLs
- Transcript-only analyses: paste a transcript and skip the audio upload entirely
- Audio transcription handled by a separate worker
- Report with summary, sentiment, participants, and transcript segments
- Diagrams and actions generated only when needed
- Actions classified as
task,decision,risk, orfollow_up - Markdown, Slack/Teams, and calendar exports
- Optional Keycloak login with tenant/user isolation
- Light/dark theme and localized dashboard
- Dedicated routes for overview, new analysis, and reports (
/,/new,/executions/{jobId})
apps/web: Next.js 15, TypeScript, UI, and/api/v1/*routesapps/worker: Node.js worker with BullMQpackages/shared: Zod schemas and shared typespackages/security: helpers for storage keys and S3 headerspackages/wasm-audio: experimental contracts for future client-side audio preprocessing- Postgres: job metadata, report results, actions, artifacts, generation status, and audit data
- Redis: job queue and session token store
- MinIO: local S3-compatible object storage
- Keycloak: local OIDC identity provider
- Node.js 20+
- npm
- Docker and Docker Compose
- an OpenAI key, or a service compatible with the OpenAI APIs used by the project
To just try OmniVox without a local Node.js toolchain, run the full Docker stack (see docs/DEPLOYMENT.md):
cp .env.example .env # set OPENAI_API_KEY and SESSION_SECRET
docker compose --profile app up -d --buildFor development, the fastest path is the bootstrap script: it creates the env files, installs dependencies, starts the compose stack, waits for the healthchecks, and applies the database migrations.
npm run setup # macOS / Linux
scripts/setup.ps1 # Windows (PowerShell)After it finishes, set OPENAI_API_KEY in apps/web/.env.local and apps/worker/.env.local, then jump to step 5.
Alternatively, the manual steps:
- Start the local infrastructure:
docker compose up -d- Create local env files:
cp apps/web/.env.example apps/web/.env.local
cp apps/worker/.env.example apps/worker/.env.local-
Set
OPENAI_API_KEYin both.env.localfiles. If you use a compatible endpoint instead of the default OpenAI endpoint, also setOPENAI_BASE_URL. -
Apply the database schema:
npm run db:migrate- Start web and worker in two terminals:
npm run dev
npm run dev:worker- Open
http://localhost:3000.
Main routes:
/ overview
/new new analysis
/executions/{jobId} analysis report
| Service | URL / port | Credentials |
|---|---|---|
| Web | http://localhost:3000 |
handled by the app |
| Keycloak | http://localhost:8080 |
admin / admin |
| MinIO console | http://localhost:9001 |
minioadmin / minioadmin |
| Postgres | localhost:5432 |
postgres / postgres |
| Redis | localhost:6379 |
none |
The local MinIO bucket is omnivox.
The compose stack imports the omnivox Keycloak realm with two demo users in the same acme tenant. They are useful for checking that analyses created by one user are not visible to the other.
| Username | Password | Tenant |
|---|---|---|
demo |
demo |
acme |
demo2 |
demo2 |
acme |
If Keycloak was already started before the realm file changed, the import is not applied again automatically. Recreate the Keycloak volume or add the user manually from the admin console.
To use Keycloak, set this in the web env:
AUTH_MODE=keycloak
APP_BASE_URL=http://localhost:3000
KEYCLOAK_ISSUER_URL=http://localhost:8080/realms/omnivox
KEYCLOAK_CLIENT_ID=omnivox-web
KEYCLOAK_CLIENT_SECRET=omnivox-local-secretAUTH_MODE=disabled uses DEFAULT_TENANT_ID and is intended for local development only.
The local configuration points to MinIO:
S3_ENDPOINT=http://localhost:9000
S3_REGION=us-east-1
S3_BUCKET=omnivox
S3_ACCESS_KEY_ID=minioadmin
S3_SECRET_ACCESS_KEY=minioadmin
S3_FORCE_PATH_STYLE=true
S3_SERVER_SIDE_ENCRYPTION=
S3_CHECKSUM_ENABLED=trueTo use another S3-compatible provider, change the S3_* variables. If the provider does not support SHA-256 checksum headers on presigned uploads, set S3_CHECKSUM_ENABLED=false. If it requires server-side encryption, set S3_SERVER_SIDE_ENCRYPTION, for example AES256.
The direct upload flow accepts:
flac, mp3, mp4, mpeg, mpga, m4a, ogg, wav, webm
The current limit is 25 MiB. Client-side chunking is not implemented yet.
Today the original file is uploaded to storage and processed by the worker. packages/wasm-audio is preparatory work: it may later be used for audio metrics, resampling, chunking, or browser-side preprocessing, but it is not part of the main pipeline yet.
OmniVox does not store application-level user profiles. In Keycloak mode, jobs only keep:
tenant_idowner_issuerowner_subject
Audio and results stay in the storage and database chosen by whoever installs the project. With the local compose stack, they stay on your machine. When the pipeline runs, audio and text are sent to OpenAI for transcription and analysis according to the account and contract you configure.
If OPENAI_BASE_URL is set, audio and text are sent to that endpoint instead of the default OpenAI endpoint. The service must support the endpoints OmniVox actually uses: audio transcription, chat/responses, and the configured models.
For a real deployment, define retention, deletion, legal basis, privacy notice, and access policy. The main notes are in docs/PRIVACY.md.
npm run db:migrate
npm run verify # typecheck + test + build (web and worker)
npm run lint
npm run format
npm run testWorker probes:
curl -s http://localhost:4010/health
curl -s http://localhost:4010/readydocs/README.md: documentation indexdocs/ARCHITECTURE.md: architecture, runtime flow, main APIs, and configurationdocs/DEPLOYMENT.md: Docker stack, development mode, and manual server deploymentdocs/PRIVACY.md: privacy and GDPR notesdocs/TROUBLESHOOTING.md: common issuesROADMAP.md: planned or desired workCONTRIBUTING.md: how to set up and contributeSECURITY.md: how to report vulnerabilities
OmniVox is provided "as is", without warranty of any kind, under the terms of the Apache-2.0 license. Whoever deploys it acts as the data controller for their instance and is responsible for its legal compliance — including privacy regulations such as GDPR, retention policies, and the choice of AI backend. See docs/PRIVACY.md for what to define before processing real data.
Apache-2.0. See LICENSE.