diff --git a/repl.lua b/repl.lua index 4041171..fa826d0 100644 --- a/repl.lua +++ b/repl.lua @@ -161,6 +161,48 @@ function M.run(config) return true, #sess:list_tools() end + -- Walk config.mcp.auto_approve and warn about keys that match no live + -- tool / no live alias (issue #33). Stale entries silently failed to + -- auto-approve, leaving the user with unexpected confirm prompts. + -- Called at startup AND after :mcp connect so newly-arrived sessions + -- retroactively validate any keys that referenced them. + local function validate_auto_approve() + local policy = config.mcp and config.mcp.auto_approve + if not policy then return end + for key, _ in pairs(policy) do + local alias_glob = key:match("^(.-)__%*$") + if alias_glob then + if not mcp_sessions[alias_glob] then + renderer.status(("auto_approve key '%s': no MCP server " + .. "connected for alias '%s'"):format(key, alias_glob)) + end + else + local alias, tname = key:match("^(.-)__(.+)$") + if not alias or alias == "" or not tname then + renderer.status(("auto_approve key '%s': not in " + .. "'alias__tool' or 'alias__*' form"):format(key)) + else + local sess = mcp_sessions[alias] + if not sess then + renderer.status(("auto_approve key '%s': no MCP " + .. "server connected for alias '%s'") + :format(key, alias)) + else + local found = false + for _, t in ipairs(sess:list_tools()) do + if t.name == tname then found = true; break end + end + if not found then + renderer.status(("auto_approve key '%s': " + .. "alias '%s' has no tool named '%s'") + :format(key, alias, tname)) + end + end + end + end + end + end + if config.mcp and config.mcp.servers then for alias, server_cfg in pairs(config.mcp.servers) do local ok, n = connect_mcp(alias, server_cfg) @@ -168,6 +210,7 @@ function M.run(config) renderer.status(("mcp %s: %d tools"):format(alias, n)) end end + validate_auto_approve() end -- Assemble OpenAI-shape `tools` array across all live sessions, with @@ -827,6 +870,9 @@ function M.run(config) if ok then renderer.status(("mcp %s: connected (%d tools)") :format(alias, n)) + -- Re-validate auto_approve so any stale keys that + -- referenced this alias become live (issue #33 bonus). + validate_auto_approve() end elseif sub == "disconnect" then local alias = sub_args:match("^%s*(%S+)")