noevia — a self-hosted workspace for project-aware chat and durable diary capture (web UI + diary sidecar)
概览
It runs on your own hardware against your own models: nothing leaves the box unless you connect something that makes it leave. - — projects carry instructions, files and memory; every chat inherits them. Files are indexed for retrieval, and each project picks its own model, or lets choose one per message (fast, smart, vision and code roles). - — toolboxes come from MCP servers and from noevia's own built-ins. A read can run on its own; . There is no global "never ask". - — browse the public MCP registry and published skills, add a server from the registry or by URL, and give it a shared key, your own key, or an OAuth sign-in. Each server becomes a toolbox a project has to choose. - — review and enable project SKILL.md files; relevant instructions are loaded for chat, with bounded automatic selection available when configured. - — a separate space whose corpus is Markdown files you can open anywhere, with retrieval, crash-safe logging and optional WebDAV or S3 storage.
README
noevia
A self-hosted workspace for project-aware chat, connected tools, and a diary that stays plain Markdown. It runs on your own hardware against your own models: nothing leaves the box unless you connect something that makes it leave.
What it does
- Projects and chat — projects carry instructions, files and memory; every chat inherits them. Files are indexed for retrieval, and each project picks its own model, or lets Auto choose one per message (fast, smart, vision and code roles).
- Tools, with an approval gate — toolboxes come from MCP servers and from noevia’s own built-ins. A read can run on its own; every write shows you its arguments and waits. There is no global “never ask”.
- Plugins — browse the public MCP registry and published skills, add a server from the registry or by URL, and give it a shared key, your own key, or an OAuth sign-in. Each server becomes a toolbox a project has to choose.
- Skills — review and enable project
SKILL.mdfiles; relevant instructions are loaded for chat, with bounded automatic selection available when configured. - Diary — a separate space whose corpus is Markdown files you can open anywhere, with retrieval, crash-safe logging and optional WebDAV or S3 storage.
- Model management — install, tune, measure and route local models from inside the app.
- Code mode — a feature-flagged coding workspace with sandboxed harnesses and approval gates for changes and other non-read actions.
- Accounts — administrators and members with separate data, passkeys or passwords, invitations and recovery links, and encrypted credentials.
Layout
noevia is split across four repos (#952). This one is the integration repo; it pins the others
in release/versions.lock, and deploy/tools/assemble-release.sh assembles a release from them.
| Where | What it is |
|---|---|
| noevia-web | The React interface |
| noevia-core | The Node API server that fronts everything, the shared contracts/, and code-sandbox/ (the sandbox Code mode runs tasks in) |
| noevia-services | The Python sidecars: diary (retrieval, crash-safe logging, corpus writes), ocr, docling (optional layout and table extraction), model-manager (model files, downloads, presets), laya |
release/versions.lock |
The SHAs (and tarball checksums) of the three repos a release is built from |
build/web.Dockerfile |
The web image, built from an assembled release tree |
deploy/ |
Compose examples, preflight checks, backup and release helpers |
docs/ |
The roadmap, specs, runbook and sources |
The core needs only an OpenAI-compatible inference API. Everything else — the diary, OCR, document extraction, model management, MCP servers — is optional and off until you configure it.
Quick start
The web image is tagged with its source Git commit (COWORK_VERSION); sidecars have their own
tags (DIARY_VERSION, OCR_VERSION, MODEL_MANAGER_VERSION, DOCLING_VERSION,
CODE_SANDBOX_VERSION; see docs/deployment.md). 0.1.0 in the web
package metadata is not the deployed application release number. The live release and current
development status are recorded in docs/roadmap.md and
docs/changelog.md.
docker compose up --build -d
No .env is required: every service variable in compose.yaml has a working
default. Open the app at http://localhost:8021 (the port binds to loopback by
default; to reach it from another device set COWORK_PORT=8021 in .env, e.g.
http://192.168.1.20:8021) — the first-run wizard
confirms that address as the canonical origin and collects the inference
endpoint, models, and everything else in the browser.
Pre-configuring is still supported if you prefer it, and is still the only way
to set things the wizard does not cover (S3/WebDAV diary storage, model
management, TRUST_PROXY):
cp .env.example .env
# Set your inference endpoint, model IDs, and any storage settings in .env.
docker compose up --build -d
The Diary service stays on the internal Compose network unless an operator deliberately publishes its port for legacy clients.
On first launch, noevia prints a one-time setup code and its protected file
location to the web container log. Enter that code in the onboarding screen to
create the first administrator. The code file is deleted after setup. For
passkeys, serve noevia from a stable HTTPS origin and set PUBLIC_ORIGIN and
WEBAUTHN_RP_ID. Plain HTTP works for localhost and for private-network
addresses (a LAN IP or a bare LAN hostname) — the wizard warns that passkeys and
other secure-context browser APIs will not work there, and you sign in with a
password instead. A public http:// domain is rejected; use https://.
Diary is an optional per-user app selected during onboarding or later in
Settings; noevia’s project and chat workspace works without it.
Password/session login is pinned to PUBLIC_ORIGIN and rejects requests from
any other Origin (CSRF hardening) — so if you also reach noevia over a bare
LAN IP or a second hostname (e.g. behind a Cloudflare Tunnel and directly on
your LAN), sign-in from that second origin 403s with “origin not allowed”
until you add it to ADDITIONAL_TRUSTED_ORIGINS (comma-separated, exact
scheme+host+port, e.g. http://10.0.0.5:8021). This only extends
password/session login. Passkeys are exempt and will never work from a second
origin: the passkey’s RP ID is fixed to PUBLIC_ORIGIN’s hostname, and
WebAuthn refuses IP-address origins outright — sign in with a password from a
secondary origin, or use PUBLIC_ORIGIN’s hostname for passkeys.
Persistent files live under ./state by default. Set COWORK_STATE_DIR to an absolute durable path in production; do not place persistent state inside a disposable source checkout.
For a first deployment — including one performed by a coding agent — follow DEPLOY.md step by step; cowork.setup.json mirrors its inputs and health checks in machine-readable form.
Configuration
noevia accepts any OpenAI-compatible chat and embeddings endpoint through INFERENCE_BASE_URL and INFERENCE_API_KEY. Each project can also select another provider in Settings.
Fresh installations use CORPUS_BACKEND=local and store Markdown files beneath the diary state directory. For WebDAV, set:
CORPUS_BACKEND=webdav
CORPUS_ROOT=Notes/Diary
WEBDAV_BASE_URL=https://cloud.example.com/remote.php/dav/files/username/
WEBDAV_USERNAME=username
WEBDAV_PASSWORD=app-password
DIARY_ENTRY_LAYOUT=daily
DIARY_ENTRIES_PREFIX=Entries
The daily layout stores entries as
Entries/YYYY/Month/Month D, YYYY.md. Set DIARY_ENTRY_LAYOUT=monthly and
DIARY_MONTH_FILE_TEMPLATE when connecting an older single-file-per-month
corpus.
Model discovery, loading, downloads and statistics are off by default (MODEL_MANAGER_KIND=none).
Set MODEL_MANAGER_KIND=llamacpp with MODEL_MANAGER_BASE_URL to manage a llama.cpp engine
directly — the shape this project runs in production, where noevia writes models.ini presets,
loads and unloads models and measures them. MODEL_MANAGER_KIND=lemonade is the older adapter,
kept for existing deployments (deploy/examples/lemonade-webdav.compose.yaml).
Administrators can connect WebDAV or S3-compatible storage from Settings; members can connect origins approved in MEMBER_OUTBOUND_ORIGINS. Credentials are encrypted per account. Connected files can be imported into project knowledge. Diary questions receive thoughtful replies in the diary conversation, without a separate Insights feature.
The deprecated LEMONADE_BASE_URL, LEMONADE_API_KEY, and CORPUS_REMOTE_ROOT variables remain readable for one compatibility release. New configuration should use the neutral names.
Development
make test
make assemble
make compose-check
make test runs the deploy-tooling suites; the web, server and sidecar suites run in their own
repos. make assemble writes a release tree for HEAD to out/tree (from the pinned repos);
set COWORK_SOURCE_DIR=$PWD/out/tree (in .env or the shell) and every Compose build context
resolves into it. make compose-check
validates every Compose file against .env.example and needs only Docker.
The web app can be run from a noevia-web checkout with npm run dev; Diary Companion from
noevia-services’ diary/ with uvicorn agent.app:app --reload.
Unraid Compose Manager
Use deploy/examples/unraid-compose-manager.yml as the stack file. Configure
Compose Manager’s Environment Path to an untracked .env containing at least
COWORK_SOURCE_DIR and COWORK_STATE_DIR. The stack includes Unraid management
and Web UI labels, and its Update action rebuilds both images from the selected
source release.
Keep the Compose Manager project metadata on the Unraid boot device, application state under appdata, and source releases separate from both. This lets the UI start, stop, rebuild, and autostart the stack without coupling durable state to a source checkout.
Documentation
| Document | For |
|---|---|
DEPLOY.md |
A first deployment, step by step |
docs/deployment.md |
The live Unraid runbook and every release to date |
docs/roadmap.md |
What is shipped, what is open, and in what order |
docs/sources.md |
Every outside source used, and where each idea came from |
SECURITY.md |
The security model and what an operator must do |
AGENTS.md |
House rules for agents working in this repo |
Data safety
Diary writes enter a SQLite write-ahead journal before the corpus is changed. Both local and WebDAV backends use conditional writes so concurrent changes are retried rather than overwritten. Back up the configured state directory and, for remote storage, the corpus itself.
noevia supports isolated administrator and member accounts, password login,
passkeys, single-use invitations, and administrator-issued recovery links.
Projects, chats, histories, and RAG indexes live under per-user directories.
Provider and storage credentials are encrypted with state/web/secrets.key;
backups are unusable without that mode-600 key file.
The Diary service is internal-only by default. DIARY_AUTH_TOKEN protects the
Web-to-Diary connection. UI_AUTH_TOKEN is accepted only when
LEGACY_AUTH_COMPAT=true, allowing a one-release migration to the first
administrator. Direct Diary clients can be temporarily mapped to a user with
DIARY_LEGACY_USER_ID. Disable both compatibility settings after migration.
Application administrators cannot browse another user’s private content, but a
host administrator with filesystem access can read unencrypted workspace and
corpus files. Secrets belong in .env or a secret manager and must never be
committed.
A full description of the security model — the diary sidecar’s trust
boundary, the outbound-request (SSRF) policy, redirect refusal, credential
storage, and an operator hardening checklist — lives in SECURITY.md.
推荐工具
换一个关键词,或者移除筛选条件。
安装
npx skillfish add sbstndalton/noevia