Skip to main content
Glama
mcp-signal

mcp-signal

mcp-signal

Python uv MCP License: MIT GitHub issues GitHub stars Sealjay/mcp-signal MCP server

Локальный сервер протокола контекста модели (MCP), который считывает историю Signal Desktop из локальной зашифрованной базы данных через signal-export и отправляет исходящие сообщения через signal-cli.

mcp-signal фокусируется на основном рабочем процессе для личной автоматизации Signal — список чатов, чтение сообщений, поиск по сообщениям, просмотр групп и отправка сообщений в личные или групповые чаты. Все работает локально; используется транспорт stdio без сетевого прослушивателя.

Внимание — смешанный бэкенд. Чтение/поиск осуществляется из локальной базы данных Signal Desktop. Для отправки используется signal-cli, который должен быть установлен и привязан к учетной записи Signal отдельно. Если signal-cli недоступен, чтение/поиск будут работать, но инструменты отправки — нет.

Функции

  • Список личных и групповых чатов из Signal Desktop

  • Чтение последних сообщений из чата

  • Поиск сообщений в одном чате или по всем чатам

  • Список групповых чатов с идентификаторами групп signal-cli для исходящих сообщений

  • Отправка сообщения:

    • прямому получателю по номеру телефона

    • в группу по идентификатору группы

    • в чат по точному названию чата (с проверкой неоднозначности)

  • Работает полностью на вашем компьютере; транспорт stdio без сетевого прослушивателя

Related MCP server: Signal MCP

Настройка

Предварительные требования

  • Python 3.13+

  • uv

  • Signal Desktop с существующей локальной базой данных сообщений

  • signal-cli, установленный и привязанный, если вы хотите отправлять сообщения

Установка

  1. Клонируйте этот репозиторий

    git clone https://github.com/Sealjay/mcp-signal.git
    cd mcp-signal
  2. Установите зависимости

    uv sync
  3. Установите signal-cli (необязательно — нужно только для исходящих сообщений)

    В macOS проще всего использовать Homebrew:

    brew install signal-cli

Настройка исходящих сообщений

Сервер автоматически загружает локальный файл .env.local из корня репозитория, если он существует. Этот файл игнорируется git и является рекомендуемым местом для локальной конфигурации машины.

cat > .env.local <<'EOF'
SIGNAL_ACCOUNT="+441234567890"
EOF

Необязательные переменные окружения:

Переменная

Назначение

SIGNAL_CLI_PATH

Переопределить путь к бинарному файлу signal-cli

SIGNAL_DATA_DIR

Переопределить директорию данных Signal Desktop

SIGNAL_DB_PASSWORD

Пароль для зашифрованных баз данных Desktop, если требуется

SIGNAL_DB_KEY

Ключ для зашифрованных баз данных Desktop, если требуется

Переменные окружения, установленные в оболочке, имеют приоритет над .env.local.

Привязка signal-cli (только при первом запуске)

mcp-signal не управляет привязкой самостоятельно. Сначала привяжите локальное устройство signal-cli:

signal-cli link -n "signal-mcp"

Отсканируйте QR-код в мобильном приложении Signal (Настройки → Связанные устройства → Связать новое устройство).

Не передавайте -a / --account в команду link в текущих версиях signal-cli — привязка нового вторичного устройства не требует номера телефона.

После того как QR-код будет принят, убедитесь, что связанная учетная запись видна:

signal-cli listAccounts

Эта учетная запись должна соответствовать значению SIGNAL_ACCOUNT в .env.local.

signal-cli хранит состояние связанной учетной записи в своей собственной локальной директории данных (обычно ~/.local/share/signal-cli/data в macOS/Linux). Это состояние находится вне этого репозитория и не коммитится в mcp-signal.

Проверьте, что все подключено:

uv run signal-mcp smoke

Конфигурация MCP-клиента

Все клиенты запускают сервер одинаково через stdio. В macOS вам может потребоваться абсолютный путь к uv — см. macOS: uv PATH ниже.

