* bots, nodejs: document chat, connection, member contact and network commands, typed commands in library * bots, nodejs: restore apiConnect, wrap domain once, test all connect responses * nodejs: JSDoc for new methods * docs: plan for bot API commands and typed Node library methods * tests: channel prepared with a domain has a verified SimpleX name * docs: apply review fixes to the plan for bot API commands * docs: apply second review pass to the plan for bot API commands * docs: refer the bot API plan to the rewritten test commit * docs: record decisions in the plan for bot API commands * docs: plan tests of the generated Python command strings * python: test the generated strings of the documented commands * docs: plan for files, /leave and library methods in the MCP server * docs: wait at stop in the MCP plan * docs: library methods and /leave mechanics in the MCP plan * mcp: typed library methods for chat commands * docs: plan the message information command for bots * mcp: /leave CHAT owner command to leave a chat at once * docs: file servers, GIF and video choices decided in the MCP plan * docs: file mechanics in the MCP plan * mcp: files of received messages * bots, nodejs: message information with the file servers for bots * docs: plan the relay approval option of receiving files in Node * mcp: download of received files with owner approval * docs: name the xftp-server test helper in the files plan * nodejs: receive files without approving unknown relays * docs: plan the user servers command for bots * bots, nodejs: user servers and relays by operator for bots * nodejs: document the message information method * docs: plan the file upload progress event for bots * mcp: send files with owner approval, refusing private keys * bots: file upload progress event for bots * mcp: /leave template in the agent control chat menu * docs: sent copies are deleted for contacts too, at sndFileCompleteXFTP * bots: drop the file upload progress event * docs: drop the upload progress event plan * nodejs: document user servers and relay approval of received files * mcp: download cards name unknown file servers after the upload * docs: record the wait for the file description in the files plan * mcp: fixed wait at stop for cancelled cards, without /sql * docs: record decision C4, a fixed wait at stop, in the files plan * ci: test the MCP server package on pull requests * ci: state when the MCP workflow can be dispatched * ci: run the MCP server tests when its libraries change * mcp: log the errors of image previews and resizing * mcp: keep files in transfer in the data folder * mcp: restrict sent files by the real paths of refused folders * mcp: validate the file at the send by its inode and change time * mcp: limit ffmpeg and ffprobe to local files and no input commands * mcp: ask the owner for unknown file servers; read approvals at creation * mcp: name downloaded files by their ID; return paths of downloads only * mcp: end each download with a result for the agent and the card * mcp: show files above their sender's size limit as failed * mcp: refuse empty files, as without file and captions too long to send * mcp: tell the owner about failed uploads and unposted received files * mcp: delete resized copies left by the last run at start * mcp: name downloads and leaving in the help and greeting, align docs * mcp: compute the download path for received files only * mcp: send a /receive file to the owner under its name * mcp: keep files received without a download in the chat's folder * mcp: keep a left chat's files and delete them with /delete CHAT files * mcp: test that sent images are resized by the core * mcp: wait 30 minutes for a download's progress before cancelling it * mcp: end a download as deleted only when its message is not found * mcp: delete the copy of a /receive file whose post fails * mcp: count the quoted content in a message's length, as the core sends it * mcp: name received bytes, unknown-server downloads and left chat files plainly * mcp: test refused folders, file changes and download approvals * docs: align MCP server docs with refused folders, leaves and download waits * mcp: move received files only in full, delete partials only of downloads * mcp: report a received file missing from its folder as failed * mcp: move received files of a group's member chats into its folder * mcp: read a video's preview and duration as an MP4 or QuickTime file * mcp: 0.2.0 on simplex-chat 7.1.0-beta.10.1 * mcp: file folders by chat type, /delete cancels downloads, files reply * docs: MCP server specs and plan for 0.2.0 * mcp: /receive gives the agent a file, /forward sends it to the owner * docs: MCP server specs for /receive and /forward of download cards * docs: MCP plan records the temp folder command as a library exception * mcp: /delete cancels resumed downloads; /forward quote fits the limit * docs: MCP specs and plans for /forward quotes and resumed downloads * docs: MCP specs name the source commit they are checked against * docs: MCP PLAN states the /forward quote and move rules * mcp: a download moves its completed file whatever its size * mcp: /receive N all covers its card and later files, not pending ones * docs: MCP files approval scope, reply text and README server wording * mcp: a download approves relays only for a card naming unknown servers * mcp: files in member chats of a group are tracked as in the main chat * docs: MCP relay approval of downloads and files in member chats * mcp: a rejected file gets a card again under the files approval * docs: MCP rejected files under the files approval, README scope * mcp: an offered file without a description gets no card or action * docs: MCP a file without a description is not downloaded * mcp: 0.2.0 on simplex-chat 7.1.0-beta.10.2 * ci: test the MCP server as a scope of build-linux
12 KiB
Testing @simplex-chat/mcp v0.2
Node.js 22. Claude Code runs on the same computer as serve: the server listens on 127.0.0.1 only.
Build
Here
All commands run in /code/simplex-chat-6/packages/simplex-chat-mcp. The dependencies are installed by npm install; simplex-chat comes from npm and downloads libsimplex and its Node.js add-on to ~/.cache/simplex-chat at the first start.
node node_modules/typescript/bin/tsc
node node_modules/jest/bin/jest.js test/unit # about 10 s
SMP_SERVER=/code/steward/node_modules/.cache/smp-server/smp-server-v7.1.0-beta.3 XFTP_SERVER=/code/simplexmq-5/dist-newstyle/build/x86_64-linux/ghc-9.6.3/simplexmq-7.1.0.9/x/xftp-server/build/xftp-server/xftp-server node node_modules/jest/bin/jest.js test/e2e # about 4 minutes; a local smp-server and xftp-server on free ports
node_modules is not writable here, so the end-to-end test takes the smp-server and xftp-server binaries from SMP_SERVER and XFTP_SERVER instead of downloading them to node_modules/.cache.
On your own machine
- Check out simplex-chat master; the package is
packages/simplex-chat-mcp. - In that folder:
npm install, thennpx tsc.tscleaves the output of deleted sources indist;npm packandnpm publishdeletedistfirst and build it again (scriptprepack). node dist/cli.js serve my-agent --display-name "My Agent". At the first start,simplex-chatdownloads libsimplex and its Node.js add-on, with aDownloading ...line each on stderr.- Tests:
npx jest test/unit;npx jest test/e2edownloads smp-server and xftp-server v7.1.0-beta.3 on Linux, and elsewhere takesSMP_SERVER=/path/to/smp-server XFTP_SERVER=/path/to/xftp-server.
Until the package is published, the printed hint npx -y @simplex-chat/mcp register my-agent stands for node dist/cli.js register my-agent.
Start, join, register
node dist/cli.js serve my-agent --display-name "My Agent". NAME, heremy-agent, names the data folder and the Claude Code entry;--display-nameis the name people see in SimpleX. It prints the data folder (~/.simplex-mcp/my-agent), creates the agent control chat "My Agent", and prints a QR code and a link that works once. For a short link the QR code has 33 modules and takes 37 columns × 19 lines;--qr-code largeprints it at 74 × 37. Keep it running; Ctrl-C stops it.node dist/cli.js --helplists the options.- In the SimpleX app, scan the QR code, or paste the link into "Connect via link". If the code does not scan, restart with
--qr-code large. The chat "My Agent" appears withI'm your agent. I ask here before I connect, send, download a file or leave a chat.The terminal printsAlice joined (member N) and is now an owner. The link is deleted.and the register hint. node dist/cli.js register my-agent. It printsAdded to Claude Code: scope user, server simplex-my-agent.Run it in a terminal with the sameCLAUDE_CONFIG_DIRas the one whereclauderuns:claude mcp add-jsonwrites to the config of its own environment.- Add
"mcp__simplex-my-agent"topermissions.allowin~/.claude/settings.json, so Claude Code does not prompt for each call; approval happens in the SimpleX app. - Start
claude./mcpshowssimplex-my-agentconnected with 6 tools. A session started beforeregisterdoes not load the entry; start a new one.
Try the tools
Prompts for Claude Code, one at a time. A call that waits more than 2 minutes, for example for an approval, moves to a background task, and its result arrives as a notification.
By name, first:
Connect to @directory.simplex as yourself.While the name is not registered: the tool errorName not found: This SimpleX name is not registered. Please check the name., and no card. Once it is registered: the cardI want to connect to bot SimpleX Directory (@directory.simplex), as myself.; after the approval, step 1 below returnsstatus: known, with no card.
The directory by its address (docs/DIRECTORY.md):
Connect to the SimpleX Directory as yourself at https://smp4.simplex.im/a#lXUjJW5vHYQzoLYgmi8GbxkGP41_kjefFvBrdwg-0Ok and tell me which commands it advertises.Card:I want to connect to bot SimpleX Directory, as myself.Tap/approve 1. The card becomesI connected to ...withApproved by Alice.; Claude getsstatus: done, the chat@N,commandsand the welcome message.Search the directory for hiking groups.Card:I want to send a message to bot SimpleX Directory:with the text. Approve it; Claude gets the bot's answers inresponses.Send /help to the directory.A bot command is sent as text.Check for new messages from the directory, waiting up to 60 seconds.receivewithwait.List your chats and pending actions.list.- Reject one card with its
/reject @N A: the call returnsstatus: rejected; the card ends withRejected by Alice./pendinglists the waiting cards.
Approval of all messages to a chat, and leaving:
Search the directory for Monero groups.On the card, tap/approve @N all. The reply isApproved for bot SimpleX Directory (@N) by Alice. /revoke @N, and the search is sent.Send /help to the directory.It is sent without a card; the agent control chat then getsI sent a message to bot SimpleX Directory:,`/help`andApproved for this chat by Alice. /revoke @N.listshowsapproved: truefor the directory.- Tap
/listin the command menu: one line per chat; the directory's line ends with, approved for this chat by Alice. - Tap
/revoke @N:Messages to bot SimpleX Directory (@N) need approval again.The next send gets a card. Leave the directory.Card:I want to delete bot SimpleX Directory (@N).Approve it: the call returnsstatus: done, andlistno longer shows the directory.- Join a group from the search results, then
Leave that group.Card:I want to leave group <name> (#N).Approve it: the members see that the agent left.
A channel:
Search the directory for channels about trail running.Take a channel link from the answers.Connect to <the channel link> as yourself.Card:I want to connect to channel <name>, as myself.Approve it; Claude getstype: channel,role: observerand the recent posts inmessages.Wait up to 10 minutes for a new post in that channel.receivewithwaitreturns the next post.
Files, in a group of yours:
- In the app, create a group and copy its link.
Connect to <the group link> as yourself.Approve the card. - Send a photo to the group from the app.
Check for new messages in that group.The message hasfilewithtype: imageandstatus: offered. Download that photo.Card:I want to download a file from Alice in group <name> (#N):, with the photo's preview, the file name, its size, andServers: known.when the app uploaded it to servers the agent also has. For a large video asked for right after sending it, the call waits until the upload finishes, and only then the card appears.- Tap
/forward #N A: the photo arrives in the agent control chat, as a reply to the card when its preview and the card fit in one message, and the card stays pending;~/.simplex-mcp/my-agent/files/group-N/has no file, and the photo is in~/.simplex-mcp/my-agent/forwarded/group-N/. - Tap
/receive #N A: the call returnsstatus: doneand the path,~/.simplex-mcp/my-agent/files/group-N/<file ID>.jpg. - Send a document,
Download that file., and tap/receive #N A allon its card: the reply isFiles approved for group <name> (#N) by Alice. /receive #N off, and the download completes. The next file downloads with no card;/listshows, files approved by Alice. Tap/receive #N off. - Send another file,
Download it., and tap/reject #N A: the call returnsstatus: rejected. Send the photo /home/alice/trail.jpg to that group, with the text "trail map".Card:I want to send a message to group <name>:,`trail map`andattaching image `/home/alice/trail.jpg`, SIZE, with the photo's preview. Approve it: the group gets the photo, resized to at most 261120 bytes, with its preview.Send ~/.ssh/id_ed25519 to that group.The call returns the errorfile: /home/alice/.ssh/id_ed25519 is refused: ..., and the agent control chat getsRefused to send `/home/alice/.ssh/id_ed25519` to group <name> (#N): .... A symbolic link to the key gets the same refusal, with the key's real path.- With
ffmpeginstalled,Send /home/alice/ride.mp4 to that group.: the card and the message show the video's first frame and its duration; withoutffmpeg, a gray preview and duration 0. - Tap
/leave #N: after the reply, the agent postsFiles from group <name> (#N) are kept in `~/.simplex-mcp/my-agent/files/group-N`: K files, SIZE. /delete #N files. Tap/delete #N files:Deleted K files from #N, SIZE.; again:No files from #N.
Incognito, as a second agent, because the first one already knows the directory:
node dist/cli.js serve scout --display-name "Scout" --port 5227; join its control chat "Scout" with the printed link;node dist/cli.js register scout; add"mcp__simplex-scout"topermissions.allow;/mcp reconnect all.Using simplex-scout, connect to the directory incognito: https://smp4.simplex.im/a#lXUjJW5vHYQzoLYgmi8GbxkGP41_kjefFvBrdwg-0OkCard:I want to connect to bot SimpleX Directory, incognito.Approve it; Claude getsknown_as, a random name.Using simplex-scout, list your chats.The directory hasincognito: trueand the sameknown_as. A send card for it sayswhere I am incognito.
Stop and restart:
- Stop the server while a card waits: the terminal prints
Stopping: sending 1 cancelled card, up to 10 s. Ctrl-C to stop now., and the card ends withCancelled: the server stopped.A second Ctrl-C during the wait stops the server at once. With no card waiting, Ctrl-C stops it at once. After a restart,/approveof that number repliesAction N is not pending., and the next card has the next number. - A second
serve my-agenton the same data folder exits withAnother server uses ... (PID N). If no server runs, remove .../lock.A port in use exits withPort 5226 is in use. Start with --port N., before any link is printed. - Restart with
--new-token, withoutregister: after the reconnection,listreturns the chats. Checked withclaude -pand an--mcp-configentry withheadersHelper, Claude Code 2.1.302, 2026-10-18.
Claude Code checks
- C2, protocol: passed with Claude Code 2.1.302 in the default runtime, with
MCP_PROTOCOL_NEGOTIATION=legacyand withMCP_SDK_GENERATION=v1. To repeat it, writec2.jsonwith{"mcpServers": {"simplex-my-agent": {"type": "http", "url": "http://127.0.0.1:5226/mcp", "headersHelper": "cat <your home folder>/.simplex-mcp/my-agent/headers.json"}}}, and run it once as is and once with each variable before it:Each run shows the chats, with the preset contact "Ask SimpleX Team".claude -p "Call the list tool and show its result." --strict-mcp-config --mcp-config c2.json --allowedTools mcp__simplex-my-agent - C3, subagent:
Use a subagent to send "trail shoes" to the directory.While the card waits, the subagent's call stays in the foreground, with no background task; it returns after/approve. - C4, reconnect: restart
serve my-agent; in the running session,/mcp reconnect all;listreturns the chats. - C5, register again:
node dist/cli.js register my-agentprintsAdded to Claude Code: scope user, server simplex-my-agent.;claude mcp listshows onesimplex-my-agent. - C6, Esc: ask for a send, and press Esc while its card waits;
List your pending actions.shows the action withopen: false; the same request again attaches to it, and/approvereturns the result to that call. - Host mode: restart with
node dist/cli.js serve my-agent --approve host, then/mcp reconnect all.Send /help to the directory.makes Claude Code prompt, despite the allow rule; so doesleave. After you allow it, the agent control chat getsI sent a message to bot SimpleX Directory:,`/help`andPerformed without approval (mode host).Aconnectto a link not yet joined gets the same prompt and an outcome card; a target already joined returnsstatus: known, with no card.