MINARA
Minara 사용하기클라이언트 및 인터페이스메시징 플랫폼

메시지 및 알림

19개 메시징 프로바이더 개요, 선택 방법, 설정 방법, 에이전트에서 사용하는 방법.

Minara는 에이전트 루프 외부의 외부 플랫폼으로 메시지를 발송할 수 있습니다. Autopilot이 거래 알림을 전송하거나, 예약된 워크플로가 관심 종목 변동을 알리거나, REPL을 사용하지 않는 동안 에이전트가 사용자에게 연락할 때 이 기능이 활용됩니다.

19개 플랫폼이 기본 제공되며 카테고리별로 분류됩니다. 각 플랫폼에는 자격 증명 단계, 인바운드 webhook 형식, 서명 방법, 플랫폼별 제한 사항을 설명하는 별도 설정 페이지가 있습니다.

7개 채널은 현재 제품에서 사용할 수 있습니다. 나머지는 설정 → 메시지에 곧 출시됩니다로 표시됩니다. 전송 계층은 구현되어 있고 운영자는 CLI나 환경 변수로 설정할 수 있으므로 아래 설정 페이지는 그대로 유효하지만, 웹 UI는 연결 폼을 제공하지 않고 알림 채널로도 선택할 수 없습니다.

현재 사용 가능:

  • Telegram, 권장 시작점, 스트리밍 편집 지원
  • Discord, 봇 + 채널, 스트리밍 편집 지원 (1초 스로틀)
  • Lark / Feishu, tenant token + 선택적 AES-256 webhook
  • Email, SMTP, 발송 전용, 제목 자동 분할
  • Email (Gmail OAuth), OAuth 기반 Gmail API, 스트리밍 편집 및 답장 지원
  • Signal, 로컬 signal-cli 서브프로세스 경유, 발송 전용
  • Home Assistant, 모든 notify.* 서비스, 발송 전용

곧 출시, 엔터프라이즈 IM:

곧 출시, 소비자 / 소셜:

  • WeChat OA (公众号), 48시간 응답 윈도우 내 고객 서비스 메시지
  • QQ Bot, Ed25519 webhook, 수동 응답 (능동 메시지는 월 4회)
  • LINE, Messaging API 푸시 + 서명된 webhook

곧 출시, 페더레이션 / 특수:

  • Matrix, Client-Server API + 롱 폴링 데몬 (E2EE 미지원)
  • BlueBubbles (iMessage), 자체 호스팅 Mac을 통한 iMessage 브릿지
  • WhatsApp, Meta Cloud API, 발송 전용, E.164 수신자

가장 쉬운 방법: Minara에 직접 요청하기

메시징 채널을 설정하는 가장 빠른 방법은 채팅에서 Minara에게 직접 말하는 것입니다. 에이전트가 자격 증명 단계를 안내하고, 테스트 메시지를 발송하며, 설정을 ~/.minara/credentials.json(messaging 슬롯)에 자동으로 저장합니다.

set up Telegram notifications, I want trade alerts

connect Slack to channel #trades using my bot token

configure email alerts, I'll give you the SMTP settings

send me a test message on Telegram to make sure it works

what notification channels are configured right now?

turn off the discord gateway, I'm not using it anymore

when ETH breaks $4000, alert me on Telegram

마지막 프롬프트의 경우, Minara가 설정된 메시징 채널을 사용하는 백그라운드 워크플로를 구성합니다. 에이전트가 알림 조건, 채널, 툴 세트 허용 목록을 한 번에 연결합니다.

Minara는 자격 증명을 저장하기 전에 확인을 요청하며 (~/.minara/credentials.json 수정은 tier-3 작업), 에코백 시 시크릿을 마스킹하고, 채널 설정이 완료되면 자동으로 테스트 메시지를 발송합니다.

수동 설정 방법

세 가지 인터페이스가 동일한 저장소와 핫 리로드 방식을 공유합니다. 모든 변경 사항은 재시작 없이 실행 중인 에이전트에 즉시 반영됩니다.

셸에서 (minara auth messaging)

minara auth messaging list                     # 설정된 프로바이더 표시
minara auth messaging add                      # 대화형 메뉴, 18개 플랫폼 전체
minara auth messaging add <provider>           # 대화형 마법사, token 마스킹
minara auth messaging test <provider>          # 테스트 메시지 발송
minara auth messaging remove <provider>        # 자격 증명 제거

