feat(agentmail): add AgentMail integration with 21 tools (#3901)

* feat(agentmail): add AgentMail integration with 21 tools

* fix(agentmail): clear stale to field when switching to reply_message operation

* fix(agentmail): guard messageId and label remappings with operation checks

* fix(agentmail): clean up subBlock titles

* fix(agentmail): guard replyTo and thread label remappings with operation checks

* fix(agentmail): guard inboxIdParam remapping with operation check

* fix(agentmail): guard permanent, replyAll, and draftInReplyTo with operation checks
This commit is contained in:
Waleed
2026-04-02 13:40:23 -07:00
committed by GitHub
parent 727bb1cadb
commit e2e53aba76
33 changed files with 4026 additions and 0 deletions

View File

@@ -1,6 +1,33 @@
import type { SVGProps } from 'react'
import { useId } from 'react'
export function AgentMailIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg {...props} viewBox='0 0 350 363' fill='none' xmlns='http://www.w3.org/2000/svg'>
<path
d='M318.029 88.3407C196.474 115.33 153.48 115.321 33.9244 88.3271C30.6216 87.5814 27.1432 88.9727 25.3284 91.8313L1.24109 129.774C-1.76483 134.509 0.965276 140.798 6.46483 141.898C152.613 171.13 197.678 171.182 343.903 141.835C349.304 140.751 352.064 134.641 349.247 129.907L326.719 92.0479C324.95 89.0744 321.407 87.5907 318.029 88.3407Z'
fill='currentColor'
/>
<path
d='M75.9931 246.6L149.939 311.655C151.973 313.444 151.633 316.969 149.281 318.48L119.141 337.84C117.283 339.034 114.951 338.412 113.933 336.452L70.1276 252.036C68.0779 248.086 72.7553 243.751 75.9931 246.6Z'
fill='currentColor'
/>
<path
d='M274.025 246.6L200.08 311.655C198.046 313.444 198.385 316.969 200.737 318.48L230.877 337.84C232.736 339.034 235.068 338.412 236.085 336.452L279.891 252.036C281.941 248.086 277.263 243.751 274.025 246.6Z'
fill='currentColor'
/>
<path
d='M138.75 198.472L152.436 192.983C155.238 191.918 157.77 191.918 158.574 191.918C164.115 192.126 169.564 192.232 175.009 192.235C180.454 192.232 185.904 192.126 191.444 191.918C192.248 191.918 194.78 191.918 197.583 192.983L211.269 198.472C212.645 199.025 214.082 199.382 215.544 199.448C218.585 199.587 221.733 199.464 224.63 198.811C225.706 198.568 226.728 198.103 227.704 197.545L243.046 188.784C244.81 187.777 246.726 187.138 248.697 186.9L258.276 185.5H259.242H263.556L262.713 190.965L256.679 234.22C255.957 238.31 254.25 242.328 250.443 245.834L187.376 299.258C184.555 301.648 181.107 302.942 177.562 302.942H175.009H172.457C168.911 302.942 165.464 301.648 162.643 299.258L99.5761 245.834C95.7684 242.328 94.0614 238.31 93.3393 234.22L87.3059 190.965L86.4624 185.5H90.7771H91.7429L101.322 186.9C103.293 187.138 105.208 187.777 106.972 188.784L122.314 197.545C123.291 198.103 124.313 198.568 125.389 198.811C128.286 199.464 131.434 199.587 134.474 199.448C135.936 199.382 137.373 199.025 138.75 198.472Z'
fill='currentColor'
/>
<path
d='M102.47 0.847827C205.434 44.796 156.456 42.1015 248.434 1.63153C252.885 -1.09955 258.353 1.88915 259.419 7.69219L269.235 61.1686L270.819 69.7893L263.592 71.8231L263.582 71.8259C190.588 92.3069 165.244 92.0078 86.7576 71.7428L79.1971 69.7905L80.9925 60.8681L91.8401 6.91975C92.9559 1.3706 98.105 -1.55777 102.47 0.847827Z'
fill='currentColor'
/>
</svg>
)
}
export function SearchIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg

View File