Claude Code

Самый быстрый путь — через CLI:

claude mcp add --transport stdio signal --scope user -- uv run --directory /absolute/path/to/mcp-signal signal-mcp serve

Альтернативно, добавьте в .mcp.json в корне вашего проекта (или ~/.claude.json для сервера на уровне пользователя):

{
  "mcpServers": {
    "signal": {
      "type": "stdio",
      "command": "uv",
      "args": ["run", "--directory", "/absolute/path/to/mcp-signal", "signal-mcp", "serve"]
    }
  }
}

Если вы редактируете файл напрямую, перезапустите сессию Claude Code, чтобы изменения вступили в силу.

Claude Desktop

Добавьте в ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):

{
  "mcpServers": {
    "signal": {
      "command": "uv",
      "args": ["run", "--directory", "/absolute/path/to/mcp-signal", "signal-mcp", "serve"]
    }
  }
}

Перезапустите Claude Desktop. Вы должны увидеть signal в списке доступных интеграций.

Cursor

Добавьте в ~/.cursor/mcp.json:

{
  "mcpServers": {
    "signal": {
      "command": "uv",
      "args": ["run", "--directory", "/absolute/path/to/mcp-signal", "signal-mcp", "serve"]
    }
  }
}

Перезапустите Cursor.

macOS: uv PATH

Графические приложения (Claude Desktop, Cursor) не всегда наследуют PATH из вашего интерактивного терминала, поэтому uv может выдать ошибку spawn uv ENOENT. Исправьте это, используя абсолютный путь к uv в command:

  • Homebrew — /opt/homebrew/bin/uv (Apple Silicon) или /usr/local/bin/uv (Intel)

  • Ручная установка — выполните which uv в терминале, чтобы найти путь

Пример:

{
  "mcpServers": {
    "signal": {
      "command": "/opt/homebrew/bin/uv",
      "args": ["run", "--directory", "/absolute/path/to/mcp-signal", "signal-mcp", "serve"]
    }
  }
}

Архитектура

Компонент

Описание

MCP-сервер

Python/FastMCP, транспорт stdio

Путь чтения

signal-export читает локальную базу данных Signal Desktop

Путь отправки

signal-cli JSON-RPC, запускается по требованию

Состояние

Нет отдельного кэша; чтение напрямую из данных Signal Desktop

Поток данных

  1. MCP-клиент запускает signal-mcp serve через stdio.

  2. Инструменты чтения/поиска вызывают signal-export для локальной базы данных Signal Desktop.

  3. Список групп и исходящие сообщения вызывают signal-cli -a ACCOUNT jsonRpc.

  4. Результаты возвращаются в виде структурированного JSON.

Структура проекта

mcp-signal/
  src/mcp_signal/
    config.py
    main.py
    reader.py
    server.py
    signal_cli.py
  tests/
  CLAUDE.md
  LICENSE
  README.md
  SECURITY.md

Инструменты

Инструмент

Назначение

list_chats

Список личных и групповых чатов из Signal Desktop

read_messages

Чтение сообщений из конкретного чата

search_messages

Поиск сообщений в одном чате или по всем чатам

list_groups

Список групп из signal-cli, включая идентификаторы групп

send_message

Отправка текстового сообщения прямому получателю или в группу

get_status

Показать состояние БД Desktop / signal-cli / учетной записи

Конфиденциальность и безопасность

  • Нет облачного ретранслятора. Нет сетевого прослушивателя. Все данные остаются на вашем компьютере.

  • Чтение/поиск использует только ваши локальные данные Signal Desktop.

  • Операции отправки требуют локально настроенной учетной записи signal-cli.

  • .env.local предназначен для локальных секретов, таких как SIGNAL_ACCOUNT, и не коммитится.

  • Состояние связанного устройства signal-cli хранится в его собственной локальной директории данных приложения, вне этого репозитория, и не коммитится.