프로바이더 ID 없이 minara auth messaging add를 실행하면 대화형 메뉴가 열립니다. 지원하는 모든 플랫폼 목록이 표시되고, 이미 설정된 항목을 확인할 수 있으며, 선택한 플랫폼의 자격 증명 입력을 안내받습니다. 저장 후에는 핑 테스트, 추가 설정, 또는 종료를 선택할 수 있습니다. 전체 흐름은 CLI 서브커맨드를 참조하시기 바랍니다.

REPL 내부에서 (/connect)

/connect                       # 번호 선택 메뉴
/connect telegram              # 대화형 자격 증명 입력
/connect slack --test          # 핑 테스트
/connect telegram --remove     # 자격 증명 삭제

슬래시 명령은 대화 중에 플랫폼 연결이 필요하다는 것을 깨달았을 때 사용하기 적합한 인터페이스입니다. 선택적 필드는 공백 입력 시 자동으로 건너뜁니다. 재설정 시 기존 필드에는 (currently set, blank to keep)가 표시됩니다. 슬래시 명령에서는 token 입력이 화면에 표시됩니다. CLI 서브커맨드는 마스킹을 지원하므로, 민감한 자격 증명은 CLI를 사용하거나 셸 rc 파일에서 환경 변수로 설정하는 것을 권장합니다.

웹 UI에서 (Settings → Messaging)

웹 UI는 모든 프로바이더를 단일 패널에 표시합니다.

  • 프로바이더별 상태 배지 (runtime ready / configured / not connected / coming soon).
  • 행별 Save / Test / Disconnect 버튼.
  • Test 버튼을 클릭하면 실제 핑이 발송되며, IM/이메일 클라이언트에서 메시지를 확인할 수 있고 해당 행에 last test ✓ 태그가 표시됩니다.
  • 빈 입력 후 Save를 클릭하면 디스크에서 해당 필드가 삭제됩니다. 이를 이용해 --remove를 실행하지 않고 Slack 모드를 봇 token에서 webhook 전용으로 전환할 수 있습니다.

자격 증명은 ~/.minara/credentials.json (권한 0600, git 제외)에 저장되므로 재설치 후에도 유지되며 저장소에 노출되지 않습니다. 세 가지 인터페이스 모두 쓰기 후 실행 중인 에이전트의 게이트웨이 맵을 핫 리로드하므로 프로세스 재시작이 필요하지 않습니다.

워크플로: send_message 스텝 종류

워크플로는 tool_call: send_message 형식을 통하지 않고도 메시지를 퍼스트 클래스 스텝 종류로 발송할 수 있습니다.

{
  "name": "notify_team",
  "kind": "send_message",
  "provider": "slack",
  "channel": "#alerts",
  "text": "BTC crossed ${trigger.threshold}"
}

디스패치 시 프로바이더 결정 순서:

  1. step.provider (스텝별 명시적 지정).
  2. definition.delivery.provider (워크플로 수준 기본값).
  3. 정확히 하나의 프로바이더가 연결된 경우 해당 프로바이더.
  4. 위 조건을 모두 충족하지 않으면 활성화가 거부되며, /connect <platform> (REPL) 또는 Settings → Messaging (웹 UI)을 안내하는 구조화된 오류가 반환됩니다.

활성화 게이트는 Autopilot 스위치와 독립적으로 작동합니다. 알림 발송은 자금을 이동시키지 않으므로 autopilotEnabled=false 상태에서도 워크플로를 활성화하고 실행할 수 있습니다. 이 독립성은 cron 기반 메시징과 Autopilot의 성공 알림에도 동일하게 적용됩니다.

대상 플랫폼이 연결되지 않아 활성화에 실패하면, 웹 UI에 Connect <provider> 버튼이 있는 모달이 표시됩니다. 버튼을 클릭하면 Settings → Messaging의 해당 행이 펼쳐진 상태로 이동하며, 저장 후 워크플로 페이지로 돌아와 활성화가 자동으로 재시도됩니다.

workflow_test로 메시징 워크플로 검증하기

