feat: read-only gate around WhatsApp send tools (connector defense-in-depth)

send_message/send_file/send_audio_message register unless WHATSAPP_READ_ONLY=true|1. Default keeps send
available (soul consent is the primary gate). Validated via stdio tools/list: default exposes 14 tools
incl send_message; read-only exposes 11 (send tools hidden).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Tim Lingo
2026-06-27 14:19:47 -05:00
parent b5434016ab
commit eaa92b4255
+19 -12
View File
@@ -62,20 +62,27 @@ func InitMcpTool() {
Description: "Get most recent WhatsApp message involving the contact.",
}, getLastInteractionHandler)
mcp.AddTool[sendMessageInput, map[string]any](server, &mcp.Tool{
Name: "send_message",
Description: "Send a text message to a person or group on WhatsApp. For groups use the group JID.",
}, sendMessageHandler)
// Send tools are registered unless the connector runs in read-only mode.
// WHATSAPP_READ_ONLY=true (or 1) hides all outbound tools — defense-in-depth on top of the
// soul's per-send consent gate. Default: send tools available (consent still required upstream).
readOnly := strings.ToLower(ReadEnv("WHATSAPP_READ_ONLY", "false")) == "true" ||
ReadEnv("WHATSAPP_READ_ONLY", "0") == "1"
if !readOnly {
mcp.AddTool[sendMessageInput, map[string]any](server, &mcp.Tool{
Name: "send_message",
Description: "Send a text message to a person or group on WhatsApp. For groups use the group JID.",
}, sendMessageHandler)
mcp.AddTool[sendFileInput, map[string]any](server, &mcp.Tool{
Name: "send_file",
Description: "Send image, video, document or any file via WhatsApp.",
}, sendFileHandler)
mcp.AddTool[sendFileInput, map[string]any](server, &mcp.Tool{
Name: "send_file",
Description: "Send image, video, document or any file via WhatsApp.",
}, sendFileHandler)
mcp.AddTool[sendAudioMessageInput, map[string]any](server, &mcp.Tool{
Name: "send_audio_message",
Description: "Send audio/voice message (converted to Opus .ogg if needed).",
}, sendAudioMessageHandler)
mcp.AddTool[sendAudioMessageInput, map[string]any](server, &mcp.Tool{
Name: "send_audio_message",
Description: "Send audio/voice message (converted to Opus .ogg if needed).",
}, sendAudioMessageHandler)
}
mcp.AddTool[downloadMediaInput, map[string]any](server, &mcp.Tool{
Name: "download_media",