Lisp
STDIOCommon Lisp的极简MCP服务器
Common Lisp的极简MCP服务器
A minimal Model Context Protocol (MCP) server for Common Lisp. It provides a newline‑delimited JSON‑RPC 2.0 transport over stdio or TCP, a small protocol layer (initialize, ping, tools/list, tools/call), and a REPL tool that evaluates forms and returns the last value.
This repo is intentionally small and test-first. It’s designed for editor/agent clients to drive Common Lisp development via MCP.
repl-eval:stdio and :tcptest-op2025-06-18, 2025-03-26, 2024-11-05
initialize, if the client’s protocolVersion is supported it is echoed
back; otherwise the server’s preferred version is selected.alexandria, yason, usocket, bordeaux-threads, rove (tests)Note: The repository currently uses yason for JSON.
Load and run from an existing REPL:
(ql:quickload :lisp-mcp-server) (asdf:load-system :lisp-mcp-server) ;; Start TCP transport on an ephemeral port, print chosen port (lisp-mcp-server:run :transport :tcp :port 12345 :accept-once nil :on-listening (lambda (p) (format t "~&port=~A~%" p)))
Or run a minimal stdio loop (one JSON‑RPC line per request):
(lisp-mcp-server:run :transport :stdio)
python3 scripts/client_init.py --host 127.0.0.1 --port 12345 --method initialize --id 1
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' | \ python3 scripts/stdio_tcp_bridge.py --host 127.0.0.1 --port 12345
The bridge uses a bounded connect timeout but disables read timeouts after connecting, so it can stay idle indefinitely (until stdin closes).
repl-evalEvaluate one or more forms and return the last value as a text item.
Input schema (JSON):
code (string, required): one or more s‑expressionspackage (string, optional): package to evaluate in (default CL-USER)printLevel (integer|null): binds *print-level*printLength (integer|null): binds *print-length*Example JSON‑RPC request:
{"jsonrpc":"2.0","id":2,"method":"tools/call", "params":{"name":"repl-eval","arguments":{"code":"(+ 1 2)"}}}
Response (excerpt):
{"result":{"content":[{"type":"text","text":"3"}]}}
*error-output*.MCP_LOG_LEVEL with one of: debug, info, warn, error.Example:
MCP_LOG_LEVEL=debug sbcl --eval '(ql:quickload :lisp-mcp-server)' ...
This project uses Rove and ASDF’s test-op.
From a REPL with Quicklisp:
(asdf:load-asd #P"lisp-mcp-server.asd") (asdf:test-system "lisp-mcp-server")
What’s covered:
initialize, ping, tools listing/calls)Note: Running tests compiles FASLs into ~/.cache/.... Ensure your environment
allows writing there or configure SBCL’s cache directory accordingly.
src/ — packages, logging, REPL, protocol, TCP, run entrypointtests/ — Rove test suites invoked by ASDF test-opscripts/ — helper clients and a stdio↔TCP bridgelisp-mcp-server.asd — main and test systems (delegates test-op to Rove)scripts/stdio_tcp_bridge.py (it disables read timeouts after
connect) and that your stdin remains open.~/.cache
or reconfigure SBCL’s cache path.MIT