Streamable HTTP security
Kioku’s HTTP transport exposes vault tools to multiple MCP clients. Treat it as a privileged local service: it can read and mutate the configured Obsidian vault with the permissions of the Kioku process.
Secure defaults
The server applies these controls before the MCP endpoint handles a request:
- binds to
127.0.0.1by default; - refuses an unauthenticated non-loopback listener;
- compares bearer tokens in constant time;
- validates every present
Originheader against an exact allowlist and returns HTTP 403 for malformed or disallowed origins; - accepts missing
Originheaders for non-browser MCP clients; - limits request bodies to 1 MiB and MCP POST execution to five minutes by default;
- trusts no forwarded headers unless exact proxy IP addresses are configured;
- exposes only a minimal public liveness response;
- protects readiness with the same bearer token as
/mcp.
These defaults follow the MCP Streamable HTTP transport requirement to validate Origin and the
recommendation to bind local servers only to loopback.
Configuration
| Variable | Default | Description |
|---|---|---|
KIOKU_HTTP_HOST |
127.0.0.1 |
Listener host or interface. Use 0.0.0.0 only for an intentional container/LAN deployment. |
KIOKU_HTTP_PORT |
5173 |
Listener port. |
KIOKU_API_KEY |
unset | Bearer token. Required for non-loopback binding. Generate at least 32 random bytes. |
KIOKU_HTTP_ALLOWED_ORIGINS |
loopback and Obsidian origins | Comma-separated exact browser origins. Do not use wildcards. |
KIOKU_HTTP_TRUSTED_PROXIES |
unset | Comma-separated exact proxy IP addresses allowed to set X-Forwarded-For and X-Forwarded-Proto. |
KIOKU_HTTP_MAX_REQUEST_BODY_BYTES |
1048576 |
Request-body limit; valid range is 1 KiB–100 MiB. |
KIOKU_HTTP_REQUEST_TIMEOUT_SECONDS |
300 |
Timeout for MCP POST calls; valid range is 1–3600 seconds. SSE GET connections are not timed out. |
KIOKU_ALLOW_INSECURE_HTTP |
false |
Explicit escape hatch for an unauthenticated non-loopback listener. Avoid in real deployments. |
Generate an API key without storing it in shell history:
openssl rand -hex 32
Local-only deployment
No API key is required when the listener remains on loopback:
export KIOKU_VAULT_PATH=/path/to/vault
export KIOKU_TRANSPORT=http
kioku
The MCP endpoint is http://127.0.0.1:5173/mcp.
Reverse proxy deployment
Keep Kioku bound to loopback and terminate TLS at nginx, Caddy, a private tunnel, or a mesh VPN. Configure the proxy address explicitly so arbitrary clients cannot spoof forwarded headers:
export KIOKU_HTTP_HOST=127.0.0.1
export KIOKU_API_KEY="$(openssl rand -hex 32)"
export KIOKU_HTTP_TRUSTED_PROXIES=127.0.0.1,::1
For a browser-based MCP client, also allow the public origin exactly:
export KIOKU_HTTP_ALLOWED_ORIGINS=https://kioku.example.com
Non-browser clients normally omit Origin and don’t need an allowlist entry. Never trust
forwarded headers from 0.0.0.0/0, and don’t enable ASP.NET Core’s unrestricted cloud-forwarding
environment switch.
See nginx.conf for a hardened example with TLS, disabled buffering, bounded body
size, and matching timeouts.
Health endpoints
| Endpoint | Authentication | Successful response | Purpose |
|---|---|---|---|
/health/live |
Public | 200 {"status":"ok"} |
Confirms the process and HTTP listener are alive. |
/health/ready |
Bearer token when configured | 200 when the vault index is ready; otherwise 503 |
Reports index and optional Ollama capability state without paths or secrets. |
Examples:
curl --fail http://127.0.0.1:5173/health/live
curl --fail \
-H "Authorization: Bearer $KIOKU_API_KEY" \
http://127.0.0.1:5173/health/ready
Use liveness for process restarts and readiness for load-balancer traffic decisions.
Client configuration
{
"mcpServers": {
"kioku": {
"type": "http",
"url": "https://kioku.example.com/mcp",
"headers": {
"Authorization": "Bearer replace-with-your-token"
}
}
}
}
Use HTTPS, a private tunnel, or a mesh VPN whenever traffic leaves the local machine. A bearer token sent over plaintext HTTP can be intercepted.
Authentication boundary
KIOKU_API_KEY is intentionally a simple shared-secret mechanism for a trusted personal or small
team deployment. It has no users, scopes, expiry, refresh, or delegated authorization. Rotate the
token if it is exposed and avoid placing it in repository files, container images, logs, or URLs.
For an internet-facing or multi-tenant service, place Kioku behind a standards-based authorization gateway today. A future Kioku multi-user mode should implement the MCP authorization specification with OAuth-based discovery and scoped access rather than extending the static API-key mechanism.
Unsafe override
Kioku refuses this configuration:
KIOKU_HTTP_HOST=0.0.0.0 KIOKU_TRANSPORT=http kioku
For isolated testing only, it can be overridden explicitly:
KIOKU_HTTP_HOST=0.0.0.0 \
KIOKU_ALLOW_INSECURE_HTTP=true \
KIOKU_TRANSPORT=http \
kioku
The server emits a prominent warning. The override is not a substitute for authentication, firewall rules, TLS, or a private network.