Self-hosted ticket/helpdesk system, database-compatible with OTRS 6.0.x / Znuny 6.0–7.3
1.2K
Tiqora is a modern, self-hosted ticket / helpdesk system that is database-compatible with OTRS 6.0.x and Znuny 6.0–7.3 (MariaDB/MySQL and PostgreSQL). It is a clean-room reimplementation (Python FastAPI + React), not a fork of Znuny — no Znuny source code is included or redistributed.
| Backend | Python 3.12+, FastAPI, SQLAlchemy 2 async, Alembic, Pydantic v2 |
| Frontend | React + TypeScript + Vite, Tailwind, theming via CSS variables |
| Search | Meilisearch (full-text; hybrid / vector RAG planned later) |
| Jobs | Plain asyncio worker loops (tiqora-worker, tiqora-ai-worker), Redis for sessions/pub-sub |
| AI surface | MCP server (FastMCP) under the same permission engine as UI/REST |
| License | AGPL-3.0 — Copyright © 2026 Cygnus Networks GmbH |
In the browser, nothing to install: the interactive demo runs the full agent, admin and portal UI against mock data.
On your machine, one command (Docker with Compose v2):
curl -fsSLO https://raw.githubusercontent.com/CygnusNetworks/tiqora/main/docker-compose.quickstart.yml
docker compose -f docker-compose.quickstart.yml up -d
Open http://localhost:8000/ and sign in as root@localhost / tiqora-demo. The first
start creates the database and seeds 40 fake tickets; docker compose -f docker-compose.quickstart.yml down -v removes everything again. The quickstart is for
evaluation only (fixed passwords, plain HTTP). For a real installation see
Getting started.
Running OTRS or Znuny already? Tiqora can work on your existing database, next to Znuny — read Moving off OTRS/Znuny without a big-bang migration or the comparison with Znuny, OTRS, Zammad and others.
Questions, ideas, war stories from your OTRS migration: GitHub Discussions.
tiqora_* tables only until
you explicitly take schema ownership). Preferred peers: Znuny 6.5 (LTS) or
7.3..po codes +
English source), RTL included; agent preference syncs with Znuny
UserLanguage (see docs/i18n.md).TIQORA_PORTAL_ENABLED) and Markdown KB./api/v1, GenericInterface REST/SOAP compatibility,
webhooks, channel plugins (email, SMS, WhatsApp, Telegram, phone/CTI).Product site — overview, features, screenshots.
Interactive demo — full agent, admin, and
portal UI in the browser against mock data (nothing is saved). Built from frontend/
with Mock Service Worker; local build:
VITE_BASE=/tiqora/demo/ pnpm --filter tiqora-frontend build:demo
Inbox sorted by last activity, with e-mail / Telegram / phone filters — and a CTI popup for the call that is ringing through.
Grouped by topic; click a section to expand it, click a picture for full size. The product site shows the same set as a gallery with a light/dark switch.
| Ticket summary | Draft grounded in MCP tools | Auto-reply with its tool trace |
|---|---|---|
![]() | ![]() | ![]() |
| Refine, reviewed as a diff | Model catalog | Task → profile routing |
![]() | ![]() | ![]() |
| Per-queue policies | AI settings | Providers |
![]() | ![]() | ![]() |
| Cost budget & tool rounds | MCP tool sources | LLM request audit |
![]() | ![]() | ![]() |
| Inbox | Ticket view | Dashboard |
|---|---|---|
![]() | ![]() | ![]() |
| Search | Reporting & SLA | Calendar |
![]() | ![]() | ![]() |
| Knowledge base | ||
![]() |
| Telegram chat | CTI call popup | Phone ticket with caller lookup |
|---|---|---|
![]() | ![]() | ![]() |
| Verified signature on arrival | Sign & encrypt in the composer | Per-queue security defaults |
|---|---|---|
![]() | ![]() | ![]() |
| PGP keys | S/MIME certificates | |
![]() | ![]() |
| Queues | Escalation matrix | Agents |
|---|---|---|
![]() | ![]() | ![]() |
| Groups | Roles ↔ groups | Customer users |
![]() | ![]() | ![]() |
| Customer user groups | Dynamic fields | Privacy / GDPR |
![]() | ![]() | ![]() |
| Two-factor | ||
![]() |
| Login | Account security | Account menu | Customer portal |
|---|---|---|---|
![]() | ![]() | ![]() | ![]() |
Generated with SCREENSHOTS=1 pnpm exec playwright test screenshots
(e2e/fixtures/rich-mock.ts) — no backend required. Use THEME=dark / LANG_UI=de for variants.
| Area | Notes |
|---|---|
| Ticket write path + Znuny invariants | Golden-master multi-peer matrix (OTRS/Znuny 6.0–7.3) |
| GenericInterface compatibility | Session*, TicketCreate/Update/Get/Search/HistoryGet, TimeAccountingGet, OutOfOffice; REST + SOAP |
| MCP tools | ticket_*, customer lookup, KB — see docs/ai-integration.md |
| AI assistance subsystem | Draft replies, summaries, triage, refine (diff review, call notes), auto-reply worker, human handoff, per-ticket pause, 🤖 origin traces, attachment/vision, PII masking, model catalog/profiles/task routing, per-subject ACL, cost budgets & audit — /admin/ai/*, docs/ai-integration.md |
| Daemon takeover (mail, escalation, notify, GA) | Per-function flags, off by default |
| Calendar / appointments | Month/week/agenda UI; reuses Znuny calendar* tables |
| Process management (BPM) | Reuses Znuny pm_* tables — docs/process-management.md |
| PGP / S-MIME | Off by default (Znuny's PGP / SMIME switches). Shared Znuny key stores, admin pages with overview/keys/settings, inbound verify/decrypt, outbound sign/encrypt with per-queue defaults and per-sender sign keys, signed/encrypted notifications, customer keys, public S/MIME roots trusted out of the box — docs/crypto.md |
| Telegram, SMS, WhatsApp, phone/CTI | Telegram chat composer; phone tickets, call logging and CTI incoming-call popup — docs/channels.md |
| New-ticket helpers | Queue suggested from the customer's history, property bar, compact phone ticket with call strip |
| Integrations endpoint | Per-customer ticket history for external tools (/api/v1/integrations/customer-tickets) |
| SSE realtime + agent presence | Live updates on ticket zoom |
| CSV ticket export | Permission-filtered streaming export |
| TiqoraSync Znuny addon | Optional OPM for cache coherence during parallel op |
┌──────────────────────────────────────────┐
│ Clients │
│ Agent UI · Portal · Admin · AI agents │
└───────────┬──────────────┬────────────────┘
│ │
/api/v1 │ │ MCP (streamable HTTP)
/znuny-compat/* │ │
▼ ▼
┌────────────────┐ ┌─────────────┐
│ tiqora-api │ │ tiqora-mcp │
│ (FastAPI) │ │ (FastMCP) │
└───────┬────────┘ └──────┬──────┘
│ │
│ domain/* │
│ permissions/* │
▼ ▼
┌─────────────────────────────────────────────┐
│ Shared domain layer │
│ TicketService · ACL · sessions · outbox │
└───────────┬───────────────────┬─────────────┘
│ │
┌──────────────▼──────┐ ┌────────▼────────┐
│ OTRS/Znuny tables │ │ tiqora_* tables│
│ (6.0–7.3; R/W, no │ │ (Alembic chain │
│ schema changes) │ │ versions_tiqora)│
└──────────┬──────────┘ └────────┬────────┘
│ │
┌────────────▼──────────┐ │
│ Peer instance │ │
│ (optional parallel) │◄── cache invalidation via TiqoraSync OPM
└───────────────────────┘
│
┌────────────▼────────────────────────────────────┐
│ tiqora-worker · ai-worker · Redis · Meili │
└─────────────────────────────────────────────────┘
flowchart TB
subgraph clients [Clients]
AgentUI[Agent UI]
Portal[Customer Portal]
Admin[Admin]
AI[AI Agents via MCP]
end
subgraph tiqora [Tiqora]
API[tiqora-api FastAPI]
MCP[tiqora-mcp FastMCP]
Worker[tiqora-worker + ai-worker]
Domain[domain + permissions]
end
subgraph data [Shared data plane]
ZTables[(Znuny tables)]
TTables[(tiqora_* tables)]
Redis[(Redis)]
Meili[(Meilisearch)]
end
Znuny[OTRS/Znuny 6.0–7.3 peer]
AgentUI --> API
Portal --> API
Admin --> API
AI --> MCP
API --> Domain
MCP --> Domain
Domain --> ZTables
Domain --> TTables
Worker --> ZTables
Worker --> TTables
Worker --> Redis
Worker --> Meili
Znuny --> ZTables
Domain -.->|tiqora_cache_invalidation| Znuny
Package layout (backend):
backend/src/tiqora/
db/legacy/ # Hand-written models for Znuny tables + conformance tests
db/tiqora/ # tiqora_* models (Alembic: versions_tiqora / versions_owned)
znuny/ # Invariants: ticket numbers, history, escalation, follow-up, …
domain/ # Services — sole write paths, bundling invariants
permissions/ # Groups/roles + ACL for UI, REST, MCP
events/ # Async bus + transactional outbox
channels/ # Channel plugins (email, SMS, WhatsApp, Telegram, phone)
storage/ # StorageBackend interface (DB MIME in V1)
api/ # v1 routers + GenericInterface compat layer
mcp_server/ # FastMCP process
worker/ # asyncio worker loops (daemon takeover, outbox, pollers)
kb/ # Knowledge base
Tiqora and Znuny can share one PostgreSQL or MariaDB/MySQL database:
| Rule | Detail |
|---|---|
| No Znuny schema changes | Tiqora never alters Znuny tables until post-cutover ownership mode |
New tables only as tiqora_* | Alembic chain versions_tiqora/ |
| Behavioural parity | Ticket numbers, history formats, escalation columns, search flags must match Znuny |
| Daemon ownership | Znuny keeps mail/escalation/notifications/GenericAgent until feature flags hand each over |
| Cache coherence | Optional TiqoraSync Znuny OPM reads tiqora_cache_invalidation; or lower Znuny cache TTLs |
See docs/parallel-operation.md for the full invariant list.
| Path | When | Doc |
|---|---|---|
| Quickstart | Evaluate locally in two minutes, demo data included | docker-compose.quickstart.yml — see Try it |
| Fresh standalone | Empty database, no Znuny — greenfield install via tiqora bootstrap | docs/guide/fresh-install.md |
| Parallel to Znuny | Co-run with an existing OTRS/Znuny 6.0–7.3 database (additive tiqora_* only) | docs/support-matrix.md, docs/parallel-operation.md, docs/guide/znuny-to-tiqora.md |
| Migrate away | After parallel operation: schema ownership, cutover checklist | docs/cutover.md |
docker compose -f docker-compose.dev.yml up -d
# MariaDB :3306, Postgres :5432, Redis :6379, Meilisearch :7700, Mailpit :8025/:1025
cd backend
uv sync
export DATABASE_URL=postgresql+asyncpg://tiqora:tiqora@localhost:5432/tiqora
# or: mysql+aiomysql://tiqora:tiqora@localhost:3306/tiqora
export REDIS_URL=redis://localhost:6379/0
export MEILI_URL=http://localhost:7700
uv run uvicorn tiqora.api.app:create_app --factory --reload --host 0.0.0.0 --port 8000
Health checks:
curl -s http://localhost:8000/health
curl -s http://localhost:8000/ready
curl -s http://localhost:8000/metrics | head
cd frontend
pnpm install
pnpm dev
# http://localhost:5173 — agent, portal, and admin UI
Content type
Image
Digest
sha256:531944b25…
Size
234.1 MB
Last updated
3 days ago
docker pull cygnusnetworks/tiqora