Admin Guide - NormB/kamailio-lsp GitHub Wiki
kamailio-lsp is a Language Server Protocol server for the Kamailio
configuration file language (kamailio.cfg), for any LSP-capable
editor. Positions are exchanged in UTF-16 units per the LSP default,
correct on multibyte lines.
The full capability list lives in Features-and-Settings and is checked against the server on every build, so it cannot fall behind what ships. It is deliberately not repeated here: a second list is a second thing to forget.
Semantic validation is delegated to Kamailio itself: the server runs
kamailio -c --all-errors -Y <tmpdir> -f <file> and maps the
parser's own errors (file, line, column — including column ranges and
multi-line spans) to LSP diagnostics, so results are exact for the
Kamailio version installed. Editor intelligence (completion, hover)
comes from a documentation catalog harvested right after
initialization (a readiness log message reports the counts; results
are cached — see Caching): module documentation from the generated
plain-text README of every module in a Kamailio source tree
(src/modules/<name>/README), and core-language documentation
(parameters, functions, pseudo-variables) from a
kamailio-wiki checkout
(docs/cookbooks/<version>/{core,pseudovariables}.md — the newest
stable cookbook is picked automatically). Version-proven: Kamailio
6.1.x (binary 6.1.4, tag 6.1.4 tree, 6.1.x cookbook) and 6.0.x
(binary 6.0.1, branch 6.0 tree).
The server itself has no runtime library dependencies. Optional but recommended:
- a
kamailiobinary — enables diagnostics (-c). Without it (or with the parameter set empty) diagnostics are disabled while all other features keep working. - a Kamailio source tree — enables module completion and hover documentation.
- a kamailio-wiki checkout — enables core-language completion and hover (core parameters, core functions, pseudo-variables).
The parameters below are passed as LSP initializationOptions (see
the editor guides in docs/EDITORS.md); most have an environment
fallback for clients that cannot pass options.
The runtime toggles — analyzerDiagnostics, snippetCompletions,
codeLensReferences, maxDiagnostics, checkTimeoutMs — can also
be retuned live via workspace/didChangeConfiguration (settings
wrapped in a kamailioLsp section or flat); the server applies them
in place and republishes diagnostics for open documents. The path
parameters (kamailioPath, kamailioSrc, kamailioWiki,
modulesPath, cacheDir) apply at initialization only.
Path to the kamailio binary used for -c diagnostics. Set to the
empty string to disable diagnostics entirely — see the Security
note below.
Default value is kamailio (PATH lookup). Environment fallback:
KAMAILIO_LSP_BIN.
{ "kamailioPath": "/usr/sbin/kamailio" }Kamailio source tree to harvest module documentation from
(src/modules/<name>/README). When unset, completion is limited to
core keywords and route names, and module hover is unavailable.
Default value is unset. Environment fallback: KAMAILIO_LSP_SRC.
{ "kamailioSrc": "/home/user/src/kamailio" }Whether built-in documentation repeats the release it came from, under every hover and completion item.
Off by default. The release is on the status bar the whole time a config is open, and every warning that turns on it names it, so a hover saying it again is the same fact a third time. Turn it on if you read hovers in isolation or paste them elsewhere and want the provenance travelling with the text.
The note distinguishes the two catalogues, because they are pinned
differently: module documentation follows kamailioVersion, while
core documentation is a single vendored artefact and names its own
release whatever you have selected.
Default value is false. Environment fallback:
KAMAILIO_LSP_VERSION_IN_HINTS.
{ "versionInHints": true }Which built-in Kamailio release to check modparam names against.
What a module exports moves between releases, so a configuration that
is correct on one can look wrong when judged against another.
In VS Code and VSCodium this is a dropdown listing exactly the
releases the shipped catalogue can answer for, so the value cannot
be mistyped. Editing settings as JSON, it accepts any release the
built-in catalogue covers — currently
5.8.8, 6.0.7 and 6.1.4. An unrecognised value is reported and
the newest is used, rather than silently checking against a release
you did not ask for.
Ignored when kamailioSrc is set: your own tree is exact for your
build, and this is a choice among the ones shipped here.
Default value is the newest release the catalogue covers.
Environment fallback: KAMAILIO_LSP_VERSION.
{ "kamailioVersion": "6.0.7" }kamailio-wiki checkout to harvest core-language documentation from.
Point it at a clone of
https://github.com/kamailio/kamailio-wiki (the newest stable
docs/cookbooks/<N.N.x> is picked), or directly at a directory
containing core.md and pseudovariables.md.
Default value is unset. Environment fallback: KAMAILIO_LSP_WIKI.
{ "kamailioWiki": "/home/user/src/kamailio-wiki" }Module search path passed to the checker as -L <path>. Useful when
the modules matching your configuration are not in the binary's
default mpath.
Default value is unset (the binary's compiled-in default applies).
{ "modulesPath": "/usr/lib/x86_64-linux-gnu/kamailio/modules" }Upper bound, in milliseconds, on one kamailio -c run. A run that
exceeds it is killed and reported via a client log message.
Default value is 10000. Environment fallback:
KAMAILIO_LSP_CHECK_TIMEOUT_MS.
{ "checkTimeoutMs": 3000 }Harvest results are cached per (source tree, wiki) pair under
$XDG_CACHE_HOME/kamailio-lsp (or ~/.cache/kamailio-lsp), keyed by
a fingerprint of the canonical paths plus a manifest of every file
the harvest reads — each module's README and the wiki cookbook
pages, by size and modification time — folded together with a cache
schema version. Adding, removing, or editing a module README or
cookbook page invalidates the cache automatically; cache format
changes invalidate via the schema version. The readiness log message
says , cached on a hit. Override the location with the
KAMAILIO_LSP_CACHE_DIR environment variable (env-only knob);
deleting the directory also forces a re-harvest.
During the harvest the server reports progress via LSP
workDoneProgress (clients that advertise
window.workDoneProgress show a busy indicator). If a configured
kamailioSrc yields zero documented modules, or a configured
kamailioWiki yields zero core symbols, a visible
window/showMessage warning names the offending path.
Draw the parameter name from the documentation before each argument
of a documented call, so t_relay("udp", 1) reads as
t_relay(flags: "udp", outbound_proxy: 1) without the document
changing. Only calls the catalogue knows are hinted, and the editor
asks for the visible range only.
Default value is true.
{ "inlayHintParameterNames": false }Draw what each #!define-family symbol expands to, at every use —
including inside #!ifdef, where the operand is a directive token
rather than code. The definition site is not hinted, since
#!define PORT 5060 already says what it binds.
Default value is true.
{ "inlayHintDefineValues": false }Bound on the diagnostics published per file.
Default value is 100.
{ "maxDiagnostics": 50 }Fast analyzer warnings between saves, debounced as you type:
route(NAME) calls whose target is defined nowhere in the file or
its include_file/import_file closure, and duplicate route
definitions. Severity warning, source kamailio-lsp; merged with the
stored kamailio -c results on every publish. The debounce is
tunable via KAMAILIO_LSP_ANALYZER_DEBOUNCE_MS (default 300).
Default value is true.
{ "analyzerDiagnostics": false }Answer hovers and completion at all. Turn it off to read a configuration without popups appearing over it — walking a colleague's file, or presenting one — and on again the same way.
In VS Code the toggle is bound to Ctrl+Alt+
H (Cmd+Alt+H on macOS),
and the status bar reads Kamailio hints off while it is off, so a
silent editor is never mistaken for a broken one. It takes effect
immediately: no restart, and no reopening the file.
Diagnostics are not part of it. Whether a configuration is valid is
not noise while reading, and analyzerDiagnostics and
diagnostics.enable already switch those separately.
Default value is true.
{ "assistance": false }Show a reference-count code lens above every named route block
(only main-table blocks are route()-callable, so only they get a
count; references are counted across the include closure).
Default value is true.
{ "codeLensReferences": false }Insert function completions as tabstop snippets.
Default value is true.
{ "snippetCompletions": false }Documentation-catalog cache directory.
Default value is the platform cache dir. Environment fallback:
KAMAILIO_LSP_CACHE_DIR.
{ "cacheDir": "/var/cache/kamailio-lsp" }Nothing the server reads leaves the machine. No HTTP client is linked into the binary, it opens no sockets, and it speaks JSON-RPC to the editor over stdin and stdout. There is no telemetry, no analytics, no crash reporting and no update check, and no language model is involved at any point: hover and completion text is parsed from Kamailio's own documentation on disk rather than generated.
Everything it touches is local:
-
Read — the open configuration and every file its
include_file/import_fileclosure names, plus the configuredkamailioSrctree andkamailioWikicheckout. - Written — the documentation catalog cache described under Caching above. It holds harvested documentation only; configuration text is never written to it.
-
Executed — the
kamailioPathbinary, once per check, under the constraints described under Security below.
Two caveats matter where configuration content is sensitive:
-
trace.serverset tomessagesorverbosewrites the LSP traffic — which carries the full text of every open configuration — into the editor's output channel. It stays on the machine, but it is the one place configuration text lands in a log that is easy to attach to a bug report. The default isoff. - The editor is a separate trust domain. Its own telemetry, and any extension with access to the buffer, see the configuration whatever this server does.
kamailio -c dlopens the modules the configuration loads, so
their constructors run: opening a configuration from an untrusted
source executes code. Rely on your editor's workspace-trust
mechanism, or set kamailioPath to the empty string for untrusted
trees. -c runs are serialized (one at a time), bounded by
checkTimeoutMs, and their output is byte-capped
(KAMAILIO_LSP_OUTPUT_CAP_BYTES, default 1 MiB). A newer save of
the same document supersedes an in-flight check: the stale run's
child process is killed and the fresh content is checked
immediately (latest wins). The checker runs with its working
directory set to the configuration's own directory, so relative
include_file/import_file paths resolve exactly as they do in
the CLI (kamailio-lsp check).
Either kamailioPath is empty/unresolvable (check the editor's LSP
log for the startup warning), or the file is not saved to disk —
diagnostics run against the on-disk file on open and save.
kamailioSrc is not set, or the module is not loadmodule-ed in the
current file: function completion is intentionally limited to loaded
modules. Core functions, parameters, and pseudo-variables come from
the wiki checkout (kamailioWiki).
The cache fingerprint watches every harvested file's size and mtime,
so editing a module README or a cookbook page re-harvests on the
next start. If something still looks stale (e.g. a tool rewrote a
file preserving both size and mtime), delete the cache directory
(see Caching) to force a re-harvest.
The -c run resolves loadmodule against the binary's compiled-in
module path. Point modulesPath at the directory holding the .so
files that match your configuration (it becomes -L <path>).
Dual-licensed under MIT or Apache-2.0, at your option. See
LICENSE-MIT and LICENSE-APACHE in the repository root.