@@ -5,6 +5,7 @@
import type { ComponentType, SVGProps } from 'react'
import {
A2AIcon,
AgentMailIcon,
AhrefsIcon,
AirtableIcon,
AirweaveIcon,
@@ -189,6 +190,7 @@ type IconComponent = ComponentType<SVGProps<SVGSVGElement>>
export const blockTypeToIconMap: Record<string, IconComponent> = {
a2a: A2AIcon,
agentmail: AgentMailIcon,
ahrefs: AhrefsIcon,
airtable: AirtableIcon,
airweave: AirweaveIcon,

View File

@@ -0,0 +1,592 @@
---
title: AgentMail
description: Manage email inboxes, threads, and messages with AgentMail
---
import { BlockInfoCard } from "@/components/ui/block-info-card"
<BlockInfoCard
type="agentmail"
color="#000000"
/>
{/* MANUAL-CONTENT-START:intro */}
[AgentMail](https://agentmail.to/) is an API-first email platform built for agents and automation. AgentMail lets you create email inboxes on the fly, send and receive messages, reply to threads, manage drafts, and organize conversations with labels — all through a simple REST API designed for programmatic access.
**Why AgentMail?**
- **Agent-Native Email:** Purpose-built for AI agents and automation — create inboxes, send messages, and manage threads without human-facing UI overhead.
- **Full Email Lifecycle:** Send new messages, reply to threads, forward emails, manage drafts, and schedule sends — all from a single API.
- **Thread & Conversation Management:** Organize emails into threads with full read, reply, forward, and label support for structured conversation tracking.
- **Draft Workflow:** Compose drafts, update them, schedule sends, and dispatch when ready — perfect for review-before-send workflows.
- **Label Organization:** Tag threads and messages with custom labels for filtering, routing, and downstream automation.
**Using AgentMail in Sim**
Sim's AgentMail integration connects your agentic workflows directly to AgentMail using an API key. With 20 operations spanning inboxes, threads, messages, and drafts, you can build powerful email automations without writing backend code.
**Key benefits of using AgentMail in Sim:**
- **Dynamic inbox creation:** Spin up new inboxes on the fly for each agent, workflow, or customer — perfect for multi-tenant email handling.
- **Automated email processing:** List and read incoming messages, then trigger downstream actions based on content, sender, or labels.
- **Conversational email:** Reply to threads and forward messages to keep conversations flowing naturally within your automated workflows.
- **Draft and review workflows:** Create drafts, update them with AI-generated content, and send when approved — ideal for human-in-the-loop patterns.
- **Email organization:** Apply labels to threads and messages to categorize, filter, and route emails through your automation pipeline.
Whether you're building an AI email assistant, automating customer support replies, processing incoming leads, or managing multi-agent email workflows, AgentMail in Sim gives you direct, secure access to the full AgentMail API — no middleware required. Simply configure your API key, select the operation you need, and let Sim handle the rest.
{/* MANUAL-CONTENT-END */}
## Usage Instructions
Integrate AgentMail into your workflow. Create and manage email inboxes, send and receive messages, reply to threads, manage drafts, and organize threads with labels. Requires API Key.
## Tools
### `agentmail_create_draft`
Create a new email draft in AgentMail
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | AgentMail API key |
| `inboxId` | string | Yes | ID of the inbox to create the draft in |
| `to` | string | No | Recipient email addresses \(comma-separated\) |
| `subject` | string | No | Draft subject line |
| `text` | string | No | Plain text draft body |
| `html` | string | No | HTML draft body |
| `cc` | string | No | CC recipient email addresses \(comma-separated\) |
| `bcc` | string | No | BCC recipient email addresses \(comma-separated\) |
| `inReplyTo` | string | No | ID of message being replied to |
| `sendAt` | string | No | ISO 8601 timestamp to schedule sending |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `draftId` | string | Unique identifier for the draft |
| `inboxId` | string | Inbox the draft belongs to |
| `subject` | string | Draft subject |
| `to` | array | Recipient email addresses |
| `cc` | array | CC email addresses |
| `bcc` | array | BCC email addresses |
| `text` | string | Plain text content |
| `html` | string | HTML content |
| `preview` | string | Draft preview text |
| `labels` | array | Labels assigned to the draft |
| `inReplyTo` | string | Message ID this draft replies to |
| `sendStatus` | string | Send status \(scheduled, sending, failed\) |
| `sendAt` | string | Scheduled send time |
| `createdAt` | string | Creation timestamp |
| `updatedAt` | string | Last updated timestamp |
### `agentmail_create_inbox`
Create a new email inbox with AgentMail
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | AgentMail API key |
| `username` | string | No | Username for the inbox email address |
| `domain` | string | No | Domain for the inbox email address |
| `displayName` | string | No | Display name for the inbox |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `inboxId` | string | Unique identifier for the inbox |
| `email` | string | Email address of the inbox |
| `displayName` | string | Display name of the inbox |
| `createdAt` | string | Creation timestamp |
| `updatedAt` | string | Last updated timestamp |
### `agentmail_delete_draft`
Delete an email draft in AgentMail
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | AgentMail API key |
| `inboxId` | string | Yes | ID of the inbox containing the draft |
| `draftId` | string | Yes | ID of the draft to delete |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `deleted` | boolean | Whether the draft was successfully deleted |
### `agentmail_delete_inbox`
Delete an email inbox in AgentMail
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | AgentMail API key |
| `inboxId` | string | Yes | ID of the inbox to delete |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `deleted` | boolean | Whether the inbox was successfully deleted |
### `agentmail_delete_thread`
Delete an email thread in AgentMail (moves to trash, or permanently deletes if already in trash)
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | AgentMail API key |
| `inboxId` | string | Yes | ID of the inbox containing the thread |
| `threadId` | string | Yes | ID of the thread to delete |
| `permanent` | boolean | No | Force permanent deletion instead of moving to trash |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `deleted` | boolean | Whether the thread was successfully deleted |
### `agentmail_forward_message`
Forward an email message to new recipients in AgentMail
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | AgentMail API key |
| `inboxId` | string | Yes | ID of the inbox containing the message |
| `messageId` | string | Yes | ID of the message to forward |
| `to` | string | Yes | Recipient email addresses \(comma-separated\) |
| `subject` | string | No | Override subject line |
| `text` | string | No | Additional plain text to prepend |
| `html` | string | No | Additional HTML to prepend |
| `cc` | string | No | CC recipient email addresses \(comma-separated\) |
| `bcc` | string | No | BCC recipient email addresses \(comma-separated\) |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `messageId` | string | ID of the forwarded message |
| `threadId` | string | ID of the thread |
### `agentmail_get_draft`
Get details of a specific email draft in AgentMail
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | AgentMail API key |
| `inboxId` | string | Yes | ID of the inbox the draft belongs to |
| `draftId` | string | Yes | ID of the draft to retrieve |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `draftId` | string | Unique identifier for the draft |
| `inboxId` | string | Inbox the draft belongs to |
| `subject` | string | Draft subject |
| `to` | array | Recipient email addresses |
| `cc` | array | CC email addresses |
| `bcc` | array | BCC email addresses |
| `text` | string | Plain text content |
| `html` | string | HTML content |
| `preview` | string | Draft preview text |
| `labels` | array | Labels assigned to the draft |
| `inReplyTo` | string | Message ID this draft replies to |
| `sendStatus` | string | Send status \(scheduled, sending, failed\) |
| `sendAt` | string | Scheduled send time |
| `createdAt` | string | Creation timestamp |
| `updatedAt` | string | Last updated timestamp |
### `agentmail_get_inbox`
Get details of a specific email inbox in AgentMail
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | AgentMail API key |
| `inboxId` | string | Yes | ID of the inbox to retrieve |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `inboxId` | string | Unique identifier for the inbox |
| `email` | string | Email address of the inbox |
| `displayName` | string | Display name of the inbox |
| `createdAt` | string | Creation timestamp |
| `updatedAt` | string | Last updated timestamp |
### `agentmail_get_message`
Get details of a specific email message in AgentMail
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | AgentMail API key |
| `inboxId` | string | Yes | ID of the inbox containing the message |
| `messageId` | string | Yes | ID of the message to retrieve |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `messageId` | string | Unique identifier for the message |
| `threadId` | string | ID of the thread this message belongs to |
| `from` | string | Sender email address |
| `to` | array | Recipient email addresses |
| `cc` | array | CC email addresses |
| `bcc` | array | BCC email addresses |
| `subject` | string | Message subject |
| `text` | string | Plain text content |
| `html` | string | HTML content |
| `createdAt` | string | Creation timestamp |
### `agentmail_get_thread`
Get details of a specific email thread including messages in AgentMail
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | AgentMail API key |
| `inboxId` | string | Yes | ID of the inbox containing the thread |
| `threadId` | string | Yes | ID of the thread to retrieve |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `threadId` | string | Unique identifier for the thread |
| `subject` | string | Thread subject |
| `senders` | array | List of sender email addresses |
| `recipients` | array | List of recipient email addresses |
| `messageCount` | number | Number of messages in the thread |
| `labels` | array | Labels assigned to the thread |
| `lastMessageAt` | string | Timestamp of last message |
| `createdAt` | string | Creation timestamp |
| `updatedAt` | string | Last updated timestamp |
| `messages` | array | Messages in the thread |
| ↳ `messageId` | string | Unique identifier for the message |
| ↳ `from` | string | Sender email address |
| ↳ `to` | array | Recipient email addresses |
| ↳ `cc` | array | CC email addresses |
| ↳ `bcc` | array | BCC email addresses |
| ↳ `subject` | string | Message subject |
| ↳ `text` | string | Plain text content |
| ↳ `html` | string | HTML content |
| ↳ `createdAt` | string | Creation timestamp |
### `agentmail_list_drafts`
List email drafts in an inbox in AgentMail
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | AgentMail API key |
| `inboxId` | string | Yes | ID of the inbox to list drafts from |
| `limit` | number | No | Maximum number of drafts to return |
| `pageToken` | string | No | Pagination token for next page of results |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `drafts` | array | List of drafts |
| ↳ `draftId` | string | Unique identifier for the draft |
| ↳ `inboxId` | string | Inbox the draft belongs to |
| ↳ `subject` | string | Draft subject |
| ↳ `to` | array | Recipient email addresses |
| ↳ `cc` | array | CC email addresses |
| ↳ `bcc` | array | BCC email addresses |
| ↳ `preview` | string | Draft preview text |
| ↳ `sendStatus` | string | Send status \(scheduled, sending, failed\) |
| ↳ `sendAt` | string | Scheduled send time |
| ↳ `createdAt` | string | Creation timestamp |
| ↳ `updatedAt` | string | Last updated timestamp |
| `count` | number | Total number of drafts |
| `nextPageToken` | string | Token for retrieving the next page |
### `agentmail_list_inboxes`
List all email inboxes in AgentMail
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | AgentMail API key |
| `limit` | number | No | Maximum number of inboxes to return |
| `pageToken` | string | No | Pagination token for next page of results |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `inboxes` | array | List of inboxes |
| ↳ `inboxId` | string | Unique identifier for the inbox |
| ↳ `email` | string | Email address of the inbox |
| ↳ `displayName` | string | Display name of the inbox |
| ↳ `createdAt` | string | Creation timestamp |
| ↳ `updatedAt` | string | Last updated timestamp |
| `count` | number | Total number of inboxes |
| `nextPageToken` | string | Token for retrieving the next page |
### `agentmail_list_messages`
List messages in an inbox in AgentMail
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | AgentMail API key |
| `inboxId` | string | Yes | ID of the inbox to list messages from |
| `limit` | number | No | Maximum number of messages to return |
| `pageToken` | string | No | Pagination token for next page of results |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `messages` | array | List of messages in the inbox |
| ↳ `messageId` | string | Unique identifier for the message |
| ↳ `from` | string | Sender email address |
| ↳ `to` | array | Recipient email addresses |
| ↳ `subject` | string | Message subject |
| ↳ `preview` | string | Message preview text |
| ↳ `createdAt` | string | Creation timestamp |
| `count` | number | Total number of messages |
| `nextPageToken` | string | Token for retrieving the next page |
### `agentmail_list_threads`
List email threads in AgentMail
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | AgentMail API key |
| `inboxId` | string | Yes | ID of the inbox to list threads from |
| `limit` | number | No | Maximum number of threads to return |
| `pageToken` | string | No | Pagination token for next page of results |
| `labels` | string | No | Comma-separated labels to filter threads by |
| `before` | string | No | Filter threads before this ISO 8601 timestamp |
| `after` | string | No | Filter threads after this ISO 8601 timestamp |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `threads` | array | List of email threads |
| ↳ `threadId` | string | Unique identifier for the thread |
| ↳ `subject` | string | Thread subject |
| ↳ `senders` | array | List of sender email addresses |
| ↳ `recipients` | array | List of recipient email addresses |
| ↳ `messageCount` | number | Number of messages in the thread |
| ↳ `lastMessageAt` | string | Timestamp of last message |
| ↳ `createdAt` | string | Creation timestamp |
| ↳ `updatedAt` | string | Last updated timestamp |
| `count` | number | Total number of threads |
| `nextPageToken` | string | Token for retrieving the next page |
### `agentmail_reply_message`
Reply to an existing email message in AgentMail
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | AgentMail API key |
| `inboxId` | string | Yes | ID of the inbox to reply from |
| `messageId` | string | Yes | ID of the message to reply to |
| `text` | string | No | Plain text reply body |
| `html` | string | No | HTML reply body |
| `to` | string | No | Override recipient email addresses \(comma-separated\) |
| `cc` | string | No | CC email addresses \(comma-separated\) |
| `bcc` | string | No | BCC email addresses \(comma-separated\) |
| `replyAll` | boolean | No | Reply to all recipients of the original message |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `messageId` | string | ID of the sent reply message |
| `threadId` | string | ID of the thread |
### `agentmail_send_draft`
Send an existing email draft in AgentMail
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | AgentMail API key |
| `inboxId` | string | Yes | ID of the inbox containing the draft |
| `draftId` | string | Yes | ID of the draft to send |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `messageId` | string | ID of the sent message |
| `threadId` | string | ID of the thread |
### `agentmail_send_message`
Send an email message from an AgentMail inbox
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | AgentMail API key |
| `inboxId` | string | Yes | ID of the inbox to send from |
| `to` | string | Yes | Recipient email address \(comma-separated for multiple\) |
| `subject` | string | Yes | Email subject line |
| `text` | string | No | Plain text email body |
| `html` | string | No | HTML email body |
| `cc` | string | No | CC recipient email addresses \(comma-separated\) |
| `bcc` | string | No | BCC recipient email addresses \(comma-separated\) |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `threadId` | string | ID of the created thread |
| `messageId` | string | ID of the sent message |
| `subject` | string | Email subject line |
| `to` | string | Recipient email address |
### `agentmail_update_draft`
Update an existing email draft in AgentMail
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | AgentMail API key |
| `inboxId` | string | Yes | ID of the inbox containing the draft |
| `draftId` | string | Yes | ID of the draft to update |
| `to` | string | No | Recipient email addresses \(comma-separated\) |
| `subject` | string | No | Draft subject line |
| `text` | string | No | Plain text draft body |
| `html` | string | No | HTML draft body |
| `cc` | string | No | CC recipient email addresses \(comma-separated\) |
| `bcc` | string | No | BCC recipient email addresses \(comma-separated\) |
| `sendAt` | string | No | ISO 8601 timestamp to schedule sending |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `draftId` | string | Unique identifier for the draft |
| `inboxId` | string | Inbox the draft belongs to |
| `subject` | string | Draft subject |
| `to` | array | Recipient email addresses |
| `cc` | array | CC email addresses |
| `bcc` | array | BCC email addresses |
| `text` | string | Plain text content |
| `html` | string | HTML content |
| `preview` | string | Draft preview text |
| `labels` | array | Labels assigned to the draft |
| `inReplyTo` | string | Message ID this draft replies to |
| `sendStatus` | string | Send status \(scheduled, sending, failed\) |
| `sendAt` | string | Scheduled send time |
| `createdAt` | string | Creation timestamp |
| `updatedAt` | string | Last updated timestamp |
### `agentmail_update_inbox`
Update the display name of an email inbox in AgentMail
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | AgentMail API key |
| `inboxId` | string | Yes | ID of the inbox to update |
| `displayName` | string | Yes | New display name for the inbox |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `inboxId` | string | Unique identifier for the inbox |
| `email` | string | Email address of the inbox |
| `displayName` | string | Display name of the inbox |
| `createdAt` | string | Creation timestamp |
| `updatedAt` | string | Last updated timestamp |
### `agentmail_update_message`
Add or remove labels on an email message in AgentMail
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | AgentMail API key |
| `inboxId` | string | Yes | ID of the inbox containing the message |
| `messageId` | string | Yes | ID of the message to update |
| `addLabels` | string | No | Comma-separated labels to add to the message |
| `removeLabels` | string | No | Comma-separated labels to remove from the message |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `messageId` | string | Unique identifier for the message |
| `labels` | array | Current labels on the message |
### `agentmail_update_thread`
Add or remove labels on an email thread in AgentMail
#### Input
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `apiKey` | string | Yes | AgentMail API key |
| `inboxId` | string | Yes | ID of the inbox containing the thread |
| `threadId` | string | Yes | ID of the thread to update |
| `addLabels` | string | No | Comma-separated labels to add to the thread |
| `removeLabels` | string | No | Comma-separated labels to remove from the thread |
#### Output
| Parameter | Type | Description |
| --------- | ---- | ----------- |
| `threadId` | string | Unique identifier for the thread |
| `labels` | array | Current labels on the thread |

View File

@@ -2,6 +2,7 @@
"pages": [
"index",
"a2a",
"agentmail",
"ahrefs",
"airtable",
"airweave",

View File

@@ -5,6 +5,7 @@
import type { ComponentType, SVGProps } from 'react'
import {
A2AIcon,
AgentMailIcon,
AhrefsIcon,
AirtableIcon,
AirweaveIcon,
@@ -189,6 +190,7 @@ type IconComponent = ComponentType<SVGProps<SVGSVGElement>>
export const blockTypeToIconMap: Record<string, IconComponent> = {
a2a: A2AIcon,
agentmail: AgentMailIcon,
ahrefs: AhrefsIcon,
airtable: AirtableIcon,
airweave: AirweaveIcon,

View File

@@ -105,6 +105,109 @@
"integrationType": "developer-tools",
"tags": ["agentic", "automation"]
},
{
"type": "agentmail",
"slug": "agentmail",
"name": "AgentMail",
"description": "Manage email inboxes, threads, and messages with AgentMail",
"longDescription": "Integrate AgentMail into your workflow. Create and manage email inboxes, send and receive messages, reply to threads, manage drafts, and organize threads with labels. Requires API Key.",
"bgColor": "#000000",
"iconName": "AgentMailIcon",
"docsUrl": "https://docs.sim.ai/tools/agentmail",
"operations": [
{
"name": "Send Message",
"description": "Send an email message from an AgentMail inbox"
},
{
"name": "Reply to Message",
"description": "Reply to an existing email message in AgentMail"
},
{
"name": "Forward Message",
"description": "Forward an email message to new recipients in AgentMail"
},
{
"name": "List Threads",
"description": "List email threads in AgentMail"
},
{
"name": "Get Thread",
"description": "Get details of a specific email thread including messages in AgentMail"
},
{
"name": "Update Thread Labels",
"description": "Add or remove labels on an email thread in AgentMail"
},
{
"name": "Delete Thread",
"description": "Delete an email thread in AgentMail (moves to trash, or permanently deletes if already in trash)"
},
{
"name": "List Messages",
"description": "List messages in an inbox in AgentMail"
},
{
"name": "Get Message",
"description": "Get details of a specific email message in AgentMail"
},
{
"name": "Update Message Labels",
"description": "Add or remove labels on an email message in AgentMail"
},
{
"name": "Create Draft",
"description": "Create a new email draft in AgentMail"
},
{
"name": "List Drafts",
"description": "List email drafts in an inbox in AgentMail"
},
{
"name": "Get Draft",
"description": "Get details of a specific email draft in AgentMail"
},
{
"name": "Update Draft",
"description": "Update an existing email draft in AgentMail"
},
{
"name": "Delete Draft",
"description": "Delete an email draft in AgentMail"
},
{
"name": "Send Draft",
"description": "Send an existing email draft in AgentMail"
},
{
"name": "Create Inbox",
"description": "Create a new email inbox with AgentMail"
},
{
"name": "List Inboxes",
"description": "List all email inboxes in AgentMail"
},
{
"name": "Get Inbox",
"description": "Get details of a specific email inbox in AgentMail"
},
{
"name": "Update Inbox",
"description": "Update the display name of an email inbox in AgentMail"
},
{
"name": "Delete Inbox",
"description": "Delete an email inbox in AgentMail"
}
],
"operationCount": 21,
"triggers": [],
"triggerCount": 0,
"authType": "api-key",
"category": "tools",
"integrationType": "email",
"tags": ["messaging"]
},
{
"type": "ahrefs",
"slug": "ahrefs",

View File

@@ -0,0 +1,621 @@
import { AgentMailIcon } from '@/components/icons'
import type { BlockConfig } from '@/blocks/types'
import { AuthMode, IntegrationType } from '@/blocks/types'
export const AgentMailBlock: BlockConfig = {
type: 'agentmail',
name: 'AgentMail',
description: 'Manage email inboxes, threads, and messages with AgentMail',
longDescription:
'Integrate AgentMail into your workflow. Create and manage email inboxes, send and receive messages, reply to threads, manage drafts, and organize threads with labels. Requires API Key.',
docsLink: 'https://docs.sim.ai/tools/agentmail',
category: 'tools',
integrationType: IntegrationType.Email,
tags: ['messaging'],
bgColor: '#000000',
icon: AgentMailIcon,
authMode: AuthMode.ApiKey,
subBlocks: [
{
id: 'operation',
title: 'Operation',
type: 'dropdown',
options: [
{ label: 'Send Message', id: 'send_message' },
{ label: 'Reply to Message', id: 'reply_message' },
{ label: 'Forward Message', id: 'forward_message' },
{ label: 'List Threads', id: 'list_threads' },
{ label: 'Get Thread', id: 'get_thread' },
{ label: 'Update Thread Labels', id: 'update_thread' },
{ label: 'Delete Thread', id: 'delete_thread' },
{ label: 'List Messages', id: 'list_messages' },
{ label: 'Get Message', id: 'get_message' },
{ label: 'Update Message Labels', id: 'update_message' },
{ label: 'Create Draft', id: 'create_draft' },
{ label: 'List Drafts', id: 'list_drafts' },
{ label: 'Get Draft', id: 'get_draft' },
{ label: 'Update Draft', id: 'update_draft' },
{ label: 'Delete Draft', id: 'delete_draft' },
{ label: 'Send Draft', id: 'send_draft' },
{ label: 'Create Inbox', id: 'create_inbox' },
{ label: 'List Inboxes', id: 'list_inboxes' },
{ label: 'Get Inbox', id: 'get_inbox' },
{ label: 'Update Inbox', id: 'update_inbox' },
{ label: 'Delete Inbox', id: 'delete_inbox' },
],
value: () => 'send_message',
},
{
id: 'apiKey',
title: 'API Key',
type: 'short-input',
placeholder: 'Enter your AgentMail API key',
required: true,
password: true,
},
// Send Message fields
{
id: 'inboxId',
title: 'Inbox ID',
type: 'short-input',
placeholder: 'Inbox ID',
condition: {
field: 'operation',
value: [
'send_message',
'reply_message',
'forward_message',
'list_threads',
'get_thread',
'update_thread',
'delete_thread',
'list_messages',
'get_message',
'update_message',
'create_draft',
'list_drafts',
'get_draft',
'update_draft',
'delete_draft',
'send_draft',
],
},
required: {
field: 'operation',
value: [
'send_message',
'reply_message',
'forward_message',
'list_threads',
'get_thread',
'update_thread',
'delete_thread',
'list_messages',
'get_message',
'update_message',
'create_draft',
'list_drafts',
'get_draft',
'update_draft',
'delete_draft',
'send_draft',
],
},
},
{
id: 'to',
title: 'To',
type: 'short-input',
placeholder: 'recipient@example.com',
condition: {
field: 'operation',
value: ['send_message', 'forward_message', 'create_draft', 'update_draft'],
},
required: { field: 'operation', value: ['send_message', 'forward_message'] },
},
{
id: 'subject',
title: 'Subject',
type: 'short-input',
placeholder: 'Email subject',
condition: {
field: 'operation',
value: ['send_message', 'forward_message', 'create_draft', 'update_draft'],
},
required: { field: 'operation', value: 'send_message' },
wandConfig: {
enabled: true,
prompt:
'Generate a compelling email subject line based on the description. Keep it concise. Return ONLY the subject line.',
placeholder: 'Describe the email topic...',
},
},
{
id: 'text',
title: 'Text',
type: 'long-input',
placeholder: 'Plain text email body',
condition: {
field: 'operation',
value: ['send_message', 'reply_message', 'forward_message', 'create_draft', 'update_draft'],
},
wandConfig: {
enabled: true,
prompt:
'Generate email content based on the description. Use clear formatting with short paragraphs. Return ONLY the email body.',
placeholder: 'Describe the email content...',
},
},
{
id: 'html',
title: 'HTML',
type: 'long-input',
placeholder: '<p>HTML email body</p>',
condition: {
field: 'operation',
value: ['send_message', 'reply_message', 'forward_message', 'create_draft', 'update_draft'],
},
mode: 'advanced',
},
{
id: 'cc',
title: 'CC',
type: 'short-input',
placeholder: 'cc@example.com',
condition: {
field: 'operation',
value: ['send_message', 'reply_message', 'forward_message', 'create_draft', 'update_draft'],
},
mode: 'advanced',
},
{
id: 'bcc',
title: 'BCC',
type: 'short-input',
placeholder: 'bcc@example.com',
condition: {
field: 'operation',
value: ['send_message', 'reply_message', 'forward_message', 'create_draft', 'update_draft'],
},
mode: 'advanced',
},
// Reply to Message fields
{
id: 'replyMessageId',
title: 'Message ID to Reply To',
type: 'short-input',
placeholder: 'Message ID',
condition: { field: 'operation', value: 'reply_message' },
required: { field: 'operation', value: 'reply_message' },
},
{
id: 'replyTo',
title: 'Override To',
type: 'short-input',
placeholder: 'Override recipient (optional)',
condition: { field: 'operation', value: 'reply_message' },
mode: 'advanced',
},
{
id: 'replyAll',
title: 'Reply All',
type: 'dropdown',
options: [
{ label: 'No', id: 'false' },
{ label: 'Yes', id: 'true' },
],
value: () => 'false',
condition: { field: 'operation', value: 'reply_message' },
mode: 'advanced',
},
// Thread ID fields (shared across thread operations)
{
id: 'threadId',
title: 'Thread ID',
type: 'short-input',
placeholder: 'Thread ID',
condition: {
field: 'operation',
value: ['get_thread', 'update_thread', 'delete_thread'],
},
required: {
field: 'operation',
value: ['get_thread', 'update_thread', 'delete_thread'],
},
},
// Update Thread Labels fields
{
id: 'addLabels',
title: 'Add Labels',
type: 'short-input',
placeholder: 'important, follow-up',
condition: { field: 'operation', value: 'update_thread' },
},
{
id: 'removeLabels',
title: 'Remove Labels',
type: 'short-input',
placeholder: 'inbox, unread',
condition: { field: 'operation', value: 'update_thread' },
},
// Delete Thread fields
{
id: 'permanent',
title: 'Permanent Delete',
type: 'dropdown',
options: [
{ label: 'No (move to trash)', id: 'false' },
{ label: 'Yes (permanent)', id: 'true' },
],
value: () => 'false',
condition: { field: 'operation', value: 'delete_thread' },
mode: 'advanced',
},
// Forward Message fields
{
id: 'forwardMessageId',
title: 'Message ID to Forward',
type: 'short-input',
placeholder: 'Message ID',
condition: { field: 'operation', value: 'forward_message' },
required: { field: 'operation', value: 'forward_message' },
},
// Update Message Labels fields
{
id: 'updateMessageId',
title: 'Message ID',
type: 'short-input',
placeholder: 'Message ID',
condition: { field: 'operation', value: 'update_message' },
required: { field: 'operation', value: 'update_message' },
},
{
id: 'msgAddLabels',
title: 'Add Labels',
type: 'short-input',
placeholder: 'important, follow-up',
condition: { field: 'operation', value: 'update_message' },
},
{
id: 'msgRemoveLabels',
title: 'Remove Labels',
type: 'short-input',
placeholder: 'inbox, unread',
condition: { field: 'operation', value: 'update_message' },
},
// Get Message fields
{
id: 'messageId',
title: 'Message ID',
type: 'short-input',
placeholder: 'Message ID',
condition: { field: 'operation', value: 'get_message' },
required: { field: 'operation', value: 'get_message' },
},
// Draft ID fields (shared across draft operations)
{
id: 'draftId',
title: 'Draft ID',
type: 'short-input',
placeholder: 'Draft ID',
condition: {
field: 'operation',
value: ['get_draft', 'update_draft', 'delete_draft', 'send_draft'],
},
required: {
field: 'operation',
value: ['get_draft', 'update_draft', 'delete_draft', 'send_draft'],
},
},
// Create/Update Draft fields
{
id: 'draftInReplyTo',
title: 'In Reply To',
type: 'short-input',
placeholder: 'Message ID this draft replies to',
condition: { field: 'operation', value: 'create_draft' },
mode: 'advanced',
},
{
id: 'sendAt',
title: 'Schedule Send',
type: 'short-input',
placeholder: 'ISO 8601 timestamp to schedule sending',
condition: { field: 'operation', value: ['create_draft', 'update_draft'] },
mode: 'advanced',
wandConfig: {
enabled: true,
generationType: 'timestamp',
prompt: 'Generate an ISO 8601 timestamp. Return ONLY the timestamp string.',
placeholder: 'Describe when to send (e.g., "tomorrow at 9am")...',
},
},
// Create Inbox fields
{
id: 'username',
title: 'Username',
type: 'short-input',
placeholder: 'Optional username for email address',
condition: { field: 'operation', value: 'create_inbox' },
},
{
id: 'domain',
title: 'Domain',
type: 'short-input',
placeholder: 'Optional domain for email address',
condition: { field: 'operation', value: 'create_inbox' },
mode: 'advanced',
},
{
id: 'displayName',
title: 'Display Name',
type: 'short-input',
placeholder: 'Inbox display name',
condition: { field: 'operation', value: ['create_inbox', 'update_inbox'] },
required: { field: 'operation', value: 'update_inbox' },
},
// Inbox ID for get/update/delete inbox
{
id: 'inboxIdParam',
title: 'Inbox ID',
type: 'short-input',
placeholder: 'Inbox ID',
condition: {
field: 'operation',
value: ['get_inbox', 'update_inbox', 'delete_inbox'],
},
required: {
field: 'operation',
value: ['get_inbox', 'update_inbox', 'delete_inbox'],
},
},
// Pagination fields (advanced)
{
id: 'limit',
title: 'Limit',
type: 'short-input',
placeholder: 'Max results to return',
condition: {
field: 'operation',
value: ['list_inboxes', 'list_threads', 'list_messages', 'list_drafts'],
},
mode: 'advanced',
},
{
id: 'pageToken',
title: 'Page Token',
type: 'short-input',
placeholder: 'Pagination token',
condition: {
field: 'operation',
value: ['list_inboxes', 'list_threads', 'list_messages', 'list_drafts'],
},
mode: 'advanced',
},
// List Threads filters (advanced)
{
id: 'labels',
title: 'Labels Filter',
type: 'short-input',
placeholder: 'Filter by labels (comma-separated)',
condition: { field: 'operation', value: 'list_threads' },
mode: 'advanced',
},
{
id: 'before',
title: 'Before',
type: 'short-input',
placeholder: 'Filter threads before this date',
condition: { field: 'operation', value: 'list_threads' },
mode: 'advanced',
wandConfig: {
enabled: true,
generationType: 'timestamp',
prompt: 'Generate an ISO 8601 timestamp. Return ONLY the timestamp string.',
placeholder: 'Describe the date (e.g., "yesterday")...',
},
},
{
id: 'after',
title: 'After',
type: 'short-input',
placeholder: 'Filter threads after this date',
condition: { field: 'operation', value: 'list_threads' },
mode: 'advanced',
wandConfig: {
enabled: true,
generationType: 'timestamp',
prompt: 'Generate an ISO 8601 timestamp. Return ONLY the timestamp string.',
placeholder: 'Describe the date (e.g., "last week")...',
},
},
],
tools: {
access: [
'agentmail_create_draft',
'agentmail_create_inbox',
'agentmail_delete_draft',
'agentmail_delete_inbox',
'agentmail_delete_thread',
'agentmail_forward_message',
'agentmail_get_draft',
'agentmail_get_inbox',
'agentmail_get_message',
'agentmail_get_thread',
'agentmail_list_drafts',
'agentmail_list_inboxes',
'agentmail_list_messages',
'agentmail_list_threads',
'agentmail_reply_message',
'agentmail_send_draft',
'agentmail_send_message',
'agentmail_update_draft',
'agentmail_update_inbox',
'agentmail_update_message',
'agentmail_update_thread',
],
config: {
tool: (params) => `agentmail_${params.operation || 'send_message'}`,
params: (params) => {
const {
operation,
inboxIdParam,
permanent,
replyMessageId,
replyTo,
replyAll,
forwardMessageId,
updateMessageId,
msgAddLabels,
msgRemoveLabels,
addLabels,
removeLabels,
draftInReplyTo,
...rest
} = params
if (['get_inbox', 'update_inbox', 'delete_inbox'].includes(operation) && inboxIdParam) {
rest.inboxId = inboxIdParam
}
if (operation === 'delete_thread' && permanent !== undefined) {
rest.permanent = permanent === 'true'
}
if (operation === 'reply_message' && replyAll !== undefined) {
rest.replyAll = replyAll === 'true'
}
if (operation === 'reply_message' && replyMessageId) {
rest.messageId = replyMessageId
}
if (operation === 'reply_message' && replyTo) {
rest.to = replyTo
} else if (operation === 'reply_message') {
rest.to = undefined
}
if (operation === 'forward_message' && forwardMessageId) {
rest.messageId = forwardMessageId
}
if (operation === 'update_message' && updateMessageId) {
rest.messageId = updateMessageId
}
if (operation === 'update_message' && msgAddLabels) {
rest.addLabels = msgAddLabels
}
if (operation === 'update_message' && msgRemoveLabels) {
rest.removeLabels = msgRemoveLabels
}
if (operation === 'update_thread' && addLabels) {
rest.addLabels = addLabels
}
if (operation === 'update_thread' && removeLabels) {
rest.removeLabels = removeLabels
}
if (operation === 'create_draft' && draftInReplyTo) {
rest.inReplyTo = draftInReplyTo
}
if (rest.limit) {
rest.limit = Number(rest.limit)
}
return rest
},
},
},
inputs: {
operation: { type: 'string', description: 'Operation to perform' },
apiKey: { type: 'string', description: 'AgentMail API key' },
inboxId: { type: 'string', description: 'Inbox ID' },
inboxIdParam: {
type: 'string',
description: 'Inbox ID for get/update/delete inbox operations',
},
to: { type: 'string', description: 'Recipient email address' },
subject: { type: 'string', description: 'Email subject' },
text: { type: 'string', description: 'Plain text email body' },
html: { type: 'string', description: 'HTML email body' },
cc: { type: 'string', description: 'CC email addresses' },
bcc: { type: 'string', description: 'BCC email addresses' },
replyMessageId: { type: 'string', description: 'Message ID to reply to' },
replyTo: { type: 'string', description: 'Override recipient for reply' },
replyAll: { type: 'string', description: 'Reply to all recipients' },
forwardMessageId: { type: 'string', description: 'Message ID to forward' },
updateMessageId: { type: 'string', description: 'Message ID to update labels on' },
msgAddLabels: { type: 'string', description: 'Labels to add to message' },
msgRemoveLabels: { type: 'string', description: 'Labels to remove from message' },
threadId: { type: 'string', description: 'Thread ID' },
addLabels: { type: 'string', description: 'Labels to add to thread (comma-separated)' },
removeLabels: { type: 'string', description: 'Labels to remove from thread (comma-separated)' },
permanent: { type: 'string', description: 'Whether to permanently delete' },
messageId: { type: 'string', description: 'Message ID' },
draftId: { type: 'string', description: 'Draft ID' },
draftInReplyTo: { type: 'string', description: 'Message ID this draft replies to' },
sendAt: { type: 'string', description: 'ISO 8601 timestamp to schedule sending' },
username: { type: 'string', description: 'Username for new inbox' },
domain: { type: 'string', description: 'Domain for new inbox' },
displayName: { type: 'string', description: 'Display name for inbox' },
limit: { type: 'string', description: 'Max results to return' },
pageToken: { type: 'string', description: 'Pagination token' },
labels: { type: 'string', description: 'Labels filter for threads' },
before: { type: 'string', description: 'Filter threads before this date' },
after: { type: 'string', description: 'Filter threads after this date' },
},
outputs: {
inboxId: { type: 'string', description: 'Inbox ID' },
email: { type: 'string', description: 'Inbox email address' },
displayName: { type: 'string', description: 'Inbox display name' },
threadId: { type: 'string', description: 'Thread ID' },
messageId: { type: 'string', description: 'Message ID' },
draftId: { type: 'string', description: 'Draft ID' },
subject: { type: 'string', description: 'Email subject' },
to: { type: 'string', description: 'Recipient email address' },
from: { type: 'string', description: 'Sender email address' },
text: { type: 'string', description: 'Plain text content' },
html: { type: 'string', description: 'HTML content' },
preview: { type: 'string', description: 'Message or draft preview text' },
senders: { type: 'json', description: 'List of sender email addresses' },
recipients: { type: 'json', description: 'List of recipient email addresses' },
labels: { type: 'json', description: 'Thread or draft labels' },
messages: { type: 'json', description: 'List of messages' },
threads: { type: 'json', description: 'List of threads' },
inboxes: { type: 'json', description: 'List of inboxes' },
drafts: { type: 'json', description: 'List of drafts' },
messageCount: { type: 'number', description: 'Number of messages in thread' },
count: { type: 'number', description: 'Total number of results' },
nextPageToken: { type: 'string', description: 'Token for next page of results' },
deleted: { type: 'boolean', description: 'Whether the resource was deleted' },
sendStatus: { type: 'string', description: 'Draft send status' },
sendAt: { type: 'string', description: 'Scheduled send time' },
inReplyTo: { type: 'string', description: 'Message ID this draft replies to' },
createdAt: { type: 'string', description: 'Creation timestamp' },
updatedAt: { type: 'string', description: 'Last updated timestamp' },
},
}

View File

@@ -1,5 +1,6 @@
import { A2ABlock } from '@/blocks/blocks/a2a'
import { AgentBlock } from '@/blocks/blocks/agent'
import { AgentMailBlock } from '@/blocks/blocks/agentmail'
import { AhrefsBlock } from '@/blocks/blocks/ahrefs'
import { AirtableBlock } from '@/blocks/blocks/airtable'
import { AirweaveBlock } from '@/blocks/blocks/airweave'
@@ -217,6 +218,7 @@ import type { BlockConfig } from '@/blocks/types'
export const registry: Record<string, BlockConfig> = {
a2a: A2ABlock,
agent: AgentBlock,
agentmail: AgentMailBlock,
ahrefs: AhrefsBlock,
airtable: AirtableBlock,
airweave: AirweaveBlock,

View File

@@ -1,6 +1,33 @@
import type { SVGProps } from 'react'
import { useId } from 'react'
export function AgentMailIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg {...props} viewBox='0 0 350 363' fill='none' xmlns='http://www.w3.org/2000/svg'>
<path
d='M318.029 88.3407C196.474 115.33 153.48 115.321 33.9244 88.3271C30.6216 87.5814 27.1432 88.9727 25.3284 91.8313L1.24109 129.774C-1.76483 134.509 0.965276 140.798 6.46483 141.898C152.613 171.13 197.678 171.182 343.903 141.835C349.304 140.751 352.064 134.641 349.247 129.907L326.719 92.0479C324.95 89.0744 321.407 87.5907 318.029 88.3407Z'
fill='currentColor'
/>
<path
d='M75.9931 246.6L149.939 311.655C151.973 313.444 151.633 316.969 149.281 318.48L119.141 337.84C117.283 339.034 114.951 338.412 113.933 336.452L70.1276 252.036C68.0779 248.086 72.7553 243.751 75.9931 246.6Z'
fill='currentColor'
/>
<path
d='M274.025 246.6L200.08 311.655C198.046 313.444 198.385 316.969 200.737 318.48L230.877 337.84C232.736 339.034 235.068 338.412 236.085 336.452L279.891 252.036C281.941 248.086 277.263 243.751 274.025 246.6Z'
fill='currentColor'
/>
<path
d='M138.75 198.472L152.436 192.983C155.238 191.918 157.77 191.918 158.574 191.918C164.115 192.126 169.564 192.232 175.009 192.235C180.454 192.232 185.904 192.126 191.444 191.918C192.248 191.918 194.78 191.918 197.583 192.983L211.269 198.472C212.645 199.025 214.082 199.382 215.544 199.448C218.585 199.587 221.733 199.464 224.63 198.811C225.706 198.568 226.728 198.103 227.704 197.545L243.046 188.784C244.81 187.777 246.726 187.138 248.697 186.9L258.276 185.5H259.242H263.556L262.713 190.965L256.679 234.22C255.957 238.31 254.25 242.328 250.443 245.834L187.376 299.258C184.555 301.648 181.107 302.942 177.562 302.942H175.009H172.457C168.911 302.942 165.464 301.648 162.643 299.258L99.5761 245.834C95.7684 242.328 94.0614 238.31 93.3393 234.22L87.3059 190.965L86.4624 185.5H90.7771H91.7429L101.322 186.9C103.293 187.138 105.208 187.777 106.972 188.784L122.314 197.545C123.291 198.103 124.313 198.568 125.389 198.811C128.286 199.464 131.434 199.587 134.474 199.448C135.936 199.382 137.373 199.025 138.75 198.472Z'
fill='currentColor'
/>
<path
d='M102.47 0.847827C205.434 44.796 156.456 42.1015 248.434 1.63153C252.885 -1.09955 258.353 1.88915 259.419 7.69219L269.235 61.1686L270.819 69.7893L263.592 71.8231L263.582 71.8259C190.588 92.3069 165.244 92.0078 86.7576 71.7428L79.1971 69.7905L80.9925 60.8681L91.8401 6.91975C92.9559 1.3706 98.105 -1.55777 102.47 0.847827Z'
fill='currentColor'
/>
</svg>
)
}
export function SearchIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg

View File

@@ -0,0 +1,164 @@
import type { CreateDraftParams, CreateDraftResult } from '@/tools/agentmail/types'
import type { ToolConfig } from '@/tools/types'
export const agentmailCreateDraftTool: ToolConfig<CreateDraftParams, CreateDraftResult> = {
id: 'agentmail_create_draft',
name: 'Create Draft',
description: 'Create a new email draft in AgentMail',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AgentMail API key',
},
inboxId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the inbox to create the draft in',
},
to: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Recipient email addresses (comma-separated)',
},
subject: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Draft subject line',
},
text: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Plain text draft body',
},
html: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'HTML draft body',
},
cc: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'CC recipient email addresses (comma-separated)',
},
bcc: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'BCC recipient email addresses (comma-separated)',
},
inReplyTo: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'ID of message being replied to',
},
sendAt: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'ISO 8601 timestamp to schedule sending',
},
},
request: {
url: (params) => `https://api.agentmail.to/v0/inboxes/${params.inboxId.trim()}/drafts`,
method: 'POST',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
body: (params) => {
const body: Record<string, unknown> = {}
if (params.to) body.to = params.to.split(',').map((e) => e.trim())
if (params.subject) body.subject = params.subject
if (params.text) body.text = params.text
if (params.html) body.html = params.html
if (params.cc) body.cc = params.cc.split(',').map((e) => e.trim())
if (params.bcc) body.bcc = params.bcc.split(',').map((e) => e.trim())
if (params.inReplyTo) body.in_reply_to = params.inReplyTo
if (params.sendAt) body.send_at = params.sendAt
return body
},
},
transformResponse: async (response): Promise<CreateDraftResult> => {
const data = await response.json()
if (!response.ok) {
return {
success: false,
error: data.message ?? 'Failed to create draft',
output: {
draftId: '',
inboxId: '',
subject: null,
to: [],
cc: [],
bcc: [],
text: null,
html: null,
preview: null,
labels: [],
inReplyTo: null,
sendStatus: null,
sendAt: null,
createdAt: '',
updatedAt: '',
},
}
}
return {
success: true,
output: {
draftId: data.draft_id ?? '',
inboxId: data.inbox_id ?? '',
subject: data.subject ?? null,
to: data.to ?? [],
cc: data.cc ?? [],
bcc: data.bcc ?? [],
text: data.text ?? null,
html: data.html ?? null,
preview: data.preview ?? null,
labels: data.labels ?? [],
inReplyTo: data.in_reply_to ?? null,
sendStatus: data.send_status ?? null,
sendAt: data.send_at ?? null,
createdAt: data.created_at ?? '',
updatedAt: data.updated_at ?? '',
},
}
},
outputs: {
draftId: { type: 'string', description: 'Unique identifier for the draft' },
inboxId: { type: 'string', description: 'Inbox the draft belongs to' },
subject: { type: 'string', description: 'Draft subject', optional: true },
to: { type: 'array', description: 'Recipient email addresses' },
cc: { type: 'array', description: 'CC email addresses' },
bcc: { type: 'array', description: 'BCC email addresses' },
text: { type: 'string', description: 'Plain text content', optional: true },
html: { type: 'string', description: 'HTML content', optional: true },
preview: { type: 'string', description: 'Draft preview text', optional: true },
labels: { type: 'array', description: 'Labels assigned to the draft' },
inReplyTo: { type: 'string', description: 'Message ID this draft replies to', optional: true },
sendStatus: {
type: 'string',
description: 'Send status (scheduled, sending, failed)',
optional: true,
},
sendAt: { type: 'string', description: 'Scheduled send time', optional: true },
createdAt: { type: 'string', description: 'Creation timestamp' },
updatedAt: { type: 'string', description: 'Last updated timestamp' },
},
}

