Skip to main content
Glama

tela

The wiki that writes itself — from the code you already ship.

License: AGPL-3.0 GitHub stars Latest release Docker npm tela-mcp

tela is a self-hostable, markdown-native team wiki built for a world where agents are first-class authors and readers. It pairs a Go + PostgreSQL backend with a React 19 / Milkdown editor, live Yjs collaboration, ranked full-text and semantic search, and a built-in Model Context Protocol (MCP) server — so the same knowledge base your team edits in the browser is one your agents can search, read, and write directly. Atlas, its documentation engine, turns the artifacts you already produce into maintained wiki pages. Your content stays canonical markdown forever — pages.body is markdown, there is no proprietary block store.

Public instance: https://telawiki.com

Atlas demo

Why tela

  • Atlas auto-doc-gen — point Atlas at your sources and it drafts and maintains real wiki pages, so docs track what you ship instead of rotting.

  • Built-in MCP server/api/mcp is part of the backend, not a bolt-on. Claude, Cursor, and other agents search, read, and author pages with scoped, per-tool write permissions.

  • Semantic + full-text search — ranked PostgreSQL FTS works out of the box; add an embedder for pgvector-backed semantic retrieval and grounded "ask your docs" answers.

  • Live collaboration — real-time multi-cursor editing over Yjs in a Milkdown editor, with comments, backlinks, and revision history.

  • Self-host & own your markdownpages.body is canonical markdown forever (no block table). Sync over WebDAV, export to zip/PDF, and run the whole stack with one make up.

Related MCP server: basic-memory

Quickstart

You need Docker (with Compose) and make. The bundled stack builds every image via Compose, so no host Node or Go toolchain is required.

git clone https://github.com/zcag/tela.git
cd tela

# 1. Write deploy/.env from the example with strong generated secrets
#    (fills TELA_API_KEY_SECRET, TELA_SHARE_SECRET, TELA_PG_PASSWORD via openssl rand)
make setup

# 2. Edit deploy/.env — set TELA_PUBLIC_BASE_URL, and optionally
#    TELA_ADMIN_* and TELA_SMTP_* (see Configuration below)

# 3. Build and start the full stack
make up

The stack comes up behind Caddy on http://localhost:8780. On first boot tela runs its embedded migrations automatically and lands you on the /setup wizard to create the first admin — unless you set TELA_ADMIN_PASSWORD in deploy/.env, which bootstraps the admin non-interactively.

One-click cloud deploy

Prefer managed hosting over running Compose? Deploy the published multi-arch images straight to a platform:

Deploy to Render   Deploy to DigitalOcean

After the first deploy, enable pgvector on the managed database once — CREATE EXTENSION IF NOT EXISTS vector; — then point the backend's TELA_PUBLIC_BASE_URL at your app's public URL. Or skip ops entirely with the free cloud tier.

Common targets:

make up         # build + start the stack on :8780 (auto-stamps git version/commit)
make down       # stop the stack
make logs       # tail logs from all services
make backup     # dump Postgres to ./backups/tela-<timestamp>.sql
make restore FILE=backups/tela-....sql
make clean FORCE=1   # stop and DELETE all volumes (destroys data)

make up is the same thing as running Compose directly — under the hood it's docker compose -f deploy/docker-compose.yml up -d --build (plus a forced proxy recreate so a changed Caddyfile re-mounts). The three load-bearing secrets must be set and stable across deploys: rotating TELA_SHARE_SECRET invalidates outstanding share cookies, and rotating TELA_API_KEY_SECRET invalidates every existing personal access token (PAT).

For full setup, TLS, backups, and upgrades see docs/self-hosting.md and the operations runbook docs/operations.md.

Local development

make dev        # backend (:8080) + frontend (:5173, proxies /api → :8080); boots a local dev Postgres
make be-dev     # backend only (go run; boots the dev Postgres on :55433)
make fe-dev     # frontend only (vite)
make test       # backend tests against a throwaway Postgres
make storybook  # component dev surface

