I’m working on an email tool for agents and comparing patterns for thread-aware workflows in LangChain.
We built EngageLab Email MCP as a small, local stdio server for agents that need to send, receive, monitor, and reply to email. The product identity is disclosed here: this is an EngageLab Email team project.
The basic workflow is:
- The agent drafts a message and asks for approval when the action is sensitive.
- A tool sends the message and returns a message/thread identifier.
- A later run polls or inspects the inbox, matches the incoming message to the thread, and exposes the reply to the agent.
- The agent decides whether to reply, escalate to a human, or stop.
The server can be started with:
npx -y @engagelabemail/mcp
At the moment it runs locally over MCP stdio and calls the EngageLab Email API. We have not added a hosted Remote MCP endpoint yet. The implementation is intentionally small: the main question we are exploring is how an agent framework should model email state and side effects.
A few questions for LangChain users:
- Should inbound email be represented as a tool, a retriever, or an external event that wakes an agent?
- Where do you keep the email thread ID so a later agent run can continue the same conversation reliably?
- Do you put human approval inside the send tool, in the agent graph, or in a separate policy layer?
- What should the tool return after sending so tracing and retries remain safe?
The reference implementation is here:
I’d especially appreciate examples of how you model long-running or asynchronous communication in LangChain / LangGraph. Practical criticism is welcome.