workflow_test는 새 플랫폼 설정을 종단간 검증하는 권장 방법입니다. 샘플 트리거로 DAG를 실행하고, 프로덕션과 동일한 채널을 통해 실제 메시지를 발송합니다. 워크플로를 활성화하기 전에 휴대폰에서 알림을 직접 확인할 수 있습니다. 대상 프로바이더가 연결되지 않은 경우 테스트는 거부되며, /connect <provider> (REPL) 또는 Settings → Messaging (웹 UI)을 안내하는 구조화된 messaging_not_configured 오류가 반환됩니다. 동일 워크플로 내 자금 이동 및 기타 파괴적 도구는 시뮬레이션 상태를 유지하며, 메시징 스텝만 실제로 발송됩니다. 전체 흐름은 워크플로 페이지의 "배포 전 로컬 워크플로 테스트" 섹션을 참조하시기 바랍니다.

일회성 알림

"X가 발생하면 알림을 보내고 종료"하는 워크플로의 경우, send_message 다음에 deactivate 단계를 추가하면 됩니다. 워크플로는 발송 후 스스로 active = false로 전환하여 트리거가 다시 발생하지 않습니다. 전체 JSON 템플릿은 워크플로 페이지의 "일회성 알림" 섹션을 참조하시기 바랍니다.

기능 매트릭스

모든 프로바이더는 일반 텍스트 발송을 지원합니다. 이는 기본 기능이므로 매트릭스에서 별도로 표시하지 않습니다. 아래 열은 그 위에 추가되는 고급 기능을 설명합니다.

프로바이더스트림이미지파일음성스레드타이핑반응리치인바운드글자 수 제한
telegram✅ (OGG)4 096
discord2 000
slack40 000
email1 000 000
whatsapp4 096
signal4 096
home_assistant4 096

범례: ✅ = 현재 빌드에서 지원됨, ❌ = 플랫폼이 지원하지 않음, 빈 셀 = 아직 연결되지 않음 (후속 PR 예정). Slack의 타이핑 셀이 비어 있는 이유는 최신 Slack Web / Events API가 봇 타이핑 트리거를 제공하지 않기 때문입니다. 해당 기능을 지원했던 구 RTM API는 더 이상 사용되지 않습니다.

"리치"는 공유 텍스트/첨부 파일 인터페이스를 넘어선 프로바이더 고유의 리치 메시지 게시 기능을 의미합니다. 현재 Slack Block Kit, 임시 메시지 (chat.postEphemeral), 예약 메시지 (chat.scheduleMessage), send_messageprovider_options.slack 터널을 통한 metadata가 해당됩니다. 다른 프로바이더는 동등한 기능을 제공하지 않거나 (WhatsApp / Signal / HomeAssistant / webhook 모드 Slack) 아직 연결되지 않은 상태입니다 (Telegram 인라인 키보드 답장 마크업, Discord 컴포넌트, 이메일 HTML 본문). 구체적인 API는 slack 페이지를 참조하시기 바랍니다.

Slack 통합 모드. 매트릭스는 권장 봇 token 모드 (전체 Slack Web API, 즉 chat.postMessage, chat.update, files.v2, reactions.add, Events API webhook)를 기준으로 표시됩니다. Minara는 Slack 앱을 설치할 수 없는 배포 환경을 위해 더 단순한 webhook URL 모드도 지원합니다. 이 모드는 스트리밍, 파일 업로드, 반응, 타이핑, 임시/예약 메시지를 지원하지 않지만, 일반 텍스트, Block Kit 블록, 스레드 답장은 지원합니다. 두 가지 설정 경로와 모드별 기능 분류는 Slack 페이지를 참조하시기 바랍니다.

Home Assistant의 모든 항목이 ❌인 이유도 구조적으로 유사합니다. notify.<service> API는 조사한 모든 구체적인 알림 플랫폼에서 텍스트 전용 싱크로 동작합니다. 이미지를 첨부해야 하는 경우 CDN에 업로드한 후 URL을 메시지 본문에 포함하는 방법을 권장합니다.

"스트리밍"은 에이전트의 token 단위 응답이 편집 방식으로 단일 메시지에 표시되는 것을 의미합니다. 스트리밍을 지원하지 않는 프로바이더는 전체 응답을 버퍼링한 후 완료 시점에 한 번에 발송합니다. 이는 apps/agent/src/messaging/stream-helpers.ts의 공유 createStreamSink 헬퍼를 통해 처리됩니다.

