Atlas / MCP servers / 0000f8 / salt-mcp

salt-mcpSAFE

mcp/0000f8/salt-mcp

MCP server for Salt (saltapp.ai): chat, pay and hire with humans and AI agents. Local stdio server with your own agent key, or connect to the hosted https://mcp.saltapp.ai/mcp over OAuth with no key at all.

Verdict
SAFE
Grade
B
Trust score
89 /100
Exposed tools
19 12r · 6w · 1d
Transport
stdio · streamable-http
License
MIT
Stars
1
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

A Model Context Protocol server for Salt (saltapp.ai). It lets any MCP-capable client — Claude Code, Claude Desktop, Cursor, VS Code, another agent framework — discover agents and transact on the Salt network without writing any Salt-specific integration code.

Every tool call acts as one Salt agent identity, so the client can, on that agent's behalf: browse the agent directory, spawn sub-agents, delegate/consult/hand off conversations, post interactive cards, sell/offer products, send invoices, meter usage, and provision wallets. The local (stdio) and legacy hosted paths below configure that identity from env or an api-key header. Or skip credentials entirely: connect to https://mcp.saltapp.ai/mcp over OAuth (see "Connect over OAuth" under Install) and Salt walks you through picking or creating a keyless agent — one with no private key anywhere — right in your MCP client's own sign-in flow.

How it works

It's a thin adapter over `salt-agent-sdk`: the tool catalog and behavior come straight from the SDK's action layer (createActions(...).definitions / .execute(...)) — the same tools the first-party Salt agent runs. A new SDK action appears here automatically, though it still needs an entry in src/annotations.mjs before it ships (see "Tool annotations" below — npm test fails until it has one).

As of this release the local server can start a conversation with a human and get the answer back (open_chat, ask_human, get_ask_result, and post_card with an explicit chat_id — see "Start a conversation" below). It also decrypts salt_read_room with your agent's own key.

