send_attachment
Send files, images, videos, or audio to a Signal contact. Supports multiple attachments in one message with optional caption and view-once media.
Instructions
Send one or more files or images to a Signal contact. Supports photos, videos, documents, and audio files. Use path for a single file or paths to send multiple files in one message. Set view_once=true to send media that auto-deletes after the recipient views it once. For groups use send_group_attachment instead.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| recipient | Yes | Phone number in E.164 format | |
| path | No | Single file path (absolute, relative, or ~/path) | |
| paths | No | Multiple file paths to send as one message | |
| caption | No | Optional caption text shown below the attachment | |
| view_once | No | Send as view-once media — recipient can only view it once before it disappears |
Implementation Reference
- src/signal_mcp/server.py:215-234 (registration)Tool schema registration for 'send_attachment' in the TOOLS list — defines name, description, and input schema.
Tool( name="send_attachment", description=( "Send one or more files or images to a Signal contact. " "Supports photos, videos, documents, and audio files. " "Use path for a single file or paths to send multiple files in one message. " "Set view_once=true to send media that auto-deletes after the recipient views it once. " "For groups use send_group_attachment instead." ), inputSchema={ "type": "object", "properties": { "recipient": {"type": "string", "description": "Phone number in E.164 format"}, "path": {"type": "string", "description": "Single file path (absolute, relative, or ~/path)"}, "paths": {"type": "array", "items": {"type": "string"}, "description": "Multiple file paths to send as one message"}, "caption": {"type": "string", "description": "Optional caption text shown below the attachment", "default": ""}, "view_once": {"type": "boolean", "description": "Send as view-once media — recipient can only view it once before it disappears", "default": False}, }, "required": ["recipient"], }, - src/signal_mcp/server.py:224-234 (schema)Input schema for send_attachment — accepts recipient (required), path/paths (one required), caption, view_once.
inputSchema={ "type": "object", "properties": { "recipient": {"type": "string", "description": "Phone number in E.164 format"}, "path": {"type": "string", "description": "Single file path (absolute, relative, or ~/path)"}, "paths": {"type": "array", "items": {"type": "string"}, "description": "Multiple file paths to send as one message"}, "caption": {"type": "string", "description": "Optional caption text shown below the attachment", "default": ""}, "view_once": {"type": "boolean", "description": "Send as view-once media — recipient can only view it once before it disappears", "default": False}, }, "required": ["recipient"], }, - src/signal_mcp/client.py:334-359 (handler)Core handler for send_attachment in SignalClient — validates E.164, resolves file paths, sends via signal-cli JSON-RPC 'send' method with attachment param, and saves message locally.
async def send_attachment( self, recipient: str, path: str | list[str], caption: str = "", view_once: bool = False, ) -> SendResult: _validate_e164(recipient) await self._rate_limiter.acquire() paths = [path] if isinstance(path, str) else path resolved = [str(Path(p).expanduser().resolve()) for p in paths] params: dict = {"recipient": [recipient], "attachment": resolved} if caption: params["message"] = caption if view_once: params["viewOnce"] = True result = await self._rpc("send", params) ts = result.get("timestamp", int(time.time() * 1000)) await asyncio.to_thread(_store.save_message, Message( id=f"sent_{ts}_{recipient}", sender=self.account, recipient=recipient, body=caption, timestamp=datetime.fromtimestamp(ts / 1000), )) return SendResult(timestamp=ts, recipient=recipient, success=True) - src/signal_mcp/server.py:1283-1293 (handler)MCP tool dispatch handler for send_attachment — extracts arguments, delegates to client.send_attachment(), returns result.
elif name == "send_attachment": path_arg = arguments.get("paths") or arguments.get("path") if not path_arg: return _err("Either path or paths is required") result = await client.send_attachment( arguments["recipient"], path_arg, caption=arguments.get("caption", ""), view_once=arguments.get("view_once", False), ) return _ok({"status": "sent", "timestamp": result.timestamp}) - src/signal_mcp/server.py:1113-1118 (registration)Required parameter validation registration — send_attachment requires 'recipient'.
_REQUIRED: dict[str, list[str]] = { "send_message": ["recipient", "message"], "send_group_message": ["group_id", "message"], "send_note_to_self": ["message"], "send_attachment": ["recipient"], "send_group_attachment":["group_id"],