📚 oikb
Keep your Open WebUI Knowledge Bases in sync. Point it at a local directory, a GitHub or Gitea repo, a Confluence space, an S3 bucket, Zotero, or any of 47 supported sources. Only new and modified files are uploaded via incremental source-checksum diffing.
Quick Start
pip install oikb
export OPEN_WEBUI_URL=http://localhost:3000
export OPEN_WEBUI_API_KEY=sk-your-api-key
# Sync a directory
oikb sync ./docs --kb-id your-kb-id
# Sync a GitHub repo
oikb sync github:owner/repo --kb-id your-kb-id
# Preview first (no upload)
oikb sync ./docs --kb-id your-kb-id --dry-run
For multi-source, scheduled sync, or daemon mode — run oikb init to generate a .oikb.yaml config file, then oikb daemon.
📖 Full Guide — installation, connectors, daemon, enterprise features, deployment, troubleshooting.
Commands
| Command | Description |
|---|---|
oikb init |
Generate .oikb.yaml interactively |
oikb sync <source> |
Incremental sync to a Knowledge Base |
oikb watch <dir> |
Watch for changes and auto-sync |
oikb daemon |
Long-lived scheduler with HTTP API |
oikb diff <source> |
Preview what a sync would do |
oikb validate |
Validate .oikb.yaml without running |
oikb history |
View sync history |
oikb ls |
List files in a Knowledge Base |
oikb status |
Show KB info and file count |
oikb reset |
Delete all files in a Knowledge Base |
oikb config |
Manage saved URL and API key |
Daemon
Run oikb daemon for production deployments. Reads .oikb.yaml and syncs each source on a schedule.
oikb daemon --port 8080
Features:
- Scheduled sync — simple intervals (
30m,1h) or cron expressions (0 6 * * 1-5) - Webhooks — sync on source changes via
/webhooks/github,/webhooks/gitlab,/webhooks/gitea,/webhooks/slack,/webhooks/confluence - Health checks —
GET /healthfor Docker/K8s readiness probes - Prometheus metrics —
GET /metricsexports sync counters, duration histograms, and error rates - Sync history —
GET /historyqueryable log of all syncs - On-demand sync —
POST /sync/{identifier}trigger bynameorkb-id - Failure notifications — webhook POST on sync errors, compatible with Slack, PagerDuty, Opsgenie
- API key auth — set
OIKB_API_KEYto secure endpoints (Docker secrets_FILEsupported) - OpenAPI tool server — add
http://oikb:8080as a Tool Server in Open WebUI (Settings → Connections) and let the LLM trigger syncs, check status, and query history
# .oikb.yaml
defaults:
interval: 1h
concurrency: 4
filter:
max-size: 50mb
notify:
url: https://hooks.slack.com/services/T.../B.../xxx
on: error
sources:
- name: wiki
source: github:owner/repo
kb-id: 8f3a2b1c-...
webhook: true
- name: handbook
source: confluence:ENG
kb-id: 4e7d9a0f-...
interval: "0 6 * * 1-5" # overrides default
oikb sync --name wiki # CLI: sync a specific entry
curl -X POST /sync/wiki # API: trigger by name
curl -X POST /sync/8f3a2b1c-.. # API: trigger by kb-id
Docker
docker run -d \
-e OPEN_WEBUI_URL=http://open-webui:8080 \
-e OPEN_WEBUI_API_KEY=sk-... \
-e OIKB_API_KEY=your-daemon-key \
-e LOG_FORMAT=json \
-v ./.oikb.yaml:/data/.oikb.yaml:ro \
-p 8080:8080 \
ghcr.io/open-webui/oikb:latest daemon
Docker Compose
services:
open-webui:
image: ghcr.io/open-webui/open-webui:main
ports:
- "3000:8080"
oikb:
image: ghcr.io/open-webui/oikb:latest
environment:
- OPEN_WEBUI_URL=http://open-webui:8080
- OPEN_WEBUI_API_KEY=${OPEN_WEBUI_API_KEY}
- OIKB_API_KEY=${OIKB_API_KEY}
- LOG_FORMAT=json
volumes:
- ./.oikb.yaml:/data/.oikb.yaml:ro
command: daemon
ports:
- "8080:8080"
depends_on:
- open-webui
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:8080/health/ready"]
interval: 30s
timeout: 5s
retries: 3
start_period: 15s
47 Connectors
| Category | Sources |
|---|---|
| Code Repos | GitHub, GitLab, Gitea, Bitbucket |
| Cloud Storage | S3, GCS, Azure Blob, Dropbox, R2, Google Drive, SharePoint, Nextcloud, Egnyte, Oracle Cloud |
| Wikis & KBs | Confluence, Notion, BookStack, Discourse, GitBook, Guru, Outline, Slab, Document360, DokuWiki, Google Sites |
| Ticketing | Jira, Linear, Zendesk, Freshdesk, Asana, ClickUp, Airtable, ServiceNow, ProductBoard |
| Messaging | Slack, Discord, Microsoft Teams, Gmail, Zulip |
| Meetings | Gong, Fireflies |
| Forums | XenForo |
| Sales & CRM | Salesforce, HubSpot |
| Web | Website / Sitemap crawler |
| Research | Zotero |
oikb sync github:owner/repo --kb-id your-kb-id
oikb sync confluence:ENG --kb-id your-kb-id
oikb sync s3://bucket/prefix --kb-id your-kb-id
oikb sync nextcloud:/Documents --kb-id your-kb-id
oikb sync servicenow:incident --kb-id your-kb-id
oikb sync "zotero:Research%%Machine Learning" --kb-id your-kb-id
Some connectors need an optional extra: pip install oikb[gdrive], pip install oikb[s3], pip install oikb[zotero], or pip install oikb[all] for everything.
Gitea
Sync repository files or built-in wiki pages from Gitea 1.24.0+ (no extra dependency):
export GITEA_URL=https://git.example.com # Instance root; /gitea subpaths work too
export GITEA_TOKEN=your-read-token # Optional for public repositories
oikb sync gitea:engineering/docs/handbook --kb-id your-kb-id
oikb diff 'gitea:engineering/docs?wiki=true' --kb-id your-wiki-kb-id
Use a personal access token with read:repository. Per-source auth.base_url
and auth.token override the environment; --url and --token always configure
Open WebUI. Repository scans and downloads use the same pinned commit. Wiki
pages are checked and cached before syncing. See the Gitea guide
for shared KBs, webhooks, compatibility tests, and wiki limitations.
Zotero
export ZOTERO_LIBRARY_ID=123456
export ZOTERO_API_KEY=...
oikb sync "zotero:" --kb-id your-kb-id # syncs all top-level collections plus _unfiled
oikb sync "zotero:Research" --kb-id your-kb-id # syncs only the 'Research' collection
oikb sync "zotero:Research%%Machine Learning" --kb-id your-kb-id # syncs only the 'Machine Learning' subcollection
Options:
| Variable | Description |
|---|---|
ZOTERO_LIBRARY_TYPE |
user (default) or group |
ZOTERO_INCLUDE_NOTES |
Append child notes when set to 1, true, yes, or on |
ZOTERO_INCLUDE_ANNOTATIONS |
Append PDF annotation text/comments |
ZOTERO_CHECKSUM |
version (default) or content |
ZOTERO_EXCLUDE |
Comma-separated collection paths to skip |
ZOTERO_UNFILED_DIR |
Directory for root library items, default _unfiled |
ZOTERO_WEBDAV_URL |
WebDAV Zotero storage base; fetches <attachment-key>.zip on Zotero file 404 |
ZOTERO_WEBDAV_USER / ZOTERO_WEBDAV_PASSWORD |
WebDAV credentials |
Filters
Narrow what gets synced with include/exclude globs and size limits:
sources:
- name: docs
source: github:owner/repo
kb-id: 4e7d9a0f-...
filter:
include: ["docs/**/*.md", "*.txt"]
exclude: ["drafts/**"]
max-size: 50mb
To split a single source across multiple Knowledge Bases, use separate entries:
sources:
- name: wiki-docs
source: github:owner/repo
kb-id: abc123-...
filter:
include: ["docs/**/*.md"]
- name: wiki-code
source: github:owner/repo
kb-id: def456-...
filter:
include: ["src/**"]
Configuration
Resolved in order (highest priority wins):
- CLI flags (
--url,--token) - Environment variables (
OPEN_WEBUI_URL,OPEN_WEBUI_API_KEY) - Config file (
~/.config/oikb/config.yaml)
All string values in .oikb.yaml support ${VAR} and ${VAR:-default} interpolation:
sources:
- name: docs
source: github:${GITHUB_ORG}/docs
kb-id: ${KB_DOCS_ID}
token: ${GITHUB_TOKEN}
notify:
url: ${SLACK_WEBHOOK:-https://hooks.slack.com/default}
History
oikb history # Table view
oikb history --json # JSON output
oikb history --errors # Failed syncs only
oikb history --clear --days 7 # Prune old entries
GitHub Actions
- name: Sync docs to Open WebUI
uses: docker://ghcr.io/open-webui/oikb:latest
with:
args: sync /github/workspace/docs --kb-id ${{ secrets.KB_ID }}
env:
OPEN_WEBUI_URL: ${{ secrets.OPEN_WEBUI_URL }}
OPEN_WEBUI_API_KEY: ${{ secrets.OPEN_WEBUI_API_KEY }}
How It Works
- Scan source, compute checksums
- Send manifest to Open WebUI
/sync/diff - Delete stale files, create missing directories
- Upload only new and modified files
License
MIT. See LICENSE for details.
Metadata
Release files for oikb 0.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| oikb-0.6.0-py3-none-any.whl | Python 3 | none | any | Details |
Release files / oikb-0.6.0-py3-none-any.whl
| Download URL | oikb-0.6.0-py3-none-any.whl |
|---|---|
| Size | 127.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
71533992f3941c9e05a5395922c00949d3c65b9b922fbb54ef770d4a31ce9bec
|
|
BLAKE2b-256 checksum How to use checksums |
da7874b6d19a6158fa493be8a6b5ac8b0ab072c0c686623b73a219420d150da1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logSecurity for oikb 0.6.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 1 file in this release has been uploaded with provenance metadata.
Attestation for oikb-0.6.0-py3-none-any.whl
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 21, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.