Server configuration
okto-pulse serve is one Python process running two uvicorn listeners — the API + Web UI on 8100 and the MCP server on 8101 (80-pulse-feature-inventory.md:213–215). Configuration is read from environment variables and an optional .env file via pydantic-settings. Every field on CoreSettings accepts an env-var override using its uppercase field name (80-pulse-feature-inventory.md:178–180).
This page covers the runtime knobs you actually need to touch: ports, bind hosts, CORS, logging, and worker tuning. For the full env-var reference, see Environment variables. For where Pulse stores data, see Storage paths.
Ports
Two listeners, two defaults.Override on the command line
--api-port writes OKTO_PULSE_PORT and --mcp-port writes OKTO_PULSE_MCP_PORT into the process environment before importing okto_pulse.community.main — that module evaluates app = create_community_app() at import time and bakes the port values into /config.js for the Web UI (inventory:53–60). Setting them later, after the import, is too late.
Override via environment
Both ports must be free on the bind host before
serve starts. Run okto-pulse status to confirm the current binding (inventory:63–80).Bind addresses
Pulse separates the two listeners’ bind hosts on purpose: the API (port 8100) defaults to loopback because it serves the Web UI and admin endpoints, while the MCP server (port 8101) needs to be reachable from the agent.- Local (default)
- Docker / container
- LAN-exposed (advanced)
Both listeners bind
127.0.0.1. Reachable only from the same machine. This is the safe default — your agent connects via http://localhost:8101/mcp?api_key=....CORS
The API enforces CORS on the Web UI and any third-party browser client.
The community edition overrides the core default to
* so the bundled Web UI works regardless of how you reach it (inventory:765, inventory:191). Override per environment by setting CORS_ORIGINS to a comma-separated list:
CORS is enforced by the API, not the MCP server. MCP requests are server-to-server and not subject to CORS — the API key is the access control there.
Logging
Pulse uses Python’s standardlogging module. Logs stream to stdout/stderr by default.
Log level
Set viaDEBUG=true or by configuring logging directly with standard Python tooling. There is no dedicated LOG_LEVEL env var; DEBUG toggles INFO → DEBUG for okto_pulse.* loggers.
Log destinations
By default, logs go to:- stdout for
INFOand below - stderr for
WARNING,ERROR,CRITICAL - No file logging — the process does not write a log file. Capture stdout/stderr if you need persistence.
systemd unit, journald captures both streams automatically:
MCP call tracing
Independent of the standard logger, Pulse can record every MCP tool call to a JSONL trace.Worker tuning (uvicorn)
Pulse runs with a single uvicorn worker, by default and by design.okto-pulse serve exposes --api-port, --mcp-port, and --accept-terms only — there is no --workers flag (okto-pulse/src/okto_pulse/community/cli.py:223–276 / inventory:53–60). The KG consolidation pipeline, the queue scheduler, and the embedded LadybugDB graph all assume one writer per process; spawning multiple uvicorn workers would create concurrent writers, lock contention, and split queue state.
What you can tune:
Sources:
CoreSettings fields kg_queue_max_concurrent_workers, kg_queue_min_interval_ms, kg_connection_pool_size, kg_kuzu_buffer_pool_mb (inventory:780–784).
The
KG_KUZU_* and kg_kuzu_* field names are legacy — Pulse uses LadybugDB (the Kùzu-derived engine) under the hood since 2026-05-03. The variable names are kept stable for backward compatibility; the underlying engine is LadybugDB.KG_QUEUE_* and KG_DECAY_TICK_* fields are hot-reloadable. APScheduler re-reads them with a 5-second debounce and kg_decay_tick_* can be updated through PUT /settings/runtime without a restart (inventory:790–793).
Reverse proxy notes
If you front Pulse with Caddy, nginx, or Traefik:- Bind Pulse to
127.0.0.1and let the proxy terminate TLS and forward. - Set
MCP_HOST=127.0.0.1to keep the MCP listener loopback-only behind the proxy. - Forward
Host,X-Forwarded-For, andX-Forwarded-Protoso the API renders absolute URLs correctly. - WebSockets are not used by the API or MCP — plain HTTP/1.1 is sufficient. Streamable HTTP responses (MCP SSE) require the proxy to disable response buffering on
/mcp.
Verifying the running config
okto-pulse status reads the SQLite metadata and probes the configured ports:
cli.py:567–614 (cmd_status) (inventory:67–78).
The 216 MCP tools exposed by the running process are listed in the MCP reference.
Related
Storage paths
Where Pulse keeps its database, attachments, and per-board knowledge graphs.
Environment variables
Full reference of every
CoreSettings field and its env-var name.Docker install
Run Pulse in a container with the right
HOST and MCP_HOST defaults.MCP setup
Connect Claude Code, Cursor, Cline, Windsurf, or Codex to your board.