View File

@@ -0,0 +1,87 @@
import type { CreateInboxParams, CreateInboxResult } from '@/tools/agentmail/types'
import type { ToolConfig } from '@/tools/types'
export const agentmailCreateInboxTool: ToolConfig<CreateInboxParams, CreateInboxResult> = {
id: 'agentmail_create_inbox',
name: 'Create Inbox',
description: 'Create a new email inbox with AgentMail',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AgentMail API key',
},
username: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Username for the inbox email address',
},
domain: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Domain for the inbox email address',
},
displayName: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Display name for the inbox',
},
},
request: {
url: 'https://api.agentmail.to/v0/inboxes',
method: 'POST',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
body: (params) => ({
...(params.username && { username: params.username }),
...(params.domain && { domain: params.domain }),
...(params.displayName && { display_name: params.displayName }),
}),
},
transformResponse: async (response): Promise<CreateInboxResult> => {
const data = await response.json()
if (!response.ok) {
return {
success: false,
error: data.message ?? 'Failed to create inbox',
output: {
inboxId: '',
email: '',
displayName: null,
createdAt: '',
updatedAt: '',
},
}
}
return {
success: true,
output: {
inboxId: data.inbox_id ?? '',
email: data.email ?? '',
displayName: data.display_name ?? null,
createdAt: data.created_at ?? '',
updatedAt: data.updated_at ?? '',
},
}
},
outputs: {
inboxId: { type: 'string', description: 'Unique identifier for the inbox' },
email: { type: 'string', description: 'Email address of the inbox' },
displayName: { type: 'string', description: 'Display name of the inbox', optional: true },
createdAt: { type: 'string', description: 'Creation timestamp' },
updatedAt: { type: 'string', description: 'Last updated timestamp' },
},
}

