Code navigation
The lsp tool lets the model ask a language server for definitions, references, symbols and call hierarchies instead of searching text, and brings the server's errors and warnings back after the model edits a file. Mework uses common language servers it finds on your PATH; lsp.json adds or replaces servers.
Turn it on
The tool is Code navigation (lsp) in the Files and search group on the Tools page of Conversation settings. The built-in mework preset turns it on. Its operations and arguments are on the lsp tool page.
Language servers have no settings page and no per-conversation choice: every conversation with the tool uses whichever server claims the file.
Servers Mework finds on its own
Each of these is used when its command is on Mework's PATH.
| Name | Command | Files |
|---|---|---|
rust-analyzer |
rust-analyzer |
.rs |
typescript-language-server |
typescript-language-server --stdio |
.ts, .mts, .cts, .tsx, .js, .mjs, .cjs, .jsx |
pyright |
pyright-langserver --stdio |
.py, .pyi |
gopls |
gopls |
.go |
clangd |
clangd |
.c, .h, .cpp, .cc, .cxx, .hpp, .hxx, .hh (needs compile_commands.json) |
lua-language-server |
lua-language-server |
.lua |
bash-language-server |
bash-language-server start |
.sh, .bash |
lsp.json
| Level | File |
|---|---|
| Global | ~/.mework/lsp.json (Windows: %USERPROFILE%\.mework\lsp.json) |
| Workspace | <workspace>/.mework/lsp.json |
{
"lspServers": {
"zls": {
"command": "zls",
"extensionToLanguage": { ".zig": "zig" }
},
"pyright": {
"command": "basedpyright-langserver",
"args": ["--stdio"],
"extensionToLanguage": { ".py": "python", ".pyi": "python" }
}
}
}This adds a Zig server, and its pyright entry replaces the built-in server of that name. The format is the one Claude Code uses for plugin language servers.
- Server names use ASCII letters, digits,
-and_. - The whole file is ignored if it is not valid JSON or the servers are not under
lspServers. A UTF-8 byte-order mark at the start is fine. A bad entry is refused on its own; the rest of the file still counts.
| Key | What it does | Default |
|---|---|---|
command |
Required. The program to start, run directly — never through a shell. Put arguments in args; an absolute path may contain spaces. |
— |
extensionToLanguage |
Required, not empty. Maps file extensions to the language id sent to the server (rs, .rs and .RS are the same). This map alone decides which files the server handles. |
— |
args |
Arguments, as an array of strings. | none |
env |
Variables added to Mework's full environment for this server. | none |
initializationOptions |
Sent to the server when it starts. | {} |
settings |
The server's settings, sent after it starts and whenever it asks for them. | none |
workspaceFolder |
The folder the server indexes, as an absolute path. | The conversation's workspace |
startupTimeout |
Milliseconds the server has to start up. | 30000 |
shutdownTimeout |
Milliseconds the server has to shut down. | 5000 |
restartOnCrash |
Restart the server if it crashes. | true |
maxRestarts |
How many times it may be restarted. | 3 |
diagnostics |
false stops error and warning reports; navigation still works. |
true |
description |
A note about the server. | none |
transport |
Only "stdio" is supported. |
"stdio" |
${VAR} and ${VAR:-default} are replaced in command, args, env values and workspaceFolder, from Mework's environment. An unset variable with no default refuses the entry.
Which server answers a file
The first server that claims the file's extension answers, looked up in this order:
- the workspace's
lsp.json; ~/.mework/lsp.json;- the built-in servers.
Within one file, if two servers claim the same extension, the one written first wins. An entry whose name already exists at a lower level replaces it completely, extensions included.
Startup and changes
- A server starts on the first call for a file it claims. The first answers can be slow or empty while it indexes.
- One server runs per machine, folder and name, shared by every conversation in that workspace, until Mework quits.
- Edits to a server's entry in
lsp.jsontake effect on the nextlspcall. A running server whose configuration changed is restarted with the new settings, and a server that failed to start is tried again once its configuration changes. - Each request has 30 seconds, whatever
startupTimeoutsays. - If startup fails, the error includes the last line the server wrote to stderr.
Diagnostics after edits
After write or edit changes a file that a running server already has open, Mework tells the server about the change. An edit never starts a server.
New problems the server reports for that folder — errors, warnings, info and hints, for the edited file or any other — reach the model before its next step, shown as a Delivered language-server diagnostics card.
- Each problem is reported once, at most 10 per file and 30 in all.
- Diagnostics are delivered only if the conversation has
writeoreditturned on. "diagnostics": falsein a server's entry turns them off for that server.
Approvals
An lsp call counts as reading filePath:
- Inside the workspace it never asks. Outside, it asks at Manual only.
- If the workspace has its own
.mework/lsp.json, everylspcall asks at Manual and Accept edits, because that file can start any program. ~/.mework/lsp.jsonand the built-in servers never add a card.- Always allow is offered.
See security levels.
Limits
- Files over 10 MB are refused.
- Results in files Git ignores are left out of definitions, references, implementations and workspace symbol searches.
Remote machines
For a workspace on WSL or an SSH machine, the language server runs on that machine, and the configuration is read there: the workspace's .mework/lsp.json, then ~/.mework/lsp.json in the remote user's home, then the built-in servers found on that machine's PATH. Your lsp.json on this computer is not used.
Troubleshooting
"No LSP server available for file type". Install one of the built-in servers so its command is on PATH, or add an entry for the extension to lsp.json.
The first calls return nothing. The server is still indexing; try again shortly. clangd also needs compile_commands.json.
A definition or reference is missing. It may be in a file Git ignores.
Diagnostics never arrive. Check that write or edit is on, that the server was already running (any lsp call on that file starts it), and that diagnostics is not false.
Every call asks for approval. The workspace has a .mework/lsp.json (or an old .naiword/lsp.json).