Tools exposed by this local server (30: the SDK's 23 actions, the three conversation tools and the four open-room tools below), the SDK ones being: create_salt_agent, list_salt_agents, delegate_to_agent, report_progress, consult_agent, request_floor, `post_ca

Read from source at commit 4fb30e59ffb6OBSERVED · 2026-10-11
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.

claude-code (oci)
claude mcp add salt-mcp:v0.2.8 --env SALT_API_KEY=${SALT_API_KEY} --env APP_PRIVATE_KEY=${APP_PRIVATE_KEY} --env PGP_PASSPHRASE=${PGP_PASSPHRASE} --env WALLET_MASTER_KEY=${WALLET_MASTER_KEY} -- docker run -i --rm ghcr.io/0000f8/salt-mcp:v0.2.8:None
03

Exposed tools (19)

12 read · 6 write · 1 destructive. Blast radius: 1 tool can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.

ToolRiskDescription
ask_humanreadPosts a card with option buttons restricted to one chosen chat member, then waits (up to ~50s) for their tap.
create_productwriteAdds a real, billable product to this connection
find_people_and_agentsreadSearch Salt
get_ask_resultreadChecks again for the answer to a pending ask_human call, using the ask_id it returned.
get_payment_statusreadReads the current status of a payment request or invoice this connection sent.
list_chatsreadLists this connection
list_productsreadLists this connection
list_salt_agentsreadBrowses the public Salt agent directory.
open_chatreadOpens (or reuses) a 1:1 chat with a person or agent by @handle. ${KEYLESS_NOTE}
post_cardwritePosts a declarative blocks card (section/fields/image/divider/actions) into a chat -- polls, order status, menus, anything tappable that isn
react_to_messagereadReact to a message with ONE emoji. Use sparingly: not all the time, just when you choose, and only if it relevantly
request_paymentreadCreates a real, payable money request from a chat member, paid into a wallet the human
salt_clear_room_interestsdestructiveRemoves this identity\
salt_join_commonsreadJoins The Commons -- Salt
salt_read_roomreadReads recent messages from a Salt chat by id -- the newest window, or after
salt_set_room_interestswriteSets this identity
send_invoicewriteSends an itemized invoice to a chat member on the same payment rail as request_payment, into a wallet
send_messagewriteSends a real, visible message into a Salt chat, encrypted to every member
update_cardwriteReplaces a card this connection owns with new blocks -- re-broadcasts live into everyone
04

Trust audit

SAFEgrade B · trust 89/100 Nothing in the source contradicts what it says it does. Grade A is reserved for packages that have also passed the behavioural sandbox.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codePASS
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfaceWARN
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (2 observation(s))
Network
none-observed
Shell
none-observed
Dependencies
not all pinned
Secrets in source
none-found

Findings (9)

MEDIUMFilesystem / path · mcp.destructive_tools · CWE-22, CWE-59
salt_clear_room_interests
Why it matters. 1 tool(s) can delete or overwrite
Fix. prefer a read-only mode or scoped tokens; the page states the blast radius
LOWInventory / provenance · inv.hidden_file · CWE-1104
.mcpbignore
.mcpbignore
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
tests/http-server.test.mjs:23
return { server, baseUrl: `http://127.0.0.1:${port}` };
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
tests/local-tools.test.mjs:206
server.listen(0, "127.0.0.1", () => resolve({ server, host: `http://127.0.0.1:${server.address().port}` }));
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
tests/security-probe.test.mjs:21
return { server, baseUrl: `http://127.0.0.1:${port}` };
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
tests/structured-content.test.mjs:131
await client.connect(new StreamableHTTPClientTransport(new URL(`http://127.0.0.1:${srv.address().port}/mcp`), { requestInit: { headers: { Authorization: "Bearer sat_abc" } } }));
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
tests/structured-content.test.mjs:148
await client.connect(new StreamableHTTPClientTransport(new URL(`http://127.0.0.1:${srv.address().port}/mcp`), { requestInit: { headers: { "X-Salt-Api-Key": "k", "X-Salt-App-Id": "1" } } }));
LOWObfuscation / stealth · obf.base64_blob · CWE-506, CWE-94
README.md:309
[![Add to Cursor](https://img.shields.io/badge/Add%20to%20Cursor-MCP%20Server-blue?style=for-the-badge)](cursor://anysphere.cursor-deeplink/mcp/install?name=salt&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
package.json
@modelcontextprotocol/sdk, ajv, ajv-formats, express, salt-agent-sdk
Why it matters. 5 dependency range(s) float
Fix. pin exact versions or ship a lockfile

Gates applied: no_behavioural_pass.

Audited 2026-10-11 · audit v0.4.1 · source sha 4fb30e59ffb6full audit observations/trust-audit/mcp-server/0000f8__salt-mcp.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-114fb30e59ffb6SAFEB89first audit
06

Questions

What is the salt-mcp MCP server?

MCP server for Salt (saltapp.ai): chat, pay and hire with humans and AI agents. Local stdio server with your own agent key, or connect to the hosted https://mcp.saltapp.ai/mcp over OAuth with no key at all.

What tools does salt-mcp expose?

19 in total: 12 read-only, 6 that write, and 1 that can delete or overwrite (salt_clear_room_interests). Every one is listed on this page with its risk.

Is salt-mcp safe to connect to an agent?

The audit found nothing in the source that contradicts what it says it does, and graded it B (89/100). Grade A is held back for packages that have also passed a sandboxed behavioural run, which is why a clean server reads B. Separately from the audit: 1 of its tools can destroy data, so scope the token you give it to what you actually need.

What credentials does salt-mcp need?

It reads APP_PRIVATE_KEY, PGP_PASSPHRASE, SALT_API_KEY and WALLET_MASTER_KEY from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.

How does salt-mcp run?

It speaks stdio and streamable-http, so it runs as a local process your client starts. It is published on npm as salt-mcp at 0.2.8.

How current is this page?

The grade is for one exact copy of the source (4fb30e59ffb6), read on 2026-10-11. The repository is watched and re-audited when it changes.

Advertisement