View File

@@ -0,0 +1,59 @@
import type { DeleteDraftParams, DeleteDraftResult } from '@/tools/agentmail/types'
import type { ToolConfig } from '@/tools/types'
export const agentmailDeleteDraftTool: ToolConfig<DeleteDraftParams, DeleteDraftResult> = {
id: 'agentmail_delete_draft',
name: 'Delete Draft',
description: 'Delete an email draft in AgentMail',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AgentMail API key',
},
inboxId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the inbox containing the draft',
},
draftId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the draft to delete',
},
},
request: {
url: (params) =>
`https://api.agentmail.to/v0/inboxes/${params.inboxId.trim()}/drafts/${params.draftId.trim()}`,
method: 'DELETE',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
}),
},
transformResponse: async (response): Promise<DeleteDraftResult> => {
if (!response.ok) {
const data = await response.json()
return {
success: false,
error: data.message ?? 'Failed to delete draft',
output: { deleted: false },
}
}
return {
success: true,
output: { deleted: true },
}
},
outputs: {
deleted: { type: 'boolean', description: 'Whether the draft was successfully deleted' },
},
}

View File

@@ -0,0 +1,52 @@
import type { DeleteInboxParams, DeleteInboxResult } from '@/tools/agentmail/types'
import type { ToolConfig } from '@/tools/types'
export const agentmailDeleteInboxTool: ToolConfig<DeleteInboxParams, DeleteInboxResult> = {
id: 'agentmail_delete_inbox',
name: 'Delete Inbox',
description: 'Delete an email inbox in AgentMail',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AgentMail API key',
},
inboxId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the inbox to delete',
},
},
request: {
url: (params) => `https://api.agentmail.to/v0/inboxes/${params.inboxId.trim()}`,
method: 'DELETE',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
}),
},
transformResponse: async (response): Promise<DeleteInboxResult> => {
if (!response.ok) {
const data = await response.json()
return {
success: false,
error: data.message ?? 'Failed to delete inbox',
output: { deleted: false },
}
}
return {
success: true,
output: { deleted: true },
}
},
outputs: {
deleted: { type: 'boolean', description: 'Whether the inbox was successfully deleted' },
},
}

