HTTP & Socket API
lci server starts a long-running, per-project index daemon (IndexServer)
that speaks HTTP/JSON. lci CLI subcommands and the MCP server talk to it as
a client; you can also reach it directly.
Transport
Section titled “Transport”- Linux / macOS: a Unix domain socket at
<tmp>/lci-<uid>.sock(no project root given) or<tmp>/lci-<uid>-<hash>.sock(hash of the absolute project root). - Windows: no Unix sockets, so the server binds a loopback TCP port —
127.0.0.1:<port>— derived deterministically from the user id (and project-root hash, when set) so repeated runs land on the same port.
Endpoints
Section titled “Endpoints”All endpoints accept POST with a JSON body; ping, status, and stats
additionally accept GET with no body. Responses are application/json.
| Endpoint | Purpose |
|----------|---------|
| POST /ping | Liveness check |
| POST /status | Server status |
| POST /search | Content search (same engine as lci search) |
| POST /symbol | Symbol lookup |
| POST /fileinfo | File info |
| POST /shutdown | Shut the server down |
| POST /reindex | Trigger a re-index of the project root |
| POST /stats | Runtime metrics |
| POST /definition | Symbol definition (lci def) |
| POST /references | Symbol references (lci refs) |
| POST /tree | Function call hierarchy (lci tree) |
| POST /git-analyze | Git change analysis (lci git-analyze) |
| POST /list-symbols | Enumerate + filter symbols |
| POST /inspect-symbol | Deep inspect one symbol |
| POST /browse-file | Symbol outline for a file |
| POST /callers | Resolved call sites for a symbol |
| POST /mcp | Generic MCP JSON-RPC bridge (lci mcp forwards stdio frames here so bridged clients share this server’s warmed index); 501 if this server has no MCP hosting enabled |
| GET /ping | Liveness check, no body |
| GET /status | Server status, no body |
| GET /stats | Runtime metrics, no body |
/definition and /references are text searches (search_definitions /
the equivalent reference scan) resolved after the fact against the symbol
table for kind and signature — they do not walk the call/reference graph.
/callers, /tree, and /inspect-symbol use resolved graph edges (the
reference tracker’s confirmed call sites, or the type hierarchy) instead of
searching text.
Talking to it directly
Section titled “Talking to it directly”Over a Unix socket, with curl’s --unix-socket flag:
curl --unix-socket /tmp/lci-$(id -u).sock \ -X POST http://localhost/search \ -H 'Content-Type: application/json' \ -d '{"pattern": "myFunction"}'On Windows, the same request goes over the loopback TCP port instead of
--unix-socket.
Lifecycle
Section titled “Lifecycle”lci server/lci server --daemonstarts the daemon;--foregroundforces it to stay attached to the terminal (for debugging).lci statusqueries a running server without going through the CLI’s own indexing path.lci shutdown [--force]stops the server for the current project root;lci shutdown --allstops every server this user is running./shutdowndoes the equivalent for a single server over HTTP.lci serverslists every index server this user is running and the root each one serves — the socket/port name hashes the root, so the filesystem alone cannot tell you.- CLI subcommands that need index state (
search,def,refs,tree, …) start the server on demand if one isn’t already running for that project root, then reuse it for subsequent calls.
Reaper policies
Section titled “Reaper policies”A standalone server bounds its own lifetime under a server block in
.lci.kdl: idle_timeout_sec (default 1800) exits it after that long with
no real request (/ping doesn’t count); max_instances (default 8) makes
a starting server ask the least-recently-active servers beyond that cap to
stop; max_rss_mb (default 4096) is a self-cap — the server sheds cache
and, if still over, exits rather than grow past that RSS (0 disables); and
independent of all three, a server always exits within about 500 ms of its
indexed root being deleted. lci shutdown / lci servers read the instance
registry these policies publish into. The index server embedded in lci mcp
registers there too, but with its idle timeout disabled — the MCP client
owns that process’s lifetime.
Indexing is in-memory only — there is no disk persistence today, so the
index is rebuilt on every server start (or via POST /reindex).