См. SECURITY.md для получения информации о том, как сообщать об уязвимостях.

Ограничения

  • Риск инъекции промптов: как и многие MCP-серверы, этот подвержен смертельному трио. Вредоносные входящие сообщения могут попытаться дать агенту команду на эксфильтрацию других сообщений. Относитесь к поверхности инструментов соответствующим образом и проверяйте исходящие действия перед их одобрением.

  • Смешанный бэкенд: история чатов берется из Signal Desktop, а исходящие сообщения — из signal-cli.

  • Нет вложений: отправка только текста.

  • Нет уведомлений в реальном времени: только опрос/чтение.

  • Одна учетная запись на экземпляр MCP.

  • Для отправки в группы нужен signal-cli: одного чтения локальной БД недостаточно для безопасной отправки в группы.

Разработка

uv sync
uv run signal-mcp smoke
uv run pytest
uv run ruff check .

Устранение неполадок

  • signal-cli не найден — убедитесь, что signal-cli находится в PATH, или установите SIGNAL_CLI_PATH в .env.local. В macOS проще всего использовать brew install signal-cli.

  • Чтение/поиск работают, но отправка не удается — signal-cli не привязан или не установлен SIGNAL_ACCOUNT. Выполните signal-cli listAccounts для проверки, затем проверьте .env.local.

  • signal-cli link зависает или выдает ошибку — не передавайте -a / --account в link в текущих версиях. Выполните signal-cli link -n "signal-mcp" и отсканируйте QR-код с телефона.

  • MCP-клиент не может запустить сервер — args должны содержать абсолютный путь к репозиторию, а не относительный. Если сам uv выдает ошибку spawn uv ENOENT, см. macOS: uv PATH.

  • Сообщения не возвращаются — убедитесь, что Signal Desktop установлен и имеет историю сообщений. Путь чтения запрашивает локальную базу данных Signal Desktop напрямую.

Участие в разработке

Приветствуются вклады через pull request. Пожалуйста:

  • Выполните uv run ruff check . перед отправкой.

  • Убедитесь, что uv run pytest проходит успешно.

См. CLAUDE.md для полного рабочего процесса разработки.

Лицензия

Лицензия MIT — см. LICENSE.

Available Tools

9 tools
chat_activityChat ActivityA
Read-onlyIdempotent

List Signal chats ranked by recent activity, showing last message date, last reply date, and count of unanswered inbound messages.

Read-only with no side effects. Use this to identify chats that need a response. Use list_chats instead for a general chat directory with message previews.

Inputs: limit. Returns: result

decrypt_attachmentDecrypt AttachmentA

Decrypt a locally stored Signal attachment and return the path to the decrypted file.

The encrypted_path and local_key values come from attachment metadata in read_messages or search_messages results. Read-only on Signal data; writes a decrypted copy to a temporary directory (the temp file is not auto-cleaned). Returns the absolute path to the decrypted file as a string on success, or a string starting with 'Error:' on failure (missing file, wrong key length, or HMAC mismatch). Use this after reading messages that contain attachments.

Inputs: local_key (required), encrypted_path (required). Returns: result

get_statusGet StatusA
Read-onlyIdempotent

Check whether the Signal MCP server can read local messages and send outbound messages.

Returns boolean fields: source_dir_exists, signal_cli_available, signal_account_configured, read_available, send_available. Read-only with no side effects. Call this before read or send operations to verify configuration; call pairing_status instead to check first-run device-linking state.

Inputs: no named parameters. Returns: object

list_chatsList ChatsA
Read-onlyIdempotent

List direct and group Signal chats from the local desktop database, sorted by most recent message.

Each result includes name, phone number, message count, and a preview of the last message. Read-only with no side effects. Use this to discover exact chat names before calling read_messages or search_messages. Use list_groups instead when you need group_id values for send_message.

Inputs: limit, query. Returns: result

list_groupsList GroupsA
Read-onlyIdempotent

List Signal groups with group_id, name, description, members, and admin lists, sorted alphabetically.

