Docs menu
Get started
Quickstart Install: Claude Code Install: Codex Install: other clients API keysConcepts
How a run works The app profile The severity model What a run does not sayTools
check_access claim_trial_key set_profile run_lint get_law resolve_domain_jurisdiction submit_feedback upload_lint_runGuides
A whole run, end to end Console TestPack in CIReference
Endpoint and transport lexlint.yml schema Errors ChangelogHelp
Support and feedbackGet started
Install LexLint in another MCP client
The configuration every streamable HTTP client shares, and the two fields that move between clients.
https://mcp.lexlint.io/mcp
Any client that speaks streamable HTTP works: the server is stateless and holds no session of its own, so nothing has to be kept between calls. The block above is the common core, and Cursor takes it exactly as written.
The shared block is a core rather than a universal config because two fields move between clients, and between them they account for nearly every failed setup: what the URL field is called, and what the transport is called. Neither is guessable and a client that dislikes your answer rarely says so. Find your client in the table before you paste.
Find your client
| Client | Root key | URL field | Transport |
|---|---|---|---|
| Cursor | mcpServers | url | omit it |
| Zed | context_servers | url | omit it |
| Antigravity | mcpServers | serverUrl | omit it |
| Devin Desktop | mcpServers | serverUrl | omit it |
| Copilot in VS Code | servers | url | http |
| Tabnine | mcpServers | url | http, or omit |
| Cline | mcpServers | url | streamableHttp |
| Kiro | mcpServers | url | streamable-http |
| IBM Bob | mcpServers | url | streamable-http |
| Kilo Code, the extension | mcpServers | url | streamable-http |
| Kilo Code, the CLI | mcp | url | remote |
| Continue | mcpServers, a YAML list | url | streamable-http |
| Codex | mcp_servers, a TOML table | url | see the Codex page |
Two of those are worth saying out loud, because they fail silently rather than
loudly. VS Code reads servers, so a file that says
mcpServers parses and registers nothing. What you see is a client with
no LexLint tools, and nothing anywhere naming the key. Antigravity and Devin
Desktop want serverUrl and reject a plain url, which is the
same failure wearing a different field name. In both cases the natural conclusion is
that mcp.lexlint.io is down, and it is not.
The transport is the other half, and the spellings are not interchangeable:
streamableHttp is camel-cased for Cline, streamable-http is
hyphenated for Kiro, Kilo and Continue, and http is VS Code's alone.
Give Cline the hyphenated form and it falls back to the older SSE transport and
answers 405. Where the table says to omit it, omit it: those clients infer the
transport from the presence of a URL, and an unexpected value is one more thing that
can be rejected.
Then add your key
Nothing above carries a key, which is deliberate: check_access answers
without one, reporting key_present: false beside a sign-in link and
the steps, so you can prove the connection before you have anything to paste.
claim_trial_key answers keyless too, and mints one. The
other six refuse until you have a key, carrying the same link in the refusal.
When you do have one it goes in a headers object, which every client in
the table accepts under that name. The key goes in X-API-Key and nowhere
else: an Authorization: Bearer header is read as an OAuth access token, never
as a key.
Mind the comma the URL line gains:
That is a second edit to the same file, and for these clients nothing will make it for
you. Claude Code has /lexlint-key to write the key where the next
session will read it, and Codex has its own documented step; a client outside those
two has neither.
${UNGOVR_API_KEY} is the plain-environment form, and expansion is the
client's job. Three of the clients above do it their own way, and a placeholder a
client does not expand is sent to us as literal text, which reads back as a rejected
key rather than as a config error. Cursor wants
${env:UNGOVR_API_KEY}. Continue templates secrets as
${{ secrets.UNGOVR_API_KEY }}. VS Code expands neither, and wants an
input declared and referenced, which is the better shape anyway because VS Code
prompts once and stores the value itself rather than leaving it in a file you might
commit:
Continue is the one whose whole shape differs: a list rather than an object, and
headers under requestOptions rather than at the top level.
Anywhere your client expands nothing, paste the key literally and treat the file as the secret it then contains.
If your client only speaks stdio
Some clients, and some older builds of clients that have since added HTTP, will only
launch a local process. mcp-remote bridges the two: it speaks stdio to
your client and streamable HTTP to mcp.lexlint.io, and it needs nothing installed
beforehand.
There is no space after that colon, and putting one back breaks it on several
clients: Cursor, the Codex CLI and Claude Desktop on Windows do not escape spaces
inside args when they invoke npx, so the value arrives
cut in half. Note also that anything written into args literally is
readable in the process list by anyone else on the machine, which is a second
reason to leave the key in the environment and let
${UNGOVR_API_KEY} stand.
On a managed or on-premises client
IBM Bob, Tabnine, Kiro and Copilot on GitHub Enterprise Server each read a file of
your own, and all four are in the table above: Bob takes
~/.bob/mcp.json, or .bob/mcp.json committed with the
project, and Tabnine takes ~/.tabnine/agent/settings.json. What
changes on their governed deployments is who is allowed to write one. An
administrator registers servers centrally and user-level additions may be refused,
and that registration usually needs two things past the URL.
The first is reachability. mcp.lexlint.io is the only
host LexLint asks for, so on an egress-filtered network it is one allowlist entry
and no more, and on one that routes through an approved proxy it is one rule there.
A genuinely air-gapped install is the exception and the answer is plain: LexLint is
a hosted service and there is no offline build of it, so it cannot run in a network
with no route out. Several of the clients above are chosen precisely for air-gapped
work, and on those deployments this is not something an allowlist fixes.
The second is the key. Admin consoles rarely expand environment variables, so it goes in as a literal and the registration becomes a secret to be handled as one. A key minted for the team rather than for a person is the usual answer, since the upstream meter counts against whoever the key belongs to.
The worked run shows what a full lint looks like from the agent's side, whichever of these got you connected.