View File

@@ -0,0 +1,70 @@
import type { DeleteThreadParams, DeleteThreadResult } from '@/tools/agentmail/types'
import type { ToolConfig } from '@/tools/types'
export const agentmailDeleteThreadTool: ToolConfig<DeleteThreadParams, DeleteThreadResult> = {
id: 'agentmail_delete_thread',
name: 'Delete Thread',
description:
'Delete an email thread in AgentMail (moves to trash, or permanently deletes if already in trash)',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AgentMail API key',
},
inboxId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the inbox containing the thread',
},
threadId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the thread to delete',
},
permanent: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Force permanent deletion instead of moving to trash',
},
},
request: {
url: (params) => {
const query = new URLSearchParams()
if (params.permanent) query.set('permanent', 'true')
const qs = query.toString()
return `https://api.agentmail.to/v0/inboxes/${params.inboxId.trim()}/threads/${params.threadId.trim()}${qs ? `?${qs}` : ''}`
},
method: 'DELETE',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
}),
},
transformResponse: async (response): Promise<DeleteThreadResult> => {
if (!response.ok) {
const data = await response.json()
return {
success: false,
error: data.message ?? 'Failed to delete thread',
output: { deleted: false },
}
}
return {
success: true,
output: { deleted: true },
}
},
outputs: {
deleted: { type: 'boolean', description: 'Whether the thread was successfully deleted' },
},
}

View File

@@ -0,0 +1,112 @@
import type { ForwardMessageParams, ForwardMessageResult } from '@/tools/agentmail/types'
import type { ToolConfig } from '@/tools/types'
export const agentmailForwardMessageTool: ToolConfig<ForwardMessageParams, ForwardMessageResult> = {
id: 'agentmail_forward_message',
name: 'Forward Message',
description: 'Forward an email message to new recipients in AgentMail',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AgentMail API key',
},
inboxId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the inbox containing the message',
},
messageId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the message to forward',
},
to: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Recipient email addresses (comma-separated)',
},
subject: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Override subject line',
},
text: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Additional plain text to prepend',
},
html: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Additional HTML to prepend',
},
cc: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'CC recipient email addresses (comma-separated)',
},
bcc: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'BCC recipient email addresses (comma-separated)',
},
},
request: {
url: (params) =>
`https://api.agentmail.to/v0/inboxes/${params.inboxId.trim()}/messages/${params.messageId.trim()}/forward`,
method: 'POST',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
body: (params) => {
const body: Record<string, unknown> = {
to: params.to.split(',').map((e) => e.trim()),
}
if (params.subject) body.subject = params.subject
if (params.text) body.text = params.text
if (params.html) body.html = params.html
if (params.cc) body.cc = params.cc.split(',').map((e) => e.trim())
if (params.bcc) body.bcc = params.bcc.split(',').map((e) => e.trim())
return body
},
},
transformResponse: async (response): Promise<ForwardMessageResult> => {
const data = await response.json()
if (!response.ok) {
return {
success: false,
error: data.message ?? 'Failed to forward message',
output: { messageId: '', threadId: '' },
}
}
return {
success: true,
output: {
messageId: data.message_id ?? '',
threadId: data.thread_id ?? '',
},
}
},
outputs: {
messageId: { type: 'string', description: 'ID of the forwarded message' },
threadId: { type: 'string', description: 'ID of the thread' },
},
}

View File

@@ -0,0 +1,110 @@
import type { GetDraftParams, GetDraftResult } from '@/tools/agentmail/types'
import type { ToolConfig } from '@/tools/types'
export const agentmailGetDraftTool: ToolConfig<GetDraftParams, GetDraftResult> = {
id: 'agentmail_get_draft',
name: 'Get Draft',
description: 'Get details of a specific email draft in AgentMail',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AgentMail API key',
},
inboxId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the inbox the draft belongs to',
},
draftId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the draft to retrieve',
},
},
request: {
url: (params) =>
`https://api.agentmail.to/v0/inboxes/${params.inboxId.trim()}/drafts/${params.draftId.trim()}`,
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
}),
},
transformResponse: async (response): Promise<GetDraftResult> => {
const data = await response.json()
if (!response.ok) {
return {
success: false,
error: data.message ?? 'Failed to get draft',
output: {
draftId: '',
inboxId: '',
subject: null,
to: [],
cc: [],
bcc: [],
text: null,
html: null,
preview: null,
labels: [],
inReplyTo: null,
sendStatus: null,
sendAt: null,
createdAt: '',
updatedAt: '',
},
}
}
return {
success: true,
output: {
draftId: data.draft_id ?? '',
inboxId: data.inbox_id ?? '',
subject: data.subject ?? null,
to: data.to ?? [],
cc: data.cc ?? [],
bcc: data.bcc ?? [],
text: data.text ?? null,
html: data.html ?? null,
preview: data.preview ?? null,
labels: data.labels ?? [],
inReplyTo: data.in_reply_to ?? null,
sendStatus: data.send_status ?? null,
sendAt: data.send_at ?? null,
createdAt: data.created_at ?? '',
updatedAt: data.updated_at ?? '',
},
}
},
outputs: {
draftId: { type: 'string', description: 'Unique identifier for the draft' },
inboxId: { type: 'string', description: 'Inbox the draft belongs to' },
subject: { type: 'string', description: 'Draft subject', optional: true },
to: { type: 'array', description: 'Recipient email addresses' },
cc: { type: 'array', description: 'CC email addresses' },
bcc: { type: 'array', description: 'BCC email addresses' },
text: { type: 'string', description: 'Plain text content', optional: true },
html: { type: 'string', description: 'HTML content', optional: true },
preview: { type: 'string', description: 'Draft preview text', optional: true },
labels: { type: 'array', description: 'Labels assigned to the draft' },
inReplyTo: { type: 'string', description: 'Message ID this draft replies to', optional: true },
sendStatus: {
type: 'string',
description: 'Send status (scheduled, sending, failed)',
optional: true,
},
sendAt: { type: 'string', description: 'Scheduled send time', optional: true },
createdAt: { type: 'string', description: 'Creation timestamp' },
updatedAt: { type: 'string', description: 'Last updated timestamp' },
},
}

View File

@@ -0,0 +1,69 @@
import type { GetInboxParams, GetInboxResult } from '@/tools/agentmail/types'
import type { ToolConfig } from '@/tools/types'
export const agentmailGetInboxTool: ToolConfig<GetInboxParams, GetInboxResult> = {
id: 'agentmail_get_inbox',
name: 'Get Inbox',
description: 'Get details of a specific email inbox in AgentMail',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AgentMail API key',
},
inboxId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the inbox to retrieve',
},
},
request: {
url: (params) => `https://api.agentmail.to/v0/inboxes/${params.inboxId.trim()}`,
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
}),
},
transformResponse: async (response): Promise<GetInboxResult> => {
const data = await response.json()
if (!response.ok) {
return {
success: false,
error: data.message ?? 'Failed to get inbox',
output: {
inboxId: '',
email: '',
displayName: null,
createdAt: '',
updatedAt: '',
},
}
}
return {
success: true,
output: {
inboxId: data.inbox_id ?? '',
email: data.email ?? '',
displayName: data.display_name ?? null,
createdAt: data.created_at ?? '',
updatedAt: data.updated_at ?? '',
},
}
},
outputs: {
inboxId: { type: 'string', description: 'Unique identifier for the inbox' },
email: { type: 'string', description: 'Email address of the inbox' },
displayName: { type: 'string', description: 'Display name of the inbox', optional: true },
createdAt: { type: 'string', description: 'Creation timestamp' },
updatedAt: { type: 'string', description: 'Last updated timestamp' },
},
}

View File

@@ -0,0 +1,91 @@
import type { GetMessageParams, GetMessageResult } from '@/tools/agentmail/types'
import type { ToolConfig } from '@/tools/types'
export const agentmailGetMessageTool: ToolConfig<GetMessageParams, GetMessageResult> = {
id: 'agentmail_get_message',
name: 'Get Message',
description: 'Get details of a specific email message in AgentMail',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AgentMail API key',
},
inboxId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the inbox containing the message',
},
messageId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the message to retrieve',
},
},
request: {
url: (params) =>
`https://api.agentmail.to/v0/inboxes/${params.inboxId.trim()}/messages/${params.messageId.trim()}`,
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
}),
},
transformResponse: async (response): Promise<GetMessageResult> => {
const data = await response.json()
if (!response.ok) {
return {
success: false,
error: data.message ?? 'Failed to get message',
output: {
messageId: '',
threadId: '',
from: null,
to: [],
cc: [],
bcc: [],
subject: null,
text: null,
html: null,
createdAt: '',
},
}
}
return {
success: true,
output: {
messageId: data.message_id ?? '',
threadId: data.thread_id ?? '',
from: data.from ?? null,
to: data.to ?? [],
cc: data.cc ?? [],
bcc: data.bcc ?? [],
subject: data.subject ?? null,
text: data.text ?? null,
html: data.html ?? null,
createdAt: data.created_at ?? '',
},
}
},
outputs: {
messageId: { type: 'string', description: 'Unique identifier for the message' },
threadId: { type: 'string', description: 'ID of the thread this message belongs to' },
from: { type: 'string', description: 'Sender email address', optional: true },
to: { type: 'array', description: 'Recipient email addresses' },
cc: { type: 'array', description: 'CC email addresses' },
bcc: { type: 'array', description: 'BCC email addresses' },
subject: { type: 'string', description: 'Message subject', optional: true },
text: { type: 'string', description: 'Plain text content', optional: true },
html: { type: 'string', description: 'HTML content', optional: true },
createdAt: { type: 'string', description: 'Creation timestamp' },
},
}

View File