If :8080 is taken on your box, run make dev DEV_BE_PORT=18080 so the backend and the vite /api proxy stay consistent.

Optional: semantic search out of the box

The bundled Compose stack ships an optional Ollama embedder behind a profile. Full-text search always works; this only lights up the semantic half:

docker compose -f deploy/docker-compose.yml --profile embed up -d
docker compose -f deploy/docker-compose.yml exec ollama ollama pull qwen3-embedding:0.6b
# then set TELA_RAG_EMBED_URL=http://ollama:11434 in deploy/.env and restart

Configuration

All configuration is environment-driven via deploy/.env (copy from deploy/.env.example). In the bundled Compose stack TELA_DATABASE_URL is auto-constructed from the TELA_PG_* vars — you only set it explicitly when running the backend against an external Postgres.

Required

Variable

Description

TELA_PUBLIC_BASE_URL

Public origin of the instance (e.g. https://wiki.example.com). Used in emails, share links, and OAuth audiences.

TELA_SHARE_SECRET

Secret signing share-link password cookies. Generate with openssl rand -hex 32; never rotate (invalidates outstanding share cookies).

TELA_API_KEY_SECRET

Secret signing personal access tokens (PATs). Generate with openssl rand -hex 32; never rotate (invalidates every existing PAT).

TELA_PG_PASSWORD

Password for the bundled Postgres. No default — must be set.

Postgres

Variable

Description

TELA_PG_USER

Postgres role for the bundled DB. Default tela.

TELA_PG_DB

Postgres database name. Default tela.

TELA_DATABASE_URL

Full DSN — only set when running outside the bundled stack (external/managed Postgres). Format postgres://USER:PASS@HOST:5432/DB?sslmode=disable.

Bootstrap admin (optional)

Variable

Description

TELA_ADMIN_USERNAME

Bootstrap admin username (first boot only).

TELA_ADMIN_PASSWORD

Bootstrap admin password. Unset → use the /setup web wizard instead.

TELA_ADMIN_EMAIL

Optional; pre-confirms the admin's email so it's exempt from the confirmation gate. Setting it later backfills the existing admin.

Email (transactional + notifications)

With TELA_SMTP_HOST unset, tela logs confirmation/reset/notification links to stdout instead of sending (fine for dev / first boot). Works with any SMTP relay.

Variable

Description

TELA_SMTP_HOST

SMTP relay host (e.g. smtp.resend.com).

TELA_SMTP_PORT

587 starttls (default) or 465 ssl.

TELA_SMTP_TLS

starttls | ssl | none.

TELA_SMTP_USERNAME

SMTP username.

TELA_SMTP_PASSWORD

SMTP password or API key.

TELA_SMTP_FROM

From identity, e.g. tela <tela@example.com>.

Custom domains & TLS (optional)

Variable

Description

TELA_SITE_ADDRESS

Canonical host Caddy binds for direct-TLS mode (e.g. telawiki.com). Empty → :80 (terminator/CF mode), which disables org custom domains.

TELA_CUSTOM_DOMAIN_TARGET

Shared CNAME target shown to org admins adding a hostname. Defaults to the canonical host.

AI: semantic retrieval, ask-your-docs, Atlas (all optional, ship dark)

These features ship dark — unset means the relevant endpoints return 503 and nothing is computed. Point them at your own Ollama / OpenAI-compatible endpoints, the bundled --profile embed Ollama, or tela cloud's managed endpoints (authenticated with a telawiki.com PAT).

Variable

Description

TELA_RAG_EMBED_URL

Embedder endpoint for semantic chunk search (e.g. http://ollama:11434). Unset → /api/rag/* 503.

TELA_RAG_EMBED_MODEL

Embedding model. Must be 1024-d; default qwen3-embedding:0.6b.

TELA_RAG_EMBED_DIM

Advisory embedding dimension (the column is fixed at vector(1024)).

TELA_RAG_EMBED_TOKEN

Bearer token for a managed/authenticated embed endpoint.

TELA_RAG_QUERY_INSTRUCT

Query-side instruction prefix for asymmetric retrieval. Unset → sensible default.

TELA_RAG_RERANK_URL

Optional cross-encoder reranker /rerank endpoint (Cohere/Jina/TEI-compatible).

TELA_RAG_RERANK_MODEL / TELA_RAG_RERANK_TOKEN

Reranker model name and token.

TELA_RAG_LOG_ASKS

Log "ask your docs" questions to surface knowledge gaps (admin-only). 0 disables.

TELA_LLM_URL

OpenAI-compatible chat base including /v1 for grounded answers (/api/rag/ask). Unset → 503.

TELA_LLM_MODEL

Chat model name (e.g. qwen2.5:7b).

TELA_LLM_TOKEN

Bearer token for a managed/authenticated LLM endpoint.

TELA_LLM_MAX_TOKENS

Completion length cap. Default 1024; 0/-1 disables the cap.

TELA_AGREEMENT

Epistemic trust pass (corroborate/contradict scoring). On when LLM+embedder are set; 0 disables.

TELA_ATLAS_MAX_CONCURRENT_RUNS

Cap on concurrent Atlas doc-gen runs. Default 1.

ATLAS_LLM_CONCURRENCY

Per-run client concurrency gate. Default 6.

TELA_ATLAS_WORKDIR

Where Atlas unpacks working files. Default: OS temp dir.

TELA_IMAGE_GEN_URL / TELA_IMAGE_GEN_MODEL / TELA_IMAGE_GEN_KEY

OpenAI-compatible Images endpoint for the MCP generate_deck_image tool. Unset → 503.

Auth: MCP OAuth & federated sign-in (optional)

Variable

Description

TELA_WORKOS_ISSUER

WorkOS AuthKit issuer to enable Claude.ai/ChatGPT "Connect" OAuth on /api/mcp. Unset → MCP stays PAT-only.

TELA_MCP_RESOURCE

The MCP endpoint's public URL (OAuth audience). Defaults to {TELA_PUBLIC_BASE_URL}/api/mcp.

WORKOS_API_KEY

Server-side WorkOS secret for the Standalone login bridge.

TELA_SSO_GOOGLE_CLIENT_ID / _SECRET

Google OIDC sign-in. Dark until both are set.

TELA_SSO_MICROSOFT_CLIENT_ID / _SECRET

Microsoft OIDC sign-in. Dark until both are set.

TELA_SSO_GITHUB_CLIENT_ID / _SECRET

GitHub OAuth2 sign-in. Dark until both are set.

Billing (optional, ships dark)

Variable

Description

TELA_POLAR_TOKEN

Polar organization access token. Unset → checkout/portal 503; plans stay operator-assigned.

TELA_POLAR_WEBHOOK_SECRET

Polar webhook signing secret (verbatim).

TELA_POLAR_BASE_URL

https://api.polar.sh or https://sandbox-api.polar.sh.

TELA_POLAR_PRODUCTS

Maps plan keys to Polar product UUIDs, e.g. personal_plus:<uuid>,org_team:<uuid>.

Services, sync & ops (optional)

Variable

Description

TELA_GOTENBERG_URL

PDF render engine. Default http://gotenberg:3000.

TELA_PDF_RENDER_BASE_URL

Internal origin Gotenberg's Chromium loads the reader from. Default http://proxy.

TELA_DECK_URL

Slidev deck render sidecar. Default http://deck:3344.

TELA_WEBDAV_ENABLED

WebDAV sync surface (/dav/). Default on; 0/false disables.

TELA_WEBDAV_CREATE_SPACES

Allow root-level MKCOL to mint spaces. Default on (any write-scoped PAT can create spaces via WebDAV).

TELA_WEBDAV_DELETE_FLOOR / TELA_WEBDAV_DELETE_FRACTION

Mass-delete guard tuning.

TELA_WEBDAV_FILE_MAX_BYTES

Per-file upload cap for space files.

TELA_ADDR

Backend listen address. Default :8080.

TELA_LOG_FORMAT

json for structured logs. Default text.

TELA_API_KEY_AUDIT_DAYS

PAT audit-log retention in days.

TELA_EVENTS_RETENTION_DAYS

Activity-feed GC window. Default 180.

TELA_DISABLE_WELCOME_SEED

Any value skips seeding the welcome space on first boot.

TELA_VERSION / TELA_COMMIT

Build metadata surfaced by GET /api/version (auto-stamped by make).

The split/deploy topology adds image-ref and Umami-analytics vars (TELA_BACKEND_IMAGE, TELA_FRONTEND_IMAGE, UMAMI_APP_SECRET, UMAMI_DB_PASSWORD, …). See deploy/.env.example and docs/deploy.md.

Connect your agents (MCP)

tela's MCP server is built into the backend at /api/mcp — it self-authenticates with a personal access token (PAT) as a bearer header. Modern hosts speak HTTP transport directly:

https://telawiki.com/api/mcp            # tela cloud
https://your-host.example.com/api/mcp   # your self-hosted origin

For hosts that can't speak HTTP transport (or want a stdio bridge), the tela-mcp npm package is a thin stdio↔HTTP proxy to the same endpoint — no second tool implementation to drift. Add it to your MCP client config (e.g. Claude Desktop / Cursor):

{
  "mcpServers": {
    "tela": {
      "command": "npx",
      "args": ["-y", "tela-mcp"],
      "env": {
        "TELA_BASE_URL": "https://telawiki.com",
        "TELA_API_KEY": "tela_pat_xxxxxxxx"
      }
    }
  }
}

Point TELA_BASE_URL at your own origin to use a self-hosted instance. Generate a PAT in Settings → API tokens; per-tool write permission is enforced server-side. The proxy requires Node ≥ 20. See mcp/README.md for the full tool catalog and troubleshooting.

One-click install

Add to Cursor Add to VS Code

Both buttons add the HTTP endpoint; auth is handled by OAuth on first use, so no token goes in the link.

Per-client setup

HTTP-transport hosts connect to the endpoint directly and sign in via OAuth. stdio-only hosts use the tela-mcp proxy with a PAT (TELA_BASE_URL + TELA_API_KEY).

Claude Code (CLI, HTTP):

claude mcp add --transport http tela https://telawiki.com/api/mcp

Cursor (HTTP) — use the button above, or add to ~/.cursor/mcp.json:

{ "mcpServers": { "tela": { "url": "https://telawiki.com/api/mcp" } } }

VS Code (HTTP) — use the button above, or:

code --add-mcp '{"name":"tela","type":"http","url":"https://telawiki.com/api/mcp"}'

ChatGPT / Claude.ai (OAuth connector) — add a custom connector and paste the URL; complete the sign-in:

https://telawiki.com/api/mcp

Claude Desktop (stdio proxy) — claude_desktop_config.json:

{
  "mcpServers": {
    "tela": {
      "command": "npx",
      "args": ["-y", "tela-mcp"],
      "env": { "TELA_BASE_URL": "https://telawiki.com", "TELA_API_KEY": "tela_pat_xxxxxxxx" }
    }
  }
}

Windsurf (stdio proxy) — ~/.codeium/windsurf/mcp_config.json, same mcpServers shape as Claude Desktop above.

Codex (stdio proxy) — ~/.codex/config.toml:

[mcp_servers.tela]
command = "npx"
args = ["-y", "tela-mcp"]
env = { TELA_BASE_URL = "https://telawiki.com", TELA_API_KEY = "tela_pat_xxxxxxxx" }

A machine-discovery manifest is published at /.well-known/mcp.json.

Screenshots

Architecture

  • Backend — Go (module github.com/zcag/tela/backend, entry cmd/tela). Hand-written database/sql over the pgx/v5 stdlib driver — no ORM, no sqlc. Embedded, forward-only SQL migrations run automatically on boot.

  • Database — PostgreSQL 17 with the pgvector extension (pgvector/pgvector:pg17). FTS lives in pages.search_tsv (ranked ts_rank_cd); semantic chunks live in page_chunks.embedding vector(1024).

  • Frontend — React 19 + Vite + TypeScript + Tailwind v4 + Radix + a Milkdown (@milkdown/kit) editor, with TanStack Query/Router, Orama, cmdk, and Storybook. Owned, token-driven UI components only.

  • Live collaboration — Yjs + y-prosemirror over a custom WebSocket transport, scoped tightly to src/lib/collab/* and the collab branch of the editor; it rebases onto the canonical markdown on save.

  • Built-in MCP — the tool/resource surface lives in the Go backend (internal/api/mcp*.go) and calls the same core functions the REST routes do, so there is one implementation. mcp/ is a dumb stdio↔HTTP pipe published as tela-mcp on npm.

  • Atlas — the documentation engine that drafts and maintains wiki pages from your sources, sharing the configured LLM endpoint.

  • Render sidecars — Gotenberg for HTML→PDF export; a Slidev deck sidecar for presentation pages.

  • Edge — Caddy serves the SPA, the API, the marketing landing at the apex, and (in direct-TLS mode) on-demand certificates for org custom domains.

Deeper internals, ops, and gotchas live in docs/ — start with docs/architecture.md, and docs/decisions.md for the rationale (PostgreSQL, custom collab transport, MCP-as-thin-client).

Self-host vs cloud

  • Self-host — run the whole stack with make up (or docker compose). You own the data, the markdown, and the Postgres volume; AI features are bring-your-own-endpoint (or the bundled Ollama profile). The split/registry deploy topology for shared-edge boxes is in docs/deploy.md.

  • Cloud — a managed instance is hosted at telawiki.com with a free tier, plus optional managed semantic search and ask-your-docs so you don't have to run an embedder or LLM yourself.

Both run the same code from this repository.

Contributing

  • Commit format: type(scope): summary (e.g. feat(backend): hybrid chunk search). Concise messages, no co-author trailer.

  • No issue/task tracker — please don't open GitHub issues or reference #NNN. Discuss via pull requests.

  • Backend changes use hand-written SQL and a new forward-only NNNN_name.sql migration (never edit an applied one). Frontend changes use owned Radix/token-based primitives — no hardcoded hex/px, no third-party component kits.

  • Run make test (backend) and npm run build in frontend/ before sending a change. See CLAUDE.md and docs/ for the full conventions.

Security

Please report security issues privately to tela@telawiki.com. Do not open a public issue or PR for a vulnerability. Note that a missing or rotated TELA_API_KEY_SECRET / TELA_SHARE_SECRET leads to forgeable tokens — keep them set and stable.

License

tela is open core. Copyright © tela contributors. The Community core — the whole product — is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0): self-host, modify, and redistribute under its terms (run a modified version as a network service and you must offer your users the corresponding source). The tela-mcp npm package is published under AGPL-3.0-only. For a commercial license without AGPL obligations (e.g. to embed or offer tela as a closed service), contact the maintainer.

The Enterprise Edition (backend/internal/ee/, source-available, not AGPL) adds the company-of-record layer (SSO, audit, SCIM, governance) and requires a license key for production use — see backend/internal/ee/LICENSE.md. Full structure in docs/licensing.md.

"tela", the tela name, and the tela logo are trademarks and are not licensed under the AGPL — see TRADEMARK.md. You may run and fork the code, but you may not use the tela branding for a redistributed or hosted version without permission.

Install Server
A
license - permissive license
A
quality
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity
Issues opened vs closed

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/zcag/tela'

If you have feedback or need assistance with the MCP directory API, please join our Discord server