Skip to main content
Glama
README.md
# LocalSend MCP

`localsend-mcp` gives MCP clients tools for moving files across your local network with [LocalSend](https://localsend.org/).

It exposes:

- `localsend_scan`: scan the LAN for LocalSend devices.
- `localsend_send`: send explicit absolute file paths to a LocalSend target.
- `localsend-mcp-inbox`: optional LocalSend-compatible receiver for collecting logs or small files.

The server uses the LocalSend v2 protocol directly with Python standard-library networking. No cloud relay is used.

## Quick start (Cursor)

```bash
cd ~/projects/localsend-mcp
./scripts/setup.sh
```

Then restart Cursor. On your phone, send files to **`Codex MCP Inbox`** — the desktop LocalSend app does not need to be open.

**Agent tools (in order):**

1. `localsend_status` — is the inbox running?
2. `localsend_inbox_list` — what arrived?
3. `localsend_inbox_read` with `path: "latest"` — read newest text file
4. `localsend_send` — reply to a trusted phone alias

See [AGENTS.md](AGENTS.md) for the short agent workflow.

## Security Warning

This MCP lets an authorized AI client request file transfers from your computer. Only install it in MCP clients you trust.

Safety controls:

- Sends require explicit absolute file paths.
- The server does not scan your folders to choose files.
- You can restrict sends and receives to `trustedDevices`.
- The inbox receiver is opt-in.
- The inbox receiver saves files only to a configured inbox directory.
- The inbox receiver echoes only small text-like files.
- This project transfers files; it does not run commands from other devices.

## Requirements

- Python 3.10 or newer.
- LocalSend running on the target device.
- Both devices on the same local network.

Optional:

- `localsend-cli` on `PATH`, or `LOCALSEND_CLI=/absolute/path/to/localsend-cli`, as a fallback sender.

## Install

From a local checkout:

```bash
python3 -m pip install -e .
```

Then configure your MCP client:

```json
{
  "mcpServers": {
    "localsend": {
      "command": "localsend-mcp"
    }
  }
}
```

Without installing, you can run the server by path:

```json
{
  "mcpServers": {
    "localsend": {
      "command": "python3",
      "args": ["/path/to/localsend-mcp/src/localsend_mcp/server.py"]
    }
  }
}
```

## Recommended Safe Setup

First scan for LocalSend devices:

```json
{
  "name": "localsend_scan",
  "arguments": {
    "timeout": 3
  }
}
```

Copy the trusted device alias and fingerprint into:

`~/.config/localsend-mcp/config.json`

Example:

```json
{
  "trustedDevices": [
    {
      "alias": "Wise blackberry",
      "fingerprint": "abc123"
    }
  ],
  "inboxDir": "~/Downloads/localsend-mcp-inbox"
}
```

If `trustedDevices` is empty or omitted, the server allows discovered targets. For regular use, configure trusted devices.

Set a custom config path with:

```bash
export LOCALSEND_MCP_CONFIG=/path/to/config.json
```

You can also manage trusted devices through MCP:

```json
{
  "name": "localsend_trust_device",
  "arguments": {
    "target": "Wise Blackberry"
  }
}
```

```json
{
  "name": "localsend_list_trusted",
  "arguments": {}
}
```

```json
{
  "name": "localsend_untrust_device",
  "arguments": {
    "alias": "Wise Blackberry"
  }
}
```

## Sending Files

Send to a trusted alias:

```json
{
  "name": "localsend_send",
  "arguments": {
    "target": "Wise Blackberry",
    "files": ["/home/me/Downloads/report.pdf"]
  }
}
```

Send to a known URL:

```json
{
  "name": "localsend_send",
  "arguments": {
    "target": "https://111.111.1.11:53317",
    "files": ["/home/me/Pictures/image.png"],
    "pin": "123456"
  }
}
``` 

If the receiving LocalSend app is still finishing the previous transfer, `localsend_send` retries busy-session responses by default:

```json
{
  "name": "localsend_send",
  "arguments": {
    "target": "Wise Blackberry",
    "files": ["/home/me/file.txt"],
    "busy_retry_seconds": 90,
    "busy_retry_interval": 3
  }
}
```

For phones or sleeping devices, opt into waiting for the target to come online:

```json
{
  "name": "localsend_send",
  "arguments": {
    "target": "Rich Brocolli",
    "files": ["/home/me/file.txt"],
    "queue_if_offline": true,
    "queue_wait_seconds": 300,
    "queue_retry_interval": 5
  }
}
```

If the target is an iPhone or Android device, open LocalSend and keep the app awake while the queued send waits.

## Optional Inbox Receiver

Start a receiver:

```bash
localsend-mcp-inbox
```

It advertises itself on LocalSend as `Codex MCP Inbox` by default and saves received files to:

`~/Downloads/localsend-mcp-inbox`

Change the alias:

```bash
LOCALSEND_INBOX_ALIAS="My MCP Inbox" localsend-mcp-inbox
```

Change the inbox directory:

```bash
localsend-mcp-inbox --dir ~/Desktop/mcp-inbox
```

For best compatibility with the LocalSend mobile apps, run the inbox on the default LocalSend port with HTTPS:

```bash
localsend-mcp-inbox --port 53317 --protocol https
```

This generates a local self-signed certificate under `~/.config/localsend-mcp/` if one does not already exist. Do not run the desktop LocalSend app on the same machine at the same time if it also needs port `53317`.

Protocol request logs are quiet by default. For debugging:

```bash
localsend-mcp-inbox --port 53317 --protocol https --verbose
```

When `trustedDevices` is configured, the inbox rejects upload requests from untrusted senders.

List recent inbox files:

```json
{
  "name": "localsend_inbox_list",
  "arguments": {
    "limit": 10
  }
}
```

Read the latest small text/log file:

```json
{
  "name": "localsend_inbox_read",
  "arguments": {
    "path": "latest"
  }
}
```

`localsend_inbox_read` refuses to read outside the configured inbox and rejects binary or oversized files.

## Safe Chat Mode

Chat mode treats trusted text files received in the inbox as remote prompts. It is not an autonomous command daemon: the MCP client still reads the prompt, decides what to do, and explicitly replies.

Get the latest unread trusted prompt:

```json
{
  "name": "localsend_chat_next_text",
  "arguments": {}
}
```

For a simple success response, send `Done` and mark the prompt handled:

```json
{
  "name": "localsend_chat_done",
  "arguments": {
    "prompt_id": "<prompt id from localsend_chat_next_text>"
  }
}
```

For a custom response, reply to the sender and mark the prompt handled:

```json
{
  "name": "localsend_chat_reply",
  "arguments": {
    "prompt_id": "<prompt id from localsend_chat_next>",
    "text": "Done"
  }
}
```

Chat replies do not wait in a long offline queue by default. If the phone or receiver is not accepting files, the reply is saved under the chat outbox, the prompt is marked handled, and the agent should stop instead of retrying in a loop. Only set `queue_if_offline: true` for chat replies when the user explicitly wants the session to wait.

Use `localsend_chat_next` instead of `localsend_chat_next_text` only when full sender metadata is needed.

Mark a prompt handled without replying:

```json
{
  "name": "localsend_chat_mark_done",
  "arguments": {
    "id": "<prompt id>"
  }
}
```

Chat mode requires sender metadata written by `localsend-mcp-inbox`. It only returns trusted text prompts by default; configure `trustedDevices` before relying on it.

## LocalSend Tips

- LocalSend discovery uses UDP multicast `224.0.0.167:53317`.
- Some networks block multicast; direct IP or URL targets may be more reliable.
- LocalSend HTTPS uses self-signed certificates. This server accepts those certificates for LAN transfers.
- LocalSend Quick Save or auto-save can avoid manual receive prompts, but enable it only for devices you trust.

## Troubleshooting

`No LocalSend device matched alias`

Run `localsend_scan`, confirm both devices are on the same network, and make sure LocalSend is open.

For phones, use `queue_if_offline: true` and open LocalSend when you are ready to receive. Mobile operating systems may suspend LocalSend when the screen is off or the app is backgrounded.

`Refusing to send to untrusted LocalSend device`

Add the device alias, IP, or fingerprint to `trustedDevices`.

`Blocked by another session`

The receiver is busy with a prior LocalSend transfer. The sender retries by default, but enabling LocalSend auto-save on trusted devices helps.

`Read operation timed out`

The receiver may be waiting for user approval or the network may be blocking the transfer. Accept the transfer in LocalSend or increase `timeout`.

## License

MIT

TDQS

B3.4/5.0

Scored across 2 tools

Disambiguation5/5

The two tools have clearly distinct purposes: one scans for receivers, the other sends files. There is no possible confusion between them.

Naming Consistency5/5

Both tools follow a consistent snake_case pattern with the 'localsend_' prefix and a clear verb: 'scan' and 'send'.

Tool Count3/5

Two tools is minimal but acceptable for a focused server that only handles scanning and sending. However, it feels thin compared to the broader file-sharing domain.

Completeness2/5

The server provides only sending capabilities; receiving files is entirely missing. This is a significant gap for a file-sharing tool, as agents cannot complete a full send-receive workflow.

Maintenance

ActivityMaintained
ResponsivenessSyncing