# lmcp — Lightweight MCP Server in Lua A minimal [Model Context Protocol](https://modelcontextprotocol.io/) server in pure Lua. ~350 lines, 2.4MB RSS, zero compiled dependencies beyond Lua + LuaSocket. ## Features - MCP 2025-03-26 protocol (JSON-RPC over HTTP) - Tool registration with JSON Schema validation - Optional Bearer token authentication (config file or explicit) - SSE and plain JSON response modes - Non-blocking shell execution with timeout - Runs on any Linux with Lua 5.4 + LuaSocket ## Quick Start ```sh # Install dependencies (Debian/Ubuntu) apt install lua5.4 lua-socket # Or use a self-contained archive (see releases) tar xzf lmcp-linux-amd64.tar.gz export PATH=$PWD/lmcp-linux-amd64/bin:$PATH # Run lua5.4 example_server.lua # lmcp: my-tools v0.1.0 listening on 0.0.0.0:8080/mcp ``` ## Files | File | Description | |------|-------------| | `lmcp.lua` | Core library — HTTP server, JSON-RPC, MCP protocol, auth | | `json.lua` | Minimal JSON encoder/decoder (bundled, no external dep) | | `example_server.lua` | Example server with shell, read/write file, list/search tools | ## Authentication To require a Bearer token, create an `lmcp.conf` next to your server: ``` .godparticle = your-secret-token-here ``` Then reference it when creating the server: ```lua local server = lmcp.new("my-tools", { port = 8080, conf = dir .. "lmcp.conf", }) ``` Clients must send `Authorization: Bearer ` on every request. OPTIONS (CORS preflight) is exempt. You can also set the token directly: ```lua local server = lmcp.new("my-tools", { auth_token = "my-secret-token", }) ``` ## Claude Code Integration Add to `~/.claude/settings.json`: ```json { "mcpServers": { "my-host": { "type": "url", "url": "http://my-host:8080/mcp", "headers": { "Authorization": "Bearer your-token-here" } } } } ``` ## Adding Tools ```lua server:tool("greet", "Say hello to someone.", { type = "object", properties = { name = { type = "string", description = "Who to greet" }, }, required = { "name" }, }, function(args) return "Hello, " .. args.name .. "!" end) ``` Tool handlers return a string (wrapped as text content) or a table (encoded as JSON). Errors thrown via `error()` are caught and returned as MCP error responses. ## Self-Contained Archives Pre-built archives with Lua 5.4 + LuaSocket for Linux: - `lmcp-linux-amd64.tar.gz` — x86_64 - `lmcp-linux-aarch64.tar.gz` — ARM64 (Pi 5, RK3588, etc.) These include the Lua interpreter and LuaSocket shared library so no system packages are needed. ## License MIT