Skip to content

feat: add create-conversation tool and message attachments#198

Open
jgalea wants to merge 2 commits into
Doist:mainfrom
jgalea:feat/create-conversation-attachments
Open

feat: add create-conversation tool and message attachments#198
jgalea wants to merge 2 commits into
Doist:mainfrom
jgalea:feat/create-conversation-attachments

Conversation

@jgalea

@jgalea jgalea commented May 31, 2026

Copy link
Copy Markdown
Contributor

This PR adds a create-conversation tool and local-file attachment support for messages.

create-conversation starts a direct or group conversation and posts an initial message. It calls getOrCreateConversation, so it reuses an existing conversation when the same set of users already has one rather than creating a duplicate. Params: workspaceId, recipients (user IDs, min 1), content, and optional attachments.

Attachments are local filesystem paths (the MCP server runs locally, so reading paths with node:fs is the right interface). A new uploadAttachments helper in src/utils/attachments.ts reads each file, uploads it to Twist, and returns the attachment objects to pass into the SDK call. The Twist SDK has no upload method, so the helper does a raw multipart POST to POST /api/v3/attachments/upload with fields attachment_id (a generated UUID) and file_name (the binary), matching the documented curl example at https://developer.twist.com/v3/#add-attachment. It reuses the client's auth token and base URL, validates file existence with a clear error, and surfaces non-OK upload responses.

Attachments are wired into create-conversation and reply (both conversation messages via createMessage and thread comments via createComment). The structured output and text summary include the attachment count and names when files are attached.

create-thread does not get attachment support: the SDK's CreateThreadArgs has no attachments field, so rather than adding a parameter that silently does nothing, it is left out and noted here. If the SDK adds it later, the same helper can be wired in.

Tests cover the new tool, the upload helper (mocked fetch, real temp files, error paths), and the attachment paths in reply. type-check, the full jest suite, build, and oxlint/oxfmt all pass.

Add a create-conversation tool that starts or reuses a direct/group
conversation and posts an initial message. Add local-file attachment
support, wired into create-conversation and reply (both conversation
messages and thread comments), via a new uploadAttachments helper that
POSTs to the Twist attachments/upload endpoint.

Thread creation does not support attachments because the SDK's
createThread args have no attachments field.
@scottlovegrove

Copy link
Copy Markdown
Collaborator

The Twist SDK has no upload method

It does now.

That said, I'm not sure whether we will accept the attachment tool right now. We have a similar PR on the Todoist MCP and we have been unable to come to a concensus on this. I will add this to the Twist CLI though.

The create-conversation tool would still be worth bringing in though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants