Model Context Protocol (MCP) Wrapper for Lisply Backends
Model Context Protocol (MCP) server to manage and talk to compliant "Lisply" lisp-speaking backend services
gornskew
README
Model Context Protocol (MCP) Wrapper for Lisply Backends
This is an MCP wrapper script for connecting Claude Desktop and similar "agentic AI clients" to certain "Lisply" services. It provides a powerful interface between Claude and any compliant Lisp-speaking backend service e.g. Gendl, enabling direct AI-assisted symbolic programming.
NOTE: this implementation currently works with the Gendl system, automatically starting and stopping a Gendl container if needed. Work is underway to generalize the implementation to support a Gnu Emacs Backend, and subsequently we welcome more compliant Lispy systems.
Table of Contents
- Overview
- Architecture
- Features
- Installation
- Configuration
- Docker Integration
- Usage Examples
- Claude Integration
- Real-World Examples
- Troubleshooting
- License
Overview
The Lisply MCP wrapper is implemented in Nodejs, and provides a bridge between Claude AI and any compliant Lisply backend system. This wrapper enables Claude to:
- Evaluate Lisp code in the Lisply Environment (LE).
- Make HTTP requests any endpoints implemented in the LE.
- Access any Introspection and Documentation lookup facilities in the LE.
- Create, manipulate, compile, load, analyze files through Lisp evaluation.
- Interact with Lisp debuggers (for locally spawned containers).
Architecture
The MCP wrapper implements the Model Context Protocol (MCP) to connect Claude with Gendl's capabilities. Here's how the components interact:
flowchart TB
User("User") <--> Claude("Claude AI Assistant")
User <-.-> Emacs("Emacs Text Editor (Optional)")
Claude <--> MCP("MCP Protocol")
MCP <--> Wrapper("NodeJS MCP Wrapper")
Wrapper --> LispyHttp("Lispy HTTP Server")
subgraph Docker ["Docker Container"]
subgraph LispyExec["Lispy Executable"]
LispyHttp
LispySwank("Lispy SWANK Server")
end
end
Wrapper <-- "Manages" --> Docker
Emacs <-.-> LispySwank
KB[("Lispy Knowledge Base")] <--> Wrapper
LispyHttp --> Endpoints("RESTful Endpoints")
LispyHttp --> LispEval("Lisp Evaluation")
style User fill:#ff9,stroke:#333,stroke-width:2px
style Claude fill:#f9f,stroke:#333,stroke-width:2px
style Emacs fill:#9ff,stroke:#333,stroke-width:2px,stroke-dasharray:5
style Wrapper fill:#bbf,stroke:#333,stroke-width:2px
style MCP fill:#bbf,stroke:#333,stroke-width:1px
style Docker fill:#bfb,stroke:#333,stroke-width:2px
style LispyExec fill:#8f8,stroke:#333,stroke-width:2px
style LispyHttp fill:#bfb,stroke:#333,stroke-width:1px
style LispySwank fill:#bfb,stroke:#333,stroke-width:1px
style KB fill:#bfb,stroke:#333,stroke-width:1px
style Endpoints fill:#bfb,stroke:#333,stroke-width:1px
style LispEval fill:#bfb,stroke:#333,stroke-width:1px
The wrapper script handles:
- Starting and managing a Lispy Docker container if needed
- Routing requests between Claude and the Lispy Backend
- Translating between the MCP protocol and the backend Lispy API
- Error handling and logging
Features
- Configurable Lispy Host & Port: Configure via command-line arguments or environment variables
- Docker Container Management: Automatically start Lispy container when needed
- Volume Mounting: Mount host directories into the Lispy container
- Run Self in Docker: Run this wrapper directly on host or inside a container with Docker socket
- Error Handling: Detection and reporting of errors
- Detailed Logging: Detailed logs with timestamps and optional debug mode for more verbosity
- Automatic Docker Image Selection: Sensible defaults based on cloned branch and selected backend type
- DockerHub Authentication: Auto-pulls latest container images with authentication handling
- Existing Service Detection: Relies on existing live services when available, avoiding the need to start & stop a dedicated container
Installation
- Install the required dependencies:
cd /path/to/lispy-mcp/scripts
npm install
chmod +x mcp-wrapper.js
-
Ensure Docker is installed on your system.
-
Test the script:
node mcp-wrapper.js --help
Configuration
You can configure the MCP wrapper using either command-line arguments or environment variables.
Command-Line Arguments
Options:
-H, --host <host> Lispy server host (default: 127.0.0.1)
--swank-host-port <port> SWANK port on host system (default: 4201)
--http-host-port <port> HTTP port on host system (default: 9081)
--https-host-port <port> HTTPS port on host system (default: 9444)
--telnet-host-port <port> TELNET port on host system (default: 4024)
--http-port <port> HTTP port inside container (default: 9080)
--https-port <port> HTTPS port inside container (default: 9443)
--swank-port <port> SWANK port inside container (default: 4200)
--telnet-port <port> TELNET port inside container (default: 4023)
--docker-image <image> Docker image for Lispy services (default: `dcooper8/gendl:<branch>-<lisp-impl>`)
--lisp-impl <impl> Lisp implementation to use, e.g. ccl or sbcl for `dcooper8/gendl` (default: ccl)
--no-auto-start Do not auto-start Gendl docker container if live service not available (resulting in an error exit).
--docker-socket <path> Path to docker socket (needed if running this nodejs wrapper inside a docker container) (default: /var/run/docker.sock)
--log-file <path> Path to log file of this script (default: /tmp/mcp-wrapper.log)
--debug Enable debug logging (more verbose)
--mount <mounts...> Mount volumes in format "src:dst" (can specify multiple times)
--start-http Start HTTP service in Gendl container (required)(default: true)
--start-https Start HTTPS service in Gendl container (default: false)
--start-swank Start SWANK service in Gendl container (default: true)
--start-telnet Start TELNET service in Gendl container (default: false)
-h, --help Display help for command
Environment Variables
The script also supports configuration via environment variables:
Environment Variable | Description | Default |
---|---|---|
GENDL_HOST |
Gendl server host | 127.0.0.1 |
SWANK_HOST_PORT |
SWANK port on host system | 5200 |
HTTP_HOST_PORT |
HTTP port on host system | 10080 |
HTTPS_HOST_PORT |
HTTPS port on host system | 10443 |
TELNET_HOST_PORT |
TELNET port on host system | 5023 |
HTTP_PORT |
HTTP port inside container | 9080 |
HTTPS_PORT |
HTTPS port inside container | 9443 |
SWANK_PORT |
SWANK port inside container | 4200 |
TELNET_PORT |
TELNET port inside container | 4023 |
START_HTTP |
Enable HTTP service | true |
START_HTTPS |
Enable HTTPS service | false |
START_SWANK |
Enable SWANK service | true |
START_TELNET |
Enable TELNET service | false |
GENDL_DOCKER_IMAGE |
Docker image for Gendl | (auto-detected) |
GENDL_LISP_IMPL |
Lisp implementation to use | ccl |
GENDL_AUTO_START |
Enable auto-starting container | true |
DOCKER_SOCKET |
Path to Docker socket | /var/run/docker.sock |
GENDL_LOG_FILE |
Path to log file | /tmp/mcp-wrapper.log |
DEBUG_GENDL |
Enable debug logging | false |
GENDL_MOUNTS |
Comma-separated mount points | (none) |
Docker Integration
The MCP wrapper integrates closely with Docker to manage Gendl containers efficiently.
Docker Image Selection
The wrapper automatically selects the appropriate Docker image based on the current branch in your lispy-mcp repository:
-
The Docker image follows the naming pattern:
dcooper8/gendl:${branch}-${impl}
${branch}
is the current git branch name with any slashes (/
) converted to double hyphens (--
)- For example,
release/1598
becomesrelease--1598
in the image tag devo
branch will use the image tagdevo
- For example,
${impl}
is the Lisp implementation (ccl or sbcl)
-
The script will attempt to pull or use an image matching your current branch:
- First tries to pull the image matching your current branch from Docker Hub
- If pull fails, checks if the image exists locally
- If neither works, falls back to the
master
branch image
-
You can override the automatic selection with:
- The
--docker-image
command-line argument - The
GENDL_DOCKER_IMAGE
environment variable
- The
-
For the Lisp implementation:
- Specify with
--lisp-impl
(ccl or sbcl) - Or use the
GENDL_LISP_IMPL
environment variable - Defaults to ccl if not specified
- Specify with
Docker Hub Authentication
The wrapper will attempt to pull the latest version of the appropriate Docker image before starting a container. This behavior includes:
- Checking for Docker Hub authentication
- Attempting to log in if not authenticated (using stored credentials or interactive login)
- Pulling the latest image matching your configuration
- Falling back to using a local image if pull fails
- Attempting to pull the default image (master-ccl) as a last resort if needed
Existing Service Detection
The wrapper will check if a Gendl service is already running on the specified host and ports before attempting to start a container:
- HTTP service (HTTP_HOST_PORT) is checked first as the primary service
- SWANK service (SWANK_HOST_PORT) is checked as a fallback
Parameter Behavior with Existing Services
Important: When an existing service is detected on the specified host and port:
-
All Docker-related settings will be ignored:
--docker-image
and--lisp-impl
--mount
volume options--start-*
service flags--*-port
internal container port settings--docker-socket
path--no-auto-start
flag
-
The wrapper will display warnings about which settings are being ignored
This ensures the wrapper works properly with external Gendl services while giving clear feedback about ignored configuration options.
Volume Mounting
You can mount host directories into the Gendl container to share files between your host system and the container:
node mcp-wrapper.js --mount /home/user/projects:/projects
Multiple mount points can be specified:
node mcp-wrapper.js --mount /home/user/projects:/projects --mount /home/user/data:/data
Or using environment variables:
GENDL_MOUNTS=/home/user/projects:/projects,/home/user/data:/data node mcp-wrapper.js
Usage Examples
All the below examples can be tested on command line and used in
claude_desktop_config.json
configuration (see Claude Desktop Configuration).
Basic Usage
Run with default settings (localhost:5200):
node mcp-wrapper.js
Custom Host and Port
Specify a custom Gendl server:
node mcp-wrapper.js --host 192.168.1.100 --swank-host-port 5200 --http-host-port 10080
Custom Lisp Implementation
Specify a different Lisp implementation:
node mcp-wrapper.js --lisp-impl sbcl
Enabling Services
Enable HTTP and HTTPS services:
node mcp-wrapper.js --start-http --start-https
Or using environment variables:
START_HTTP=true START_HTTPS=true node mcp-wrapper.js
Configuring Internal Container Ports
Specify all internal ports:
node mcp-wrapper.js --http-port 9080 --https-port 9443 --swank-port 4200 --telnet-port 4023
Or using environment variables:
HTTP_PORT=9080 HTTPS_PORT=9443 SWANK_PORT=4200 TELNET_PORT=4023 node mcp-wrapper.js
Running in a Container
If running the wrapper inside a container, make sure to mount the Docker socket:
docker run -v /var/run/docker.sock:/var/run/docker.sock -v /path/to/scripts:/app node:18 node /app/mcp-wrapper.js
Claude Integration
This wrapper enables Claude to interact with Gendl through the Model Context Protocol (MCP).
Tools for Claude
The MCP wrapper exposes several tools that Claude can use to interact with Gendl:
Lisp Evaluation Tool
The lisp_eval
tool allows Claude to evaluate Lisp code directly within the Gendl environment. This enables Claude to:
- Create and manipulate GDL objects
- Perform complex calculations using Gendl's geometric primitives
- Access and modify Gendl's state
The tool accepts the following parameters:
code
(required): The Lisp code to evaluatepackage
(optional): The package to use for the evaluationmode
(optional): The mode to use to talk to Gendlhttp
(default): Uses HTTP communication for structured responsesstdio
: Uses standard input/output communication for a raw REPL experience
Mode Comparison:
Feature | HTTP Mode | STDIO Mode |
---|---|---|
Response Format | Structured with separate Result and Stdout fields | Raw REPL-like output |
Error Handling | Traps errors and returns them as strings | Can enter interactive debugger |
Debugger Support | No interactive debugging | Supports interactive debugger |
Compatibility | Works with local & remote servers | Only for local containers started by MCP |
Use Case | Clean integration, simple queries | Development, debugging, complex interactions |
Example usage with default HTTP mode:
(in-package :gdl-user)
(defparameter *test-box* (make-box :width 10 :height 5 :depth 3))
(theo *test-box* width)
Example usage with STDIO mode (for debugging):
;; This will allow interactive debugging if errors occur
(in-package :gdl-user)
(defparameter *test-box* (make-box :width 10 :height 5 :depth 3))
(theo *test-box* width)
HTTP Request Tool
The http_request
tool enables Claude to interact with any HTTP endpoint exposed by Gendl:
{
"path": "/color-map",
"method": "GET",
"headers": {
"Accept": "application/json"
}
}
Knowledge Base Integration
The query_gendl_kb
tool allows Claude to search for information about Gendl/GDL (General-purpose Declarative Language):
query_gendl_kb("How do I create a box in GDL?")
Ping Tool
The ping_gendl
tool lets Claude check if the Gendl server is available:
ping_gendl()
Claude Desktop Configuration
Here's an example of how to configure Claude Desktop to use this wrapper:
{
"mcpServers": {
"filesystem": {
"command": "wsl",
"args": [
"docker",
"run",
"-i",
"--rm",
"-u",
"1000:1000",
"--mount",
"type=bind,src=/home/user/projects,dst=/projects",
"mcp/filesystem",
"/projects"
]
},
"gendl": {
"command": "wsl",
"args": [
"node",
"/home/user/projects/lispy-mcp/scripts/mcp-wrapper.js",
"--mount", "/home/user/projects:/projects"
],
"env": {
"NODE_ENV": "production",
"DEBUG": "*"
}
}
},
"globalShortcut": ""
}
Real-World Examples
Example 1: Creating a Parametric Box
In this example, Claude creates a parametric box in Gendl and then modifies its properties based on user requirements.
User: "Can you create a box in Gendl with width 10, height 5, and depth 3? Then show me how to change the height to 8."
Claude:
I'll create a parametric box in Gendl using the lisp_eval tool, then show you how to modify its height.
First, let's create the box with the specified dimensions:
(in-package :gdl-user)
;; First, create a box with the specified dimensions
(defparameter *my-box* (make-object 'box
:width 10
:height 5
:depth 3))
;; Let's verify the dimensions
(list (theo *my-box* width)
(theo *my-box* height)
(theo *my-box* depth))
Now, let's change the height from 5 to 8:
;; Change the height using setf with accessor
(theo *my-box* (set-slot! :height 8))
;; Alternatively, we could create a new box
(defparameter *new-box* (make-object 'box
:width 10
:height 8 ;; Updated height
:depth 3))
;; Verify the new dimensions of original box
(list (theo *my-box* width)
(theo *my-box* height)
(theo *my-box* depth))
You can visualize this box by creating a GWL web interface or using Gendl's built-in visualization tools.
Would you like me to show you how to create a more complex parametric object or how to set up visualization?
Example 2: Querying the Knowledge Base for GDL Information
User: "How do I create a cylinder in GDL and what parameters does it accept?"
Claude:
I'll use the Gendl knowledge base to find information about creating cylinders in GDL:
The basic syntax for creating a cylinder in GDL is:
(make-object 'cylinder :radius 5 :height 8)
The main parameters for cylinders are:
:radius
- The radius of the cylinder (default is 1):height
- The height of the cylinder (default is 1):orientation
- The orientation matrix normally created withalignment
:center
- The center point (default is (make-point 0 0 0))
Here's a complete example:
(in-package :gdl-user)
(defparameter *my-cylinder* (make-object 'cylinder
:radius 2.5
:height 10
:orientation
(alignment :rear (the (face-normal-vector :top)))))
;; Verify the parameters
(list (theo *my-cylinder* radius)
(theo *my-cylinder* height)
(theo *my-cylinder* center))
Note that the :display-controls
is a plist of display properties
e.g. :color
for rendering
Would you like me to explain any other aspects of working with cylinders in GDL?
Troubleshooting
Common Issues and Solutions
Container Won't Start
If the Gendl container fails to start:
- Check if Docker is running:
docker info
- Check if the ports are already in use:
sudo lsof -i :5200
sudo lsof -i :10080
- Verify that the Docker image exists:
docker images | grep gendl
- Try pulling the image manually:
docker pull dcooper8/gendl:master-ccl
Connection Errors
If Claude can't connect to Gendl:
- Check if the Gendl server is running:
docker ps | grep gendl
- Enable debug logging:
node mcp-wrapper.js --debug
- Check the log file:
tail -f /tmp/mcp-wrapper.log
- Try pinging the Gendl HTTP server:
curl http://localhost:10080/mcp/ping-gendl
- Try connecting to the Gendl SWANK server:
telnet localhost 5200
Permission Issues
If you encounter permission errors:
- Check Docker socket permissions:
ls -l /var/run/docker.sock
- Make sure your user has permission to access Docker:
sudo usermod -aG docker $USER
- Check mounted directory permissions:
ls -l /path/to/mounted/directory
Diagnostic Commands
Use these commands to diagnose issues:
- Check wrapper logs:
tail -f /tmp/mcp-wrapper.log
- Check Docker container logs:
docker logs $(docker ps --filter "name=lispy-mcp" --format "{{.ID}}")
- Check Gendl service status:
curl http://localhost:10080/mcp/ping-gendl
- Verify Docker environment:
docker system info
License
This software is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0), the same license used by Gendl.
License Implications
Important Note: Simply using this MCP server to interact with Gendl and obtain outputs does not trigger the requirements of the AGPL. You can use this wrapper to interact with Gendl without being required to share your code.
However, if you modify this wrapper and host a service based on the modified software, the AGPL would require you to share your modifications with the users of that service. In other words, if you run a modified version of this software as a network service, you must make the modified source code available to the users of that service.
For applications that need to keep their source code closed, Genworks offers an "AGPL escape clause" in the form of a 5% self-reported quarterly royalty. More information and a payment gateway are available at payments.genworks.com.
The full text of the license can be found in the COPYING.txt file in this directory.
Recommended Servers
Crypto Price & Market Analysis MCP Server
A Model Context Protocol (MCP) server that provides comprehensive cryptocurrency analysis using the CoinCap API. This server offers real-time price data, market analysis, and historical trends through an easy-to-use interface.
MCP PubMed Search
Server to search PubMed (PubMed is a free, online database that allows users to search for biomedical and life sciences literature). I have created on a day MCP came out but was on vacation, I saw someone post similar server in your DB, but figured to post mine.
dbt Semantic Layer MCP Server
A server that enables querying the dbt Semantic Layer through natural language conversations with Claude Desktop and other AI assistants, allowing users to discover metrics, create queries, analyze data, and visualize results.
mixpanel
Connect to your Mixpanel data. Query events, retention, and funnel data from Mixpanel analytics.

Sequential Thinking MCP Server
This server facilitates structured problem-solving by breaking down complex issues into sequential steps, supporting revisions, and enabling multiple solution paths through full MCP integration.

Nefino MCP Server
Provides large language models with access to news and information about renewable energy projects in Germany, allowing filtering by location, topic (solar, wind, hydrogen), and date range.
Vectorize
Vectorize MCP server for advanced retrieval, Private Deep Research, Anything-to-Markdown file extraction and text chunking.
Mathematica Documentation MCP server
A server that provides access to Mathematica documentation through FastMCP, enabling users to retrieve function documentation and list package symbols from Wolfram Mathematica.
kb-mcp-server
An MCP server aimed to be portable, local, easy and convenient to support semantic/graph based retrieval of txtai "all in one" embeddings database. Any txtai embeddings db in tar.gz form can be loaded
Research MCP Server
The server functions as an MCP server to interact with Notion for retrieving and creating survey data, integrating with the Claude Desktop Client for conducting and reviewing surveys.