Karakeep
Karakeep saves bookmarks, pages and PDFs. An LLM tags them and, if you turn it on, summarizes them.
Plugboard options
Give Karakeep its own key and two aliases. vision must accept images, because INFERENCE_IMAGE_MODEL sends them. Docker needs a reachable address (Serving other machines).
jsonc
{
"options": {
"listen": { "host": "0.0.0.0", "port": 4010 },
"keys": { "karakeep": "{env:PLUGBOARD_KEY_KARAKEEP}" },
"models": ["opencode-go/glm-5.3-flash", "anthropic/claude-sonnet-4-6"],
"aliases": {
"tag": "opencode-go/glm-5.3-flash",
"vision": "anthropic/claude-sonnet-4-6"
},
"apps": { "karakeep": { "allowedModels": ["tag", "vision"] } }
}
}Connect
Set these in the .env that Karakeep's compose file reads:
ini
# The plugboard app key, not an OpenAI key.
OPENAI_API_KEY=<the karakeep app key>
OPENAI_BASE_URL=http://host.docker.internal:4010/v1
# Aliases from plugboard's `aliases` option.
INFERENCE_TEXT_MODEL=tag
INFERENCE_IMAGE_MODEL=vision
# Plugboard serves no embeddings. Keep semantic search off.
SEMANTIC_SEARCH_ENABLED=falseOPENAI_API_KEY takes the plugboard key. SEMANTIC_SEARCH_ENABLED=false hides the semantic and hybrid search modes, which need embeddings.
On Linux, add the host name to the web service in docker-compose.override.yml:
yml
services:
web:
extra_hosts:
# Linux needs this to resolve host.docker.internal. Docker Desktop and Colima already provide it.
- "host.docker.internal:host-gateway"The files are in examples/self-hosted/karakeep/.
What works
- Tagging, with
INFERENCE_TEXT_MODEL. It is on by default. - Image tagging, with
INFERENCE_IMAGE_MODEL. - Summaries, with
INFERENCE_ENABLE_AUTO_SUMMARIZATION=true. - Structured output.
INFERENCE_OUTPUT_SCHEMAdefaults tostructured, and plugboard answers it through a tool.
Limits
- Semantic search, hybrid search and related bookmarks need embeddings, which plugboard does not serve. Leave them off, or point
EMBEDDING_OPENAI_BASE_URLat an embedding provider you run. - Keep
toolson for this app. Atools: falsepolicy drops the schema (Per-app policy). If a model fails on structured output, setINFERENCE_OUTPUT_SCHEMA=json. INFERENCE_CONTEXT_LENGTHdefaults to 2048 tokens, so long pages are cut before tagging. Raise it.- A large import sends many calls at once. Set
limits.perApp.requestsPerMinuteon thekarakeepapp if your provider rate-limits.