From textforge
Draft, search, and manage emails via TextForge — human approval required before anything sends.
How this skill is triggered — by the user, by Claude, or both
Slash command
/textforge:textforgeThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Use this skill when the user wants to draft emails, read inbox threads, search email, or manage email follow-ups via TextForge. Every email draft requires human approval before it sends.
Use this skill when the user wants to draft emails, read inbox threads, search email, or manage email follow-ups via TextForge. Every email draft requires human approval before it sends.
For email composition best practices, see the email-writing skill.
TextForge uses two types of thread identifiers:
| ID Type | Format | Example | Where It Appears |
|---|---|---|---|
Internal ID (id) | GUID | 3fa85f64-5717-4562-b3fc-2c963f66afa6 | list_threads, list_engaged_threads, search_threads_by_contact, matched results in search_messages |
Provider ID (externalThreadId) | Hex string | 19d2243fcda1917c | search_messages (unmatched results), email headers |
get_thread, sync_thread, create_draft (threadId param)get_thread_by_external_id, import_threadget_thread — it requires GUID format and will errorsearch_messages, search_threads_by_contact, list_threads, or list_recent_messages
search_messages returns two groups: matched threads (already in TextForge, have an id GUID) and unmatched provider threads (only have externalThreadId)list_recent_messages returns individual messages filtered by date — useful for "what came in recently?"search_messages, use import_thread with the externalThreadId to pull the thread into TextForge. This returns the internal id.get_thread with the internal id (GUID format). Do NOT pass provider thread IDs to this tool — use get_thread_by_external_id for those.create_draft with bodyFormat: "Html" (see email-writing skill for composition guidelines)get_draft_attachment_upload_url then upload via presigned URLupdate_draft, never delete/recreateget_draft_activity to see full draft historyNever tell the user an email was "sent" — it was drafted and queued for their approval.
<br> for line breaks, not <p> tags<br><br> between paragraphsbodyFormat: "Html" unless the user explicitly wants MarkdownFor the full writing guide, anti-pattern reference, and AI pattern audit, see the email-writing skill.
mcp__textforge__create_draftCreate an email draft for human approval.
subject (string, required): Email subject linebody (string, required): Email bodybodyFormat (string): "Html" or "Markdown" (default: "Html")toRecipients (string, required): Comma-separated recipient emailsccRecipients (string, optional): Comma-separated CC emailsbccRecipients (string, optional): Comma-separated BCC emailsthreadId (string, optional): Internal TextForge thread ID (GUID) to reply to an existing threadscheduledFor (string, optional): ISO 8601 datetime for scheduled sendDrafts are automatically submitted for approval upon creation.
mcp__textforge__list_draftsList email drafts with optional filtering by status or recipient.
status (string, optional): Filter by status (e.g., "PendingApproval", "Approved", "Sent")recipient (string, optional): Filter by recipient emaillimit (number, optional): Max results (default: 20)mcp__textforge__get_draftGet detailed information about a specific draft including body, recipients, and status.
draftId (string, required): The draft IDmcp__textforge__update_draftUpdate an existing draft's content. Only works on editable drafts. Always use this instead of deleting/recreating — drafts in PendingApproval status cannot be deleted.
draftId (string, required): The draft ID to updatesubject (string, optional): Updated subjectbody (string, optional): Updated bodybodyFormat (string, optional): "Html" or "Markdown"toRecipients (string, optional): Updated recipientsccRecipients (string, optional): Updated CCbccRecipients (string, optional): Updated BCCmcp__textforge__submit_draftSubmit a draft for human approval. Rarely needed since create_draft auto-submits.
draftId (string, required): The draft IDmcp__textforge__get_draft_activityGet the complete activity history for a draft (created, edited, submitted, approved, rejected, sent).
draftId (string, required): The draft IDmcp__textforge__reject_draftReject a draft that is pending approval.
draftId (string, required): The draft IDreason (string, optional): Rejection reasonmcp__textforge__delete_draftPermanently delete a draft. Only works on non-sendable statuses.
draftId (string, required): The draft IDmcp__textforge__list_threadsList email threads with optional filtering. Returns threads with hasUnreadReply, lastInboundAt, and lastOutboundAt fields.
participantEmail (string, optional): Filter by participant email addresspage (number, optional): Page number, 1-based (default: 1)pageSize (number, optional): Items per page (default: 25, max: 100)mcp__textforge__list_engaged_threadsList threads where you have previously sent at least one message, ordered by most recent activity. Includes hasUnreadReply (true when the latest message is inbound — the ball is in your court) plus lastInboundAt and lastOutboundAt timestamps. Use this to find conversations that need a response.
page (number, optional): Page number, 1-based (default: 1)pageSize (number, optional): Items per page (default: 25, max: 100)mcp__textforge__get_threadGet full thread details including messages and threading headers for replies. Requires an internal TextForge thread ID (GUID format).
threadId (string, required): Internal TextForge thread ID (GUID format, e.g., "3fa85f64-5717-4562-b3fc-2c963f66afa6"). Use the id field from list_threads, search_threads_by_contact, or matched search_messages results. Do NOT pass provider/Gmail thread IDs here — use get_thread_by_external_id for those.maxMessages (number, optional): Max messages to return (default: 5, set to 0 for all)stripQuotedReplies (boolean, optional): Strip quoted reply content (default: true)mcp__textforge__get_thread_by_external_idLook up a thread by the email provider's thread ID. Use this with provider thread IDs from search_messages results or email headers. If not found, use import_thread to import it first.
externalThreadId (string, required): Provider thread ID (e.g., Gmail thread ID like "19d2243fcda1917c")maxMessages (number, optional): Max messages to return (default: 5, set to 0 for all)stripQuotedReplies (boolean, optional): Strip quoted reply content (default: true)mcp__textforge__search_messagesSearch emails using Gmail-style query syntax. Returns two result groups:
threads — already in TextForge, have id (GUID) and full metadata (subject, participants, timestamps) for use with get_thread
unmatchedProviderThreads — not yet imported, have externalThreadId only — use import_thread first
query (string, required): Search query (e.g., "from:[email protected] after:2026-01-01", "subject:invoice", "has:attachment")
maxResults (number, optional): Max results (default: 100, max: 500)
pageToken (string, optional): Page token for pagination (from previous response)
mcp__textforge__search_threads_by_contactFind all threads involving a specific email address or domain. Returns threads with full metadata including hasUnreadReply.
email (string, required): Contact email to search for (e.g., "[email protected]" or "@example.com" for domain)mcp__textforge__sync_threadSync a specific thread from the email provider to fetch new messages. Requires an internal TextForge thread ID (GUID).
threadId (string, required): Internal TextForge thread ID (GUID format)mcp__textforge__sync_inboxTrigger a full inbox sync to discover new threads and messages.
mcp__textforge__import_threadImport a thread from the email provider by its external thread ID (e.g., from the unmatchedProviderThreads array in search_messages results). Returns the thread with its internal id (GUID) for use with get_thread, create_draft, etc. Idempotent: if already imported, syncs instead.
externalThreadId (string, required): Provider thread ID to importmcp__textforge__list_recent_messagesList recent email messages across all threads, filtered by date and optionally by direction. Returns individual messages (not threads) with thread context (threadId, threadSubject) so you can navigate to the full thread via get_thread. Use this to quickly find recent inbound emails without paging through threads.
since (string, required): Return messages after this date/time (ISO 8601, e.g., "2026-03-25T00:00:00Z")direction (string, optional): Filter by direction: "inbound", "outbound", or omit for alllimit (number, optional): Max results (default: 50, max: 100)newestFirst (boolean, optional): Sort order (default: true)mcp__textforge__list_message_attachmentsList attachments for a received email message.
messageId (string, required): The message IDmcp__textforge__list_draft_attachmentsList attachments currently attached to a draft.
draftId (string, required): The draft IDmcp__textforge__get_attachment_download_urlGet a presigned URL to download an attachment. URL expires in 10 minutes.
attachmentId (string, required): The attachment IDmcp__textforge__get_draft_attachment_upload_urlGet a presigned URL to upload an attachment to a draft.
draftId (string, required): The draft IDfileName (string, required): Name of the file to uploadcontentType (string, required): MIME type (e.g., "application/pdf")mcp__textforge__remove_draft_attachmentRemove an attachment from a draft email.
draftId (string, required): The draft IDattachmentId (string, required): The attachment IDTo attach a file to a draft:
create_draftget_draft_attachment_upload_url with the draft ID, filename, and content typeuploadUrl:
curl -X PUT "<uploadUrl>" \
-H "Content-Type: application/pdf" \
--data-binary "@/path/to/file.pdf"
To access received attachments:
list_message_attachments on a message IDget_attachment_download_url to get a presigned download URLCommon attachment types: PDF, images (PNG/JPG), documents (DOCX), spreadsheets (XLSX).
After creating a draft:
"I've queued a draft in TextForge for your review. You'll be notified via your configured channel — approve or edit it there before it sends."
Never say "I sent an email" or "the email was sent."
Both plans include a 7-day free trial. No credit card required to start.
| Plan | Price | Includes |
|---|---|---|
| Solo | $9.99/month | 20 drafts/day, 2 webhooks, 30-day inbox sync |
| Pro | $19.99/month | Unlimited drafts, 10 webhooks, full inbox history |
npx claudepluginhub textforge-app/textforge-claude-plugin --plugin textforgeTriage, draft, reply, send, and verify email through the real mail surface. Reports exact send status with Sent-folder proof.
Creates and edits Markdown fragments for rich text drafts in Gmail, Outlook, and WhatsApp, assembling platform-specific HTML previews via Python build script with live server.