@@ -0,0 +1,118 @@
import type { GetThreadParams, GetThreadResult } from '@/tools/agentmail/types'
import type { ToolConfig } from '@/tools/types'
export const agentmailGetThreadTool: ToolConfig<GetThreadParams, GetThreadResult> = {
id: 'agentmail_get_thread',
name: 'Get Thread',
description: 'Get details of a specific email thread including messages in AgentMail',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AgentMail API key',
},
inboxId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the inbox containing the thread',
},
threadId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the thread to retrieve',
},
},
request: {
url: (params) =>
`https://api.agentmail.to/v0/inboxes/${params.inboxId.trim()}/threads/${params.threadId.trim()}`,
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
}),
},
transformResponse: async (response): Promise<GetThreadResult> => {
const data = await response.json()
if (!response.ok) {
return {
success: false,
error: data.message ?? 'Failed to get thread',
output: {
threadId: '',
subject: null,
senders: [],
recipients: [],
messageCount: 0,
labels: [],
lastMessageAt: null,
createdAt: '',
updatedAt: '',
messages: [],
},
}
}
return {
success: true,
output: {
threadId: data.thread_id ?? '',
subject: data.subject ?? null,
senders: data.senders ?? [],
recipients: data.recipients ?? [],
messageCount: data.message_count ?? 0,
labels: data.labels ?? [],
lastMessageAt: data.timestamp ?? null,
createdAt: data.created_at ?? '',
updatedAt: data.updated_at ?? '',
messages: (data.messages ?? []).map((msg: Record<string, unknown>) => ({
messageId: msg.message_id ?? '',
from: (msg.from as string) ?? null,
to: (msg.to as string[]) ?? [],
cc: (msg.cc as string[]) ?? [],
bcc: (msg.bcc as string[]) ?? [],
subject: (msg.subject as string) ?? null,
text: (msg.text as string) ?? null,
html: (msg.html as string) ?? null,
createdAt: (msg.created_at as string) ?? '',
})),
},
}
},
outputs: {
threadId: { type: 'string', description: 'Unique identifier for the thread' },
subject: { type: 'string', description: 'Thread subject', optional: true },
senders: { type: 'array', description: 'List of sender email addresses' },
recipients: { type: 'array', description: 'List of recipient email addresses' },
messageCount: { type: 'number', description: 'Number of messages in the thread' },
labels: { type: 'array', description: 'Labels assigned to the thread' },
lastMessageAt: { type: 'string', description: 'Timestamp of last message', optional: true },
createdAt: { type: 'string', description: 'Creation timestamp' },
updatedAt: { type: 'string', description: 'Last updated timestamp' },
messages: {
type: 'array',
description: 'Messages in the thread',
items: {
type: 'object',
properties: {
messageId: { type: 'string', description: 'Unique identifier for the message' },
from: { type: 'string', description: 'Sender email address', optional: true },
to: { type: 'array', description: 'Recipient email addresses' },
cc: { type: 'array', description: 'CC email addresses' },
bcc: { type: 'array', description: 'BCC email addresses' },
subject: { type: 'string', description: 'Message subject', optional: true },
text: { type: 'string', description: 'Plain text content', optional: true },
html: { type: 'string', description: 'HTML content', optional: true },
createdAt: { type: 'string', description: 'Creation timestamp' },
},
},
},
},
}

View File

@@ -0,0 +1,65 @@
export { agentmailCreateDraftTool } from '@/tools/agentmail/create_draft'
export { agentmailCreateInboxTool } from '@/tools/agentmail/create_inbox'
export { agentmailDeleteDraftTool } from '@/tools/agentmail/delete_draft'
export { agentmailDeleteInboxTool } from '@/tools/agentmail/delete_inbox'
export { agentmailDeleteThreadTool } from '@/tools/agentmail/delete_thread'
export { agentmailForwardMessageTool } from '@/tools/agentmail/forward_message'
export { agentmailGetDraftTool } from '@/tools/agentmail/get_draft'
export { agentmailGetInboxTool } from '@/tools/agentmail/get_inbox'
export { agentmailGetMessageTool } from '@/tools/agentmail/get_message'
export { agentmailGetThreadTool } from '@/tools/agentmail/get_thread'
export { agentmailListDraftsTool } from '@/tools/agentmail/list_drafts'
export { agentmailListInboxesTool } from '@/tools/agentmail/list_inboxes'
export { agentmailListMessagesTool } from '@/tools/agentmail/list_messages'
export { agentmailListThreadsTool } from '@/tools/agentmail/list_threads'
export { agentmailReplyMessageTool } from '@/tools/agentmail/reply_message'
export { agentmailSendDraftTool } from '@/tools/agentmail/send_draft'
export { agentmailSendMessageTool } from '@/tools/agentmail/send_message'
export type {
CreateDraftParams,
CreateDraftResult,
CreateInboxParams,
CreateInboxResult,
DeleteDraftParams,
DeleteDraftResult,
DeleteInboxParams,
DeleteInboxResult,
DeleteThreadParams,
DeleteThreadResult,
ForwardMessageParams,
ForwardMessageResult,
GetDraftParams,
GetDraftResult,
GetInboxParams,
GetInboxResult,
GetMessageParams,
GetMessageResult,
GetThreadParams,
GetThreadResult,
ListDraftsParams,
ListDraftsResult,
ListInboxesParams,
ListInboxesResult,
ListMessagesParams,
ListMessagesResult,
ListThreadsParams,
ListThreadsResult,
ReplyMessageParams,
ReplyMessageResult,
SendDraftParams,
SendDraftResult,
SendMessageParams,
SendMessageResult,
UpdateDraftParams,
UpdateDraftResult,
UpdateInboxParams,
UpdateInboxResult,
UpdateMessageParams,
UpdateMessageResult,
UpdateThreadParams,
UpdateThreadResult,
} from '@/tools/agentmail/types'
export { agentmailUpdateDraftTool } from '@/tools/agentmail/update_draft'
export { agentmailUpdateInboxTool } from '@/tools/agentmail/update_inbox'
export { agentmailUpdateMessageTool } from '@/tools/agentmail/update_message'
export { agentmailUpdateThreadTool } from '@/tools/agentmail/update_thread'

View File

@@ -0,0 +1,116 @@
import type { ListDraftsParams, ListDraftsResult } from '@/tools/agentmail/types'
import type { ToolConfig } from '@/tools/types'
export const agentmailListDraftsTool: ToolConfig<ListDraftsParams, ListDraftsResult> = {
id: 'agentmail_list_drafts',
name: 'List Drafts',
description: 'List email drafts in an inbox in AgentMail',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AgentMail API key',
},
inboxId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the inbox to list drafts from',
},
limit: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of drafts to return',
},
pageToken: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Pagination token for next page of results',
},
},
request: {
url: (params) => {
const query = new URLSearchParams()
if (params.limit) query.set('limit', String(params.limit))
if (params.pageToken) query.set('page_token', params.pageToken)
const qs = query.toString()
return `https://api.agentmail.to/v0/inboxes/${params.inboxId.trim()}/drafts${qs ? `?${qs}` : ''}`
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
}),
},
transformResponse: async (response): Promise<ListDraftsResult> => {
const data = await response.json()
if (!response.ok) {
return {
success: false,
error: data.message ?? 'Failed to list drafts',
output: { drafts: [], count: 0, nextPageToken: null },
}
}
return {
success: true,
output: {
drafts: (data.drafts ?? []).map((draft: Record<string, unknown>) => ({
draftId: draft.draft_id ?? '',
inboxId: draft.inbox_id ?? '',
subject: (draft.subject as string) ?? null,
to: (draft.to as string[]) ?? [],
cc: (draft.cc as string[]) ?? [],
bcc: (draft.bcc as string[]) ?? [],
preview: (draft.preview as string) ?? null,
sendStatus: (draft.send_status as string) ?? null,
sendAt: (draft.send_at as string) ?? null,
createdAt: (draft.created_at as string) ?? '',
updatedAt: (draft.updated_at as string) ?? '',
})),
count: data.count ?? 0,
nextPageToken: data.next_page_token ?? null,
},
}
},
outputs: {
drafts: {
type: 'array',
description: 'List of drafts',
items: {
type: 'object',
properties: {
draftId: { type: 'string', description: 'Unique identifier for the draft' },
inboxId: { type: 'string', description: 'Inbox the draft belongs to' },
subject: { type: 'string', description: 'Draft subject', optional: true },
to: { type: 'array', description: 'Recipient email addresses' },
cc: { type: 'array', description: 'CC email addresses' },
bcc: { type: 'array', description: 'BCC email addresses' },
preview: { type: 'string', description: 'Draft preview text', optional: true },
sendStatus: {
type: 'string',
description: 'Send status (scheduled, sending, failed)',
optional: true,
},
sendAt: { type: 'string', description: 'Scheduled send time', optional: true },
createdAt: { type: 'string', description: 'Creation timestamp' },
updatedAt: { type: 'string', description: 'Last updated timestamp' },
},
},
},
count: { type: 'number', description: 'Total number of drafts' },
nextPageToken: {
type: 'string',
description: 'Token for retrieving the next page',
optional: true,
},
},
}

View File

@@ -0,0 +1,98 @@
import type { ListInboxesParams, ListInboxesResult } from '@/tools/agentmail/types'
import type { ToolConfig } from '@/tools/types'
export const agentmailListInboxesTool: ToolConfig<ListInboxesParams, ListInboxesResult> = {
id: 'agentmail_list_inboxes',
name: 'List Inboxes',
description: 'List all email inboxes in AgentMail',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AgentMail API key',
},
limit: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of inboxes to return',
},
pageToken: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Pagination token for next page of results',
},
},
request: {
url: (params) => {
const query = new URLSearchParams()
if (params.limit) query.set('limit', String(params.limit))
if (params.pageToken) query.set('page_token', params.pageToken)
const qs = query.toString()
return `https://api.agentmail.to/v0/inboxes${qs ? `?${qs}` : ''}`
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
}),
},
transformResponse: async (response): Promise<ListInboxesResult> => {
const data = await response.json()
if (!response.ok) {
return {
success: false,
error: data.message ?? 'Failed to list inboxes',
output: { inboxes: [], count: 0, nextPageToken: null },
}
}
return {
success: true,
output: {
inboxes: (data.inboxes ?? []).map((inbox: Record<string, unknown>) => ({
inboxId: inbox.inbox_id ?? '',
email: inbox.email ?? '',
displayName: inbox.display_name ?? null,
createdAt: inbox.created_at ?? '',
updatedAt: inbox.updated_at ?? '',
})),
count: data.count ?? 0,
nextPageToken: data.next_page_token ?? null,
},
}
},
outputs: {
inboxes: {
type: 'array',
description: 'List of inboxes',
items: {
type: 'object',
properties: {
inboxId: { type: 'string', description: 'Unique identifier for the inbox' },
email: { type: 'string', description: 'Email address of the inbox' },
displayName: {
type: 'string',
description: 'Display name of the inbox',
optional: true,
},
createdAt: { type: 'string', description: 'Creation timestamp' },
updatedAt: { type: 'string', description: 'Last updated timestamp' },
},
},
},
count: { type: 'number', description: 'Total number of inboxes' },
nextPageToken: {
type: 'string',
description: 'Token for retrieving the next page',
optional: true,
},
},
}

View File

@@ -0,0 +1,102 @@
import type { ListMessagesParams, ListMessagesResult } from '@/tools/agentmail/types'
import type { ToolConfig } from '@/tools/types'
export const agentmailListMessagesTool: ToolConfig<ListMessagesParams, ListMessagesResult> = {
id: 'agentmail_list_messages',
name: 'List Messages',
description: 'List messages in an inbox in AgentMail',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AgentMail API key',
},
inboxId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the inbox to list messages from',
},
limit: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of messages to return',
},
pageToken: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Pagination token for next page of results',
},
},
request: {
url: (params) => {
const query = new URLSearchParams()
if (params.limit) query.set('limit', String(params.limit))
if (params.pageToken) query.set('page_token', params.pageToken)
const qs = query.toString()
return `https://api.agentmail.to/v0/inboxes/${params.inboxId.trim()}/messages${qs ? `?${qs}` : ''}`
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
}),
},
transformResponse: async (response): Promise<ListMessagesResult> => {
const data = await response.json()
if (!response.ok) {
return {
success: false,
error: data.message ?? 'Failed to list messages',
output: { messages: [], count: 0, nextPageToken: null },
}
}
return {
success: true,
output: {
messages: (data.messages ?? []).map((msg: Record<string, unknown>) => ({
messageId: msg.message_id ?? '',
from: (msg.from as string) ?? null,
to: (msg.to as string[]) ?? [],
subject: (msg.subject as string) ?? null,
preview: (msg.preview as string) ?? null,
createdAt: (msg.created_at as string) ?? '',
})),
count: data.count ?? 0,
nextPageToken: data.next_page_token ?? null,
},
}
},
outputs: {
messages: {
type: 'array',
description: 'List of messages in the inbox',
items: {
type: 'object',
properties: {
messageId: { type: 'string', description: 'Unique identifier for the message' },
from: { type: 'string', description: 'Sender email address', optional: true },
to: { type: 'array', description: 'Recipient email addresses' },
subject: { type: 'string', description: 'Message subject', optional: true },
preview: { type: 'string', description: 'Message preview text', optional: true },
createdAt: { type: 'string', description: 'Creation timestamp' },
},
},
},
count: { type: 'number', description: 'Total number of messages' },
nextPageToken: {
type: 'string',
description: 'Token for retrieving the next page',
optional: true,
},
},
}

View File