첨부 파일

send_message({attachments: [...]}) 를 사용하면 에이전트가 샌드박스 내에서 생성한 이미지, 문서, 음성 메모를 첨부할 수 있습니다 (image_generate, audio_generate, write_file, 코드 실행 등을 통해 생성). LLM은 샌드박스 상대 경로로 파일을 참조합니다.

send_message({
  provider: "telegram",
  text: "BTC/USD daily with key levels",
  attachments: [
    { kind: "image", sandbox_path: "images/btc-2026-04-19.png" },
    { kind: "file", sandbox_path: "files/levels.csv", caption: "CSV of levels" },
  ],
})

첨부 파일 종류:

  • image: 이미지용. 프로바이더의 이미지 최적화 엔드포인트로 라우팅됩니다 (Telegram sendPhoto, WhatsApp image 등).
  • file: 일반 문서 첨부 파일. PDF, CSV, 압축 파일에 사용됩니다.
  • voice: 짧은 음성 메모. Telegram은 OGG/Opus를 요구하며, OGG가 아닌 음성 전송 시 리졸버가 명확한 오류를 반환합니다.
  • audio: 음악 / 팟캐스트 / 긴 오디오. Telegram sendAudio에 해당하며, 전용 음성 UI가 없는 프로바이더에서는 voice와 동일하게 처리됩니다.

보안 정책:

  • 샌드박스 경로만 허용됩니다. 리졸버는 .. 이스케이프, 절대 경로, 샌드박스를 벗어나는 심볼릭 링크를 바이트 업로드 이전에 거부합니다. 공격자는 send_message를 데이터 유출 채널로 활용할 수 없습니다.
  • 첨부 파일당 50 MB 제한 (MESSAGING_MAX_ATTACHMENT_BYTES로 설정 가능). 프로바이더 API는 자체적인 최대값을 별도로 적용합니다.
  • 프로바이더 지원은 기능 게이팅을 통해 관리됩니다. 연결된 프로바이더가 지원하지 않는 kind를 지정하면 (예: WhatsApp에 voice 전송), API 레이어에서 400 오류가 발생하는 것이 아니라 도구 경계에서 명확한 오류가 반환됩니다.

스레드

send_messagethread를 전달하면 스레드 대화에 게시할 수 있습니다.

send_message({
  provider: "slack",
  text: "follow-up",
  thread: "1700000000.000100",  // parent message's ts
})

프로바이더별 의미 (자동 처리, 호출자는 thread만 전달):

  • Telegram: 포럼 토픽의 message_thread_id (슈퍼그룹 + 개인 채팅).
  • Discord: 스레드는 채널로, URL에서 스레드 ID가 채널 ID를 대체합니다. 신규 스레드와 보관된 스레드 모두 지원합니다.
  • Slack: thread_ts, 부모 메시지의 타임스탬프. 봇 모드 전용 (webhook 모드는 거부됨).
  • Email: 값이 In-Reply-ToReferences 헤더로 사용됩니다. 부모 이메일의 Message-ID를 전달하시기 바랍니다. (예: <abc@host> 형식의 앵글 브래킷 포함).

스레드를 지원하지 않는 프로바이더 (whatsapp, signal, home_assistant)에 thread를 전달하면 도구 경계에서 명확한 오류가 반환됩니다.

타이핑 인디케이터 + 반응

두 가지 추가 도구인 set_typingadd_reaction이 대화 내 피드백을 위해 제공됩니다. 이 도구들은 tier-2 CONFIRM_ONCE 등급입니다. 장식적 신호이므로 egress로 분류되지 않으며, send_message의 tier-3 확인과는 별개로 동작합니다.

// 긴 응답 전에 봇이 생각 중임을 사용자에게 알립니다.
set_typing({ provider: "telegram", on: true })

// 텍스트를 작성하는 대신 이모지로 인바운드 메시지를 확인합니다.
add_reaction({
  provider: "discord",
  message_id: "1234567890",
  emoji: "👍",
})

