MCP Servers
August 2, 2026 · View on GitHub
MCP (Model Context Protocol) servers add third-party tools to LLxprt Code. They let you connect to external services, databases, APIs, or custom tooling that goes beyond the built-in tools.
This page walks through the tasks you perform with MCP servers, in order: add a server, authenticate to it, verify the connection, use what it exposes, restrict how much you trust it, troubleshoot, and remove it.
Add a server
You can add an MCP server two ways: with the llxprt mcp add command, or by
editing your settings.json directly. Both write to the same configuration.
Via the CLI
llxprt mcp add my-server -- npx -y @example/mcp-server
This adds the server to your project configuration by default. To add it to your
user configuration (available in every project), pass --scope user.
The add command writes to either the user settings.json or the project
.llxprt/settings.json — see
Application Directories.
Command:
llxprt mcp add [options] <name> <commandOrUrl> [args...]
<name>— a unique name for the server.<commandOrUrl>— the command to run (forstdio) or the URL (forhttp,streamable-http, orsse).[args...]— optional arguments for astdiocommand. Use--to separate flags that belong to the server command itself.
Options:
| Flag | Description | Default |
|---|---|---|
-s, --scope | Configuration scope: user or project. | project |
-t, --transport | Transport type: stdio, sse, http, streamable-http. | stdio |
-e, --env | Environment variable, as KEY=value. Repeatable. | — |
-H, --header | HTTP header, as Key: Value. For SSE and HTTP transports. Repeatable. | — |
--timeout | Connection timeout in milliseconds. | — |
--trust | Trust the server (skip per-tool-call confirmation prompts). | — |
--description | Description for the server. | — |
--include-tools | Comma-separated list of tools to include. | — |
--exclude-tools | Comma-separated list of tools to exclude. | — |
Examples
# stdio server with environment variables
llxprt mcp add -e API_KEY=123 -e DEBUG=true my-stdio-server /path/to/server arg1 arg2
# stdio server, separating server-specific args with --
llxprt mcp add python-server python server.py -- --server-arg my-value
# HTTP (Streamable HTTP) server
llxprt mcp add --transport http http-server https://api.example.com/mcp/
# HTTP server with an authentication header
llxprt mcp add --transport http secure-http https://api.example.com/mcp/ --header "Authorization: Bearer abc123"
# SSE server
llxprt mcp add --transport sse sse-server https://api.example.com/sse/
Via settings.json
Add entries under the mcpServers key:
{
"mcpServers": {
"my-server": {
"command": "npx",
"args": ["-y", "@example/mcp-server"],
"env": {
"API_KEY": "your-key"
}
}
}
}
Transport types
stdio (default) — runs a local process:
{
"my-server": {
"command": "npx",
"args": ["-y", "@example/mcp-server"]
}
}
Streamable HTTP — preferred transport for remote MCP servers. Set the url
and optionally type:
{
"my-http": {
"url": "https://mcp.example.com/mcp",
"type": "http"
}
}
"type": "streamable-http"is accepted as an alias for"type": "http"— both select the Streamable HTTP transport. If you omittypeon a URL-based server, Streamable HTTP is used by default.
SSE — legacy remote transport for servers that have not migrated to Streamable HTTP:
{
"my-remote": {
"url": "https://mcp.example.com/sse",
"type": "sse"
}
}
The
httpUrlfield is deprecated. Useurlwith"type": "http"instead. If bothhttpUrlandurlare present,httpUrlis used and a deprecation warning is logged.
Tool filtering
Limit which tools a server exposes with includeTools and excludeTools:
{
"filteredServer": {
"command": "python",
"args": ["-m", "my_mcp_server"],
"includeTools": ["safe_tool", "file_reader", "data_processor"],
"excludeTools": ["dangerous_tool"]
}
}
excludeTools takes precedence over includeTools.
Authenticate
Remote MCP servers may require authentication. LLxprt Code supports OAuth and custom HTTP headers, and can impersonate a service account for Google Cloud IAP-protected services.
OAuth
Remote servers that require OAuth are supported through an authorization-code flow with PKCE and a loopback redirect. Whether OAuth activates, and when you must step in manually, depends on how the server is configured and how it responds at connect time.
Pre-configured OAuth (oauth.enabled: true). When a server entry sets
oauth.enabled to true, LLxprt Code treats that server as OAuth-protected on
every connect. It loads any stored access token; if none is stored (or the
stored token is expired and cannot be refreshed), the connect fails with a
message directing you to run /mcp auth <server>:
MCP server '<server>' requires OAuth authentication.
Please authenticate using the /mcp auth command.
OAuth does not start automatically for a oauth.enabled: true server at
connect time — you must complete the interactive flow once via /mcp auth.
Discovery-driven OAuth (no oauth block). When a server has no explicit
OAuth configuration, LLxprt Code first tries to connect directly. If the server
responds with a 401 and supplies OAuth metadata (via a WWW-Authenticate
header or /.well-known/oauth-authorization-server), LLxprt Code attempts the
full flow automatically: discover the endpoints, register a client if needed,
open the browser for authorization, and store the token. This automatic path
only succeeds when the server's OAuth metadata is discoverable; if discovery or
the flow fails, LLxprt Code reports that you must authenticate manually with
/mcp auth <server>.
Dynamic client registration (RFC 7591) is conditional, not unconditional.
During the flow, registration is skipped when you already provide a
clientId in the oauth block. When no clientId is configured, LLxprt Code
looks for a registration endpoint in the server's authorization-server metadata.
If the server exposes one, it registers dynamically; if the server exposes no
registration endpoint and no clientId was supplied, registration fails with an
error and the flow does not proceed.
Browser-based authorization. The authorization step always opens a browser to the provider's consent page. The OAuth configuration displayed in the terminal includes the full authorization URL so you can copy and paste it manually if the browser does not launch on its own. There is no MCP-specific headless or manual-paste OAuth mode.
You can pre-configure OAuth explicitly. Set enabled: true to activate OAuth
for the server; the remaining fields are optional and, if omitted, are
discovered automatically via /.well-known/oauth-authorization-server:
{
"my-oauth-server": {
"url": "https://mcp.example.com/mcp",
"type": "http",
"oauth": {
"enabled": true,
"clientId": "your-client-id",
"authorizationUrl": "https://auth.example.com/authorize",
"tokenUrl": "https://auth.example.com/token",
"scopes": ["read", "write"]
}
}
}
If a server's OAuth discovery or registration does not work with the built-in
flow, fall back to the mcp-remote stdio bridge:
{
"mcpServers": {
"webflow": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://mcp.webflow.com/mcp"],
"type": "stdio"
}
}
}
To authenticate or re-authenticate a server during a session:
/mcp auth <server-name>
This runs the interactive OAuth flow (discovery, optional registration, browser
authorization, token storage) and then re-discovers that server's tools.
Running /mcp auth with no argument lists the servers that are configured with
OAuth or have reported an authentication requirement.
Custom headers
For servers that use static API keys or bearer tokens, pass headers directly:
{
"mcpServers": {
"httpServerWithAuth": {
"url": "http://localhost:3000/mcp",
"type": "http",
"headers": {
"Authorization": "Bearer your-api-token",
"X-Custom-Header": "custom-value"
}
}
}
}
Service-account impersonation
For Google Cloud IAP-protected services, you can impersonate a service account:
{
"mcpServers": {
"myIapProtectedServer": {
"url": "https://my-iap-service.run.app/sse",
"type": "sse",
"authProviderType": "service_account_impersonation",
"targetAudience": "YOUR_IAP_CLIENT_ID.apps.googleusercontent.com",
"targetServiceAccount": "your-sa@your-project.iam.gserviceaccount.com"
}
}
}
Verify it worked
After adding a server, check that it connected successfully.
With /mcp
/mcp
This lists every configured server, its connection status, and a count of tools, prompts, and resources it exposes. A server entry looks like:
[READY] my-server - Ready (3 tools, 1 prompt, 2 resources)
Status indicators:
[READY]— connected and available.[STARTING]— connecting; first startup may take longer.[DISCONNECTED]— not connected or failed.
You can show tool descriptions and parameter schemas:
/mcp desc # show server and tool descriptions
/mcp schema # show tool parameter schemas (also shows descriptions)
/mcp nodesc # hide descriptions
If no servers are configured, /mcp links you to this documentation.
With llxprt mcp list
Outside a session, test whether each server is reachable:
llxprt mcp list
This attempts a live connection to each server and prints its name, configuration, and whether the connection succeeded.
Connection states
Each server tracks one of these states:
- Disconnected — not connected, or a connection error occurred.
- Connecting — a connection attempt is in progress.
- Connected — the server is connected and ready.
Apply configuration changes
After editing settings.json or running llxprt mcp add or
llxprt mcp remove in another terminal, apply the persisted changes to the
current session:
/mcp reload
Reloading adds newly configured servers, disconnects removed servers, and
reconnects servers whose configuration changed. Use /mcp refresh when you only
want to restart the servers already loaded, without rereading configuration.
Changing OAuth settings may still require
/mcp auth <server>. Installing or removing an extension still requires the extension reload flow or a new session.
Use it
Once a server is connected, its tools, prompts, and resources become available.
Tools
MCP tools work like built-in tools. The model selects them based on your request, asks for confirmation before running each call (unless the server is trusted — see Restrict trust), executes them, and displays the results.
Tool names are namespaced as mcp__<server-name>__<tool-name> so tools from
different servers never collide.
Prompts as slash commands
MCP servers can define prompts — reusable templates that appear as /
commands in LLxprt Code. Each prompt becomes a slash command you can invoke by
name.
/poem-writer --title="LLxprt Code" --mood="reverent"
Or, using positional arguments:
/poem-writer "LLxprt Code" reverent
When you invoke a prompt, LLxprt Code calls the prompts/get method on the MCP
server with the arguments you provide. The server substitutes the arguments
into the prompt template and returns the final text, which is sent to the
model.
Use <prompt-name> help to see the arguments a prompt accepts, or /help to
see all available commands.
Defining prompts on the server
Here is a minimal stdio MCP server that defines a prompt using the
@modelcontextprotocol/sdk:
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';
const server = new McpServer({
name: 'prompt-server',
version: '1.0.0',
});
server.registerPrompt(
'poem-writer',
{
title: 'Poem Writer',
description: 'Write a nice haiku',
argsSchema: { title: z.string(), mood: z.string().optional() },
},
({ title, mood }) => ({
messages: [
{
role: 'user',
content: {
type: 'text',
text: `Write a haiku${mood ? ` with the mood ${mood}` : ''} called ${title}. Note that a haiku is 5 syllables followed by 7 syllables followed by 5 syllables.`,
},
},
],
}),
);
const transport = new StdioServerTransport();
await server.connect(transport);
Resources
MCP servers can expose resources — readable content you can pull into your
conversation. You reference a resource with the @ syntax:
@serverName:resourceUri
For example:
@docs:file:///workspace/README.md
When this pattern matches a discovered resource, LLxprt Code reads it via
resources/read and injects the content into the request. Binary resources are
shown as a safe placeholder summary (MIME type and size) rather than raw bytes.
Resources also appear in /mcp output, which lists each server's discovered
resource names and URIs.
Rich content from tools
MCP tools can return rich, multi-part content in a single response — text,
images, audio, and embedded resources. To return rich content, your tool's
response must follow the MCP specification for a
CallToolResult:
the content field is an array of content blocks.
Supported block types:
textimageaudioresource(embedded content)resource_link
{
"content": [
{
"type": "text",
"text": "Here is the logo you requested."
},
{
"type": "image",
"data": "BASE64_ENCODED_IMAGE_DATA_HERE",
"mimeType": "image/png"
},
{
"type": "text",
"text": "The logo was created in 2025."
}
]
}
LLxprt Code extracts text blocks and combines them into the model's context, presents images and audio as separate parts, and shows a readable summary in the CLI.
Restrict trust
MCP servers run code and make network requests. Control how much trust each server gets.
Confirmation prompts
By default, every MCP tool call asks for confirmation before it runs. When prompted, you can choose to:
- Proceed once — run this call only.
- Always allow this tool — skip confirmation for this specific tool going forward.
- Always allow this server — skip confirmation for every tool from this server.
- Cancel — abort the call.
The trust option
The trust option bypasses all confirmation dialogs for a server. Use it only
for servers you completely control:
{
"my-server": {
"command": "npx",
"args": ["-y", "@example/mcp-server"],
"trust": true
}
}
You can also set trust when adding a server:
llxprt mcp add --trust my-server /path/to/server
Trust bypasses confirmation only when the working directory is a trusted folder. In an untrusted folder, confirmation is still required.
Security considerations
- Access tokens. Be careful when configuring environment variables or headers that contain API keys or tokens.
- Personal access tokens. Broadly scoped tokens can leak information between repositories or projects.
- Sandboxing. When running in a sandbox, MCP servers must
be available inside the container. If your server uses
npx, the npm package must be installable within the sandbox environment.
Lazy MCP schema loading
When you have many MCP servers with large tool schemas, every tool schema is
sent to the model on each request. The mcp.lazy setting defers those schemas
so only the servers you actually need are published.
- Servers stay connected. Discovery, connection, tool registration, prompts, and resources all work as before. Only model-facing schema publication is deferred.
- The model gets an
activate_mcp_servertool. Its description lists each deferred server's name, tool count, and up to 12 tool names — never full parameter schemas. The model calls it with a server name to activate that server. - Activation is session-scoped. Once activated, a server's full schemas are published for the rest of the session. There is no automatic deactivation; to restart, create a new session.
- Eager exceptions. Use
mcp.eagerServersto keep specific servers always-eager even when lazy mode is on.
Scope: ephemeral (also persistable to a profile).
Default: false (eager). Persistable: yes.
Enable lazy mode:
/set mcp.lazy true
Keep specific servers eager:
/set mcp.eagerServers ["my-important-server","another-server"]
/setupdates ephemeral settings but does not republish tools in an already-initialized chat. To apply lazy mode, save and reload a named profile (/profile save lazy-mcp, then/profile load lazy-mcp) or start a new session with that profile.
Tradeoffs
Lazy mode reduces token overhead for sessions with large MCP tool sets, but the
model must spend a turn calling activate_mcp_server before it can use a
deferred server's tools. For sessions where you always use every MCP tool,
eager mode (the default) is better.
Troubleshoot
Server won't connect
-
Verify the
command,args, andcwdare correct in your configuration. -
For
stdioservers, run the command manually to see startup errors. -
Check the server's dependencies are installed.
-
Enable debug logging for detailed connection output:
llxprt --debug llxprt:mcp:*You can also use
LLXPRT_DEBUG=llxprt:mcp:*. Debug output is written to a JSONL file in your log directory and to stderr. Use F12 to open the debug console in an interactive session.
No tools discovered
- Run
/mcpto confirm the server is connected. - The server may need time to start — tools appear after the connection is established.
- If tool names conflict with built-in tools, the built-in tool takes precedence.
- Verify the server actually registers tools and implements the MCP tool-listing protocol correctly.
Tools not executing
- Ensure your tool accepts the parameters the model sends.
- Verify your input schemas are valid JSON Schema.
- Check whether the tool is throwing unhandled exceptions (review server logs).
- If calls time out, increase the
timeoutsetting.
OAuth failures
- Ensure the OAuth URLs and client ID are correct.
- Check whether the server's OAuth flow requires specific scopes.
- Try re-authenticating:
/mcp auth <server>. - Remove cached tokens from your OS-standard data directory and reconnect.
"SSE is no longer supported" error
Some MCP providers have deprecated their SSE endpoint in favor of Streamable
HTTP. Switch your configuration from the SSE endpoint to the Streamable HTTP
endpoint with "type": "http":
{
"mcpServers": {
"webflow": {
"url": "https://mcp.webflow.com/mcp",
"type": "http"
}
}
}
If the provider's OAuth flow does not work with the automatic mode, fall back to
the mcp-remote stdio bridge as shown in Authenticate.
Environment variables not reaching the server
- Variables in the
envblock are passed to the server process. - A stdio server inherits the full parent environment (the environment
LLxprt Code itself runs with). Entries in the
envblock are applied on top of, and override, any inherited value with the same name.
Security implication. Because a stdio server inherits the parent environment, the server process can see every variable in it — including API keys, tokens, and other secrets. The
envblock is not an allowlist: it only adds or overrides entries on top of the inherited environment. It cannot remove or hide inherited variables such as an API key that LLxprt Code itself uses. To prevent a server from seeing secrets it should not, do one of the following:
- Launch LLxprt Code from a sanitized environment where the secrets are not set, then pass only what the server needs via its
envblock.- Wrap the server command in a script that unsets the sensitive variables before starting the server process.
- Run the server (and LLxprt Code) inside a sandbox so the inherited environment is already bounded.
Sandbox compatibility
When sandboxing is enabled, MCP servers must be available inside the container:
- Use Docker-based servers that include all dependencies.
- Ensure server executables are reachable from inside the sandbox.
- Configure the sandbox to allow any network connections the server needs.
- Verify required environment variables are passed through.
Remove a server
llxprt mcp remove my-server
By default this removes the server from your project configuration. To remove it
from your user configuration, pass --scope user:
llxprt mcp remove --scope user my-server
If the server is not found in the specified scope, the command reports that and makes no change.
You can also remove a server by deleting its entry from mcpServers in your
settings.json, then running /mcp reload to apply the change to a running
session.
Related
- Tools — all built-in tools
- Sandboxing — running in a container
- Settings — where MCP configuration lives