@@ -0,0 +1,135 @@
import type { ListThreadsParams, ListThreadsResult } from '@/tools/agentmail/types'
import type { ToolConfig } from '@/tools/types'
export const agentmailListThreadsTool: ToolConfig<ListThreadsParams, ListThreadsResult> = {
id: 'agentmail_list_threads',
name: 'List Threads',
description: 'List email threads in AgentMail',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AgentMail API key',
},
inboxId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the inbox to list threads from',
},
limit: {
type: 'number',
required: false,
visibility: 'user-or-llm',
description: 'Maximum number of threads to return',
},
pageToken: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Pagination token for next page of results',
},
labels: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated labels to filter threads by',
},
before: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter threads before this ISO 8601 timestamp',
},
after: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter threads after this ISO 8601 timestamp',
},
},
request: {
url: (params) => {
const query = new URLSearchParams()
if (params.limit) query.set('limit', String(params.limit))
if (params.pageToken) query.set('page_token', params.pageToken)
if (params.labels) {
for (const label of params.labels.split(',')) {
query.append('labels', label.trim())
}
}
if (params.before) query.set('before', params.before)
if (params.after) query.set('after', params.after)
const qs = query.toString()
return `https://api.agentmail.to/v0/inboxes/${params.inboxId.trim()}/threads${qs ? `?${qs}` : ''}`
},
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
}),
},
transformResponse: async (response): Promise<ListThreadsResult> => {
const data = await response.json()
if (!response.ok) {
return {
success: false,
error: data.message ?? 'Failed to list threads',
output: { threads: [], count: 0, nextPageToken: null },
}
}
return {
success: true,
output: {
threads: (data.threads ?? []).map((thread: Record<string, unknown>) => ({
threadId: thread.thread_id ?? '',
subject: (thread.subject as string) ?? null,
senders: (thread.senders as string[]) ?? [],
recipients: (thread.recipients as string[]) ?? [],
messageCount: (thread.message_count as number) ?? 0,
lastMessageAt: (thread.timestamp as string) ?? null,
createdAt: (thread.created_at as string) ?? '',
updatedAt: (thread.updated_at as string) ?? '',
})),
count: data.count ?? 0,
nextPageToken: data.next_page_token ?? null,
},
}
},
outputs: {
threads: {
type: 'array',
description: 'List of email threads',
items: {
type: 'object',
properties: {
threadId: { type: 'string', description: 'Unique identifier for the thread' },
subject: { type: 'string', description: 'Thread subject', optional: true },
senders: { type: 'array', description: 'List of sender email addresses' },
recipients: { type: 'array', description: 'List of recipient email addresses' },
messageCount: { type: 'number', description: 'Number of messages in the thread' },
lastMessageAt: {
type: 'string',
description: 'Timestamp of last message',
optional: true,
},
createdAt: { type: 'string', description: 'Creation timestamp' },
updatedAt: { type: 'string', description: 'Last updated timestamp' },
},
},
},
count: { type: 'number', description: 'Total number of threads' },
nextPageToken: {
type: 'string',
description: 'Token for retrieving the next page',
optional: true,
},
},
}

View File

@@ -0,0 +1,115 @@
import type { ReplyMessageParams, ReplyMessageResult } from '@/tools/agentmail/types'
import type { ToolConfig } from '@/tools/types'
export const agentmailReplyMessageTool: ToolConfig<ReplyMessageParams, ReplyMessageResult> = {
id: 'agentmail_reply_message',
name: 'Reply to Message',
description: 'Reply to an existing email message in AgentMail',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AgentMail API key',
},
inboxId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the inbox to reply from',
},
messageId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the message to reply to',
},
text: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Plain text reply body',
},
html: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'HTML reply body',
},
to: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Override recipient email addresses (comma-separated)',
},
cc: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'CC email addresses (comma-separated)',
},
bcc: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'BCC email addresses (comma-separated)',
},
replyAll: {
type: 'boolean',
required: false,
visibility: 'user-or-llm',
description: 'Reply to all recipients of the original message',
},
},
request: {
url: (params) => {
const endpoint = params.replyAll ? 'reply-all' : 'reply'
return `https://api.agentmail.to/v0/inboxes/${params.inboxId.trim()}/messages/${params.messageId.trim()}/${endpoint}`
},
method: 'POST',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
body: (params) => {
const body: Record<string, unknown> = {}
if (params.text) body.text = params.text
if (params.html) body.html = params.html
// /reply-all endpoint auto-determines recipients; only /reply accepts to/cc/bcc
if (!params.replyAll) {
if (params.to) body.to = params.to.split(',').map((e) => e.trim())
if (params.cc) body.cc = params.cc.split(',').map((e) => e.trim())
if (params.bcc) body.bcc = params.bcc.split(',').map((e) => e.trim())
}
return body
},
},
transformResponse: async (response): Promise<ReplyMessageResult> => {
const data = await response.json()
if (!response.ok) {
return {
success: false,
error: data.message ?? 'Failed to reply to message',
output: { messageId: '', threadId: '' },
}
}
return {
success: true,
output: {
messageId: data.message_id ?? '',
threadId: data.thread_id ?? '',
},
}
},
outputs: {
messageId: { type: 'string', description: 'ID of the sent reply message' },
threadId: { type: 'string', description: 'ID of the thread' },
},
}

View File

@@ -0,0 +1,66 @@
import type { SendDraftParams, SendDraftResult } from '@/tools/agentmail/types'
import type { ToolConfig } from '@/tools/types'
export const agentmailSendDraftTool: ToolConfig<SendDraftParams, SendDraftResult> = {
id: 'agentmail_send_draft',
name: 'Send Draft',
description: 'Send an existing email draft in AgentMail',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AgentMail API key',
},
inboxId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the inbox containing the draft',
},
draftId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the draft to send',
},
},
request: {
url: (params) =>
`https://api.agentmail.to/v0/inboxes/${params.inboxId.trim()}/drafts/${params.draftId.trim()}/send`,
method: 'POST',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
body: () => ({}),
},
transformResponse: async (response): Promise<SendDraftResult> => {
const data = await response.json()
if (!response.ok) {
return {
success: false,
error: data.message ?? 'Failed to send draft',
output: { messageId: '', threadId: '' },
}
}
return {
success: true,
output: {
messageId: data.message_id ?? '',
threadId: data.thread_id ?? '',
},
}
},
outputs: {
messageId: { type: 'string', description: 'ID of the sent message' },
threadId: { type: 'string', description: 'ID of the thread' },
},
}

View File

@@ -0,0 +1,114 @@
import type { SendMessageParams, SendMessageResult } from '@/tools/agentmail/types'
import type { ToolConfig } from '@/tools/types'
export const agentmailSendMessageTool: ToolConfig<SendMessageParams, SendMessageResult> = {
id: 'agentmail_send_message',
name: 'Send Message',
description: 'Send an email message from an AgentMail inbox',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AgentMail API key',
},
inboxId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the inbox to send from',
},
to: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Recipient email address (comma-separated for multiple)',
},
subject: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Email subject line',
},
text: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Plain text email body',
},
html: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'HTML email body',
},
cc: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'CC recipient email addresses (comma-separated)',
},
bcc: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'BCC recipient email addresses (comma-separated)',
},
},
request: {
url: (params) => `https://api.agentmail.to/v0/inboxes/${params.inboxId.trim()}/messages/send`,
method: 'POST',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
body: (params) => {
const body: Record<string, unknown> = {
to: params.to.split(',').map((e) => e.trim()),
subject: params.subject,
}
if (params.text) body.text = params.text
if (params.html) body.html = params.html
if (params.cc) body.cc = params.cc.split(',').map((e) => e.trim())
if (params.bcc) body.bcc = params.bcc.split(',').map((e) => e.trim())
return body
},
},
transformResponse: async (response, params): Promise<SendMessageResult> => {
const data = await response.json()
if (!response.ok) {
return {
success: false,
error: data.message ?? 'Failed to send message',
output: {
threadId: '',
messageId: '',
subject: '',
to: '',
},
}
}
return {
success: true,
output: {
threadId: data.thread_id ?? '',
messageId: data.message_id ?? '',
subject: params?.subject ?? '',
to: params?.to ?? '',
},
}
},
outputs: {
threadId: { type: 'string', description: 'ID of the created thread' },
messageId: { type: 'string', description: 'ID of the sent message' },
subject: { type: 'string', description: 'Email subject line' },
to: { type: 'string', description: 'Recipient email address' },
},
}

View File

@@ -0,0 +1,447 @@
import type { ToolResponse } from '@/tools/types'
/** Create Inbox */
export interface CreateInboxParams {
apiKey: string
username?: string
domain?: string
displayName?: string
}
export interface CreateInboxResult extends ToolResponse {
output: {
inboxId: string
email: string
displayName: string | null
createdAt: string
updatedAt: string
}
}
/** List Inboxes */
export interface ListInboxesParams {
apiKey: string
limit?: number
pageToken?: string
}
export interface ListInboxesResult extends ToolResponse {
output: {
inboxes: Array<{
inboxId: string
email: string
displayName: string | null
createdAt: string
updatedAt: string
}>
count: number
nextPageToken: string | null
}
}
/** Get Inbox */
export interface GetInboxParams {
apiKey: string
inboxId: string
}
export interface GetInboxResult extends ToolResponse {
output: {
inboxId: string
email: string
displayName: string | null
createdAt: string
updatedAt: string
}
}
/** Update Inbox */
export interface UpdateInboxParams {
apiKey: string
inboxId: string
displayName: string
}
export interface UpdateInboxResult extends ToolResponse {
output: {
inboxId: string
email: string
displayName: string | null
createdAt: string
updatedAt: string
}
}
/** Delete Inbox */
export interface DeleteInboxParams {
apiKey: string
inboxId: string
}
export interface DeleteInboxResult extends ToolResponse {
output: {
deleted: boolean
}
}
/** Send Message (Create Thread) */
export interface SendMessageParams {
apiKey: string
inboxId: string
to: string
subject: string
text?: string
html?: string
cc?: string
bcc?: string
}
export interface SendMessageResult extends ToolResponse {
output: {
threadId: string
messageId: string
subject: string
to: string
}
}
/** Reply to Message */
export interface ReplyMessageParams {
apiKey: string
inboxId: string
messageId: string
text?: string
html?: string
to?: string
cc?: string
bcc?: string
replyAll?: boolean
}
export interface ReplyMessageResult extends ToolResponse {
output: {
messageId: string
threadId: string
}
}
/** Forward Message */
export interface ForwardMessageParams {
apiKey: string
inboxId: string
messageId: string
to: string
subject?: string
text?: string
html?: string
cc?: string
bcc?: string
}
export interface ForwardMessageResult extends ToolResponse {
output: {
messageId: string
threadId: string
}
}
/** Update Message Labels */
export interface UpdateMessageParams {
apiKey: string
inboxId: string
messageId: string
addLabels?: string
removeLabels?: string
}
export interface UpdateMessageResult extends ToolResponse {
output: {
messageId: string
labels: string[]
}
}
/** Create Draft */
export interface CreateDraftParams {
apiKey: string
inboxId: string
to?: string
subject?: string
text?: string
html?: string
cc?: string
bcc?: string
inReplyTo?: string
sendAt?: string
}
export interface CreateDraftResult extends ToolResponse {
output: {
draftId: string
inboxId: string
subject: string | null
to: string[]
cc: string[]
bcc: string[]
text: string | null
html: string | null
preview: string | null
labels: string[]
inReplyTo: string | null
sendStatus: string | null
sendAt: string | null
createdAt: string
updatedAt: string
}
}
/** Update Draft */
export interface UpdateDraftParams {
apiKey: string
inboxId: string
draftId: string
to?: string
subject?: string
text?: string
html?: string
cc?: string
bcc?: string
sendAt?: string
}
export interface UpdateDraftResult extends ToolResponse {
output: {
draftId: string
inboxId: string
subject: string | null
to: string[]
cc: string[]
bcc: string[]
text: string | null
html: string | null
preview: string | null
labels: string[]
inReplyTo: string | null
sendStatus: string | null
sendAt: string | null
createdAt: string
updatedAt: string
}
}
/** Delete Draft */
export interface DeleteDraftParams {
apiKey: string
inboxId: string
draftId: string
}
export interface DeleteDraftResult extends ToolResponse {
output: {
deleted: boolean
}
}
/** Send Draft */
export interface SendDraftParams {
apiKey: string
inboxId: string
draftId: string
}
export interface SendDraftResult extends ToolResponse {
output: {
messageId: string
threadId: string
}
}
/** List Drafts */
export interface ListDraftsParams {
apiKey: string
inboxId: string
limit?: number
pageToken?: string
}
export interface ListDraftsResult extends ToolResponse {
output: {
drafts: Array<{
draftId: string
inboxId: string
subject: string | null
to: string[]
cc: string[]
bcc: string[]
preview: string | null
sendStatus: string | null
sendAt: string | null
createdAt: string
updatedAt: string
}>
count: number
nextPageToken: string | null
}
}
/** Get Draft */
export interface GetDraftParams {
apiKey: string
inboxId: string
draftId: string
}
export interface GetDraftResult extends ToolResponse {
output: {
draftId: string
inboxId: string
subject: string | null
to: string[]
cc: string[]
bcc: string[]
text: string | null
html: string | null
preview: string | null
labels: string[]
inReplyTo: string | null
sendStatus: string | null
sendAt: string | null
createdAt: string
updatedAt: string
}
}
/** List Threads */
export interface ListThreadsParams {
apiKey: string
inboxId: string
limit?: number
pageToken?: string
labels?: string
before?: string
after?: string
}
export interface ListThreadsResult extends ToolResponse {
output: {
threads: Array<{
threadId: string
subject: string | null
senders: string[]
recipients: string[]
messageCount: number
lastMessageAt: string | null
createdAt: string
updatedAt: string
}>
count: number
nextPageToken: string | null
}
}
/** Get Thread */
export interface GetThreadParams {
apiKey: string
inboxId: string
threadId: string
}
export interface GetThreadResult extends ToolResponse {
output: {
threadId: string
subject: string | null
senders: string[]
recipients: string[]
messageCount: number
labels: string[]
lastMessageAt: string | null
createdAt: string
updatedAt: string
messages: Array<{
messageId: string
from: string | null
to: string[]
cc: string[]
bcc: string[]
subject: string | null
text: string | null
html: string | null
createdAt: string
}>
}
}
/** Update Thread Labels */
export interface UpdateThreadParams {
apiKey: string
inboxId: string
threadId: string
addLabels?: string
removeLabels?: string
}
export interface UpdateThreadResult extends ToolResponse {
output: {
threadId: string
labels: string[]
}
}
/** Delete Thread */
export interface DeleteThreadParams {
apiKey: string
inboxId: string
threadId: string
permanent?: boolean
}
export interface DeleteThreadResult extends ToolResponse {
output: {
deleted: boolean
}
}
/** List Messages */
export interface ListMessagesParams {
apiKey: string
inboxId: string
limit?: number
pageToken?: string
}
export interface ListMessagesResult extends ToolResponse {
output: {
messages: Array<{
messageId: string
from: string | null
to: string[]
subject: string | null
preview: string | null
createdAt: string
}>
count: number
nextPageToken: string | null
}
}
/** Get Message */
export interface GetMessageParams {
apiKey: string
inboxId: string
messageId: string
}
export interface GetMessageResult extends ToolResponse {
output: {
messageId: string
threadId: string
from: string | null
to: string[]
cc: string[]
bcc: string[]
subject: string | null
text: string | null
html: string | null
createdAt: string
}
}

