Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c5375b8a77 | |||
| e05438f0e3 |
+47
@@ -200,6 +200,13 @@ end
|
||||
local server_name = os.getenv("LMCP_NAME") or (WINDOWS and "windows-tools" or "linux-tools")
|
||||
local server = lmcp.new(server_name, {
|
||||
port = tonumber(os.getenv("LMCP_PORT") or arg[1]) or 8080,
|
||||
-- LMCP_HOST: bind interface (default 0.0.0.0). Hosts that need
|
||||
-- single-interface binding (hertz: 192.168.88.18 only) set this.
|
||||
host = os.getenv("LMCP_HOST"),
|
||||
-- LMCP_CONF: path to a conf file with bearer-token entries
|
||||
-- (e.g. /opt/herding/etc/hertz-tools.conf). Read by lmcp.lua's
|
||||
-- read_conf; the `.godparticle` entry becomes the bearer token.
|
||||
conf = os.getenv("LMCP_CONF"),
|
||||
})
|
||||
|
||||
-- ---- Tools ----
|
||||
@@ -1066,6 +1073,46 @@ if WINDOWS then
|
||||
})
|
||||
end
|
||||
|
||||
-- ---- host-local tool plugins (issue #22) ----
|
||||
-- Load every .lua file in LMCP_TOOLS_DIR (default /opt/lmcp/tools.d on POSIX,
|
||||
-- %ProgramData%\lmcp\tools.d on Windows). Each file is invoked as a function
|
||||
-- receiving the configured `server` instance and the `run` helper:
|
||||
--
|
||||
-- local server, run = ...
|
||||
-- server:tool("my_local_tool", "...", {...}, function(a) return run(...) end)
|
||||
--
|
||||
-- This is the standard plugin pattern (nginx conf.d/, systemd-tmpfiles.d, …).
|
||||
-- Hosts can ship their own tools alongside the packaged generics without
|
||||
-- forking the upstream server.lua.
|
||||
local plugin_dir = os.getenv("LMCP_TOOLS_DIR")
|
||||
or (WINDOWS and (os.getenv("ProgramData") or "C:\\ProgramData") .. "\\lmcp\\tools.d"
|
||||
or "/opt/lmcp/tools.d")
|
||||
local list_cmd = WINDOWS
|
||||
and ('dir /b "' .. plugin_dir .. '\\*.lua" 2>nul')
|
||||
or ('ls -1 "' .. plugin_dir .. '"/*.lua 2>/dev/null')
|
||||
local lh = io.popen(list_cmd)
|
||||
if lh then
|
||||
for path in lh:lines() do
|
||||
-- On Windows `dir /b` emits bare filenames; prefix the dir.
|
||||
local full = path:match("[/\\]") and path
|
||||
or (plugin_dir .. (WINDOWS and "\\" or "/") .. path)
|
||||
local chunk, err = loadfile(full)
|
||||
if chunk then
|
||||
local ok, perr = pcall(chunk, server, run)
|
||||
if ok then
|
||||
io.stderr:write("lmcp: loaded plugin " .. full .. "\n")
|
||||
else
|
||||
io.stderr:write("lmcp: plugin " .. full .. " errored: "
|
||||
.. tostring(perr) .. "\n")
|
||||
end
|
||||
else
|
||||
io.stderr:write("lmcp: plugin " .. full .. " load error: "
|
||||
.. tostring(err) .. "\n")
|
||||
end
|
||||
end
|
||||
lh:close()
|
||||
end
|
||||
|
||||
local transport = os.getenv("LMCP_TRANSPORT") or "http"
|
||||
if transport == "stdio" then
|
||||
if os.getenv("LMCP_PORT") then
|
||||
|
||||
Reference in New Issue
Block a user