타이핑 지속: Telegram과 Discord의 인디케이터는 약 5~10초 후 만료됩니다. apps/agent/src/messaging/typing-heartbeat.tstyping-heartbeat 헬퍼가 자동으로 재발송하므로, 긴 LLM 턴 동안 "타이핑 중..." 상태를 유지하려면 이 헬퍼를 사용하시기 바랍니다.

기능 지원 현황 (위 매트릭스 참조): 타이핑은 telegram / discord / signal에서 지원되며, 반응은 discord / slack (봇) / signal에서 지원됩니다. 다른 프로바이더는 도구 경계에서 두 기능 모두 거부합니다.

인바운드 메시지: 양방향 대화

Minara는 메시지를 수신하고 답장할 수도 있어, CLI 대신 채팅 앱에서 직접 에이전트와 대화할 수 있습니다. 메시지가 에이전트에 도달하는 경로는 두 가지이며, 플랫폼이 어느 쪽을 쓰는지에 따라 공인 IP가 없는 머신에서 양방향 대화가 가능한지가 결정됩니다.

클라이언트 아웃바운드 데몬 (기본값)

대부분의 플랫폼에서 에이전트는 바깥쪽으로 연결해 장기 연결 (HTTP 롱 폴링 또는 WebSocket)을 유지하고, 그 연결을 통해 메시지가 내려옵니다. 에이전트가 클라이언트가 되므로 NAT 뒤, 개인 노트북, 공인 주소 없음, 터널 없음, 제3자 없음 환경에서도 동작합니다. 이것이 기본값입니다. 플랫폼의 아웃바운드 자격 증명이 설정되어 있고 해당 플랫폼용 공인 webhook이 구성되지 않았을 때, 대응 데몬이 자동으로 시작됩니다. MESSAGING_<PLATFORM>_* 스위치로 플랫폼별로 재정의할 수 있습니다 (환경 변수 참조). 스위치는 3상태입니다 (미설정 = 자동, 1 = 강제 켜기, 0 = 강제 끄기).

클라이언트 아웃바운드 데몬을 갖춘 플랫폼: Telegram (getUpdates), Discord (Gateway), Slack (Socket Mode), Mattermost (v4 WebSocket), QQ (v2 게이트웨이), DingTalk (Stream Mode), Lark (장기 연결), 그리고 Matrix (/sync)와 Signal (signal-cli).

Webhook 수신기 (플랫폼이 요구하는 경우)

일부 플랫폼은 공인 HTTPS 엔드포인트로 POST하는 방식으로만 인바운드를 전달합니다. 이런 플랫폼을 위해 Minara는 MESSAGING_INBOUND_ENABLED로 게이트된 HTTP webhook 서버 (apps/agent/src/messaging/inbound/server.ts 참조)를 실행합니다. 기본적으로 127.0.0.1에 바인드하므로, 공인 IP가 없는 호스트에는 TLS를 종료하고 전달하는 리버스 프록시나 터널이 필요합니다. 어떤 플랫폼의 webhook 서명 시크릿을 설정하면, 데몬이 있어도 그 플랫폼은 webhook 인바운드로 되돌아갑니다.

보안 정책:

  • 모든 요청은 디스패치 전에 서명 검증을 거칩니다 (Telegram의 X-Telegram-Bot-Api-Secret-Token, Slack의 v0:{ts}:{body} 기반 HMAC-SHA256, Discord와 QQ의 Ed25519, Lark의 AES 엔벨로프, Teams와 Google Chat의 JWT). 검증에 실패한 요청은 401을 반환합니다.
  • 타임스탬프 기반 방식에는 5분 재생 윈도우가 적용됩니다.
  • 본문 크기 제한 (기본 4 MB). 더 큰 본문은 413을 반환합니다.

도달성: 어떤 플랫폼이 완전히 로컬에서 동작하는가

인바운드 모델플랫폼공인 IP 없이 양방향 대화
클라이언트 아웃바운드 데몬Telegram, Discord, Slack, Mattermost, QQ, DingTalk, Lark, Matrix, Signal가능, 터널 불필요
webhook 전용 (플랫폼이 접속해 옴)WhatsApp, LINE, WeCom, WeChat OA, Teams불가, 공인 webhook (터널 / 리버스 프록시) 필요
송신 전용 (인바운드 없음)Email, Gmail, Home Assistant아웃바운드 알림만