Read-only with no side effects. Queries signal-cli when available; falls back to the local desktop database (without group_id). Use this to obtain group_id values needed by send_message. Use list_chats instead for a combined view of both direct and group chats.

Inputs: limit, query. Returns: result

pairing_statusPairing StatusA

Report the Signal device-linking setup state for first-run pairing, so a client can surface the live link QR.

Returns a setup_state envelope: state 'ready' with the linked account once signal-cli is linked; 'awaiting_qr' with a 'qr_payload' sgnl://linkdevice URI to scan in Signal (Settings → Linked devices → Link new device) while a link is in progress (no payload yet on the first call, until the URI is captured); or 'error' when signal-cli is unavailable. Read-only from the caller's view, but the first call on an unlinked device starts a background signal-cli link process as a side effect. Poll this to drive a pairing UI; call get_status instead to check read/send availability once linked.

Inputs: no named parameters. Returns: object

read_messagesRead MessagesA
Read-onlyIdempotent

Read messages from a single Signal chat, returned newest-first.

Each message includes sender, date, body text, reactions, and attachment metadata. Read-only with no side effects. Requires an exact chat name from list_chats. Use search_messages instead to find messages by keyword across chats.

Inputs: chat_name (required), after, limit, before, +1 more. Returns: result

search_messagesSearch MessagesA
Read-onlyIdempotent

Search Signal message bodies for a keyword, within one chat or across all chats, returned newest-first.

Each result includes sender, date, chat name, body text, reactions, and attachment metadata. Read-only with no side effects. Use this to find messages by content. Use read_messages instead to browse a specific chat chronologically.

Inputs: query (required), limit, chat_name. Returns: result

send_messageSend MessageA

Send a text message via Signal to a direct recipient or group.

This is a write operation that delivers a real message through signal-cli. Sends are not reversible from this server — Signal supports user-initiated message deletion only via the official clients. Exactly one of phone_number, group_id, or chat_name must be supplied; providing zero or more than one raises an error. Rate-limited to 1 message per recipient per second and 10 messages per 60-second window globally. Requires signal-cli and SIGNAL_ACCOUNT to be configured — call get_status first to verify send_available is true. Returns target_type, target identifier, and timestamp on success.

Inputs: message (required), group_id, chat_name, phone_number. Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.5/5.0

    Scored across 9 tools

    Disambiguation5/5

    Each tool has a narrow, distinct purpose, and descriptions explicitly route the agent elsewhere when overlap exists (e.g. chat_activity vs list_chats, read_messages vs search_messages, get_status vs pairing_status). The only natural overlap is list_chats also covering groups, but list_groups is clearly framed as the source of group_id values. An agent should never misselect here.

    Naming Consistency4/5

    Most tools follow a clean verb_noun pattern (list_chats, read_messages, search_messages, send_message, decrypt_attachment). Two names deviate by dropping the verb (chat_activity, pairing_status), where get_ is implied by analogy with get_status. Minor and still readable.

    Tool Count5/5

    Nine tools is well-scoped for a Signal read/send bridge: discovery, reading, search, activity triage, attachment decryption, diagnostic/pairing state, and one write path. No obviously redundant or filler tools.

    Completeness4/5

    Core lifecycle is covered: discover chats/groups, read and search messages, decrypt attachments, check configuration/pairing, and send text messages. Gaps remain on the write side — no sending attachments, no group creation/management, no message deletion — though these are reasonable scope limits rather than dead ends for the stated read-focused purpose.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      Not graded
      quality
      D
      maintenance
      MCP server for Signal via signal-cli that enables sending and receiving messages, managing contacts and groups, and reacting over stdio.
      8 npm
      -
    • A
      license
      Not graded
      quality
      B
      maintenance
      MCP server for a local-first messaging workspace that integrates Google Messages, WhatsApp, and Signal. It enables reading, sending, searching messages, and managing conversations through MCP tools.
      72
      -