Autolith is an MCP client. It supports MCP 2025-11-25 and 2025-06-18 through stdio and Streamable HTTP, using mcparen. It requests the newer revision and accepts either one the server selects.
As with other agents servers can offer tools, resources, resource templates, prompts, and server instructions.
Autolit’s MCP configuration is an S-expression, see below.
Create ${XDG_CONFIG_HOME:-~/.config}/autolith/mcp.sexp:
(:version 1
:servers
((:name "local-tools"
:transport
(:type :stdio
:command "/absolute/path/to/server"
:arguments ("--stdio")
:directory :workspace
:environment
(("SERVICE_TOKEN" :environment "AUTOLITH_SERVICE_TOKEN")))
:required-p nil
:startup-timeout-seconds 15
:tool-timeout-seconds 60
:approval :prompt
:child-tools ("lookup"))))There is a couple important notes:
- Server names are case-sensitive
- A stdio
:directoryis:workspaceor an existing pathname :workspaceis resolved when the process starts, so a reconnect follows the current working directory
Here is how a remote server with read-only approval would look:
(:name "remote-tools"
:transport
(:type :http
:url "https://mcp.example.net/"
:headers
(("Authorization" :environment "AUTOLITH_MCP_AUTHORIZATION"))
:connect-timeout-seconds 10)
:approval :read-only
:trusted-read-only-tools ("lookup"))Streamable HTTP requires HTTPS, except plain HTTP to a loopback host.
Map an environment variable into a server environment or HTTP header:
("TARGET-NAME" :environment "SOURCE_VARIABLE")For an Authorization header, the source value is the full value the
server expects, such as Bearer ....
Do not put secrets into files you may share with others and/or the CCP.
- Autolith reads every referenced source variable once at the start of each credential-bearing MCP operation
- A changed credential closes the old process before reconnecting
- Stdio servers get a small baseline environment plus
AUTOLITH_MCP=1. They do not inherit Autolith’s full environment. Add every other value with:environment
By default, a repository cannot turn on its own MCP server. To opt in,
create ${XDG_CONFIG_HOME:-~/.config}/autolith/directory-scopes.sexp:
(:version 1
:directories ("~/project/"))When the workspace is that directory or a descendant,
Autolith reads <trusted-directory>/.autolith/mcp.sexp.
- Only exact manifest anchors count
- A nested repository needs its own exact manifest entry
- Matching anchors apply from outermost to nearest
- A nearer file replaces an outer file’s same-name server
- Directory files override the global
mcp.sexp init.lispand live registrations have higher precedence
A trusted anchor may also supply .autolith/init.lisp. Autolith loads
these from outermost to nearest, then
${XDG_CONFIG_HOME:-~/.config}/autolith/init.lisp.
They are full-power Common Lisp in the AUTOLITH package. They can
register servers. Arbitrary side effects remain until you reverse them
or restart. Workspace changes replace extension registrations, not
arbitrary Lisp effects.
:prompt is the default. Choose one policy per server:
:promptasks for every tool call:read-onlyskips approval only for an exact:trusted-read-only-toolsname whose MCP annotations say read-only and non-destructive. Everything else prompts for approval:allowpermits every server tool without a prompt:denydenies every server tool
An approval picker names the configured server and raw tool, and shows complete JSON arguments.
A child agent gets a server tool only when both the server’s
:child-tools list names its exact raw name and the selected child
role permits that resulting tool.
Autolith connects effective servers and discovers tools while building its tool registry.
- A
:required-p tserver makes startup or reload fail when initialization or discovery fails - An optional server stays visible as failed, so unrelated work can continue
- Retry it with
mcp.refreshor/mcp refresh
Servers without tools may still provide resources or prompts. Autolith
validates advertised tool names and schemas before showing them to the
model. Each server’s tools appear under a deterministic mcp__*
namespace.
(mcp.status)
(mcp.refresh)
(mcp.resources :server "configured-server-name")
(mcp.resource-templates :server "configured-server-name")
(mcp.read-resource :server "configured-server-name"
:uri "resource-uri")
(mcp.prompts :server "configured-server-name")
(mcp.get-prompt :server "configured-server-name"
:name "prompt-name")mcp.statusreports source, transport, state, requirement, failure, and tool count, without credentialsmcp.refreshreconnects where needed and refreshes advertised tools- Resource and prompt helpers use the exact configured server name
mcp.get-promptaccepts an optional object of string arguments
As for commands:
(mcp)shows connection state.(mcp refreshrefreshes connections and tool discovery (does not reread config).(mcp reload)rereads the global and active directory files plusinit.lisp, closes old runtimes, and
installs a fresh registry. (cwd) does the equivalent replacement before changing directory.
A notifications/tools/list_changed notification marks one server
stale. Autolith refreshes it before the next provider request.
Text, structured content, embedded resources, and supported images in MCP results become ordinary Autolith tool results, and will be recorded.
Your global init.lisp, or whatever other file you load,
can register the same property list used by mcp.sexp:
(register-mcp-server
'(:name "project-service"
:transport
(:type :stdio
:command "/absolute/path/to/server"
:directory :workspace)
:approval :prompt))Precedence, low to high:
- global
mcp.sexp - active directory-scoped
mcp.sexpfiles init.lisp- live runtime registrations
A higher layer shadows the same case-sensitive name.
Reloading init.lisp atomically replaces its prior registrations.
A load failure restores the previous registry.
- One MCP manager retains at most 8 MiB of encoded input schemas
- Required servers receive capacity first, then optional servers
- A required overflow fails startup or refresh
- An optional overflow marks that server failed and clears its tools
Shutdown, MCP reload, conversation replacement, and checkpoint preparation close live clients.