salt-api-cli MCP server
Commit Nov 4, 2026Provides a command-line interface and MCP server to manage SaltStack infrastructure, execute modules, and manage minion keys.
Also known as laurentL/salt-api-cli
- Stars
- 1
- Tools
- 12
- Downloads, 30 days
- —
- Latest version
- —
- Last commit
- Nov 4, 2026
- License
- MIT
What is salt-api-cli MCP?
salt-api-cli provides a command-line interface and MCP server to manage SaltStack infrastructure, execute modules, and manage minion keys. It exposes 12 tools, such as salt_list_profiles, salt_ping, salt_run.
Summary generated from the project's README
About salt-api-cli MCP server
Managing SaltStack infrastructure through AI agents is possible with salt-api-cli, a Go-based tool that provides both a command-line interface and a full-access MCP server. It acts as a wrapper for SaltStack's netapi, allowing users to interact with Salt Masters via rest_cherrypy or rest_tornado. The tool supports multiple profiles for different environments like production or staging, managed through a configuration file.
Users can connect their AI clients, such as Claude Code, Cursor, or Gemini CLI, by running the mcp command to start a server over stdio. The server exposes 12 specific tools that allow an agent to perform complex operations like applying states, running master runners, or managing minion keys. It handles authentication by caching tokens in a secure local file and can resolve credentials using environment variables or external secret tools. This setup enables automated infrastructure management directly from an AI chat interface.
What you can do with it
- 1Automated infrastructure state applicationAn AI agent can apply a specific Salt state or a highstate to targeted minions using the state apply tool.
- 2Minion key lifecycle managementA developer can instruct an AI to accept, reject, or delete minion keys to maintain security.
- 3Infrastructure inventory inspectionYou can ask an AI to list all known minions and retrieve their specific grains or online status.
- 4Executing master-side functionsAn AI client can trigger Salt Master Runner modules or Wheel functions to perform orchestration tasks.
Written from the project's README. Every use case is checked against a quote from it.
salt-api-cli MCP tools 12
Detected from the READMEsalt_list_profilessalt_pingsalt_runsalt_state_applysalt_list_minionssalt_get_minion_grainssalt_list_jobssalt_get_jobsalt_runnersalt_wheelsalt_keys_managesalt_send_hook
| salt_list_profiles | — | |
| salt_ping | — | |
| salt_run | — | |
| salt_state_apply | — | |
| salt_list_minions | — | |
| salt_get_minion_grains | — | |
| salt_list_jobs | — | |
| salt_get_job | — | |
| salt_runner | — | |
| salt_wheel | — | |
| salt_keys_manage | — | |
| salt_send_hook | — |
Automated checks
Ran Nov 14, 2026Full report →Not verified yet. A server needs a score of 80, no serious finding, and enough data for us to check. How checks work · What to fix for more points
- Source repository linked and reachablelaurentl/salt-api-cli is public and reachablegithub.com/laurentl/salt-api-cli ↗Pass
- Package names this repository as its sourceNot checked
- Build provenance (Sigstore attestation)Not checked
- Open source license (OSI)MITspdx.org/licenses/MIT.html ↗Pass
- Commit or release in the last yearLast commit or release 2026-11-04github.com/laurentl/salt-api-cli ↗Pass
- OpenSSF ScorecardNot checked
- Package name not close to a popular packageNot checked
- No critical advisory in the package or its dependenciesNot checked
- No hidden instructions to the model12 tool descriptions and the README read; no override phrases, credential paths or hidden charactersPass
- Destructive tools are labelledNo tool named like delete, drop or execPass
- Remote endpoint answers the MCP handshakeNot checked
README
View on GitHubsapi — SaltStack salt-api CLI & Full-Access MCP Server
sapi is a fast, zero-dependency Go command-line client that wraps SaltStack's salt-api (netapi: rest_cherrypy / rest_tornado) and embeds a Full-Access Model Context Protocol (MCP) server (stdio) for AI coding and operations agents (Claude Code, Gemini CLI, Cursor, Google Antigravity).
Key Features
- Hybrid CLI Experience:
- Drop-in
saltShortcut Mode: Runsapi '*' test.ping,sapi -G 'os:Debian' cmd.run 'uptime', orsapi -b 25% '*' state.highstatedirectly without verbose subcommands. - Structured Subcommands:
run,async,batch,job,minion,runner,wheel,key,event,profile,auth,stats, andmcp.
- Drop-in
- Multi-Profile & Flexible Secret Resolution:
- Manage multiple Salt Masters (
prod,staging,dev) in~/.config/sapi/config.toml. - Resolve credentials via
password_env,password_cmd(e.g.,pass,secret-tool,1password), environment variables (SALT_API_*), or interactive terminal prompt.
- Manage multiple Salt Masters (
- Automatic Token Caching & Renewal:
- Caches
X-Auth-Tokenin~/.cache/sapi/tokens.jsonwith strict0600permissions. - Proactively refreshes tokens before expiration and transparently retries once on
HTTP 401 Unauthorized.
- Caches
- Rich Output Renderers:
pretty(colorized tree output matching native Salt CLI + automaticstate.apply/highstatesummary table),json,yaml, andtable.
- Built-in Full-Access MCP Server (
sapi mcp):- Exposes 12 MCP tools over
stdioallowing AI agents to inspect minions/grains/jobs, run execution modules, apply states, execute Master runners/wheel functions, manage minion keys (list,accept,reject,delete,finger), and trigger Salt webhooks across any configured profile.
- Exposes 12 MCP tools over
Architecture
flowchart LR
subgraph Inputs["Interfaces"]
CLI_Sub["Structured CLI\nsapi run / job / key..."]
CLI_Short["Native Shortcut\nsapi '*' test.ping"]
MCP_Stdio["MCP Server (stdio)\nsapi mcp"]
end
subgraph Core["Go Core (internal/)"]
Cfg["Config & Profiles\nconfig.toml + SALT_API_*"]
Auth["Token Cache (0600)\nAuto-renew /login"]
Client["NetAPI HTTP Client\nlocal, async, batch, runner, wheel, SSE"]
Out["Output Renderers\nPretty / JSON / YAML / Table"]
end
subgraph SaltMasters["Salt Infrastructure"]
M1["Salt Master (Prod)\nhttps://salt-prod:8000"]
M2["Salt Master (Staging)\nhttps://salt-stg:8000"]
end
CLI_Sub --> Cfg
CLI_Short --> Cfg
MCP_Stdio --> Cfg
Cfg --> Auth
Auth --> Client
Client --> Out
Client --> M1
Client --> M2
Installation
Via go install
go install github.com/laurentL/salt-api-cli/cmd/sapi@latest
Debian / Ubuntu Package (.deb)
Build and install the native .deb package (includes /usr/bin/sapi, man pages sapi(1) + sapi-*(1), and bash/zsh/fish completions):
make deb
sudo dpkg -i dist/sapi_1.0.0-1_amd64.deb
# Or using standard debhelper:
dpkg-buildpackage -us -uc -b
From Source (Makefile)
git clone https://github.com/laurentL/salt-api-cli.git
cd salt-api-cli
make all
make install
# Installs binary to ~/bin/sapi and man pages to ~/.local/share/man/man1/
Man Pages
man sapi
man sapi-run
man sapi-key
man sapi-mcp
Configuration (~/.config/sapi/config.toml)
Initialize a sample configuration file:
sapi profile init
Or create/update a profile directly from the CLI:
sapi profile set prod \
--url https://salt-master.prod.example.com:8000 \
--user saltadmin \
--eauth pam \
--password-env SALT_PROD_PASSWORD \
--default
Example ~/.config/sapi/config.toml (see config.example.toml):
default_profile = "prod"
default_output = "pretty" # pretty | json | yaml | table
[profiles.prod]
url = "https://salt-master.prod.example.com:8000"
username = "saltadmin"
password_env = "SALT_PROD_PASSWORD" # or password_cmd = "secret-tool lookup service salt-prod"
eauth = "pam" # pam | ldap | file | sharedsecret | auto
verify_ssl = true
timeout = "60s"
[profiles.staging]
url = "https://salt-master.staging.example.com:8000"
username = "saltadmin"
password_env = "SALT_STAGING_PASSWORD"
eauth = "pam"
verify_ssl = false
timeout = "30s"
Environment Variable Overrides
CLI flags take precedence over environment variables, which take precedence over config.toml:
SALT_API_PROFILE: Active profile nameSALT_API_URL: Salt Mastersalt-apiURLSALT_API_USER: UsernameSALT_API_PASSWORD: PasswordSALT_API_EAUTH: External auth backend (pam,ldap,file,sharedsecret)SALT_API_TOKEN: Pre-existingX-Auth-TokenSALT_API_INSECURE: Skip TLS verification (true/1)
CLI Usage
1. Native salt Shortcut Mode
Any command whose first positional argument is not a reserved subcommand is automatically executed against targeted minions:
# Connectivity check
sapi '*' test.ping
# Target by Grain (-G), PCRE (-E), List (-L), Pillar (-I), Compound (-C), Nodegroup (-N), Subnet (-S)
sapi -G 'os_family:Debian' pkg.install htop refresh=True
sapi -L 'web-01,web-02' service.restart nginx
sapi -C 'G@os:Ubuntu and E@db-.*' cmd.run 'df -h'
# Asynchronous execution with live job polling
sapi --async --wait '*' state.apply common test=True
# Progressive batch execution
sapi -b 20% '*' state.highstate
2. Structured Subcommands
# Authentication & token cache inspection
sapi auth login -p prod
sapi auth status
sapi auth logout
# Jobs management
sapi job list --limit 15 --function state.apply
sapi job get 20261015130000123456 --info
sapi job wait 20261015130000123456 --interval 2s --timeout 5m
sapi job active
# Minions & Grains inventory
sapi minion list
sapi minion grains web-01 os ipv4 mem_total
sapi minion status
# Master Runners & Wheel modules
sapi runner manage.up
sapi runner state.orchestrate orch.deploy pillar='{"version":"2.1.0"}'
sapi wheel config.values
# Minion Keys management (via Wheel)
sapi key list
sapi key accept web-new-01
sapi key reject web-unwanted-01
sapi key delete web-old-01
sapi key finger '*'
# Real-time Event Bus (SSE) & Webhooks
sapi event listen --tag 'salt/job/*' --count 10
sapi event hook deploy/app -d '{"env":"staging","version":"1.2.3"}'
# Salt-API server statistics
sapi stats
MCP Server Integration (Claude Code / Gemini CLI / Antigravity / Cursor)
sapi mcp (or sapi --mcp) starts a Model Context Protocol server over stdio. Technical logs are written to /tmp/sapi_mcp.log so stdout remains strictly reserved for JSON-RPC frames.
Add the following entry to your mcp_config.json (or .mcp.json):
{
"mcpServers": {
"salt": {
"command": "sapi",
"args": ["mcp"]
}
}
}
Exposed MCP Tools (Full Access)
Every tool accepts an optional profile parameter so the AI agent can dynamically target prod, staging, or dev:
| Tool Name | Description |
|---|---|
salt_list_profiles |
List configured Salt Master profiles from ~/.config/sapi/config.toml and show the default profile. |
salt_ping |
Test connectivity (test.ping) against targeted minions (tgt, tgt_type). |
salt_run |
Execute any Salt execution module (local, local_async with optional wait, or local_batch). |
salt_state_apply |
Apply a Salt state or highstate (state, test, pillar, saltenv, wait). |
salt_list_minions |
List known minions and their grains or online/offline status (manage.status). |
salt_get_minion_grains |
Fetch full or filtered grains for a specific minion (minion_id, grain). |
salt_list_jobs |
List historical jobs (/jobs) or currently running jobs (active_only=true). |
salt_get_job |
Retrieve full return data for a jid (with optional wait=true polling). |
salt_runner |
Execute any Salt Master Runner module (fun, args, kwargs, async). |
salt_wheel |
Execute any Salt Master Wheel function (fun, args, kwargs, async). |
salt_keys_manage |
Manage minion keys (list, accept, reject, delete, finger). |
salt_send_hook |
Trigger a Salt-API webhook (POST /hook/<tag>) with a JSON payload. |
License
Released under the MIT License.
salt-api-cli MCP questions
What tools does salt-api-cli MCP provide?
It exposes 12 tools, including salt_list_profiles, salt_ping, salt_run, salt_state_apply, salt_list_minions.
Can I manage multiple Salt Masters?
Yes, you can manage multiple Salt Masters (e.g., prod, staging, dev) by defining profiles in ~/.config/sapi/config.toml.