40ants-lisp-dev-mcp - MCP which gives LLM tools for working with running Lisp image.

40ANTS-LISP-DEV-MCP ASDF System Details

Installation

You can install this library from Quicklisp, but you want to receive updates quickly, then install it from Ultralisp.org:

(ql-dist:install-dist "http://dist.ultralisp.org/"
                      :prompt nil)

then:

ros install 40ants/lisp-dev-mcp

Usage

Running in stdio mode

Here is an example config to add lisp-dev-mcp to Qwen:

{
  "mcpServers": {
    "lisp-dev": {
      "command": "lisp-dev-mcp",
      "args": []
    }
  },
  "$version": 2
}

If you want to debug MCP server, then you might start it will logging output and a SLYNK port opened:

{
  "mcpServers": {
    "lisp-dev": {
      "command": "lisp-dev-mcp",
      "args": ["--log", "mcp.log", "--verbose"],
      "env": {
        "SLYNK_PORT": "9991"
      }
    }
  },
  "$version": 2
}

Running in HTTP streaming mode

With OpenCode

Let the server pick a free port and record it into opencode.json automatically. Start the lisp process:

qlot exec roswell/lisp-dev-mcp.ros --port auto --update-config

or, from the REPL:

(ql:quickload :40ants-lisp-dev-mcp)

(40ants-lisp-dev-mcp/core:start-server :port :auto :update-config t)

The server reuses the port already recorded in opencode.json when it is still free, otherwise it chooses a new one and writes http://localhost:<port>/mcp into the mcp.lisp-dev-mcp.url key. The resulting config is picked up by OpenCode without any manual editing:

{
    "$schema": "https://opencode.ai/config.json",
    "mcp": {
        "lisp-dev-mcp": {
            "type": "remote",
            "url": "http://localhost:<port>/mcp"
        }
    }
}

With Codex or multiple agents

Select Codex to create or update .codex/config.toml in the current directory:

qlot exec roswell/lisp-dev-mcp.ros --port auto --update-config --agents codex

or, from the REPL:

(40ants-lisp-dev-mcp/core:start-server
 :port :auto :update-config t :agents '(:codex))

The minimal Codex config contains:

[mcp_servers.lisp-dev-mcp]
url = "http://localhost:40001/mcp"
enabled = true
startup_timeout_sec = 10
tool_timeout_sec = 60

The URL uses the chosen port. Existing settings, other sections and MCP servers are preserved; enabled and timeout defaults are added only when absent. A file containing only [features] is supported, as are missing files and directories. For example, starting the server on port 40001 with :agents '(:codex) and :update-config t updates this existing file:

[features]
hooks = true

to a config with both sections:

[features]
hooks = true

[mcp_servers.lisp-dev-mcp]
url = "http://localhost:40001/mcp"
enabled = true
startup_timeout_sec = 10
tool_timeout_sec = 60

An existing enabled = false and custom timeout values remain unchanged. Comments and formatting may change. The cl-toml library supports TOML 0.4; unsupported syntax causes an error before config files are written.

To update both agents, use --agents opencode,codex or :agents '(:opencode :codex). Automatic port selection checks recorded ports in the selected order and reuses the first free port. Both agents receive the same URL, including when one config already has the chosen port and the other needs to be created. The default is :agents '(:opencode); :agents nil skips config reads and updates. Stdio mode never writes config files.

Override paths with :opencode-config and :codex-config, or rebind *opencode-config-pathname* and *codex-config-pathname*. The config helpers also accept :agent :codex, for example:

(40ants-lisp-dev-mcp/core:update-port-in-config
 40001 :agent :codex :config #P".codex/config.toml")

With a fixed port (other IDEs)

For clients that use a different config format, or when you prefer a fixed port, pass an explicit port number. Start the lisp process:

qlot exec roswell/lisp-dev-mcp.ros --port 7890

or in the REPL:

(ql:quickload :40ants-lisp-dev-mcp)

(40ants-lisp-dev-mcp/core:start-server :port 7890)

then configure your IDE:

{
  "mcpServers": {
    "lisp-dev": {
      "url": "http://localhost:7890/mcp"
    }
  },
  "$version": 2
}

API

40ANTS-LISP-DEV-MCP/CORE

Functions

function
port &key (config \*opencode-config-pathname\*) (codex-config \*codex-config-pathname\*) (agents '(:opencode))

Resolves PORT into a concrete TCP port number and returns it as the first value.

As the second value returns T when the resolved port differs from at least one selected agent's recorded port (including a missing config).

PORT can be: - an INTEGER, used as-is after checking it is free; - the :AUTO keyword (or the string "auto"), in which case a free port is selected automatically, reusing the first free recorded port in AGENTS order. AGENTS defaults to (:OPENCODE); NIL skips reading configs. CONFIG points to OpenCode, CODEX-CONFIG points to Codex.

function
&key (agent :opencode) (config (agent-config-pathname agent))

Returns the MCP port recorded in CONFIG for AGENT, or NIL. AGENT is :OPENCODE (the default) or :CODEX; CONFIG defaults to that agent's pathname.

Returns the default OpenCode config with a placeholder MCP URL.

Reads the OpenCode JSON config at PATH, preserving arrays, booleans and nulls.

function
&key port (in-thread t) update-config (agents '(:opencode)) (opencode-config \*opencode-config-pathname\*) (codex-config \*codex-config-pathname\*)

Starts the MCP server.

PORT controls the transport and the port: - NIL (the default) uses the stdio transport; - an INTEGER uses the Streaming HTTP transport on that TCP port; - :AUTO selects a free TCP port automatically, reusing the port from the selected agents' configs in AGENTS order when it is still available.

IN-THREAD controls whether the server runs in a background thread (the default) or blocks the caller.

When UPDATE-CONFIG is true and a port was selected (or reused), the chosen port is written into every selected agent's config, creating missing files and directories. AGENTS is a list of :OPENCODE and :CODEX, defaulting to (:OPENCODE); NIL disables config reads and updates. OPENCODE-CONFIG and CODEX-CONFIG default to *opencode-config-pathname* and *codex-config-pathname*. Codex settings other than the URL are preserved; missing enabled and timeout settings receive defaults. TOML comments and formatting may change.

Returns the server thread when IN-THREAD is true, otherwise blocks.

function
port &key (agent :opencode) (config (agent-config-pathname agent))

Writes PORT into the MCP URL in CONFIG for AGENT (:OPENCODE or :CODEX). Creates missing directories and config tables. Codex gets enabled=true and timeouts of 10 and 60 seconds when those settings are absent; existing values are preserved. TOML comments and formatting are not preserved.

Writes DATA as an OpenCode JSON config to FILE.

Variables

Pathname of the Codex config, relative to the current working directory. Rebind this variable or pass :CODEX-CONFIG to start-server and choose-port, or :CONFIG with :AGENT :CODEX to the config helpers.

Pathname of the Opencode config file which is updated when start-server is called with :UPDATE-CONFIG T.

You can rebind this variable, pass :OPENCODE-CONFIG to start-server, or pass :CONFIG to the config helpers and choose-port.