This is an efficient, low-maintenance, and feature-rich web server for TiddlyWiki. It is a fork of the original tiddly-wiki-server, rewritten in Rust to provide better performance, file management, cloud integration, and quick capture capabilities.
It uses the web server API provided by the TiddlyWeb plugin to save tiddlers in a SQLite database, while smartly offloading binary files to local storage or S3-compatible cloud storage.
Compared to the original implementation, this fork includes significant enhancements:
- Optimized Wiki Rendering: Dynamically injects tiddlers into
empty.htmlvia efficient memory splitting. - Low Footprint: Runs with approx. 10MB RAM, compared to 70MB+ for the standard NodeJS server.
- Direct Reading: Embeds a custom Foliate-js reader directly into the server binary.
- Seamless UX: Automatically detects
application/epub+ziptiddlers (via_canonical_uri) and renders them in a modern reading interface, replacing the default "Binary file" warning. - S3 & Local Support: Streams EPUB files directly from S3 or local storage without requiring full downloads first.
- Note on CSP: This embedded reader does not perform client-side Content Security Policy (CSP) sanitization. If you are importing EPUBs generated by tools like Readeck that inject strict CSP meta tags, please ensure you clean/sanitize the files before uploading.
- Local File Offloading: Binary files (images, PDFs) are kept out of the SQLite database to ensure speed. They are stored in
files/, and Tiddlers simply reference them via_canonical_uri. - S3/R2 Direct Upload:
- Generates pre-signed URLs for secure, direct browser-to-cloud uploads.
- Saves server bandwidth and supports huge files.
- Metadata-Driven Robustness: Tiddlers store storage metadata (Bucket, Key, Region) directly in their fields (
_s3_key, etc.). This means file management remains accurate even if server configurations change. - Cascade Delete: When you delete a Tiddler in the Wiki, the server automatically cleans up the corresponding file on S3 or the local disk. No more orphaned files!
- Basic Authentication: Built-in HTTP Basic Auth middleware to protect your wiki on public networks.
- Authorization Headers: Supports standard
Authorizationheaders for API integration.
- A specialized Webhook endpoint (
/api/inbox) designed for mobile automation. - Easily integrates with iOS Shortcuts or Android HTTP Shortcuts to capture thoughts instantly without loading the full interface.
Create a config.toml file in the working directory.
Security Note: When using Basic Auth, it is highly recommended to run this server behind a reverse proxy (like Nginx/Caddy) with HTTPS enabled.
[server]
bind = "0.0.0.0"
port = 3032
db_path = "./data/tiddlers.sqlite3"
files_dir = "./files/"
# Display name for edits in the Wiki
[status]
username = "YourName"
# [Optional] HTTP Basic Authentication
[auth]
username = "admin"
password = "change_me_please"
[s3]
enable = true
name = "r2"
access_key = "YOUR_AWS_ACCESS_KEY"
secret_key = "YOUR_AWS_SECRET_KEY"
endpoint = "https://<ACCOUNT_ID>.r2.cloudflarestorage.com"
region = "auto"
bucket_name = "your-wiki-assets"
public_url_base = "https://assets.your-domain.com"Capture thoughts from external tools without opening the wiki.
- Endpoint:
POST /api/inbox - Content-Type:
application/json
{
"text": "This is a quick thought captured from my phone.",
"tags": "idea mobile"
}tags is optional. Default: "Inbox".
- URL:
https://your-wiki.com/api/inbox - Method:
POST - Headers:
Authorization: Basic <Base64_Credentials> - Body: JSON (Pass clipboard or input as
text)
Captured items will appear in your Wiki with the tag Inbox and a timestamped title.
- Build:
cargo build --release
- Run:
Ensure
config.tomlandempty.htmlare in the directory../target/release/tiddly-wiki-server --config config.toml
This server embeds custom TiddlyWiki plugins and static assets (like the reader). You can modify them as follows:
Handles drag-and-drop uploads to S3/Local storage.
- Source:
s3_uploader/ - Repack Command:
cargo run --bin pack_plugin -- ./s3_uploader/manifest.json ./s3_uploader_plugin.json
Handles the TiddlyWiki UI integration for EPUB files.
- Source:
epub_plugin/ - Repack Command:
cargo run --bin pack_plugin -- ./epub_plugin/manifest.json ./epub_viewer_plugin.json
The actual reader engine is a customized build of Foliate-js, embedded directly into the server binary.
- Source:
web/foliate-js/(Contains the modified source code) - Build Artifacts:
web/foliate/ebook_reader/(The optimized static files embedded by Rust) - To Update:
If you modify the reader's source code, you must rebuild the frontend assets before rebuilding the Rust server:
cd web/foliate-js npm install npx vite build # Ensure the output is in ./ebook_reader and includes reader.html
After modifying any plugin or asset, run cargo build to embed the new versions into the server executable.
The server provides REST APIs designed for AI Agents and automation, plus a Python wrapper library and CLI.
Located at tools/wiki_client/. Requires requests:
pip install requestsfrom wiki_client import WikiClient
wiki = WikiClient(
base_url="http://localhost:3032",
username="admin",
password="change_me_please",
)
# Search with Chinese word segmentation
results = wiki.search("天气", mode="fts")
# Regex search (Agent-friendly)
results = wiki.search(r"observ\w+tion", mode="regex")
# Get / Put / Inbox / List / Delete
tiddler = wiki.get("My Title")
wiki.put("New Tiddler", content="Body", tags="tag1,tag2")
wiki.inbox("Quick Note", content="From mobile", tags=["idea"])
wiki.list(tag="Inbox", limit=10)
wiki.delete("Tiddler")
# Links and backlinks
links = wiki.links("Some Title") # → ["linked 1", "linked 2"]
backlinks = wiki.backlinks("Some Title") # → ["referrer 1", ...]
# All tags
tags = wiki.tags() # → [{"tag": "cognition", "count": 41}, ...]
# Unlimited results with limit=0
wiki.search("weather", limit=0) # all results
wiki.list(tag="Inbox", limit=0) # all inbox items
# Time-range filtering (YYYYMMDDHHMMSSmmm format)
wiki.search("", created_after="20251201000000000", limit=0)
wiki.search("", modified_after="20260501000000000", tag="cognition", full=True)| Mode | Description | Performance |
|---|---|---|
fts (default) |
FTS5 + jieba Chinese tokenization, prefix matching | O(log N) |
regex |
Full regex via Rust regex crate |
O(N) |
Two implementations available. Rust version recommended (zero dependencies, faster startup):
# Build the Rust CLI (one time)
cargo build --bin wiki
# Now use it directly:
./target/debug/wiki search "weather" --full --limit 5
# Rust (recommended)
wiki search "weather" --full --limit 5
wiki search ".*observation.*" --mode regex
wiki get "My Title" --text-only
wiki put "New Tiddler" --content "body" --tags "tag1,tag2"
wiki inbox "Quick Note" --content "body" --tags "idea,mobile"
wiki list --tag Inbox --limit 10
wiki list --tag Inbox --limit 0 --plain
wiki delete "Tiddler" --force
wiki links "Some Title"
wiki backlinks "Some Title"
wiki batch-links "Title1" "Title2" --plain
wiki graph "Some Title" --depth 2 --plain
wiki tags
wiki tags --plain
wiki changes
wiki changes --since 7d
wiki changes --since 20260501 --tag cognition --plain
# Python (fallback)
python3 tools/wiki_cli.py search "weather" --full --limit 5
python3 tools/wiki_cli.py search ".*observation.*" --mode regex
python3 tools/wiki_cli.py get "My Title" --text-only
python3 tools/wiki_cli.py put "New Tiddler" --content "body" --tags "tag1,tag2"
python3 tools/wiki_cli.py inbox "Quick Note" --content "body" --tags "idea,mobile"
python3 tools/wiki_cli.py list --tag Inbox --limit 10
python3 tools/wiki_cli.py list --tag Inbox --limit 0 --plain
python3 tools/wiki_cli.py delete "Tiddler" --force
python3 tools/wiki_cli.py links "Some Title"
python3 tools/wiki_cli.py backlinks "Some Title"
python3 tools/wiki_cli.py batch-links "Title1" "Title2" --plain
python3 tools/wiki_cli.py graph "Some Title" --depth 2 --plain
python3 tools/wiki_cli.py tags
python3 tools/wiki_cli.py tags --plain
python3 tools/wiki_cli.py changes
python3 tools/wiki_cli.py changes --since 7d
python3 tools/wiki_cli.py changes --since 20260501 --tag cognition --plain| Endpoint | Method | Description |
|---|---|---|
/api/search?q=keyword&mode=fts&tag=Inbox&limit=20 |
GET | Search (supports modified_after/before, created_after/before) |
/api/tiddlers?title=title |
GET | Get tiddler (no URL-encoding) |
/api/tags |
GET | All tags with counts |
/recipes/default/tiddlers.json |
GET | List all |
/api/tiddlers/tag/{tag} |
GET | List by tag (supports time range params) |
/api/tiddlers/{title}/links |
GET | Forward links |
/api/tiddlers/{title}/backlinks |
GET | Backlinks |
/recipes/default/tiddlers/{title} |
PUT | Create / update |
/api/inbox |
POST | Inbox capture |
/api/inbox |
GET | List inbox |
/bags/default/tiddlers/{title} |
DELETE | Delete |
/status |
GET | Server status |
This project is made available under [The Prosperity Public License 3.0.0].
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
Contributors are expected to abide by the Contributor Covenant.