Overview
1
Load configuration
The MCP Manager loads the MCP server configuration.
2
Start servers
Starts the configured servers (stdio, SSE or Streamable HTTP).
3
Discover tools
Discovers the available tools on each server.
4
Expose to the model
Exposes the tools to the AI model as
ToolDefinition.5
Route calls
Routes tool calls to the correct server.
Configuration
The chatcli mcp subcommand (recommended)
Manage servers from the shell β same developer experience as claude mcp add, writing to ~/.chatcli/mcp_servers.json atomically (hand-maintained extension keys survive rewrites; re-adding a name replaces it):
add: --cwd DIR (stdio working directory), --description TEXT, --disabled (add without enabling).
Configuration File
Create~/.chatcli/mcp_servers.json:
Extended server capabilities
Beyond the minimum (name, command, args, env, transport, enabled, overrides), each server entry accepts an opt-in set of fields covering the same cases Claude Code, Cline, Cursor, and the AWS EKS MCP server support β tool auto-approval, enabledTools/disabledTools filtering, per-server timeouts, working directory, custom HTTP headers, and HTTP authentication (bearer/basic/header, shared by sse and http), plus metadata (description, tags, category) shown in /mcp status.
Any key outside the typed schema is preserved verbatim across save/load (the Extensions catch-all), so a config copied from another client works without losing vendor-specific annotations.
Full reference with semantics, examples and troubleshooting: MCP Servers Configuration.
Environment Variables
Via Server Flag
Transports
- stdio
- SSE (HTTP+SSE)
- http (Streamable HTTP)
The Use case: Local servers distributed as npm packages, standalone binaries, or scripts.
stdio transport starts a local process and communicates via stdin/stdout using JSON-RPC 2.0:OAuth 2.1 authorization (remote servers)
Remote (http/sse) MCP servers increasingly gate access behind OAuth 2.1 rather than a static token β the AWS MCP server is the motivating case. ChatCLI supports this end-to-end, and it needs no client ID, secret, or endpoints in your config: everything is discovered at runtime.
When a server answers a request with 401 and an OAuth challenge, ChatCLI:
1
Discovers the authorization server
Reads the
WWW-Authenticate header, fetches the Protected Resource Metadata (RFC 9728), then the Authorization Server Metadata (RFC 8414) to learn the authorization, token, and registration endpoints.2
Registers a client dynamically
Registers a public PKCE client via Dynamic Client Registration (RFC 7591) β so you never paste a
client_id.3
Runs the browser flow
Opens your browser for the authorization-code + PKCE flow through a localhost callback, binding the token to the server via the resource indicator (RFC 8707).
4
Stores and refreshes the token
Persists the access/refresh tokens in the encrypted auth store (AES-256-GCM, the same vault as
/auth login) and refreshes them transparently thereafter.Authorizing a server
Once a remote server is configured, authorize it in either of two ways:/mcp status shows a server waiting on authorization with a π authorization required state and a login hint. After a successful login the server reconnects and its mcp_* tools become available.
No config changes are required for an OAuth server β just add it as a normal
http/sse server (chatcli mcp add --transport http aws-mcp https://β¦/mcp). The first tool call surfaces the authorization prompt. To pin the loopback callback port (for strict redirect-URI allowlists), set CHATCLI_MCP_OAUTH_PORT (default 8765; falls back to an ephemeral port if busy).bearer/basic/header auth documented above still applies for servers that accept a pre-minted token; OAuth is used only when a server actively challenges for it.
Tool Naming
MCP tools are automatically prefixed withmcp_ and receive a description from the source server:
The
mcp_ prefix prevents collisions with ChatCLIβs native tools.Built-in Overrides (Shadow + Fallback)
When an MCP server provides a tool that replaces a native plugin (e.g.,@webfetch, @websearch), use the overrides field to declare which built-ins it replaces. ChatCLI automatically hides the listed built-ins while the MCP server is connected. If the server disconnects, the built-ins are immediately restored β the user never loses the capability.
Why use overrides?
Withoutoverrides, the LLM sees two tools that do the same thing (e.g., @webfetch and mcp_web_fetch) and picks randomly. With overrides, the behavior is deterministic: the LLM only sees the MCP tool, with no ambiguity.
Configuration
Addoverrides to the MCP server configuration:
- CLI (mcp_servers.json)
- Helm (values.yaml)
- Operator (Instance CRD)
How it works
Shadow sync happens on every conversation turn, not just at startup. This means if the MCP server crashes mid-conversation, the built-ins return on the very next message β no restart needed.
Important rules
Deploy via Helm
- Inline MCP Servers
- Existing ConfigMap
mcp_servers.json and mounts it at /etc/chatcli/mcp/.
Deploy via Operator (Instance CRD)
When using the ChatCLI Operator, configure MCP directly in theInstance resource:
- Generates a ConfigMap
<instance>-mcpwithmcp_servers.json - Mounts at
/etc/chatcli/mcp/(read-only) - Passes
--mcp-config /etc/chatcli/mcp/mcp_servers.jsonto the container
The
MCPSpec CRD mirrors the mcp_servers.json format exactly. Each MCPServerSpec field maps to a JSON field β including overrides for built-in shadowing.Checking Status
The MCP Manager exposes the status of each server:Popular MCP Servers
MCP in Client Mode (TTY)
MCP now works directly in interactive mode (TTY), not just server mode.
ChatCLI auto-detects
~/.chatcli/mcp_servers.json and initializes servers automatically on startup.Deferred Schemas (Token Savings)
To save tokens in the system prompt, ChatCLI uses deferred schemas:- Only name + description are sent in the prompt (lightweight)
- Before first use, the model queries the catalog with
@tools describeand gets the full block: owning server, description, parameter JSON Schema and invocation form - The model invokes with the correct arguments
@tools list also indexes MCP tools alongside the builtins, grouped by owning server β every entry carries the [MCP:server] tag, so the model always knows which server a tool comes from.
As a fallback, if the model invokes an MCP tool without its required parameters, the full schema is returned as feedback for correction.
Index descriptions are clamped: each toolβs description in the system-prompt index is reduced to its first line, capped at 160 characters. Enterprise MCP servers ship multi-paragraph descriptions β with 100+ tools connected, unclamped descriptions alone add tens of KB to every request, which is exactly the payload floor that trips corporate proxy/WAF body caps (see Context Recovery). The full description and schema remain one @tools describe away.
Dynamic tool discovery
Some MCP servers have a dynamic tool list (thetools.listChanged capability): they connect exposing a minimal catalog and grow it at runtime. HTTP Toolkit is the canonical case β it exposes only start on connect, and after start runs it registers the real tools and emits a notifications/tools/list_changed notification.
ChatCLI handles this end-to-end:
- The notification fires a debounced, per-server refresh (bursts coalesce into a single
tools/listcall). The refresh runs asynchronously β a synchronous round-trip from the transportβs reader would deadlock the response pump. - The registry is reconciled: new tools added, changed schemas replaced, vanished tools dropped β touching only tools owned by that server.
- At the next turn boundary the agent is told what changed, so it can use the new tools immediately:
@tools describe before first use. Tool dispatch, @tools list/describe and the completer all read the live registry, so the change is visible everywhere at once. The tools/list_changed event is also recorded in the channel inbox for auditability β but as a handled protocol event it does not inflate the unread counter.
Controlled by CHATCLI_MCP_DYNAMIC_TOOLS (default on); surfaced under /config integrations.
/mcp Command
Manage MCP servers directly from the interactive terminal. Every subcommand that takes a server name has autocomplete β press Tab after /mcp <subcommand> to list the configured servers.
Example: status and logs
Start/stop semantics
Difference between
/mcp restart and /mcp reload:/mcp restartforces a restart even if the config didnβt change (useful for βreload credentialsβ after editing shell env)./mcp reloadis a diff-and-apply againstmcp_servers.jsonβ nothing that hasnβt changed gets restarted.
Per-server log buffer
Each stdio server keeps a 200-line ring buffer fed from the child processβs stderr. That means:/mcp logs <name>shows the last 200 lines without enabling--debug;- Chatty servers donβt grow memory unboundedly β old lines drop off the front;
- Captures like
npm 404, panic stacks and startup messages stay available even after startup ends.
Push notifications β MCP Channels
Beyond tools (request/response), ChatCLI accepts push notifications from any MCP server across all three transports. Notifications are JSON-RPC messages withoutid (the spec form for βthe server wants to tell me something, it isnβt asking for anything backβ). ChatCLI captures, persists, and automatically injects them into the next conversations, and β optionally β fires the agent via trigger rules.
The essentials
- Works on
stdio,sse, andhttpβ each transport has its own listener:sse: the GET/ssethat already carries tool responses receives notifications on the same stream.http: a separate GET on the endpoint (opt-in by the client, optional by the spec) pulls notifications. Servers that donβt support it respond with 405/404/501 and the listener stops cleanly, no retries.stdio: JSON-RPC lines on stdout withoutidare treated as notifications.
- Durable persistence at
~/.chatcli/mcp/channels.jsonl(up to 10 MiB, rotates, replays on boot). - Auto-injection of the 5 most recent in the system prompt of
chat/agent/coder(uncached so cache isnβt trashed). - Per-server filter:
channelsfield inmcp_servers.jsonaccepts a literal allow-list. - Optional rules engine in
~/.chatcli/mcp/triggers.jsonwith 3 modes:notify(discreet banner, default),confirm(manual yes/no),auto(runs the agent β requires tool whitelist). - Slash commands:
/channel list,/channel ack,/channel pause,/channel rules,/channel confirm <id>,/channel run <seq>,/channel inject.
Minimal example β server with channels
/channel list, show up in the next prompt banner, and are auto-injected into the agent context.
Example β trigger that investigates CI failures
~/.chatcli/mcp/triggers.json:
/channel confirm <id> accepts and the agent starts investigating.
Full channels, rules, and troubleshooting docs: MCP Channels. Complete
channels schema and triggers.json reference: MCP Config.Next steps
MCP Channels
Push messages across all three transports (
stdio, sse, http) with durable persistence, per-server filter, and a rules engine (notify/confirm/auto).Agentic plugins
ChatCLIβs plugin system β compared with MCP.
Native Tool Use
Native Anthropic/OpenAI APIs that power MCP under the hood.
MCP Config
Full
mcp_servers.json format and examples.