Atlas / MCP servers / sendmux / sendmux-sdk

sendmux-sdkBLOCK

mcp/sendmux/sendmux-sdk

Official monorepo of SDKs, CLI, and MCP servers for Sendmux email APIs across TypeScript, Python, Go, PHP, Rust, and Ruby.

Verdict
BLOCK
Grade
F
Trust score
46 /100
Exposed tools
29 26r · 2w · 1d
Transport
stdio · streamable-http
License
MIT
Stars
65
01

Overview

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

[](https://www.npmjs.com/package/@sendmux/sdk) [](https://pypi.org/project/sendmux-sdk/) [](https://pkg.go.dev/sendmux.ai/go/v3) [](https://crates.io/crates/sendmux) [](https://github.com/Sendmux/sendmux-sdk/actions/workflows/ci.yml) [](https://www.npmjs.com/package/@sendmux/sdk) [](LICENSE)

Official SDK, CLI, and MCP workspace for Sendmux.

Packages

Read from source at commit 94930e1491b4OBSERVED · 2026-10-07
Advertisement
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 (npm)
claude mcp add sendmux-mcp --env SENDMUX_MAILBOX_API_KEY=${SENDMUX_MAILBOX_API_KEY} --env SENDMUX_MANAGEMENT_API_KEY=${SENDMUX_MANAGEMENT_API_KEY} --env SENDMUX_SENDING_API_KEY=${SENDMUX_SENDING_API_KEY} -- npx -y [email protected]
claude-code (pypi)
claude mcp add sendmux-mcp --env SENDMUX_MAILBOX_API_KEY=${SENDMUX_MAILBOX_API_KEY} --env SENDMUX_MANAGEMENT_API_KEY=${SENDMUX_MANAGEMENT_API_KEY} --env SENDMUX_SENDING_API_KEY=${SENDMUX_SENDING_API_KEY} -- None sendmux-mcp==2.2.0
03

Exposed tools (29)

26 read · 2 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
confirm_deletedestructiveParks the task on one elicitation before doing the (pretend) deletion.
greetwriteA sync-only tool: never runs as a task.
multi_inputreadParks the task on two elicitations at once, so they can be answered separately.
protocol_error_jobreadRaises a protocol-level error: `failed` with an inlined `error`.
remote_contract_probereadFixture operation
slow_computereadSleeps for *seconds*, so a cancel can land while it is still running.
test_audio_contentreadReturns WAV audio.
test_custom_headersreadMirrors an argument into an `Mcp-Param-Message` header (SEP-2243).
test_elicitationreadRequests user input via elicitation.
test_elicitation_sep1034_defaultsreadTests elicitation with default values per SEP-1034.
test_elicitation_sep1330_enumsreadTests elicitation with enum schema improvements per SEP-1330.
test_embedded_resourcereadReturns an embedded resource.
test_error_handlingreadAlways returns an error.
test_image_contentreadReturns a PNG image.
test_input_required_result_capabilitiesreadAsks only for the input methods this client declared it can answer.
test_input_required_result_elicitationreadAsks the client one elicitation question, then greets the answer.
test_input_required_result_list_rootsreadAsks the client for its roots, then reports them back.
test_input_required_result_multi_roundreadAsks two dependent questions across three rounds.
test_input_required_result_multiple_inputsreadAsks for elicitation, sampling, and roots in a single round.
test_input_required_result_request_statereadCarries opaque state across the round trip and confirms it came back.
test_input_required_result_samplingreadAsks the client to sample an answer, then echoes the sampled text.
test_input_required_result_tampered_statereadRound-trips sealed state so a tampered echo is rejected by the framework.
test_missing_capabilityreadRequires the client to have declared the sampling capability (SEP-2575).
test_multiple_content_typesreadReturns mixed text, image, and resource content.
test_reconnectionwriteCloses the POST stream mid-call so the client must resume (SEP-1699).
test_samplingreadRequests LLM sampling via the client.
test_simple_textreadA simple text tool for conformance testing.
test_tool_with_loggingreadSends log notifications during execution.
test_tool_with_progressreadReports progress notifications.
04

Trust audit

BLOCKgrade F · trust 46/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

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

What the source does

Filesystem
declared (10 observation(s))
Network
declared (1 observation(s))
Shell
declared (6 observation(s))
Dependencies
pinned
Secrets in source
found

Findings (25)

HIGHInventory / provenance · inv.suspicious_name · CWE-1104
packages/ts/cli/src/commands/management/get-delivery-payload.ts
get-delivery-payload.ts
Why it matters. member named after an attack tool
Fix. remove or justify
HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
scripts/test-connection-adapters.mjs:48
const { stdout } = await exec(command, args, {
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
packages/python/tests/test_attachment_helpers.py:445
return create_sending_client(api_key="smx_mbx_test_attachment_replay", base_url="https://sending-replay.test"), requests
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
packages/python/tests/test_langchain.py:125
secret = "smx_mbx_private_fixture" if field == "api_key" else "oauth-private-fixture"
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
scripts/test-live-e2e-safety.mjs:1327
return { status: 201, body: envelope({ credential: { public_id: "key_owned", secret: "smx_mbx_private_test" } }) };
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
scripts/test-live-e2e-safety.mjs:1351
if (req.method === "POST") return { status: 201, body: envelope(boundary === "key_delete" ? { credential: { public_id: "key_owned", secret: "smx_mbx_private_test" } } : { id: "folder_owned", name: "Fi
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
scripts/test-ts-helpers.mjs:543
apiKey: "smx_agent_test_mailbox",
MEDIUMFilesystem / path · mcp.destructive_tools · CWE-22, CWE-59
confirm_delete
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
.release-please-manifest.json
.release-please-manifest.json
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
.rubocop.yml
.rubocop.yml
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
.ruby-version
.ruby-version
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
go/.golangci.yml
.golangci.yml
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWCode injection · code.dynamic_import · CWE-78, CWE-94, CWE-95
packages/python/tests/test_generated_runtime_versions.py:22
package = importlib.import_module(package_name)
LOWCode injection · code.dynamic_import · CWE-78, CWE-94, CWE-95
packages/python/tests/test_generated_runtime_versions.py:23
api_client = importlib.import_module(f"{package_name}.api_client")
LOWCode injection · code.dynamic_import · CWE-78, CWE-94, CWE-95
packages/python/tests/test_generated_runtime_versions.py:24
configuration = importlib.import_module(f"{package_name}.configuration")
LOWCode injection · code.dynamic_import · CWE-78, CWE-94, CWE-95
packages/python/tests/test_generated_runtime_versions.py:46
package = importlib.import_module(package_name)
LOWCode injection · code.dynamic_import · CWE-78, CWE-94, CWE-95
packages/python/tests/test_generated_runtime_versions.py:47
api_client = importlib.import_module(f"{package_name}.api_client")
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
packages/ts/cli/src/commands/agent/invite-owner.ts:3
import { inviteAgentOwner } from "../../agent-auth.js";
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
packages/ts/cli/src/commands/agent/invite-owner.ts:4
import { SendmuxCommand } from "../../base-command.js";
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
packages/ts/cli/src/commands/agent/register.ts:3
import { registerAgent } from "../../agent-auth.js";
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
packages/ts/cli/src/commands/agent/register.ts:4
import { SendmuxCommand } from "../../base-command.js";
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
packages/ts/cli/src/commands/auth/login.ts:2
import { SendmuxCommand } from "../../base-command.js";
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
packages/python/tests/test_mailbox_stream_arguments.py:33
yield f"http://127.0.0.1:{server.server_port}/api/v1", requests
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
packages/python/tests/test_oauth_retry.py:61
yield f"http://127.0.0.1:{server.server_port}/api/v1", requests, responses
LOWNetwork egress · net.raw_ip · CWE-200, CWE-319
packages/ruby/tests/oauth_http_fixture.rb:25
yield "http://127.0.0.1:#{server.addr[1]}/api/v1", requests

Gates applied: no_behavioural_pass.

Audited 2026-10-07 · audit v0.4.1 · source sha 94930e1491b4full audit observations/trust-audit/mcp-server/sendmux__sendmux-sdk.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-0794930e1491b4BLOCKF46first audit
06

Questions

What is the sendmux-sdk MCP server?

Official monorepo of SDKs, CLI, and MCP servers for Sendmux email APIs across TypeScript, Python, Go, PHP, Rust, and Ruby.

What tools does sendmux-sdk expose?

29 in total: 26 read-only, 2 that write, and 1 that can delete or overwrite (confirm_delete). Every one is listed on this page with its risk.

Is sendmux-sdk safe to connect to an agent?

No — not without reading the findings first. The audit graded it F (46/100) and found 2 critical or high issues in the source. Each one is listed on this page with the file and line it is on. 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 sendmux-sdk need?

It reads CHOCOLATEY_API_KEY, GH_TOKEN, GITHUB_TOKEN, INTERNAL_API_SECRET, POSTHOG_PROJECT_TOKEN, SENDMUX_ACCESS_TOKEN, SENDMUX_API_KEY, SENDMUX_MAILBOX_API_KEY, SENDMUX_MANAGEMENT_API_KEY, SENDMUX_MCP_ALLOW_UNAUTHENTICATED_HTTP, SENDMUX_MCP_AUTHORIZATION_SERVERS and SENDMUX_MCP_HTTP_BEARER_TOKEN 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 sendmux-sdk run?

It speaks stdio and streamable-http, so it runs as a local process your client starts. It is published on npm as @sendmux/sending at 1.6.0.

How current is this page?

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

Advertisement