Zett
A local-first, AI-assisted workspace for turning fleeting thoughts, conversations, links, and assets into reusable knowledge.
Zett is a private workspace where you think out loud with an AI assistant and keep what matters. Catch a fleeting thought in one line before it slips away, bring in the sources around it, and work it into something durable — a card, an article, a slide deck, or a paper — organized, searchable, and stored on your own machine.
No account, no cloud workspace, no telemetry. Zett runs as a single local
application that listens on 127.0.0.1 and keeps every database and file under
one directory. It talks to the model provider you configure, and to a chat
platform only when you connect one.
What you can do
- Think in a conversation. Ask, refine, and iterate; the answer streams with its reasoning and the tools it used, so you can see how it got there.
- Catch a fleeting thought. Jot down the idea, a rough note, or a question the moment it arrives, and develop it into something durable whenever you come back to it.
- Keep the good parts. Cards, articles, images, slide decks, and LaTeX PDFs are built from the conversation and saved only when you say so.
- Build a library. Everything published is searchable and tagged with a nested tag tree, and every item links back to the conversation it came from.
- Bring your sources. Attach notes, links, images, and files to a conversation, or keep a global library of material you reuse everywhere.
- Choose your models. Configure several providers and pick the model and the reasoning effort for each conversation.
- Work hands-free. Set a prompt to run on a schedule and read the transcript of what it produced while you were away.
- Talk to it from your phone. Connect a chat platform and keep a separate conversation per chat, images and voice notes included.
Install
Zett ships as one Python package — the application, the zett command, and the
compiled interface — so this is the whole install:
uv tool install zettelekasten # or: pipx install zettelekasten
zett start # serves 127.0.0.1:6280 in the background
The distribution is zettelekasten; the command it installs is zett. It is
published to PyPI together with the agim and zett-weixin packages it
depends on, so one install is enough. To work from a checkout instead:
git clone https://github.com/Chang-LeHung/zettelekasten
cd zettelekasten
make install # builds the interface and installs the `zett` command
zett start # serves 127.0.0.1:6280 in the background
Either way, open http://127.0.0.1:6280, add a model provider in Settings,
and start a conversation. zett start returns once the server answers and
leaves it running without the terminal, zett status reports it, and
zett stop shuts it down; zett start --foreground stays attached instead.
Updating
Zett checks PyPI for a newer release (the answer is cached for six hours) and,
when one exists and this copy was installed with uv tool, pipx, or pip,
shows Update to X above Settings in the sidebar. One click runs that
installer for the new release, keeping the Python and any extensions you added
beside Zett, and the same spot then becomes Restart Zett to use X. Click it:
Zett restarts itself on the same address and the page reloads into the new
release. The running process keeps the old code until then.
The terminal does the same: zett restart, and zett --version shows what is
installed. A checkout never shows the button; update it with
git pull && make install. To update by hand, run uv tool upgrade zettelekasten
(or pipx upgrade zettelekasten), then zett restart.
First steps
- Connect a model.
Settings→Provider→New provider. Give it a name, pick the provider, set the model, and paste an API key. Keys are encrypted with a local key file before they are stored. - Start a conversation. Ask a question, drop in a note or a screenshot, and keep going. You can queue your next message while it is still answering, or steer the running answer with a correction.
- Save what is worth keeping. Ask for a card, an article, a deck, or a paper. The Assistant writes a draft; you review the diff and publish it.
- Optional. Connect a channel under
Channels, or create a recurring prompt underScheduled tasks.
MCP servers
Zett reads MCP servers from
~/.zettelekasten/mcp.json (a servers or mcpServers object, Streamable HTTP
or local stdio) and exposes their tools as <server>__<tool>. MCP is best
effort: a server that is down or slow only loses its own tools for that
request, an invalid entry is skipped and logged while the other servers keep
working, and a file that cannot be parsed is ignored until it is fixed. Edits
apply to the next request, with no restart.
Where your data lives
Everything is under ~/.zettelekasten/ — the databases, attachments, artifact
projects, user skills, and rotating logs. Set ZETT_STORAGE_ROOT to move it.
Deleting a conversation removes its messages, files, and artifacts with it.
Documentation
The project site is published at https://chang-lehung.github.io/zettelekasten/, with the full documentation under https://chang-lehung.github.io/zettelekasten/docs/:
- Conversations, the Chrome extension, artifacts and the library, assets, scheduled tasks, channels, settings and local data, the command line
- Writing a plugin — add tools, hooks, or a new chat platform
- Backend reference — layers, storage boundaries, and the HTTP surface, for contributors
Development
git clone https://github.com/Chang-LeHung/zettelekasten
cd zettelekasten
make install # build the frontend and install the `zett` command
make dev # run from source with reload on 127.0.0.1:6280
make check # Ruff, backend/agim/channel tests, frontend tests, typecheck, build
The repository holds the FastAPI application and the Vue interface that Zett
serves. backend/README.md documents how the backend is put together, and
AGENTS.md records the rules a change has to follow.
The repository also carries two packages that are released on their own:
agim, the stateless chat
SDK, and zett-weixin,
the WeChat channel plugin built on it. The agent runtime
Zett runs on lives in its own repository,
zett-agent.
zett3rd/ keeps integrations that live beside Zett without being part of its
build — nothing there is imported by the backend or the interface, so a broken
one can never fail Zett itself. It currently holds a
Zettelekasten Chrome extension (Vue 3 +
TypeScript, built with Vite) that embeds a separate conversation in each
webpage, reads that page, and saves useful results into your library.
Plugins
Zett discovers installed packages through entry points, so an extension is a normal distribution rather than a patch:
zett.agent— tools, lifecycle hooks, slash commands, and@references inside a conversation.zett.channels— a chat platform, from QR login to inbound media.
Install one into the same environment as Zett and restart; the plugin guide walks through a complete example, including what the host guarantees and which boundaries stay closed.
License
This project is available under the MIT License.
Metadata
Release files for zettelekasten 0.0.7
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| zettelekasten-0.0.7.tar.gz | 5.4 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| zettelekasten-0.0.7-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 10.5 MB
Release files / zettelekasten-0.0.7.tar.gz
| Download URL | zettelekasten-0.0.7.tar.gz |
|---|---|
| Size | 5.4 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d34065c0ce27e0661c8d7ca25f12ae4e08205c7d06e87967d7c4236a58d6bb1a
|
|
BLAKE2b-256 checksum How to use checksums |
3e7c7cd572c884180b6ef0945a9fe75759cb0b97cc216813ee8b9db4102edb24
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / zettelekasten-0.0.7-py3-none-any.whl
| Download URL | zettelekasten-0.0.7-py3-none-any.whl |
|---|---|
| Size | 5.2 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1431d69e2b0070f33152489a343f8ac9066b3bd8e2eddf213112acf49487d79f
|
|
BLAKE2b-256 checksum How to use checksums |
92c0acf26b21a97d571879b1f044d2e32be8efcb8ce3bdc8f18ddb80de7a370f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|