中文EN

dsh-agentmail

toolsnpmMIT

用 AgentMail 给 agent 配一个自己的收件箱:发信、读信、搜索与打标签共十一个工具;收到的邮件按邮件线程分派,每个线程对应一个独立会话;所有外发邮件都要过审批与收件人白名单。

下载量 / Downloads
699

安装

dsh plugin --profile web add dsh-agentmail

沙箱测试

这个插件还没测过。提交测试 →

README

<p align="center">

<img src="https://raw.githubusercontent.com/agentmail-to/dsh-agentmail/main/assets/hero.svg" width="100%" alt="dsh-agentmail — an AgentMail plugin for DeepSeek Harness. Give an agent its own email inbox; inbound mail becomes one harness session per email thread." />

</p>

<p align="center">

<a href="https://www.npmjs.com/package/dsh-agentmail"><img src="https://img.shields.io/npm/v/dsh-agentmail?style=flat-square&labelColor=0A0A0A&color=3A3A3A" alt="npm" /></a>

<a href="tests"><img src="https://img.shields.io/badge/tests-74-3A3A3A?style=flat-square&labelColor=0A0A0A" alt="74 tests" /></a>

<a href="https://github.com/topics/dsh-plugin"><img src="https://img.shields.io/badge/dsh--plugin-topic-3A3A3A?style=flat-square&labelColor=0A0A0A" alt="dsh-plugin topic" /></a>

<a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-3A3A3A?style=flat-square&labelColor=0A0A0A" alt="MIT license" /></a>

</p>

<p align="center">

<a href="#two-ways-to-install">Install</a> ·

<a href="#tools">Tools</a> ·

<a href="#how-thread-binding-works">Thread binding</a> ·

<a href="#follow-ups-why-not-schedule_create">Follow-ups</a> ·

<a href="#security">Security</a> ·

<a href="#configuration">Config</a>

</p>

Two ways to install

The 5-minute on-ramp: the built-in MCP client

The harness ships @deepseek-ai/dsh-mcp-client, and AgentMail runs an MCP server. Zero code:

- id: mcp-agentmail
  name: '@deepseek-ai/dsh-mcp-client'
  config:
    serverName: agentmail
    transport: streamable-http
    url: https://mcp.agentmail.to/mcp
    headers:
      Authorization: !!js '`Bearer ${process.env.AGENTMAIL_API_KEY}`'

That gives you mcp__agentmail__send_message and friends today. It does not give you the

four things below.

This plugin

export AGENTMAIL_API_KEY=...
dsh plugin --profile demo add dsh-agentmail   # or: add github:agentmail-to/dsh-agentmail#<sha>
dsh --profile demo

Capability · MCP client · This plugin

Send, read and search tools · yes · yes

Inbound mail reaches the agent · no · yes

Bounces reported back, so a failed send isn't assumed delivered · no · yes

Approval gate and recipient allowlist on outbound · no · yes

Follow-ups that survive the conversation ending · no · yes

Inbox identity and untrusted-content rules in the system prompt · no · yes

Local development

npm install && npm run build
dsh web --patch ./cordis.patch.yml

What gets mounted

Four independent plugins, so a deployment can drop any one from its own patch layer:

Entry · Injects · Role

dsh-agentmail/tools · tools · The model-facing tool surface

dsh-agentmail/identity · systemPrompt · Inbox identity and the untrusted-content rules

dsh-agentmail/approval · tools · Recipient allowlist + human approval on outbound

dsh-agentmail/inbound · agents · Inbound mail, thread sessions, follow-up sweep

Tools

Eleven, curated rather than a mirror of the REST API — every registered schema is paid on every

model request.

Tool · Notes

agentmail_list_inboxes ·

agentmail_create_inbox ·

agentmail_list_threads · Cursor-paged, label-filterable

agentmail_get_thread · Bodies truncated to maxBodyChars

agentmail_search · Relevance-ranked full text

agentmail_send_message · Idempotency-keyed on the tool call id

agentmail_reply · replyAll opt-in; idempotency-keyed

agentmail_create_draft · The human-in-the-loop path

agentmail_send_draft ·

agentmail_update_labels · Workflow state

agentmail_followup · Due-date label; wakes a cold thread session

Canonical returns are a programmatic API — ids and fields, never prose to re-parse — so Code

Mode can drive batch triage through await tools.agentmail_list_threads(...) in one call.


How thread binding works

The session id is a total function of the thread id:

sessionId = "agentmail-" + threadId
flowchart LR
  M([inbound mail<br/>on thread T]) --> Q{"session<br/>agentmail-T ?"}
  Q -->|live| L[inject the new message]
  Q -->|persisted on disk| R[resume, then inject]
  Q -->|neither| C[create, then seed<br/>from the AgentMail API]
  L --> A([agent handling thread T])
  R --> A
  C --> A

Inbound mail on thread T takes one of three branches:

Branch · When · What happens

live · an agent is already running · inject just the new message

persisted · a session log exists on disk · resume it, then inject the new message

fresh · neither · create it, and seed from threads.get(threadId)

The third branch is why there is no mapping store: AgentMail is the store. A session lost

to a restart, a cleared profile, or a different machine rebuilds itself from the API.

Consequences that are handled, and worth knowing:

  • Concurrent mail on one thread hits an in-flight latch, so two messages arriving inside the

create window produce one session, not two.

  • Idle disposal is non-destructive. Sessions idle past idleDisposeMs are disposed with no

eviction ordering to reason about — the log survives, and the API can rebuild regardless.

maxLive is only a flood cap.

  • Outbound-initiated threads start life in whatever session sent the first mail. When the

reply arrives, the new thread session seeds from the API, so it knows everything that was

said but not the sending session's private reasoning. Accepted for v1.

Set threadSessions.enabled: false to route all mail into one fallbackSessionId instead.

Follow-ups: why not schedule_create?

Harness Schedule reminders only fire while a session has a live root Agent, and the only

other thing that revives a thread session is inbound mail. But "follow up in 3 days if they

haven't replied" is precisely the case where no mail arrives — so a session-local reminder

would never fire.

`agentmail_followu

…(truncated)

以上内容来自 npm 上的 README,我们只做格式化,不改内容。

版本

npm 上共发布:1,最后更新 2026-08-18

链接

GitHub · Homepage · npm

同类插件