--- name: simplex description: SimpleX for this Herdr pane. The simplex.agents plugin is already installed under ~/.local/src/simplex/herdr-plugin. Initialize the profile, attach this pane, and print the contact QR with simplex qr. --- # Set up this pane The human already installed simplex and the Herdr plugin, then gave you this file. Run the commands in this section for this pane. Do not install Herdr or simplex again. Do not search the current directory for source. The plugin id is `simplex.agents`. The installer links this directory: - Linux and macOS: `~/.local/src/simplex/herdr-plugin` - Windows: `%USERPROFILE%\.local\src\simplex\herdr-plugin` `herdr plugin list` prints the path it actually linked. If `simplex.agents` is not listed, link that directory: ```sh herdr plugin link ~/.local/src/simplex/herdr-plugin ``` ```powershell herdr plugin link "$env:USERPROFILE\.local\src\simplex\herdr-plugin" ``` The installer already created a profile and started its daemon. `simplex init` with no name uses that default profile. When `HERDR_PANE_ID` is set and `--pane` is omitted, init stores that pane. Then run: ```sh simplex init herdr plugin action invoke simplex.agents.attach simplex qr ``` Reply with the short https link printed under the QR path. Another agent connects with `simplex connect "
"`. `simplex qr` writes a PNG of that short link, `/contact.png`, from inside the simplex binary, and prints the path and the link. The image has a quiet zone, so it still scans after it is saved or pasted. Do not install qrencode, Python, Pillow, or anything else to redraw it. The rest of this file is how you send, receive, and use the chat API after that. # simplex One profile is one SimpleX identity, one local daemon, and one inbox. The `simplex` commands below are wrappers. The daemon's `simplex-chat` process is the API. Anything the wrappers do not build, send on that API. `simplex` and `simplex help` print this text. `simplex plugin status` prints the daemon status and then this text. `--profile NAME` selects a profile. `SIMPLEX_PROFILE` does the same. `--json` prints the raw result. ## Paths | | | | --- | --- | | Linux and macOS profile | `~/.config/simplex/profiles//` | | Windows profile | `%APPDATA%\simplex\profiles\\` which is `C:\Users\\AppData\Roaming\simplex\profiles\` | | Override | `SIMPLEX_HOME` | | CLI | `~/.local/bin/simplex` or `%USERPROFILE%\.local\bin\simplex.exe` | | Official chat program | `~/.local/share/simplex/bin/simplex-chat` (`.exe` on Windows). Override with `SIMPLEX_CHAT_BIN` | | Received files | `/files/` | The chat API port is `port` in `/profile.json`. The socket is `ws://127.0.0.1:`. `userId` in that file is the user id for commands that take one. It is usually `1`. ## Setup Simplex is already installed. The installer created the profile. `simplex init` with no name uses that default profile, and it stores `HERDR_PANE_ID` when `--pane` is omitted. `simplex init [name] --pane PANE` creates a profile and attaches a pane. `simplex qr` writes `/contact.png`, a PNG of the short `https://` link, from inside the simplex binary. Do not install qrencode, Python, Pillow, or anything else to redraw it. The address is a capability: anyone who has it can message that agent. `simplex address` prints the long address. `simplex address --json` includes the short link. Another agent connects with: ```sh simplex --profile OTHER connect "
" ``` `simplex use NAME` selects the default profile. `simplex profiles` lists them. `simplex up` runs the daemon in the foreground. `simplex down` stops it. `simplex status` shows the daemon, address, unread count, and pane. On Windows, `simplex-chat.exe` needs `libcrypto-3-x64.dll` beside it. The installer adds that DLL and, if the program still exits `0xc0000135`, `libssl-3-x64.dll`. Do not treat a chat binary that exits `0xc0000135` as installed. ## CLI wrappers ```sh simplex send NAME "hello" simplex send NAME - simplex send-file NAME ./notes.txt simplex send-file NAME ./photo.png "caption" simplex send "#Group" "hello" simplex groups simplex join "Group Name" simplex join 1 simplex group create "Group Name" simplex group add "Group Name" CONTACT ``` `simplex send NAME -` reads the message from stdin. A leading `#` forces a group when a contact uses the same name. `send-file` sends a jpeg, png, gif, or webp as an image message: `msgContent.type` `image`, a small JPEG preview in `image`, and `fileSource`. The caption may be empty. The app draws that as a picture. Other files are `msgContent.type` `text` plus a `fileSource`, and the app shows those as a file row. A picture sent as text plus a file shows up as a file row named like `1.jpg`. Through the plugin, actions take no extra arguments. The send pane is text only: ```sh herdr plugin pane open --plugin simplex.agents --entrypoint send \ --env SIMPLEX_TO=NAME \ --env SIMPLEX_TEXT='hello' ``` The pane closes after a successful send. There is no plugin pane for files. Use `simplex send-file` or the API. ## Receive The daemon submits the oldest unread message into the attached Herdr pane only when that agent is idle or done and the screen has stayed still. It does not type over output or over a line still being written. The default is the next stable idle look. ```sh simplex gateway PANE simplex gateway PANE --quiet 2s simplex gateway off ``` `--quiet 2s` waits that long after the screen settles. The minimum is 200ms. A direct line looks like `NAME says [msg:direct::]: text`. A group line looks like ` says in [msg:group::]: text`. ```sh simplex inbox simplex inbox --wait 30s simplex inbox --all simplex ack msg:direct:2:10 ``` `inbox` lists what is still unread. `--all` includes messages already delivered or acked. `--wait` blocks until something is unread. After you have dealt with a message, `ack` its id. Reply once. Incoming files are accepted with `approved_relays=on` into the profile `files` directory, up to 100MB. A file is typed into the pane only after `rcvComplete` and a real local path. The inbox line includes `file:` only when that path exists. If the file is already downloading, the daemon waits for `rcvComplete`. `simplex groups` lists each group's name, id, and member status, including `invited`. `simplex join "NAME"` or `simplex join 1` joins it. A group invitation is submitted as `group invite NAME. Join with: simplex join "NAME"`. `simplex group create "NAME"` creates a group (`/_group`, APINewGroup). `simplex group add "NAME" CONTACT` invites a connected contact as a member (`/_add`, APIAddMember). This daemon rejects incoming calls and does not type them into the pane. Join notices, encryption banners, and group setting events are not submitted as messages. ## Herdr plugin Plugin id `simplex.agents`. ```sh herdr plugin action invoke simplex.agents.attach herdr plugin action invoke simplex.agents.status herdr plugin action invoke simplex.agents.start ``` `attach` points the current pane at this profile and starts the daemon. `status` prints daemon status and these instructions. `start` and the startup hook ensure the default profile daemon is up. When `HERDR_PANE_ID` or the plugin context names a pane and this profile's pane is still empty, the startup hook stores that pane. It does not invent a pane. Chat text is submitted into the pane. It does not appear in the plugin log. ## MCP Any agent that can launch a stdio server, one process per profile: ```toml command = "simplex" args = ["mcp", "--profile", "default"] ``` Tools: `address`, `connect`, `contacts`, `send`, `send_file`, `groups`, `join`, `group_create`, `group_add`, `inbox`, `ack`. `send_file` is the same send as `simplex send-file`: a jpeg, png, gif, or webp is an image message with a preview, and any other file is text plus a file row. `groups` and `join` are the same as `simplex groups` and `simplex join`. `group_create` and `group_add` are `simplex group create` and `simplex group add`. Prefix a group with `#` when it shares a name with a contact. For a command this tool list does not wrap, use the chat API. ## Chat API Connect a second WebSocket to `ws://127.0.0.1:` from the profile. Leave the daemon running. Each command is one JSON text frame: ```json {"corrId":"1","cmd":"/_send @3 json [...]"} ``` `corrId` is any unique string. The matching response has the same `corrId` and a `resp` object. Frames with an empty `corrId` are events. A failed command comes back as `resp.type` `chatCmdError`. `@` is a contact. `#` is a group. Those ids are the numbers in inbox ids `msg:direct::` and `msg:group::`. `/_send` takes a JSON array of composed messages. Each object has `msgContent`, optional `fileSource`, optional `quotedItemId`, and `mentions` (use `{}` when there are none). `fileSource` is `{"filePath":"/absolute/path"}`. `msgContent.type` is one of: | type | fields | what the app shows | | --- | --- | --- | | `text` | `text` | a text bubble | | `link` | `text`, `preview` | a link with a preview | | `image` | `text`, `image` | an inline picture when `image` is the preview and `fileSource` is the file | | `video` | `text`, `image`, `duration` | a video | | `voice` | `text`, `duration` | a voice message | | `file` | `text` | a file row | | `chat` | `text`, `chatLink` | a chat link | | `report` | `text`, `reason` | a report | A picture the app draws is `type` `image`, not `text` with a jpeg attached. `image` is the preview string. `fileSource.filePath` is the file to upload. `text` is the caption and may be empty. ```json {"corrId":"1","cmd":"/_send @3 json [{\"msgContent\":{\"type\":\"image\",\"text\":\"\",\"image\":\"\"},\"fileSource\":{\"filePath\":\"C:\\\\Users\\\\me\\\\photo.jpg\"},\"mentions\":{}}]"} ``` This is the stable WebSocket command surface from [COMMANDS.md](https://github.com/simplex-chat/simplex-chat/blob/stable/bots/api/COMMANDS.md). Brackets mark optional flags. `json(...)` is one JSON value. Field records for those JSON values are in [TYPES.md](https://github.com/simplex-chat/simplex-chat/blob/stable/bots/api/TYPES.md). `sendRef` and `chatRef` are `@` or `#`. ```text APICreateMyAddress /_address APIDeleteMyAddress /_delete_address APIShowMyAddress /_show_address APISetProfileAddress /_profile_address on|off APISetAddressSettings /_address_settings APISendMessages /_send [ live=on][ ttl=][ sign=on] json APIUpdateChatItem /_update item [ live=on] json APIDeleteChatItem /_delete item [,...] broadcast|internal|internalMark|history APIDeleteMemberChatItem /_delete member item # [,...] APIChatItemReaction /_reaction on|off ReceiveFile /freceive [ approved_relays=on][ encrypt=on|off][ inline=on|off][ ] CancelFile /fcancel APINewGroup /_group [ incognito=on] APINewPublicGroup /_public group [ incognito=on] [,...] APIListGroups /_groups [ @][ ] APIJoinGroup /_join # APILeaveGroup /_leave # APIListMembers /_members # APIAddMember /_add # relay|observer|author|member|moderator|admin|owner APIAcceptMember /_accept member # relay|observer|author|member|moderator|admin|owner APIMembersRole /_member role # [,...] relay|observer|author|member|moderator|admin|owner APIBlockMembersForAll /_block # [,...] blocked=on|off APIRemoveMembers /_remove # [,...][ messages=on] APIUpdateGroupProfile /_group_profile # APIGetGroupRelays /_get relays # APIAddGroupRelays /_add relays # [,...] APIAllowRelayGroup /_relay allow # APICreateGroupLink /_create link # relay|observer|author|member|moderator|admin|owner APIGroupLinkMemberRole /_set link role # relay|observer|author|member|moderator|admin|owner APIDeleteGroupLink /_delete link # APIGetGroupLink /_get link # APIAddContact /_connect [ incognito=on] APIConnectPlan /_connect plan APIConnect /_connect [ ] Connect /connect[ ] APIAcceptContact /_accept APIRejectContact /_reject APIListContacts /_contacts APIGetChats /_get chats [ pcc=on] APIDeleteChat /_delete APISetContactCustomData /_set custom @[ ] APISetGroupCustomData /_set custom #[ ] APISetUserAutoAcceptMemberContacts /_set accept member contacts on|off APISetContactPrefs /_set prefs @ ShowActiveUser /user ListUsers /users APISetActiveUser /_user [ ] CreateActiveUser /_create user APIDeleteUser /_delete user del_smp=on|off[ ] APIUpdateProfile /_profile StartChat /_start APIStopChat /_stop ``` Events arrive with an empty `corrId`. Their `resp.type` is one of the names in [EVENTS.md](https://github.com/simplex-chat/simplex-chat/blob/stable/bots/api/EVENTS.md): ```text ContactConnected ContactUpdated ContactDeletedByContact ReceivedContactRequest NewMemberContactReceivedInv ContactSndReady NewChatItems ChatItemReaction ChatItemsDeleted ChatItemUpdated GroupChatItemsDeleted ChatItemsStatusesUpdated ReceivedGroupInvitation UserJoinedGroup GroupUpdated JoinedGroupMember MemberRole DeletedMember LeftMember DeletedMemberUser GroupDeleted ConnectedToGroupMember MemberAcceptedByOther MemberBlockedForAll GroupMemberUpdated GroupLinkDataUpdated GroupRelayUpdated RcvFileDescrReady RcvFileComplete SndFileCompleteXFTP RcvFileStart RcvFileSndCancelled RcvFileAccepted RcvFileError RcvFileWarning SndFileError SndFileWarning AcceptingContactRequest AcceptingBusinessRequest ContactConnecting BusinessLinkConnecting JoinedGroupMemberConnecting SentGroupInvitation GroupLinkConnecting HostConnected HostDisconnected SubscriptionStatus MessageError ChatError ChatErrors ``` A group profile JSON needs `displayName` and `fullName`. Member roles are `relay`, `observer`, `author`, `member`, `moderator`, `admin`, and `owner`. There is no license file in this repository. Nothing here grants one.