The MCPorter-based approach has an MCP SDK version incompatibility:
agentmail-mcpuses@modelcontextprotocol/sdk@^1.24.1mcporteruses@modelcontextprotocol/sdk@^1.25.1
This causes structuredContent validation errors. Until agentmail-mcp updates, we'll build a direct CLI using the agentmail SDK.
- Build a direct CLI using the
agentmailnpm package - Keep existing MCPorter setup intact for future use
- Maintain same command interface as documented in SKILL.md
- Support all 11 tools from the MCP server
bin/
├── agentmail.js # Entry point (direct CLI - NEW)
├── agentmail-mcp.js # MCPorter wrapper (existing, renamed)
src/
├── cli.js # Commander.js CLI definition
├── commands/
│ ├── inboxes.js # Inbox commands (list, get, create, delete)
│ ├── threads.js # Thread commands (list, get)
│ ├── messages.js # Message commands (send, reply, forward, update)
│ └── attachments.js # Attachment commands (get)
└── utils/
├── client.js # AgentMail client initialization
└── output.js # JSON output formatting
mv bin/agentmail.js bin/agentmail-mcp.jsAdd both entry points:
{
"bin": {
"agentmail": "./bin/agentmail.js",
"agentmail-mcp": "./bin/agentmail-mcp.js"
},
"scripts": {
"start": "node bin/agentmail.js",
"start:mcp": "node bin/agentmail-mcp.js"
}
}import { AgentMailClient } from 'agentmail';
export function getClient() {
const apiKey = process.env.AGENTMAIL_API_KEY;
if (!apiKey) {
console.error('Error: AGENTMAIL_API_KEY required');
process.exit(1);
}
return new AgentMailClient({ apiKey });
}export function output(data) {
console.log(JSON.stringify(data, null, 2));
}
export function handleError(error) {
console.error(JSON.stringify({
error: error.message,
statusCode: error.statusCode
}, null, 2));
process.exit(1);
}import { Command } from 'commander';
import { inboxCommands } from './commands/inboxes.js';
import { threadCommands } from './commands/threads.js';
import { messageCommands } from './commands/messages.js';
import { attachmentCommands } from './commands/attachments.js';
const program = new Command();
program
.name('agentmail')
.description('CLI for AgentMail - Email accounts for AI agents')
.version('1.0.0');
// Register command groups
inboxCommands(program);
threadCommands(program);
messageCommands(program);
attachmentCommands(program);
program.parse();| Command | SDK Method | Parameters |
|---|---|---|
agentmail inboxes list |
client.inboxes.list() |
--limit, --page-token |
agentmail inboxes get <id> |
client.inboxes.get(id) |
|
agentmail inboxes create |
client.inboxes.create() |
--username, --domain, --display-name |
agentmail inboxes delete <id> |
client.inboxes.delete(id) |
| Command | SDK Method | Parameters |
|---|---|---|
agentmail threads list <inbox-id> |
client.inboxes.threads.list() |
--limit, --labels, --before, --after |
agentmail threads get <inbox-id> <thread-id> |
client.inboxes.threads.get() |
| Command | SDK Method | Parameters |
|---|---|---|
agentmail messages send <inbox-id> |
client.inboxes.messages.send() |
--to, --cc, --bcc, --subject, --text, --html |
agentmail messages reply <inbox-id> <message-id> |
client.inboxes.messages.reply() |
--text, --html, --reply-all |
agentmail messages forward <inbox-id> <message-id> |
client.inboxes.messages.forward() |
--to, --text, --subject |
agentmail messages update <inbox-id> <message-id> |
client.inboxes.messages.update() |
--add-labels, --remove-labels |
| Command | SDK Method | Parameters |
|---|---|---|
agentmail attachments get <thread-id> <attachment-id> |
client.threads.getAttachment() |
#!/usr/bin/env node
import '../src/cli.js';Update the SKILL.md to reflect the new command structure:
Old (MCPorter):
npx mcporter call agentmail.list_inboxesNew (Direct CLI):
agentmail inboxes listCreate a mapping section showing both syntaxes for compatibility.
# Load env
export $(grep -v '^#' .env | xargs)
# Test inboxes
agentmail inboxes list
agentmail inboxes create --display-name "Test Bot"
agentmail inboxes get <inbox-id>
agentmail inboxes delete <inbox-id>
# Test threads
agentmail threads list <inbox-id>
agentmail threads get <inbox-id> <thread-id>
# Test messages
agentmail messages send <inbox-id> --to user@example.com --subject "Test" --text "Hello"
agentmail messages reply <inbox-id> <message-id> --text "Reply"
agentmail messages update <inbox-id> <message-id> --add-labels processed
# Test attachments
agentmail attachments get <thread-id> <attachment-id>| MCP Tool | MCPorter Command | Direct CLI Command |
|---|---|---|
list_inboxes |
npx mcporter call agentmail.list_inboxes |
agentmail inboxes list |
get_inbox |
npx mcporter call agentmail.get_inbox inboxId:X |
agentmail inboxes get X |
create_inbox |
npx mcporter call agentmail.create_inbox displayName:Y |
agentmail inboxes create --display-name Y |
delete_inbox |
npx mcporter call agentmail.delete_inbox inboxId:X |
agentmail inboxes delete X |
list_threads |
npx mcporter call agentmail.list_threads inboxId:X |
agentmail threads list X |
get_thread |
npx mcporter call agentmail.get_thread inboxId:X threadId:Y |
agentmail threads get X Y |
get_attachment |
npx mcporter call agentmail.get_attachment ... |
agentmail attachments get X Y |
send_message |
npx mcporter call agentmail.send_message ... |
agentmail messages send X --to ... --subject ... |
reply_to_message |
npx mcporter call agentmail.reply_to_message ... |
agentmail messages reply X Y --text ... |
forward_message |
npx mcporter call agentmail.forward_message ... |
agentmail messages forward X Y --to ... |
update_message |
npx mcporter call agentmail.update_message ... |
agentmail messages update X Y --add-labels ... |
| File | Action | Description |
|---|---|---|
bin/agentmail.js |
Modify | New direct CLI entry point |
bin/agentmail-mcp.js |
Rename | Keep MCPorter wrapper |
src/cli.js |
Create | Commander.js setup |
src/utils/client.js |
Create | Client initialization |
src/utils/output.js |
Create | Output formatting |
src/commands/inboxes.js |
Create | Inbox commands |
src/commands/threads.js |
Create | Thread commands |
src/commands/messages.js |
Create | Message commands |
src/commands/attachments.js |
Create | Attachment commands |
package.json |
Modify | Add both bin entries |
skills/agentmail/SKILL.md |
Modify | Update command syntax |
- Phase 1: Restructure project
- Rename
bin/agentmail.jstobin/agentmail-mcp.js - Update
package.jsonwith both bin entries
- Rename
- Phase 2: Create core utilities
-
src/utils/client.js -
src/utils/output.js -
src/cli.js
-
- Phase 3: Implement commands
-
src/commands/inboxes.js(4 commands) -
src/commands/threads.js(2 commands) -
src/commands/messages.js(4 commands) -
src/commands/attachments.js(1 command)
-
- Phase 4: Create entry point
-
bin/agentmail.js
-
- Phase 5: Update documentation
- Update
SKILL.mdwith new command syntax - Update
README.md
- Update
- Phase 6: Test all commands
- Test with real API key
When agentmail-mcp updates to MCP SDK 1.25.1+:
-
Test MCPorter again:
npm run start:mcp list-tools
-
If working, update
package.jsonto use MCPorter as default:{ "bin": { "agentmail": "./bin/agentmail-mcp.js", "agentmail-direct": "./bin/agentmail.js" } } -
Revert SKILL.md to MCPorter syntax