Wikantik ships an OpenAPI 3.1 tool server under /tools/ that exposes hybrid search and
page retrieval as LLM-callable tools. It is designed for OpenWebUI and any other OpenAPI
tool runtime; the OpenAPI document at /tools/openapi.json advertises two operations:
| Operation | Method + path | Purpose |
|---|---|---|
search_wiki | POST /tools/search_wiki | BM25 + hybrid search across the wiki corpus |
get_page | GET /tools/page/{name} | Fetch a single page's Markdown body with truncation |
Tool-server access has two layers:
/admin/apikeys, bound to a Wikantik principal, and stored SHA-256 hashed. Each
call runs under the key's principal, so page ACLs and JAAS permissions apply
exactly as they would for that user's interactive session.wikantik-tools.properties. Defaults ship inside
the module JAR; overrides go in tomcat/lib/wikantik-tools.properties.| Property | Purpose | Default |
|---|---|---|
tools.access.keys | Legacy comma-separated Bearer tokens (no principal binding — avoid in new deployments) | (none) |
tools.access.allowedCidrs | Comma-separated CIDR allowlist (e.g. 10.0.0.0/8) | (none) |
tools.access.allowUnrestricted | Explicit opt-in to run with no auth and no CIDR | false |
tools.ratelimit.global | Global requests per second (0 disables) | 100 |
tools.ratelimit.perClient | Per-client requests per second (0 disables) | 10 |
wikantik.public.baseURL | Public base URL used for citation links + OpenAPI servers entry | (request host) |
Navigate to Administration → API Keys and click Generate Key. Pick:
OpenWebUI production) to identify the key later.tools (OpenAPI only), mcp (MCP server only), or all (both).The plaintext token (wkk_…) is shown once at creation time and only the SHA-256
hash is persisted. Revoking a key is a single click; any client using the revoked
token starts receiving HTTP 403 immediately.
When none of the DB-backed keys, legacy tools.access.keys, tools.access.allowedCidrs,
or tools.access.allowUnrestricted=true is configured, the server refuses every request
with 503 Service Unavailable and logs a CRITICAL line at startup. With at least one
DB-backed key generated via the admin UI, the server accepts Bearer tokens from that
table — no configuration reload required.
search_wikicurl -X POST http://localhost:8080/tools/search_wiki \
-H "Authorization: Bearer $TOOLS_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "hybrid retrieval", "maxResults": 5}'
Response:
{
"query": "hybrid retrieval",
"results": [
{
"name": "HybridRetrieval",
"url": "https://wiki.example.com/wiki/HybridRetrieval",
"score": 18,
"summary": "Fusion of BM25 and dense vector ranking",
"tags": ["search", "design"],
"snippet": "…fused ranking …",
"lastModified": "2026-04-12T18:22:11Z"
}
],
"total": 1
}
maxResults is clamped to [1, 25]; values outside the range snap to the default of 10.
get_pagecurl -H "Authorization: Bearer $TOOLS_KEY" \
"http://localhost:8080/tools/page/HybridRetrieval?maxChars=4000"
The response strips YAML frontmatter from text, includes summary/tags from
frontmatter as top-level fields, and reports truncation via truncated/totalChars/
truncatedAt when the body exceeds the limit (default 6000 chars, hard cap 20000).
The tool server publishes to the process-wide Micrometer registry (scraped at
/observability/metrics). All meters are prefixed wikantik.tools:
| Meter | Type | Notes |
|---|---|---|
wikantik.tools.requests{endpoint,status} | counter | endpoint ∈ {search_wiki, get_page, openapi}; status ∈ {success, error, not_found} |
wikantik.tools.search.results_returned | counter | total result rows emitted |
wikantik.tools.get_page.truncated | counter | get_page responses that hit the truncation cap |
In OpenWebUI:
https://wiki.example.com/tools/openapi.json and your Bearer token.description fields
double as the LLM's tool prompts, so no extra authoring is required.tools.access.keys) are unbound and behave like a shared
service account that bypasses JAAS. Prefer DB-backed keys for any new deployment
and drop the legacy list once all clients have migrated.Retry-After: 1 header is
returned with every 429.