View File

@@ -0,0 +1,164 @@
import type { UpdateDraftParams, UpdateDraftResult } from '@/tools/agentmail/types'
import type { ToolConfig } from '@/tools/types'
export const agentmailUpdateDraftTool: ToolConfig<UpdateDraftParams, UpdateDraftResult> = {
id: 'agentmail_update_draft',
name: 'Update Draft',
description: 'Update an existing email draft in AgentMail',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AgentMail API key',
},
inboxId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the inbox containing the draft',
},
draftId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the draft to update',
},
to: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Recipient email addresses (comma-separated)',
},
subject: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Draft subject line',
},
text: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Plain text draft body',
},
html: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'HTML draft body',
},
cc: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'CC recipient email addresses (comma-separated)',
},
bcc: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'BCC recipient email addresses (comma-separated)',
},
sendAt: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'ISO 8601 timestamp to schedule sending',
},
},
request: {
url: (params) =>
`https://api.agentmail.to/v0/inboxes/${params.inboxId.trim()}/drafts/${params.draftId.trim()}`,
method: 'PATCH',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
body: (params) => {
const body: Record<string, unknown> = {}
if (params.to) body.to = params.to.split(',').map((e) => e.trim())
if (params.subject) body.subject = params.subject
if (params.text) body.text = params.text
if (params.html) body.html = params.html
if (params.cc) body.cc = params.cc.split(',').map((e) => e.trim())
if (params.bcc) body.bcc = params.bcc.split(',').map((e) => e.trim())
if (params.sendAt) body.send_at = params.sendAt
return body
},
},
transformResponse: async (response): Promise<UpdateDraftResult> => {
const data = await response.json()
if (!response.ok) {
return {
success: false,
error: data.message ?? 'Failed to update draft',
output: {
draftId: '',
inboxId: '',
subject: null,
to: [],
cc: [],
bcc: [],
text: null,
html: null,
preview: null,
labels: [],
inReplyTo: null,
sendStatus: null,
sendAt: null,
createdAt: '',
updatedAt: '',
},
}
}
return {
success: true,
output: {
draftId: data.draft_id ?? '',
inboxId: data.inbox_id ?? '',
subject: data.subject ?? null,
to: data.to ?? [],
cc: data.cc ?? [],
bcc: data.bcc ?? [],
text: data.text ?? null,
html: data.html ?? null,
preview: data.preview ?? null,
labels: data.labels ?? [],
inReplyTo: data.in_reply_to ?? null,
sendStatus: data.send_status ?? null,
sendAt: data.send_at ?? null,
createdAt: data.created_at ?? '',
updatedAt: data.updated_at ?? '',
},
}
},
outputs: {
draftId: { type: 'string', description: 'Unique identifier for the draft' },
inboxId: { type: 'string', description: 'Inbox the draft belongs to' },
subject: { type: 'string', description: 'Draft subject', optional: true },
to: { type: 'array', description: 'Recipient email addresses' },
cc: { type: 'array', description: 'CC email addresses' },
bcc: { type: 'array', description: 'BCC email addresses' },
text: { type: 'string', description: 'Plain text content', optional: true },
html: { type: 'string', description: 'HTML content', optional: true },
preview: { type: 'string', description: 'Draft preview text', optional: true },
labels: { type: 'array', description: 'Labels assigned to the draft' },
inReplyTo: { type: 'string', description: 'Message ID this draft replies to', optional: true },
sendStatus: {
type: 'string',
description: 'Send status (scheduled, sending, failed)',
optional: true,
},
sendAt: { type: 'string', description: 'Scheduled send time', optional: true },
createdAt: { type: 'string', description: 'Creation timestamp' },
updatedAt: { type: 'string', description: 'Last updated timestamp' },
},
}

View File

@@ -0,0 +1,79 @@
import type { UpdateInboxParams, UpdateInboxResult } from '@/tools/agentmail/types'
import type { ToolConfig } from '@/tools/types'
export const agentmailUpdateInboxTool: ToolConfig<UpdateInboxParams, UpdateInboxResult> = {
id: 'agentmail_update_inbox',
name: 'Update Inbox',
description: 'Update the display name of an email inbox in AgentMail',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AgentMail API key',
},
inboxId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the inbox to update',
},
displayName: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'New display name for the inbox',
},
},
request: {
url: (params) => `https://api.agentmail.to/v0/inboxes/${params.inboxId.trim()}`,
method: 'PATCH',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
body: (params) => ({
display_name: params.displayName,
}),
},
transformResponse: async (response): Promise<UpdateInboxResult> => {
const data = await response.json()
if (!response.ok) {
return {
success: false,
error: data.message ?? 'Failed to update inbox',
output: {
inboxId: '',
email: '',
displayName: null,
createdAt: '',
updatedAt: '',
},
}
}
return {
success: true,
output: {
inboxId: data.inbox_id ?? '',
email: data.email ?? '',
displayName: data.display_name ?? null,
createdAt: data.created_at ?? '',
updatedAt: data.updated_at ?? '',
},
}
},
outputs: {
inboxId: { type: 'string', description: 'Unique identifier for the inbox' },
email: { type: 'string', description: 'Email address of the inbox' },
displayName: { type: 'string', description: 'Display name of the inbox', optional: true },
createdAt: { type: 'string', description: 'Creation timestamp' },
updatedAt: { type: 'string', description: 'Last updated timestamp' },
},
}

View File

@@ -0,0 +1,87 @@
import type { UpdateMessageParams, UpdateMessageResult } from '@/tools/agentmail/types'
import type { ToolConfig } from '@/tools/types'
export const agentmailUpdateMessageTool: ToolConfig<UpdateMessageParams, UpdateMessageResult> = {
id: 'agentmail_update_message',
name: 'Update Message',
description: 'Add or remove labels on an email message in AgentMail',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AgentMail API key',
},
inboxId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the inbox containing the message',
},
messageId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the message to update',
},
addLabels: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated labels to add to the message',
},
removeLabels: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated labels to remove from the message',
},
},
request: {
url: (params) =>
`https://api.agentmail.to/v0/inboxes/${params.inboxId.trim()}/messages/${params.messageId.trim()}`,
method: 'PATCH',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
body: (params) => {
const body: Record<string, unknown> = {}
if (params.addLabels) {
body.add_labels = params.addLabels.split(',').map((l) => l.trim())
}
if (params.removeLabels) {
body.remove_labels = params.removeLabels.split(',').map((l) => l.trim())
}
return body
},
},
transformResponse: async (response): Promise<UpdateMessageResult> => {
const data = await response.json()
if (!response.ok) {
return {
success: false,
error: data.message ?? 'Failed to update message',
output: { messageId: '', labels: [] },
}
}
return {
success: true,
output: {
messageId: data.message_id ?? '',
labels: data.labels ?? [],
},
}
},
outputs: {
messageId: { type: 'string', description: 'Unique identifier for the message' },
labels: { type: 'array', description: 'Current labels on the message' },
},
}

View File

@@ -0,0 +1,85 @@
import type { UpdateThreadParams, UpdateThreadResult } from '@/tools/agentmail/types'
import type { ToolConfig } from '@/tools/types'
export const agentmailUpdateThreadTool: ToolConfig<UpdateThreadParams, UpdateThreadResult> = {
id: 'agentmail_update_thread',
name: 'Update Thread Labels',
description: 'Add or remove labels on an email thread in AgentMail',
version: '1.0.0',
params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'AgentMail API key',
},
inboxId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the inbox containing the thread',
},
threadId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'ID of the thread to update',
},
addLabels: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated labels to add to the thread',
},
removeLabels: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Comma-separated labels to remove from the thread',
},
},
request: {
url: (params) =>
`https://api.agentmail.to/v0/inboxes/${params.inboxId.trim()}/threads/${params.threadId.trim()}`,
method: 'PATCH',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
body: (params) => ({
...(params.addLabels && {
add_labels: params.addLabels.split(',').map((l) => l.trim()),
}),
...(params.removeLabels && {
remove_labels: params.removeLabels.split(',').map((l) => l.trim()),
}),
}),
},
transformResponse: async (response): Promise<UpdateThreadResult> => {
const data = await response.json()
if (!response.ok) {
return {
success: false,
error: data.message ?? 'Failed to update thread',
output: { threadId: '', labels: [] },
}
}
return {
success: true,
output: {
threadId: data.thread_id ?? '',
labels: data.labels ?? [],
},
}
},
outputs: {
threadId: { type: 'string', description: 'Unique identifier for the thread' },
labels: { type: 'array', description: 'Current labels on the thread' },
},
}

View File

@@ -8,6 +8,29 @@ import {
a2aSendMessageTool,
a2aSetPushNotificationTool,
} from '@/tools/a2a'
import {
agentmailCreateDraftTool,
agentmailCreateInboxTool,
agentmailDeleteDraftTool,
agentmailDeleteInboxTool,
agentmailDeleteThreadTool,
agentmailForwardMessageTool,
agentmailGetDraftTool,
agentmailGetInboxTool,
agentmailGetMessageTool,
agentmailGetThreadTool,
agentmailListDraftsTool,
agentmailListInboxesTool,
agentmailListMessagesTool,
agentmailListThreadsTool,
agentmailReplyMessageTool,
agentmailSendDraftTool,
agentmailSendMessageTool,
agentmailUpdateDraftTool,
agentmailUpdateInboxTool,
agentmailUpdateMessageTool,
agentmailUpdateThreadTool,
} from '@/tools/agentmail'
import {
ahrefsBacklinksStatsTool,
ahrefsBacklinksTool,
@@ -2680,6 +2703,27 @@ export const tools: Record<string, ToolConfig> = {
a2a_resubscribe: a2aResubscribeTool,
a2a_send_message: a2aSendMessageTool,
a2a_set_push_notification: a2aSetPushNotificationTool,
agentmail_create_draft: agentmailCreateDraftTool,
agentmail_create_inbox: agentmailCreateInboxTool,
agentmail_delete_draft: agentmailDeleteDraftTool,
agentmail_delete_inbox: agentmailDeleteInboxTool,
agentmail_delete_thread: agentmailDeleteThreadTool,
agentmail_forward_message: agentmailForwardMessageTool,
agentmail_get_draft: agentmailGetDraftTool,
agentmail_get_inbox: agentmailGetInboxTool,
agentmail_get_message: agentmailGetMessageTool,
agentmail_get_thread: agentmailGetThreadTool,
agentmail_list_drafts: agentmailListDraftsTool,
agentmail_list_inboxes: agentmailListInboxesTool,
agentmail_list_messages: agentmailListMessagesTool,
agentmail_list_threads: agentmailListThreadsTool,
agentmail_reply_message: agentmailReplyMessageTool,
agentmail_send_draft: agentmailSendDraftTool,
agentmail_send_message: agentmailSendMessageTool,
agentmail_update_draft: agentmailUpdateDraftTool,
agentmail_update_inbox: agentmailUpdateInboxTool,
agentmail_update_message: agentmailUpdateMessageTool,
agentmail_update_thread: agentmailUpdateThreadTool,
airweave_search: airweaveSearchTool,
amplitude_send_event: amplitudeSendEventTool,
amplitude_identify_user: amplitudeIdentifyUserTool,