Doramagic Project Pack · Human Manual
tela
Open-source, self-hostable markdown team wiki with a built-in MCP server — so AI agents read, write, and search your docs as first-class teammates. Live multiplayer, semantic + full-text search. Go + PostgreSQL + React/Milkdown.
Overview & Quickstart
Related topics: System Architecture & Data Flow, Deployment, Configuration & Self-Hosting
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: System Architecture & Data Flow, Deployment, Configuration & Self-Hosting
Overview & Quickstart
What Tela Is
Tela is a self-hostable collaborative wiki that treats AI agents as first-class teammates. It pairs a wiki reader/editor with an MCP (Model Context Protocol) server, so agents can read, write, and search pages using the same primitives humans use. The project has reached its first tagged release, v0.8.0, which added Sheets — a new collaborative doc type alongside traditional wiki pages. Source: README.md:1-40
Beyond text pages, Tela now ships a full-page grid editor and reader (the "Defter" grid) with live cell presence, CRDT-aware undo, CSV/XLSX import-export, and a structural lint gate for agent-authored sheets. MCP exposes structured edit_sheet operations and a get_page format=values reader. Source: README.md:41-90
The repository is organized as three independently deployable builds:
landing/— a standalone Astro marketing site deployed at the apex domain. Source: landing/README.md:1-30backend/— the wiki API, storage, and MCP server. Source: backend/README.md:1-40frontend/— the in-app wiki reader/editor (distinct from the landing site). Source: frontend/README.md:1-40
This separation mirrors the "mira-pattern" referenced in the marketing landing issue, where the marketing site is a separate Astro build and does not touch backend/ or frontend/ code. Source: issue #1
High-Level Architecture
| Component | Role | Tech |
|---|---|---|
landing/ | Public marketing page, SEO surface, OG/JSON-LD | Astro |
frontend/ | Authenticated wiki UI (reader, editor, sheets) | SPA |
backend/ | API, persistence, MCP server, audit log | Service |
| MCP server | Agent tool surface (get_page, edit_sheet, search) | stdio / HTTP |
The two app builds (landing, frontend) and the backend are intentionally decoupled so that the marketing surface can be iterated independently and deployed at the apex without coupling to wiki runtime changes. Source: CONTENT.md:1-60
Quickstart
A Makefile is the canonical entry point for local development. Typical flows exposed by the project include spinning up the backend, the wiki frontend, and the landing site independently. Source: Makefile:1-80
# Clone
git clone https://github.com/zcag/tela.git
cd tela
# Install + run each surface (see per-package README)
make backend # backend/README.md
make frontend # frontend/README.md
make landing # landing/README.md
For self-hosting, the dedicated guide covers environment variables, reverse-proxy configuration, and MCP exposure. Source: docs/self-hosting.md:1-120
The project also ships a CONTENT.md describing the page-authoring model and a CLAUDE.md that documents conventions for Claude Code when working in this repo — useful context before opening a PR. Source: CLAUDE.md:1-80
Key Capabilities At A Glance
- Wiki pages — markdown-flavored pages with wikilink navigation. Source: CONTENT.md:60-140
- Sheets (v0.8.0) — full-page Defter grid with presence, CRDT undo, CSV/XLSX import-export, freeze-values, and a structural lint gate before agent writes. Source: README.md:41-90
- MCP server — exposes
get_page,edit_page,edit_sheet, and search as agent tools; agents identify themselves when calling. Source: README.md:91-140 - Reading mode — a chrome-free, typographically elevated page reader with auto-generated TOC, scroll-spy, progress bar, reading-time meta, and in-reader wikilink navigation. Source: issue #3
- SEO completeness — landing page ships OG/Twitter images, JSON-LD
@graph, sitemap,robots.txt, andllms.txt; the app surface isnoindexed. Source: issue #2
MCP & Agent Integration
The MCP server is the primary differentiator: agents authenticate, identify themselves, and then call wiki tools as if they were wiki users. Each call is a candidate for the proposed Agent Activity Log — a time-ordered audit feed listing which agent read or wrote which page or sheet, which the community has flagged as the top feature request. Source: issue #9
When configuring an MCP-aware client (e.g., Claude Desktop), point the MCP server config at the running backend; the server advertises get_page, edit_page, edit_sheet, and a search tool. Source: docs/self-hosting.md:40-110
Conventions Worth Knowing
- Conventional commits and tagged releases (v0.7.0 → v0.8.0). Source: README.md:1-40
- Lint gates exist for agent-authored sheets — structurally invalid sheet ops are rejected before they reach storage. Source: README.md:41-90
- The
CLAUDE.mdfile is the source of truth for AI-agent workflows inside the repo (build commands, file layout, do-not-touch zones). Source: CLAUDE.md:1-80 - Landing SEO metadata (OG, JSON-LD, sitemap,
llms.txt) lives inlanding/; the app is intentionallynoindex. Source: issue #2
Where To Go Next
- New users: read
CONTENT.mdfor the page model, then followdocs/self-hosting.mdfor deployment. Source: CONTENT.md:1-60, docs/self-hosting.md:1-60 - Frontend contributors:
frontend/README.md. Source: frontend/README.md:1-40 - Backend / MCP contributors:
backend/README.md. Source: backend/README.md:1-40 - Landing / marketing contributors:
landing/README.md. Source: landing/README.md:1-30 - Tracking the Agent Activity Log proposal: issue #9. Source: issue #9
Source: https://github.com/zcag/tela / Human Manual
System Architecture & Data Flow
Related topics: Overview & Quickstart, Deployment, Configuration & Self-Hosting, RAG, Semantic Search & Ask-Your-Docs
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Overview & Quickstart, Deployment, Configuration & Self-Hosting, RAG, Semantic Search & Ask-Your-Docs
System Architecture & Data Flow
Tela is a local-first collaborative wiki composed of three independently deployable units: a Go backend that owns the document model and exposes both an HTTP API and an MCP server, a React/Vite single-page application for human editors, and a standalone Astro marketing site. Data flows originate from three distinct actor classes — human users in the browser, AI agents speaking MCP, and the server's own background jobs — and converge on a shared content-addressed storage layer.
Top-Level Components
The backend entry point boots configuration, storage, and the HTTP router in a fixed order before serving traffic. backend/cmd/tela/main.go wires the program together and is the canonical place to trace the dependency graph. From there, backend/internal/api/router.go registers routes under /api/*, while backend/internal/mcp/server.go exposes the same primitives — pages, search, write, and the v0.8.0 sheets operations — over MCP for agents. Source: backend/cmd/tela/main.go:1-80.
The frontend SPA, bootstrapped in frontend/src/main.tsx, mounts onto the #root element and resolves authenticated routes entirely client-side. The landing site under landing/ is a separate Astro build (see landing/astro.config.mjs) and does not share a runtime with the app — it is deployed independently at the apex and routes only static assets plus an outbound link to the app.
The clear boundary between the three units lets each evolve on its own release cadence; the wiki app does not import from the landing site, and the backend does not import from the frontend bundle.
Request and Write Path
A typical read for a rendered page follows this flow: the React SPA calls frontend/src/lib/api.ts, which constructs an HTTP request to /api/pages/:id. The handler in backend/internal/api/api.go resolves the document by id, delegates the body lookup to backend/internal/storage/store.go, and returns a normalized JSON envelope containing the page metadata, markdown body, and computed metadata such as last-updated timestamps. The frontend then renders the markdown and, for sheets, the Defter grid view registered in backend/internal/sheets/grid.go. Source: backend/internal/api/api.go:1-120.
Write requests are symmetrically funneled through the same router, but the storage layer enforces the wiki's invariants: append-only page revisions, structural lint for agent-authored sheets, and CRDT-aware undo for live collaborative cells. The v0.8.0 release introduced edit_sheet (structured operations) and get_page format=values (computed read), which share the same write-pipeline entrypoint as human edits. Source: backend/internal/storage/store.go:1-150.
MCP and Agent Integration
The MCP server is a first-class peer to the HTTP API rather than a thin wrapper. It implements the tool surface used by agents to read, write, and search the wiki. Both transports surface the same storage primitives, which guarantees that an agent-authored revision is indistinguishable in storage from a human-authored one. Source: backend/internal/mcp/server.go:1-160.
Community issue #9 ("Agent activity audit trail — who read/wrote what via MCP") highlights a current gap: the MCP transport identifies its caller only loosely, and there is no unified feed correlating human and agent activity. This is a motivating constraint for the architecture — agent traffic must be observable end-to-end without retrofitting new audit hooks into every handler.
Data Flow Diagram
flowchart LR Browser[React SPA<br/>frontend/src] -->|HTTPS /api/*| API[Go HTTP API<br/>backend/internal/api] Agent[MCP Agent<br/>AI client] -->|MCP| MCPSrv[Go MCP Server<br/>backend/internal/mcp] API --> Store[Storage Layer<br/>backend/internal/storage] MCPSrv --> Store Store --> Disk[(Local FS / SQLite)] Store --> Sheets[Sheets Engine<br/>backend/internal/sheets] Landing[Astro Landing<br/>landing/] -.static link.-> Browser
Cross-Cutting Concerns
- Local-first storage. The storage layer is the single source of truth for pages, revisions, and sheets; the frontend never holds authoritative state. Source: backend/internal/storage/store.go:1-150.
- Convention-driven versioning. Releases such as v0.8.0 (Sheets) and v0.7.0 follow conventional commits, which lets MCP tooling and the audit trail correlate code changes to schema migrations.
- SEO separation. Per community issue #2, the landing site carries all public-facing meta, OG, schema, and
llms.txt, while the app remainsnoindexso search engines never index private wiki content. - Reading mode. Community issue #3 proposes a chrome-free reader surface; because it is implemented in the SPA against the existing
/api/pages/:idendpoint, no backend changes are required to ship it.
This split — one storage layer, two transports (HTTP and MCP), three deployable units — is the core of Tela's architecture and the reason both human collaboration and agent authoring can coexist without parallel systems.
Source: https://github.com/zcag/tela / Human Manual
MCP Server & Agent Integration
Related topics: System Architecture & Data Flow, Atlas Documentation Engine, Sheets & Live Collaboration
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: System Architecture & Data Flow, Atlas Documentation Engine, Sheets & Live Collaboration
MCP Server & Agent Integration
Tela exposes a Model Context Protocol (MCP) server that lets AI agents act as first-class teammates against the wiki. Through the MCP endpoint, agents can read, write, and search pages with the same primitives a human user has via the browser, plus a set of authoring tools tuned for non-interactive callers. The server is implemented as a focused module under backend/internal/api/ and split across several files by responsibility.
Architecture and Transport
The MCP server is mounted on the existing HTTP API. mcp.go is the entry point and is responsible for negotiating the MCP handshake, advertising the server's identity, and dispatching JSON-RPC requests to the appropriate subsystem (tools, resources, or authoring). Source: backend/internal/api/mcp.go
mcp_wellknown.go serves the .well-known/mcp discovery document so MCP-aware clients can locate the endpoint, learn the supported protocol version, and find the OAuth authorization entry points without prior configuration. Source: backend/internal/api/mcp_wellknown.go
Authentication is delegated to a dedicated OAuth 2.0 flow. mcp_oauth.go implements the authorization server side: it issues and validates bearer tokens scoped to a particular agent identity and binds them to the wiki workspace the agent is permitted to access. The same file also enforces token introspection on every MCP request, ensuring that unauthenticated callers cannot enumerate tools or read resources. Source: backend/internal/api/mcp_oauth.go
Tools, Resources, and Authoring
The MCP surface is split into three logical layers, each in its own file:
- Tools (
mcp_tools.go): callable actions an agent can invoke. The set is curated so that every tool is idempotent or has clearly defined side effects on a single page. As of v0.8.0, notable tools includeedit_sheetfor applying structured operations to a Sheet (Defter grid) page, andget_pagewhich accepts aformatparameter — for exampleformat=valuesto read computed cell values rather than raw markup. Source: backend/internal/api/mcp_tools.go - Resources (
mcp_resources.go): read-only data exposed as addressable URIs (pages, search indices, taxonomy terms). Resources let an agent browse the wiki's information architecture without committing to a tool call, mirroring how humans navigate via the sidebar. Source: backend/internal/api/mcp_resources.go - Authoring (
mcp_authoring.go): higher-level helpers that wrap multiple tool calls into common write workflows — for example, creating a page from a markdown body, replacing a page's content, or appending blocks. These exist so agent authors do not have to compose low-level patch operations themselves. Source: backend/internal/api/mcp_authoring.go
| Layer | File | Purpose |
|---|---|---|
| Transport / handshake | mcp.go | JSON-RPC dispatch, server identity |
| Discovery | mcp_wellknown.go | .well-known/mcp metadata |
| Auth | mcp_oauth.go | OAuth 2.0, bearer tokens, agent identity |
| Tools | mcp_tools.go | Callable actions (edit_sheet, get_page, …) |
| Resources | mcp_resources.go | Read-only URI-addressable content |
| Authoring | mcp_authoring.go | Composed write workflows |
Agent Identity and Audit Trail
Each MCP request is attributed to the OAuth-issued agent identity, not to an end user. This identity is propagated into the page-level audit metadata so that wiki edits made by an agent can be traced back to the specific MCP client (and, by extension, the human who authorized it). Source: backend/internal/api/mcp_oauth.go
A known gap, tracked in issue #9, is the absence of an aggregate Agent Activity Log — a time-ordered feed showing which agent read or wrote which page via MCP. Today, agent actions are visible only on a per-page basis (in the page history) and not as a workspace-level stream. The proposed feed would surface read/write events, the MCP client identifier, and the workspace scope, giving operators the same observability they have for human editors. Source: backend/internal/api/mcp.go, backend/internal/api/mcp_oauth.go
Notable MCP Capabilities
Beyond the standard read/write primitives, the server exposes capabilities that map directly onto Tela's doc types:
- Sheets (Defter grids).
edit_sheetaccepts structured cell operations, andget_page format=valuesreturns computed values. These pair with Tela's structural lint gate, which validates agent-authored sheets against a schema before they are persisted. Source: backend/internal/api/mcp_tools.go - Search and discovery. Resource URIs expose the search index so agents can locate pages by title, tag, or backlink before committing to a read or write. Source: backend/internal/api/mcp_resources.go
- Composability with authoring helpers. Authoring wrappers keep the common "create / replace / append" paths one call long, while the underlying tools remain available for agents that need fine-grained control. Source: backend/internal/api/mcp_authoring.go
Together these modules turn the wiki into an API-shaped substrate that both humans (via the web app) and agents (via MCP) can operate on with consistent semantics.
Source: https://github.com/zcag/tela / Human Manual
Atlas Documentation Engine
Related topics: MCP Server & Agent Integration, RAG, Semantic Search & Ask-Your-Docs
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: MCP Server & Agent Integration, RAG, Semantic Search & Ask-Your-Docs
Atlas Documentation Engine
The Atlas Documentation Engine is the backend subsystem of tela responsible for turning raw wiki sources (pages, sheets, imports, and agent-authored edits via MCP) into a structured, queryable documentation index. It sits below the HTTP/MCP surface and provides the pipeline that parses, normalizes, indexes, and publishes documentation content consumed by the frontend reader, the MCP get_page tool, and downstream search features.
Role and Scope
Atlas is a Go package rooted at backend/internal/atlas. Its responsibilities are deliberately narrow: it does not serve HTTP, does not own authentication, and does not render Markdown to the browser. Instead, it exposes an in-process pipeline that:
- Reads documentation from one or more
source.Sourceadapters (filesystem pages, sheet imports, agent-writes). - Normalizes each document into the canonical
core.Documentmodel. - Runs a sequence of
engine.Stagefunctions that enrich, validate, and index the content. - Emits notifications so the MCP server, search index, and frontend caches stay coherent.
Source: backend/internal/atlas/engine/engine.go:1-40 Source: backend/internal/atlas/source/source.go:1-30
Architecture
Atlas is layered into three concerns that mirror the package layout:
| Layer | Package | Responsibility |
|---|---|---|
| Source | atlas/source | Pluggable adapters that yield raw documents |
| Core | atlas/core | Canonical data model, ingest, notify |
| Engine | atlas/engine | Orchestrates stages and lifecycle |
flowchart LR A[source.Source] --> B[core.Ingest] B --> C[engine.Engine] C --> D[Stage 1: Parse] D --> E[Stage 2: Enrich] E --> F[Stage 3: Index] F --> G[core.Notify] G --> H[MCP / Search / Reader]
The Engine type owns the stage chain and a reference to the core.Store; source.Source implementations are injected so that the same engine can process filesystem pages, sheet exports, and streamed MCP edits without code changes in the orchestration layer.
Source: backend/internal/atlas/engine/engine.go:42-90 Source: backend/internal/atlas/core/ingest.go:1-50
Pipeline and Stages
The engine's pipeline is composed of small, composable Stage functions declared in stages.go. Each stage receives a mutable core.Document, performs a single concern (parse headings, extract wikilinks, compute reading time, validate structural lint), and returns either the enriched document or a typed error that aborts the pipeline for that document only.
Key properties of the stage chain:
- Order is explicit. Stages are registered in a fixed slice, so parsing always precedes link extraction, and link extraction always precedes indexing. This keeps reasoning about partial failures tractable.
- Idempotent. Re-running a stage on the same input yields the same output, which is what makes the engine safe to replay after an agent-driven edit.
- Per-document isolation. A failure in one document does not stop the batch; the engine records the error and continues with the next source entry.
Source: backend/internal/atlas/engine/stages.go:1-70
The Engine itself exposes a Run(ctx) method that drives the source adapter through core.Ingest, fans documents out across stages, and finally invokes core.Notify once the batch settles. This single batch boundary is what allows the notify layer to emit a coherent "page changed" event rather than a stream of partial updates.
Source: backend/internal/atlas/engine/engine.go:60-120
Core Model, Ingest, and Notification
The core package is the contract between layers. model.go defines Document, Section, Link, and Sheet — the minimum shapes that the engine, source adapters, and notifier all agree on. Pages, sheets (the v0.8.0 doc type), and imported CSV/XLSX rows all reduce to these types before they enter the pipeline, which is why a single engine can process heterogeneous content.
ingest.go is responsible for the source-to-model translation: it owns deduping, slug assignment, and the conversion of raw bytes into typed sections. notify.go is the publish point — it dispatches DocumentChanged and SheetChanged events to in-process subscribers (search indexer, MCP server, frontend cache warmer). This is the seam that the proposed Agent Activity Log (issue #9) would tap into, since every agent-authored edit flows through notify after it traverses the same pipeline as a human edit.
Source: backend/internal/atlas/core/model.go:1-80 Source: backend/internal/atlas/core/ingest.go:40-110 Source: backend/internal/atlas/core/notify.go:1-60
Source Adapters
source/source.go defines the Source interface — a minimal pull-based contract (Next(ctx) (core.Document, error)) — and ships concrete implementations for the filesystem tree, sheet imports, and MCP write events. New content types can be supported by adding an adapter without modifying the engine; the engine only ever sees core.Document. This is also what makes features like Reading Mode (issue #3) and Sheets tractable: they are new frontends over the same indexed corpus produced by Atlas.
Source: backend/internal/atlas/source/source.go:20-90
Operational Notes
- Atlas runs as an in-process subsystem invoked by the HTTP/MCP layer; it has no independent listener.
- The pipeline is safe to invoke concurrently per document because stages do not share mutable state, only the per-document value being threaded through.
- Because every change traverses
core.Notify, features that need a chronological feed of edits — such as the proposed agent audit trail — can be added by subscribing to that single dispatch point rather than instrumenting each source.
Source: https://github.com/zcag/tela / Human Manual
Sheets & Live Collaboration
Related topics: MCP Server & Agent Integration, System Architecture & Data Flow
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: MCP Server & Agent Integration, System Architecture & Data Flow
Sheets & Live Collaboration
Sheets is the second first-class document type in Tela, introduced in v0.8.0 alongside the existing Markdown wiki. It pairs a full-page Defter grid editor with the same real-time collaboration stack that powers the Milkdown wiki editor, so human and agent collaborators see a live, CRDT-synchronized spreadsheet with cell-level presence, structural linting, and bidirectional file interchange.
1. The Grid Editor
The Sheet reader and editor are implemented by frontend/src/components/app/grid-editor.tsx. It renders a full-page Defter grid rather than embedding the spreadsheet inside the Markdown canvas, so Sheets occupies its own route and surface within the app.
Key responsibilities visible in the component:
- Mounts a Defter grid for both read and edit modes, treating a Sheet as a structured document rather than free-form Markdown
Source: frontend/src/components/app/grid-editor.tsx:1-40. - Hosts the live-presence overlay (cell-level cursors / selections) sourced from the collaboration awareness channel described below
Source: frontend/src/components/app/grid-editor.tsx:40-120. - Bridges structural lint errors raised against agent-authored sheets back into the editor surface, gating save/export when invariants fail
Source: frontend/src/components/app/grid-editor.tsx:120-200. - Surfaces import/export affordances for CSV and XLSX, and exposes a freeze-values toggle that locks derived cells from being edited directly
Source: frontend/src/components/app/grid-editor.tsx:200-280.
The CRDT-aware undo behavior advertised in the v0.8.0 notes is wired through the same Yjs UndoManager shared with the Milkdown editor, which means Sheet edits, Markdown edits, and MCP-driven edit_sheet operations all participate in one undo stack per session.
2. The Collaboration Layer
Live collaboration is not specific to Sheets; it is a reusable subsystem under frontend/src/lib/collab/ that both grid-editor.tsx and milkdown-editor.tsx consume. The boundaries are deliberately small so a Sheet and a wiki page can co-edit without coupling.
| Hook | Role | Key behavior |
|---|---|---|
tela-provider.ts | Yjs transport | Connects to the backend sync endpoint, manages websocket lifecycle, persists document state |
use-collab-session.ts | Session orchestrator | Spins up provider + awareness + undo for the active document |
use-awareness.ts | Presence channel | Publishes cursor, selection, and user identity to peers |
use-leader-election.ts | Election | Selects one client per document to perform write coalescing / external side-effects |
The provider owns the Yjs Doc and the network adapter, isolating the rest of the app from transport details Source: frontend/src/lib/collab/tela-provider.ts:1-80. use-collab-session composes provider, awareness, and leader election into a single React hook that the grid editor calls once on mount; it returns the shared Y.Doc, the awareness state, and the leader handle so the editor can subscribe to cell changes without re-implementing sync Source: frontend/src/lib/collab/use-collab-session.ts:1-60. Presence is published through use-awareness, which writes user color, name, current cell, and selection range into the awareness map so other clients can render the live cell cursor overlay inside the Defter grid Source: frontend/src/lib/collab/use-awareness.ts:1-90. Leader election via use-leader-election.ts ensures only one tab per document drives coalesced writes and agent-effect dispatches, preventing duplicate MCP calls when multiple humans have the Sheet open Source: frontend/src/lib/collab/use-leader-election.ts:1-70.
flowchart LR A[grid-editor.tsx] --> B[use-collab-session] C[milkdown-editor.tsx] --> B B --> D[tela-provider] B --> E[use-awareness] B --> F[use-leader-election] D --> G[(Backend Sync)] E --> H[Peers / MCP agents] F --> I[Agent effect dispatch]
3. MCP Surface for Sheets
Because the v0.8.0 release promotes Sheets to a first-class doc type, the MCP server exposes it through two structured entry points so AI agents can read and mutate Sheets without scraping the DOM.
edit_sheet— accepts structured operations (cell set, row insert, column resize, freeze) that are translated into Yjs updates against the sharedY.Doc, so agent edits merge cleanly with human edits and are undoable through the same CRDT undo manager.get_page format=values— returns the computed sheet as typed values rather than the raw structural document, giving agents a stable read API for downstream reasoning.
Agent-authored sheets are still subject to the structural lint gate inside grid-editor.tsx, which mirrors the human editing rules (types, freeze constraints, header invariants) so that agent writes cannot silently produce an inconsistent grid Source: frontend/src/components/app/grid-editor.tsx:120-200. The agent activity audit trail proposed in issue #9 would naturally extend this surface by recording each edit_sheet invocation alongside the awareness identity of the calling agent.
4. Operational Notes
- Import / export — CSV and XLSX round-trip through the grid editor; on import, the file is parsed into a Yjs document so collaborators joining after import see the same state.
- Freeze values — toggled per-cell; frozen cells are read-only in the editor and rejected by
edit_sheet, preserving derived values from being clobbered. - Presence — every connected client (human or MCP agent) appears in the awareness channel; Sheet cell cursors reflect this, so an agent's in-flight edit is visible to humans in real time.
- Undo scope — CRDT-aware undo is per-document, not per-tab, and covers both human keypresses and agent
edit_sheetoperations within the same window.
Together, the Defter grid editor and the lib/collab subsystem turn Sheets into a live, multi-actor surface that is consistent with the rest of Tela's wiki: one sync layer, one presence channel, one undo stack, and one structured MCP entry point for agents.
Source: https://github.com/zcag/tela / Human Manual
RAG, Semantic Search & Ask-Your-Docs
Related topics: Atlas Documentation Engine, Deployment, Configuration & Self-Hosting
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Atlas Documentation Engine, Deployment, Configuration & Self-Hosting
RAG, Semantic Search & Ask-Your-Docs
Tela exposes a Retrieval-Augmented Generation (RAG) subsystem that lets AI agents and end users perform semantic search across the wiki and run an Ask-Your-Docs flow that grounds answers in page content rather than the model's parametric memory. The subsystem lives entirely under backend/internal/rag/, following the project's modular Go layout (backend/internal/<domain>/), and is consumed by the MCP server so agents can search and read the wiki as first-class teammates (see issue #9, which proposes an audit trail on top of this exact access surface). Source: backend/internal/rag/rag.go.
Architecture Overview
The package is split by responsibility: one orchestrator file plus one file per pipeline stage. This keeps each stage swappable and lets providers (e.g. OpenAI vs. local) be added without touching the rest of the pipeline.
| File | Stage | Role |
|---|---|---|
rag.go | Orchestration | Wires embedder, indexer, search, and reranker behind a single RAG entry point used by MCP and HTTP handlers. |
index.go | Ingestion | Splits page content into chunks, attaches metadata, and persists embeddings to the vector store. |
embed.go | Embedding interface | Defines the embedder contract used by the rest of the package. |
embed_openai.go | Embedding provider | OpenAI-backed implementation of the embedder (vector API). |
search.go | Retrieval | Embeds the query and runs the vector similarity search over the index. |
rerank.go | Re-ranking | Reorders the candidate set before returning/snippeting, improving top-k precision for Ask-Your-Docs. |
Source: backend/internal/rag/rag.go, backend/internal/rag/index.go, backend/internal/rag/search.go, backend/internal/rag/rerank.go.
flowchart LR A[Page content] --> B[index.go<br/>chunk + store] B --> C[(Vector index)] Q[User / Agent query] --> D[embed.go / embed_openai.go] D --> E[search.go<br/>vector similarity] E --> C C --> F[rerank.go<br/>reorder top-k] F --> G[rag.go<br/>RAG answer] G --> H[MCP tool / HTTP response]
Indexing Pipeline
Pages enter the indexer when content changes (page writes, MCP edits). index.go is responsible for the offline side of RAG: it splits page markdown into chunks, pairs each chunk with metadata (page id, title, heading anchors, timestamps), and produces embeddings through the embedder interface defined in embed.go. Source: backend/internal/rag/index.go, backend/internal/rag/embed.go.
The embedder interface in embed.go decouples the vector model from the rest of the package; embed_openai.go provides the OpenAI implementation, so swapping providers (local models, other hosted APIs) is a matter of adding a sibling file that satisfies the same contract rather than editing the search or index code. Source: backend/internal/rag/embed.go, backend/internal/rag/embed_openai.go.
Because Tela's wiki is a directed graph of pages with wikilinks, the indexer must be idempotent — re-indexing a page must not duplicate vectors for unchanged chunks, and updates to a single section must not invalidate the rest of the page's embeddings. This is what makes the agent-driven edit workflow (issue #9) safe to combine with continuous re-indexing. Source: backend/internal/rag/index.go.
Query Pipeline (Search + Rerank)
The online side is split into two stages on purpose:
search.go— broad recall. Embeds the incoming query through the same embedder and runs a vector similarity search, returning a candidate set that is intentionally larger than the final top-k. This keeps recall high even when the query phrasing does not match any chunk literally.rerank.go— precision. Reorders the candidate set using a cross-encoder / scoring pass so the chunks most likely to actually answer the question rise to the top. The reranker is what makes Ask-Your-Docs answers point at the right passage rather than a thematically adjacent one.
Source: backend/internal/rag/search.go, backend/internal/rag/rerank.go.
rag.go ties these stages together: it receives a query (and optional page scope), calls search.go, passes the candidates through rerank.go, and assembles the final response — typically the top reranked chunks plus the page metadata needed to render source citations. Because the MCP server is the primary consumer, the response shape is designed to be machine-friendly (snippet + page ref) as well as human-readable. Source: backend/internal/rag/rag.go.
Ask-Your-Docs via MCP
The MCP server exposes RAG as a search/read tool so agents can ask questions of the wiki without a separate UI. From an agent's point of view, the flow is: submit a natural-language question → receive grounded snippets with page references → optionally read the referenced page through get_page for full context. This is the same surface the v0.8.0 release extends to Sheets (get_page format=values), and it is the surface the proposed Agent Activity Log (issue #9) would audit. Source: backend/internal/rag/rag.go.
Two design choices follow from this:
- Grounding over generation. The reranker (
rerank.go) is a load-bearing piece: it is what keeps the answer attached to real pages instead of drifting into the model's own knowledge, which matters more in a wiki context than in a general chatbot. - Provider-agnostic embeddings. Keeping
embed_openai.gobehind theembed.gointerface means the wiki is not locked to a single vendor — a useful property as the project evolves its RAG stack alongside Sheets and other doc types introduced in v0.8.0.
Source: backend/internal/rag/embed.go, backend/internal/rag/embed_openai.go, backend/internal/rag/rerank.go.
Source: https://github.com/zcag/tela / Human Manual
Deployment, Configuration & Self-Hosting
Related topics: Overview & Quickstart, Operations, Licensing, Editions & Extensibility
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Overview & Quickstart, Operations, Licensing, Editions & Extensibility
Deployment, Configuration & Self-Hosting
Tela is a self-hostable collaborative wiki with an embedded MCP server that lets AI agents read, write, and search pages as first-class teammates. Deployment is intentionally portable: a single deploy/ bundle ships three Docker Compose variants, a Caddy reverse proxy recipe, and a .env.example template so operators can choose between an all-in-one run, a split frontend/backend topology, or pulling prebuilt images from a container registry.
Scope and Layout of the `deploy/` Bundle
The deploy/ directory is the canonical self-hosting surface and is kept independent from the backend/, frontend/, and landing/ source trees. This separation lets application code evolve at its own cadence while operators consume a stable deployment contract.
The bundle contains:
docker-compose.yml— the unified stack, best for small single-host installs.docker-compose.split.yml— a topology override that runs backend and frontend as separately scalable services.docker-compose.registry.yml— pulls published images from a registry instead of building locally..env.example— the configuration contract; every variable that the compose files reference.proxy/Caddyfile— the recommended TLS-terminating reverse proxy with automatic HTTPS.docs/deploy.md— the operator-facing guide.
Together these files cover build-from-source, publish-and-pull, and proxy-in-front workflows from one directory, so a single cp -r deploy/ /opt/tela is enough to bootstrap a host. Source: deploy/docker-compose.yml:1-40, docs/deploy.md:1-40.
Compose Variants and When to Use Each
Unified Compose
deploy/docker-compose.yml is the default, low-friction option. It builds the backend and frontend images from their respective Dockerfiles in one compose project, then wires them onto a shared network with the proxy in front. Recommended for local development, homelabs, and small teams where one host has enough capacity for all three containers. Source: deploy/docker-compose.yml:1-40.
Split Compose
deploy/docker-compose.split.yml is the multi-service overlay: it keeps the application containers separate so they can be scheduled, restarted, and scaled independently. The backend/ API and frontend/ static/app tier are decoupled, which is the natural target when moving from a single host to a small cluster or to managed container platforms. Source: deploy/docker-compose.split.yml:1-40.
Registry Compose
deploy/docker-compose.registry.yml does not build anything. It declares image: references to the published Tela container artifacts, so operators without a local toolchain can pin a release tag and run it. This file is the right choice for air-gapped or read-only hosts, and for upgrades tied to GitHub releases (the project shipped its first conventional tag at v0.8.0 with the new Sheets doc type). Source: deploy/docker-compose.registry.yml:1-40.
The three files are intentionally shaped so that operators can switch modes by changing which compose file they invoke; the application contract — environment variables, exposed ports, proxy upstream — stays identical. Source: docs/deploy.md:1-60.
Configuration via `.env`
deploy/.env.example is the single source of truth for runtime configuration. Any value that the compose files, the backend service, or the proxy need to interpolate must be declared here. The file is shipped as .example precisely so that operators copy it to .env, fill in secrets, and keep the template in version control.
Typical concerns covered by this contract include:
- The public base URL used to mint canonical links, OG/Twitter metadata, and sitemap entries — important for the SEO completeness work tracked in issue #2.
- The origin the proxy forwards to (backend vs. frontend, depending on split mode).
- Secrets for the MCP server, since agents authenticate as first-class teammates and their activity is a community-tracked concern (see issue #9 on the proposed Agent Activity Log).
- Feature toggles such as the Sheets doc type and reading mode flags (issue #3).
Source: deploy/.env.example:1-40, deploy/docker-compose.yml:1-40.
Reverse Proxy and Apex Routing
deploy/proxy/Caddyfile is the recommended edge. Caddy handles automatic HTTPS via ACME, terminates TLS, and routes traffic between the public marketing site, the app, and any subpaths the operator wants to expose. The apex-domain routing model that issue #1 introduces — a standalone Astro marketing landing deployed at the apex while the app lives at an app. subdomain — is expressed in this Caddyfile, which is what makes the landing/ + frontend/ + backend/ triple deployable from a single host. Source: deploy/proxy/Caddyfile:1-60, docs/deploy.md:1-60.
| Concern | Unified | Split | Registry |
|---|---|---|---|
| Builds locally | yes | yes | no |
| Scales services independently | no | yes | yes |
| Requires local toolchain | yes | yes | no |
| Best for | dev / homelab | small cluster | pinned releases |
Self-Hosting Workflow
The end-to-end self-hosting flow is intentionally short. An operator copies the deploy/ directory to the host, copies .env.example to .env and fills in required values, chooses one of the three compose files, and starts the stack behind Caddy. From there, upgrades consist of editing the pinned image tag in docker-compose.registry.yml and running docker compose pull && docker compose up -d, or rebuilding with the unified file from a fresh git pull. The app and any MCP-aware agents then share the same deployment contract, and the Agent Activity Log proposed in issue #9 would be a first-class consumer of the same audit surface. Source: docs/deploy.md:1-80, deploy/docker-compose.registry.yml:1-40, deploy/.env.example:1-40, deploy/proxy/Caddyfile:1-60, deploy/docker-compose.yml:1-40, deploy/docker-compose.split.yml:1-40.
Limitations and Operator Notes
Self-hosting is bounded by what the compose files declare: there is no first-class Helm chart or Kubernetes manifest in deploy/, so cluster deployments require the operator to translate the compose contract themselves. The MCP server inherits the same network identity as the backend, which means agent activity (and any future audit log from issue #9) is co-located with the API rather than isolated. Finally, because the landing page is a separate Astro build, marketing-domain routing and app-domain routing must both be kept in sync in the Caddyfile whenever the public surface changes. Source: deploy/docker-compose.yml:1-40, deploy/proxy/Caddyfile:1-60, docs/deploy.md:1-80.
Source: https://github.com/zcag/tela / Human Manual
Operations, Licensing, Editions & Extensibility
Related topics: Deployment, Configuration & Self-Hosting, System Architecture & Data Flow
Continue reading this section for the full explanation and source context.
Related Pages
Related topics: Deployment, Configuration & Self-Hosting, System Architecture & Data Flow
Operations, Licensing, Editions & Extensibility
This page documents how Tela is operated as a product, how it is licensed, how its editions and billing are structured, and how the platform can be extended by humans and AI agents.
1. Operations
Tela is operated as an open-core product with a single tagged release channel. The project moved to conventional development prior to v0.8.0, which is recorded as the first tagged GitHub release under that workflow. Source: CHANGELOG.md:1-20.
Day-to-day operations cover:
- Release flow — Conventional Commits drive version bumps; tags map to GitHub Releases with a per-release summary block (e.g., the
v0.8.0entry introducing Sheets). Source: CHANGELOG.md:8-34. - Deployment surface — The repository separates the marketing site (
landing/, a standalone Astro build) from the app (backend/+frontend/); apex routing serves the landing while the app stays at an app path. Source: docs/operations.md:5-22. - SEO & discoverability hygiene — Landing metadata, JSON-LD (
@graph/SoftwareApplication),robots.txt,sitemap.xml, andllms.txtare maintained per the SEO completeness pass, while app routes are markednoindex. Source: docs/operations.md:24-41. - Operational artifacts —
apple-touch-icon,web manifest, and icon-192/512 assets are produced as part of the same pass; a generated 1200×630 OG card lives under the landing. Source: docs/operations.md:42-58.
2. Licensing
Tela's licensing model is dual-layered: source code under a permissive OSS license, with name and logo usage governed by a separate trademark policy.
- Source license — The repository ships an
Apache-2.0style permissive license granting rights to use, modify, and distribute the code subject to standard terms. Source: LICENSE:1-30. - Trademark — The
telaname and marks are not licensed under the OSS license; usage is governed byTRADEMARK.md, which is referenced from the license for convenience. Source: TRADEMARK.md:1-18. - License policy doc —
docs/licensing.mdconsolidates the practical interpretation: contributors retain copyright, the grant covers the bundled code only, and downstream redistributors must preserve notices. Source: docs/licensing.md:6-29. - Combined attribution — A
NOTICEfile is generated from the dependency graph and surfaced in ship checklists; removed/proprietary modules are excluded from the OSS distribution. Source: docs/licensing.md:31-47.
3. Editions & Pricing
Tela is offered as a tiered product line where the OSS edition is the base and commercial editions bundle hosted surfaces, support, and collaboration features.
- Editions catalog —
docs/editions-and-pricing.mdenumerates Community (self-hosted, free), Team (hosted multi-seat workspace), and Business (SAML, audit, retention); per-edition feature matrices are maintained there. Source: docs/editions-and-pricing.md:8-44. - Feature gating — Capability flags such as Sheets import/export (CSV/XLSX), MCP-driven
edit_sheet, and presence indicators are evaluated against the workspace's edition at request time. Source: docs/editions-and-pricing.md:46-72. - Billing mechanics —
docs/billing.mddocuments seat-based subscription logic, proration on mid-cycle seat changes, and the toggling of commercial modules at the workspace level. Source: docs/billing.md:5-26. - Upgrade/downgrade — Switching editions triggers a feature-entitlement reconciliation; downgrades preserve data but disable edition-locked surfaces, with a clear audit trail for administrators. Source: docs/billing.md:28-49.
The following table summarizes edition differentiation as documented:
| Capability | Community | Team | Business |
|---|---|---|---|
| Self-host / OSS | ✅ | — | — |
| Hosted workspaces | — | ✅ | ✅ |
| MCP agent access | ✅ | ✅ | ✅ |
| Sheets (grid editor, import/export) | ✅ | ✅ | ✅ |
| SAML / audit / retention | — | — | ✅ |
Source: docs/editions-and-pricing.md:50-78.
4. Extensibility
Extensibility in Tela spans human-facing surfaces (UI themes, integrations) and machine-facing surfaces (the MCP server).
- MCP server — Tela exposes a Model Context Protocol server so AI agents can read, write, and search the wiki as first-class teammates; tool calls include
edit_sheet(structured ops) andget_page format=values. Source: CHANGELOG.md:22-31. - Agent activity (proposed) — Community issue #9 proposes an Agent Activity Log — a time-ordered feed capturing which agent identified by MCP client read or wrote which page — to close the visibility gap that the MCP server introduces. Source: docs/operations.md:60-75, issue #9.
- UI surfaces — The landing aesthetic (dark-first, OKLCH tokens, self-hosted Geist, woven-loom signature) is isolated under
landing/so the app CSS and token graph remain unaffected. Source: docs/operations.md:11-23. - Reader extensions — A reading mode (chrome-free, TOC scroll-spy, reading-progress bar, wikilink navigation, reader preferences) is tracked as feature work that any edition can adopt because it lives in the shared renderer. Source: issue #3.
Related Community Threads
- #9 — Agent activity audit trail directly intersects extensibility (MCP) and operations (audit log surface). Source: issue #9.
- #3 — Reading mode relates to UI extensibility for the shared reader. Source: issue #3.
- #2 / #1 — SEO completeness and landing page are operational artifacts governed by
docs/operations.md. Source: issue #2, issue #1.
See also
- Repository root:
LICENSE,TRADEMARK.md,CHANGELOG.md - Product docs:
docs/licensing.md,docs/editions-and-pricing.md,docs/billing.md,docs/operations.md - MCP surface:
backend/mcp/(referenced fromCHANGELOG.mdforv0.8.0)
Source: https://github.com/zcag/tela / Human Manual
Doramagic Pitfall Log
Source-linked risks stay visible on the manual page so the preview does not read like a recommendation.
May increase setup, validation, or first-run risk for the user.
May increase setup, validation, or first-run risk for the user.
May increase setup, validation, or first-run risk for the user.
May increase setup, validation, or first-run risk for the user.
Doramagic Pitfall Log
Found 11 structured pitfall item(s), including 0 high/blocking item(s). Top priority: Installation risk - Installation risk requires verification.
1. Installation risk: Installation risk requires verification
- Severity: medium
- Finding: Project evidence flags a installation risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: community_evidence:github | https://github.com/zcag/tela/issues/2
2. Configuration risk: Configuration risk requires verification
- Severity: medium
- Finding: Project evidence flags a configuration risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: capability.host_targets | https://github.com/zcag/tela
3. Capability evidence risk: Capability evidence risk requires verification
- Severity: medium
- Finding: README/documentation is current enough for a first validation pass.
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: capability.assumptions | https://github.com/zcag/tela
4. Maintenance risk: Maintenance risk requires verification
- Severity: medium
- Finding: Project evidence flags a maintenance risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: evidence.maintainer_signals | https://github.com/zcag/tela
5. Security or permission risk: Security or permission risk requires verification
- Severity: medium
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: downstream_validation.risk_items | https://github.com/zcag/tela
6. Security or permission risk: Security or permission risk requires verification
- Severity: medium
- Finding: no_demo
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: risks.scoring_risks | https://github.com/zcag/tela
7. Security or permission risk: Security or permission risk requires verification
- Severity: medium
- Finding: Project evidence flags a security or permission risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: community_evidence:github | https://github.com/zcag/tela/issues/9
8. Security or permission risk: Security or permission risk requires verification
- Severity: medium
- Finding: Project evidence flags a security or permission risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: community_evidence:github | https://github.com/zcag/tela/issues/1
9. Security or permission risk: Security or permission risk requires verification
- Severity: medium
- Finding: Project evidence flags a security or permission risk. Review the linked source before relying on this workflow.
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: community_evidence:github | https://github.com/zcag/tela/issues/3
10. Maintenance risk: Maintenance risk requires verification
- Severity: low
- Finding: issue_or_pr_quality=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: evidence.maintainer_signals | https://github.com/zcag/tela
11. Maintenance risk: Maintenance risk requires verification
- Severity: low
- Finding: release_recency=unknown。
- User impact: May increase setup, validation, or first-run risk for the user.
- Recommended check: Reproduce the official install and quickstart path in an isolated environment.
- Evidence: evidence.maintainer_signals | https://github.com/zcag/tela
Source: Doramagic discovery, validation, and Project Pack records
Community Discussion Evidence
These external discussion links are review inputs, not standalone proof that the project is production-ready.
Count of project-level external discussion links exposed on this manual page.
Open the linked issues or discussions before treating the pack as ready for your environment.
Community Discussion Evidence
Doramagic exposes project-level community discussion separately from official documentation. Review these links before using tela with real data or production workflows.
- Feature: Agent activity audit trail — who read/wrote what via MCP - github / github_issue
- Reading mode — chrome-free, typographically elevated page reader - github / github_issue
- SEO completeness pass — landing meta/OG/schema + robots/sitemap/llms + a - github / github_issue
- Marketing landing page (standalone Astro) + apex deploy routing - github / github_issue
- v0.8.0 - github / github_release
- Configuration risk requires verification - GitHub / issue
Source: Project Pack community evidence and pitfall evidence