Google Chat (Cloud Pub/Sub 풀)과 BlueBubbles (자체 호스팅 서버로의 소켓)도 클라이언트 아웃바운드로 전환할 수 있으나, 현재는 webhook 인바운드로 제공됩니다.

음성 전사: MESSAGING_INBOUND_TRANSCRIBE=1이 설정되고 OPENAI_API_KEY가 구성된 경우, 인바운드 음성 메시지는 OpenAI Whisper를 통해 전사된 후 디스패치됩니다. 전사 결과는 InboundMessage.text에 저장되며, 원본 오디오는 재생을 위해 attachments에 유지됩니다.

Minara의 메시징 활용 방법

프로바이더가 설정되면 세 가지 방법으로 메시지를 발송할 수 있습니다.

1. send_message 도구, Agent 내부에서

LLM이 알림이 필요하다고 판단하면 다음을 호출합니다.

send_message({
  provider: "telegram",
  text: "BTC drawdown 5% triggered the watch",
})

에이전트는 대화 중에 이를 활용합니다. 예를 들어 "ETH가 $4,000을 돌파하면 Telegram으로 알려줘"라고 하면, 조건이 충족될 때 send_message를 호출하는 예약 워크플로가 설정됩니다.

2. 자동 운용, 거래 실행 보고서

Autopilot이 활성화된 경우, 각 실행 후 요약을 발송합니다.

🟢 Bought $100 of SOL @ $167.23
   Position: +$100 | Slippage: 0.04% | Gas: $0.12
   Reason: momentum > 3σ on 1h chart

이 보고서는 ~/.minara/settings.json에서 기본 알림 대상으로 설정된 프로바이더로 전송됩니다.

3. 워크플로, cron 기반 알림

예약된 모니터링이 읽기 전용 + 메시징 권한으로 백그라운드에서 실행됩니다.

you: watch the top 20 tokens by 24h volume, alert me on >5% moves every 15 min

agent: [sets up a cron workflow with tool set "read, memory, messaging"]

워크플로는 관찰하고 알림을 보낼 수 있지만, LLM이 실행 중 마음을 바꾸더라도 허용 목록이 거래를 차단합니다.

대상 채널 재정의

send_messagechannel 재정의를 지원하므로 단일 프로바이더에서 여러 대상으로 발송할 수 있습니다.

send_message({
  provider: "telegram",
  channel: "-1009876543210",    // different chat from the default
  text: "Critical: position liquidation imminent",
})

긴급 알림을 별도의 휴대폰이나 그룹으로 라우팅하면서 일반 알림은 기본 채널로 유지할 때 유용합니다.

보안 정책

  • 자격 증명은 ~/.minara/credentials.json에 저장됩니다. 저장소 외부, 프로젝트 디렉터리 외부에 위치합니다.
  • minara auth messaging list는 시크릿을 마스킹합니다. 원본 token이 아닌 12***xyz (46 chars) 형태로 표시됩니다.
  • 메시징은 대화형 호출에서 tier-3 (ALWAYS_CONFIRM) 등급이며, REPL의 모든 send_message 호출은 확인을 요청합니다. 자율 실행 (cron / Autopilot)에서는 safetyConfig.autopilotEnabled가 설정된 경우에만 tier-3 도구를 사용할 수 있으며, 그렇지 않으면 해당 경로에서 메시징이 거부됩니다. minara auth messaging add를 통한 자격 증명 저장은 대화형 마법사 내부에서 이루어집니다. 별도의 도구 수준 확인 프롬프트는 없으며, 마법사 자체가 확인 역할을 합니다.
  • 메시징은 거래를 실행할 수 없습니다. 툴 세트 허용 목록이 "관찰 및 알림 가능"과 "거래 가능"을 분리합니다. 메시징 활성화 워크플로는 LLM이 시도하더라도 자금 이동 도구를 사용할 수 없습니다.

다음 단계

위에서 플랫폼을 선택하고 설정을 시작하시기 바랍니다. Telegram이 가장 간단합니다. 구성 요소가 가장 적고, 스트리밍 지원 게이트웨이가 가장 충분히 검증되었으며, 테스트 루프 (/newbot → 채팅 ID → minara auth messaging test telegram)가 3분 이내에 완료됩니다.

목차