mcpField
I
IMAP mailbox

IMAP mailbox

本地服务
imap-mcp.ni-c.de通信协作33 天前更新

关于 IMAP mailbox

面向任意 IMAP 邮箱的 MCP 服务,供 MCP 客户端读取、搜索和整理邮件,并保存附件或撰写草稿。写入工具默认关闭,邮件内容会作为不可信数据处理;服务不能发送邮件。

主要功能

  1. 01列出邮箱并搜索邮件
  2. 02读取邮件和安全评估
  3. 03保存或提取附件
  4. 04整理邮件与文件夹
  5. 05在草稿箱保存回复

适用场景

  1. 01按发件人、主题或日期查找邮件
  2. 02查看新邮件及其安全提示
  3. 03提取邮件附件中的文本
  4. 04整理邮件并起草回复

MCP 相关

向 MCP 客户端提供 IMAP 邮箱的邮件、文件夹和附件工具及附件资源。写入工具默认未注册,删除和移动等操作可要求人工确认;不提供发送邮件功能。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"ni-c-imap": {
"command": "npx",
"args": [
"-y",
"@ni-c/imap-mcp"
],
"env": {
"IMAP_HOST": "<IMAP_HOST>",
"IMAP_USER": "<IMAP_USER>",
"IMAP_PASSWORD": "<IMAP_PASSWORD>",
"IMAP_PORT": "<IMAP_PORT>",
"IMAP_TLS": "<IMAP_TLS>",
"IMAP_MAILBOX": "<IMAP_MAILBOX>",
"IMAP_SEEN_KEYWORD": "<IMAP_SEEN_KEYWORD>",
"IMAP_READ_ONLY": "<IMAP_READ_ONLY>",
"IMAP_ALLOW_TOOLS": "<IMAP_ALLOW_TOOLS>",
"IMAP_DENY_TOOLS": "<IMAP_DENY_TOOLS>",
"IMAP_DOWNLOAD_DIR": "<IMAP_DOWNLOAD_DIR>",
"IMAP_INSECURE_TLS": "<IMAP_INSECURE_TLS>",
"IMAP_DRAFTS_MAILBOX": "<IMAP_DRAFTS_MAILBOX>",
"IMAP_MAX_MESSAGES": "<IMAP_MAX_MESSAGES>",
"IMAP_MAX_ATTACHMENT_BYTES": "<IMAP_MAX_ATTACHMENT_BYTES>",
"IMAP_MAX_DOWNLOAD_BYTES": "<IMAP_MAX_DOWNLOAD_BYTES>",
"IMAP_MAX_EXTRACT_BYTES": "<IMAP_MAX_EXTRACT_BYTES>",
"IMAP_ATTACHMENT_TYPES": "<IMAP_ATTACHMENT_TYPES>",
"IMAP_TRUSTED_AUTHSERV_ID": "<IMAP_TRUSTED_AUTHSERV_ID>"
}
}
}
}
启动命令npx -y @ni-c/imap-mcp
需要配置的环境变量
IMAP_HOSTHostname of the IMAP server, e.g. imap.example.net
IMAP_USERMailbox user name
IMAP_PASSWORD密钥Mailbox password or app password
IMAP_PORTDefaults to 993 with implicit TLS, 143 otherwise
IMAP_TLSimplicit (default), starttls or none
IMAP_MAILBOXDefault mailbox to work in (default: INBOX)
IMAP_SEEN_KEYWORD密钥IMAP keyword marking what the assistant has already seen (default: AiSeen)
IMAP_READ_ONLYSet to false to register the mailbox write tools; defaults to true
IMAP_ALLOW_TOOLSComma-separated tool names or list_* prefixes to register; 'essential' selects a curated preset (default: all tools)
IMAP_DENY_TOOLSComma-separated tool names or list_* prefixes to remove from whatever IMAP_ALLOW_TOOLS left
IMAP_DOWNLOAD_DIRDirectory attachments may be written to; unset means the server never touches the filesystem
IMAP_INSECURE_TLSSet to true to accept self-signed certificates, scoped to this connection
IMAP_DRAFTS_MAILBOXDrafts folder to save into; by default the one flagged \Drafts is used
IMAP_MAX_MESSAGESDefault number of messages a listing returns (default: 100)
IMAP_MAX_ATTACHMENT_BYTESCeiling for returning an attachment inline (default: 1048576)
IMAP_MAX_DOWNLOAD_BYTESCeiling for writing an attachment to disk (default: 26214400)
IMAP_MAX_EXTRACT_BYTESCeiling for reading a document's text with mode=text (default: 10485760, maximum: 67108864)
IMAP_ATTACHMENT_TYPESComma-separated content-type allowlist for attachments
IMAP_TRUSTED_AUTHSERV_ID密钥authserv-id your provider stamps into Authentication-Results; without it every verdict is reported as forgeable

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@ni-c/imap-mcp0.5.3
ocighcr.io/ni-c/imap-mcp:0.5.3

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

imap-mcp

CI OpenSSF Scorecard Socket Badge Glama score
npm version container image HTTP via mcp-hub
文档 赞助

适用于任何 IMAP 邮箱的模型上下文协议(MCP)服务。它使用 IMAP,而不是某个厂商的 API,因此可与您现有的任意服务提供商配合使用。

让 Claude Code、Claude Desktop 或 Codex 等 MCP 客户端能够阅读和搜索邮件、将邮件整理到文件夹中、保存附件并起草回复——每封邮件都会被标记为不可信内容,写入工具则默认关闭,除非您主动启用。

只有 11 个工具,而不是 50 个:邮件账户是一个工作流,而不是 API 接口,因此相关操作会合并到一个工具中,并通过模式区分,而不是拆分成许多工具。11 个是上限,不是起点——设置 IMAP_ALLOW_TOOLS=essential 只会注册精心挑选的 6 个工具;在默认只读设置下则会缩减为 4 个。请参阅选择要加载的工具。

一个 MCP 客户端通过标准输入输出与 imap-mcp 通信;imap-mcp 通过 TLS 连接 IMAP 服务,并返回被标记为不可信内容的邮件正文 列出只读默认设置下注册的工具、列出收件箱并阅读一封钓鱼邮件——返回内容会先列出注入内容的特征,逐行标记正文,并解除追踪信标的作用 ## 它的不同之处

它不能发送邮件。这就是它的功能。 能访问私密数据、接触不可信内容,又能与外界通信的 Agent,任何能往收件箱里放入消息的人都可以利用它——这正是 EchoLeak 漏洞所展示的模式:一封精心构造的邮件,就能在没有用户交互的情况下,从 Microsoft 365 Copilot 中窃取内部数据。 这个服务具备前两项能力,并且有意不具备第三项。save_draft 会将回复写入你的“草稿”文件夹;你可以在自己的邮件客户端中发送。无论消息中的文字多么巧妙,都无法让这个服务向任何地方发送内容。

写入功能默认关闭,需由你开启。 只设置 IMAP_HOST、IMAP_USER 和 IMAP_PASSWORD 时,服务只会注册六个读取工具,不会注册其他工具。设置 IMAP_READ_ONLY=false 后,邮箱工具才会出现——请注意,其默认值为 true,与这一系列其他服务相反,因为这个服务会访问邮箱。关闭的工具根本不会注册——模型看不到的能力,自然无法被诱导使用。

邮件会被视为恶意输入,因为它确实如此。 世界上的任何人都可以往你的收件箱里写入文本。邮件正文会被带有每次调用随机随机数的标记包围,而且 其中每一行都会加上该随机数前缀,因此,即使转发的邮件串很长,“这是数据”的提示也不会只停留在边界处。代码块后还会附上一条提醒,否则模型上下文中最后一条看起来像指令的句子就会是攻击者写的。模型看到内容前,会剥除零宽字符和方向控制符,并尽力移除隐藏的 HTML 元素(起关键作用的是边界标记,而非剥除操作);同时会消除行内和引用样式的 Markdown 图片语法,防止渲染客户端被诱导去请求跟踪 URL。

文件夹名称也会受到同样处理:文件夹名称由创建者选择,在共享邮箱中,创建者未必是你。list_mailboxes 会返回两种名称——服务器提供的原始名称 path,因为其他所有工具都使用它作为标识;以及经过清理、便于阅读的 display_name。如果两者不同,该条目还会附带警告。

除了邮件内容,你还会获得服务端评估结果:SPF/DKIM/DMARC 判定及其来源的 authserv-id、匹配到的提示词注入模式,以及混用拉丁字母与西里尔字母或希腊字母的词语。若有匹配项,警告会显示在结果最前面,而不是埋在 JSON 字段中。

这些判定带有 forgeable 标记,默认值始终为 true。发件人可以自行写入 Authentication-Results 标头;如果你的邮件服务提供商没有添加该标头,那么发件人写入的就是唯一的标头——消息本身没有任何信息可以区分二者。将 IMAP_TRUSTED_AUTHSERV_ID 设置为你的服务提供商添加的 ID(它是你已有任意一封邮件的标头中的第一个词),这样只有该 ID 才会被视为可信。在此之前,spf=pass 会如实报告为一项声明:来自任何人都能写入的标头。

真正有效的“新邮件”功能。 服务会使用自定义 IMAP 关键字(默认为 AiSeen)标记已交付的邮件,因此 list_new_messages 会对每封邮件只返回一次。它绝不会更改人工使用的 \Seen 状态——所有邮件都通过 BODY.PEEK 读取。

删除和移动操作需要由人确认。 如果客户端支持 MCP elicitation,delete_messages、move_messages 和删除文件夹的操作会弹出真实对话框,模型无法代替用户作答。如果客户端不支持,这些操作会改用两次调用的令牌流程,并明确说明这一点,而不会暗示有人已批准。设置 ELICITATION=false 会主动启用这一备用流程;保护机制仍会保留。参见征求用户确认。

要求

  • Node.js 22 或更高版本
  • 一个 IMAP 账户。使用双重身份验证的服务商通常需要应用专用密码。

配置

变量必需默认值描述
IMAP_HOST是—IMAP 服务器的主机名,例如 imap.example.net
IMAP_USER是—账户用户名,通常是邮箱地址
IMAP_PASSWORD是—密码或应用专用密码
IMAP_PORT否993 / 143根据 TLS 模式设置默认值
IMAP_TLS否implicitimplicit、starttls 或 none
IMAP_MAILBOX否INBOX消息工具默认使用的邮箱
IMAP_READ_ONLY否true仅当值为 false 时才会注册五个邮箱工具
IMAP_ALLOW_TOOLS否—工具名称、list_* 前缀或 essential
IMAP_DENY_TOOLS否—语法相同;从允许列表中排除
IMAP_SEEN_KEYWORD否AiSeen跟踪新邮件的关键词;留空则关闭
IMAP_TRUSTED_AUTHSERV_ID否—服务商添加标记的 authserv-id;见下文
IMAP_DRAFTS_MAILBOX否自动覆盖通过 \Drafts 标记找到的文件夹
IMAP_MAX_MESSAGES否100默认页大小
IMAP_MAX_ATTACHMENT_BYTES否1048576内联返回附件的大小上限
IMAP_MAX_DOWNLOAD_BYTES否26214400将附件写入磁盘的大小上限
IMAP_MAX_EXTRACT_BYTES否10485760读取文档文本的大小上限;最大为 67108864
IMAP_ATTACHMENT_TYPES否见下文以逗号分隔的内容类型允许列表
IMAP_DOWNLOAD_DIR否—设置后可在此处保存附件
IMAP_INSECURE_TLS否false仅当值为 true 时才接受自签名证书
ELICITATION否truefalse 会用令牌替代对话框。不带前缀

布尔值会与字面字符串 true 进行比较;1、yes 和 True 均不表示真。 IMAP_READ_ONLY 的逻辑相反:只有字面值 false 才会关闭它,因此拼写错误会导致写入工具无法注册。

选择要加载的工具

IMAP_ALLOW_TOOLS 和 IMAP_DENY_TOOLS 接受以逗号分隔的工具名称;末尾的 * 可匹配整个工具系列。essential 是精选的六项预设——list_mailboxes、 list_new_messages、list_messages、get_message、set_message_flags 和 move_messages。 其中四项是读取工具,因此在默认只读模式下仍然实用。

IMAP_ALLOW_TOOLS=essential
IMAP_ALLOW_TOOLS=list_new_messages,get_message,move_messages
IMAP_DENY_TOOLS=delete_messages

此列表无法划定的一条边界:move_messages 既会复制,也会移动(mode: "copy"), 而这两种操作属于同一个工具。禁用 move_messages 会同时移除两者;无法保留移动 功能并禁止复制,反之亦然。两种模式都会要求确认。

如果某个条目与任何工具都不匹配,启动就会中止并指出该条目,因此拼写错误不会悄悄 隐藏工具——没人会追查一个缺失工具是否源于环境变量。被筛选的工具永远不会注册,因此它 不会出现在 tools/list 中,也无法通过 tools/call 调用,这与 IMAP_READ_ONLY 下的写入工具完全一样。

此设置针对的是工具。此服务还公开的附件资源不会经过筛选。

如果你同时运行多个此类服务,mcp-hub 是另一种 解决方案——它的 /hub 端点会用六个元工具取代所有服务的工具。 密码读出后会立即从进程环境中删除,因此子进程和 /proc/<pid>/environ 都无法看到它。

如果未设置 IMAP_DOWNLOAD_DIR,此服务绝不会写入文件系统。三个大小限制有意分开, 因为它们分别解决三个不同的问题: IMAP_MAX_ATTACHMENT_BYTES 保护模型的上下文窗口, IMAP_MAX_DOWNLOAD_BYTES 保护你的磁盘,而 IMAP_MAX_EXTRACT_BYTES 限制单个 解析器接收的不可信输入量。提高其中任何一个,都不代表要提高其他限制。

服务会有意在没有凭据的情况下启动——它会完成握手并列出工具,而之后的每次调用都会 返回设置说明,而不是连接到服务。

安装

Claude Code
claude mcp add imap-mcp \
  -e IMAP_HOST=imap.example.net -e [email protected] -e IMAP_PASSWORD=… \
  -- npx -y @ni-c/imap-mcp
Claude Desktop
{
  "mcpServers": {
    "imap-mcp": {
      "command": "npx",
      "args": ["-y", "@ni-c/imap-mcp"],
      "env": {
        "IMAP_HOST": "imap.example.net",
        "IMAP_USER": "[email protected]",
        "IMAP_PASSWORD": "…"
      }
    }
  }
}
Codex
[mcp_servers.imap-mcp]
command = "npx"
args = ["-y", "@ni-c/imap-mcp"]
env = { IMAP_HOST = "imap.example.net", IMAP_USER = "[email protected]", IMAP_PASSWORD = "…" }
Docker
docker run --rm -i \
  -e IMAP_HOST=imap.example.net \
  -e [email protected] \
  -e IMAP_PASSWORD=… \
  ghcr.io/ni-c/imap-mcp

保存附件需要可写目录,而镜像以 uid 1000 运行——因此,绑定挂载的目录必须在主机上 归该用户所有:-e IMAP_DOWNLOAD_DIR=/data -v "$PWD/attachments:/data",并使用 chown 1000:1000 attachments。如果未设置 IMAP_DOWNLOAD_DIR,容器绝不会写入任何内容。

通过 mcp-hub

无法启动本地进程的客户端——ChatGPT 连接器、网页版 Claude、Cursor、LibreChat——可通过 mcp-hub 访问 imap-mcp:一个容器通过 Streamable HTTP 为许多 stdio MCP 服务提供服务,并在单个密码后提供 OAuth 2.1 登录,以及供无法使用 OAuth 的客户端使用的长期令牌。它的 /hub 端点会将所有服务置于六个元工具之后,因此 一个连接器就能访问所有服务,而无需在模型的上下文中放入 N×工具架构;它也支持两个 协议修订版——此服务提出的问题会经由它传递给远端的用户。

它的 /config/mcp.json 使用 Claude Code 的格式,因此配置项就是你已经 拥有的那一项:

{
  "mcpServers": {
    "imap-mcp": {
      "command": "npx",
      "args": ["-y", "@ni-c/imap-mcp"],
      "env": {
        "IMAP_HOST": "imap.example.net",
        "IMAP_USER": "[email protected]",
        "IMAP_PASSWORD": "…",
        "IMAP_ALLOW_TOOLS": "essential"
      },
      "denyTools": ["delete_messages"]
    }
  }
}

其中的 allowTools 和 denyTools 是 hub 自己针对每个服务的筛选器,与 env 中的 *_ALLOW_TOOLS 并不是一回事——两者的区别以及容易因此犯下的错误,详见 客户端指南。

工具

读取 — 始终注册

工具功能
get_server_info能力、永久标志、关键字是否可存储,以及启用了哪些工具组
list_mailboxes每个文件夹及其邮件数、未读数和特殊用途角色
list_messages列出和搜索:发件人、收件人、主题、正文、日期范围、标志
list_new_messages尚未移交的邮件;之后会标记这些邮件,dry_run 可用于预览
get_message标头和正文(以围栏标记为不可信),以及安全评估;include_thread
get_attachments不带 part_id 时列出附件,带 part_id 时读取、提取或保存一个附件

邮箱 — 需要 IMAP_READ_ONLY=false

工具确认
set_message_flags无 — 标志可撤销,且会拒绝 \Deleted
move_messages👤 对 move 和 copy 均需确认,🔒 适用于客户端无法确认的情况
delete_messages👤 询问用户,🔒 适用于客户端无法确认的情况
manage_mailbox👤 对 delete 需确认,🔒 对 rename 需确认,create 无需确认
save_draft无 — 草稿不会离开邮箱

👤 会弹出模型无法作答的对话框 · 🔒 需要确认令牌:先调用一次以获取令牌,再携带令牌调用一次。

copy 和 move 一样需要确认,因为无法挽回的不是删除,而是信息泄露。目标是自由填写的文件夹名称;在共享账户或公共命名空间中,一次调用就会把每封邮件交给所有有权读取它的人,同时保留源文件夹。出于同样的原因,set_message_flags 会拒绝添加 \Deleted:这相当于删除了一半,下一个关闭邮箱的客户端可能会完成删除。请使用会询问用户的 delete_messages。

确认和对话框都不会在自身的句子中引用邮箱名称 — 文件夹名称来自账户;对于共享邮箱,这意味着它们是由同事选择的。

结构化输出

每个工具都声明了一个 outputSchema,并在文本块之外同时返回 structuredContent,因此客户端无需解析文字即可使用结果:

{
  "untrusted": true,
  "source": "imap",
  "mailbox": "INBOX",
  "total_matching": 214,
  "offset": 0,
  "returned": 25,
  "next_offset": 25,
  "messages": [{ "uid": 4711, "subject": "…", "from": "…", "seen": false }],
}

每个会报告邮箱内容的工具都会携带字段 untrusted: true 和 source: "imap" — 发件人显示名称、同事选择的文件夹名称和附件文件名都可能由攻击者控制,而且它们早在任何人打开邮件之前,就会通过列表工具传递给模型。只有 get_server_info 和五个写入工具不带这些字段:它们报告的是此服务自身的配置,或它刚刚对传入的 UID 执行的操作。

get_message 和文本附件会在文本块中保留每次调用的随机数围栏 — 结构化部分会注明相同字段,因此客户端无需解析围栏来查找这些字段。图片附件会将其字节保留在内容块中,供客户端渲染,而不是重复提供 Base64。

现在,拒绝操作会返回错误结果:被策略拒绝的附件、字节内容实际上是可执行文件(无论其声称是什么)的附件,以及过大而无法内联的附件。过去,这些都会返回看起来像答案的普通结果。

附件也可作为 MCP 资源通过 imap://message/{uid}/part/{partId} 获取,这对于没有可用文件系统的服务很重要。资源路径会执行与工具相同的允许列表、大小限制和魔数检查 — 它不是另一个不受保护的入口。

有意不提供的功能

不发送邮件、不提供 SMTP、不透传原始 IMAP、不支持任意 MIME 的 APPEND、不编写 HTML、不支持 OAuth2,也不支持 OCR——扫描版 PDF 没有可提取的文本,我们会明确说明这一点,而不是猜测。前几项构成了完整的安全论证(参见 SECURITY.md);最后一项已列入计划,但需要先有一个测试账户才能发布。

还有一项工具过滤器无法涵盖:附件资源。IMAP_ALLOW_TOOLS 限制的是 tools/list,而非 resources/list,因此即使服务的允许列表范围很窄,附件资源仍会提供。真正限制附件资源的是 IMAP_DOWNLOAD_DIR 和内容类型允许列表——在得出过滤后的安装能访问的邮箱内容更少之前,值得先了解这一点。

安全性

  • 所有包含邮箱内容的结果都标记为不可信;邮件正文还会用每次调用独有的随机数进行围栏标记,并逐行标注。
  • 附件必须通过两道独立关卡。 我们会根据内容类型允许列表、可执行文件扩展名拒绝列表和大小上限检查附件声明;随后再通过魔数检查字节内容。一个被改名为 .pdf、并声明为 application/pdf 的可执行文件能够通过所有声明检查,但会在字节检查中被拒绝——即使是保存到磁盘时也一样;那样只会更危险,不会更安全。
  • part_id 必须来自列表调用,因此无法通过附件工具提取正文并绕过其围栏标记。
  • 文档会在可终止的进程中解析。 mode: "text" 使用捆绑的 PDF.js 和 ZIP 读取器读取 PDF 或 Office 文件——这是本服务解析陌生人发送的二进制文件的唯一位置。解析在子进程中运行,设有堆内存限制和超时时间;其标准输出会被丢弃,不会与 JSON-RPC 传输共享;PDF.js 的 eval 支持已关闭;在 PDF.js 解压之前,会先检查压缩流是否超过上限;在计算缓冲区大小之前,会先通过条目允许列表决定哪些内容可以解压。此路径中的任何操作都不会访问网络或文件系统。
  • 提取的文本会说明自身的性质。 提取会返回文件中每一条绘制文本的指令,包括字号小于 1 磅或以纸张颜色绘制的文本;以图片形式绘制的内容则不会返回。结果会在围栏标记上方说明这一点,因为否则“文档写着 X”就会成为用户无法核实的说法。
  • 下载不会逃逸其目录。 目标目录只能通过环境变量指定,文件名会经过清理,解析后的路径会再次检查,文件会以 wx 和 0600 模式打开——因此既不会覆盖任何内容,也不会跟随预先放置的符号链接。
  • 邮箱名称、标志和地址只要包含换行符就会被拒绝。 IMAP 是行协议,草稿是邮件头;CR 是注入手段,不是笔误。
  • 绝不会全局禁用 TLS。 IMAP_INSECURE_TLS 仅作用于其指定的连接;任何地方都没有 NODE_TLS_REJECT_UNAUTHORIZED。
  • 邮箱中的每项更改都会记录到 stderr,包含 UID 和文件夹——绝不记录主题。stderr 是模型不会读取的唯一通道。
  • 响应长度有上限。 超出部分会整项丢弃,而不是截断 JSON;截断提示会放在最前面,确保保留恢复提示。

SECURITY.md 介绍了信任模型、这些措施未涵盖的内容,以及如何报告漏洞。

文档

完整指南、工具参考和安全说明见 imap-mcp.ni-c.de(源文件位于 docs/)。

开发

npm install
npm test
npm run build

测试套件使用内存中的 IMAP 模拟,因此无需服务器或网络。若要连接真实服务器进行测试,请参阅 CONTRIBUTING.md——其中会在容器中启动一个临时邮箱。

发布

  1. 添加 CHANGELOG 条目并更新 package.json 中的版本号。
  2. npm run lint && npm run build && npm run test:coverage
  3. 提交后推送签名标签:git tag -s vX.Y.Z -m "vX.Y.Z" && git push origin main vX.Y.Z

发布工作流会将软件包发布到 npm(通过 Trusted Publishing,并提供来源证明)、根据 CHANGELOG 部分创建 GitHub 发布版本,并更新 MCP Registry 条目。

参与贡献

欢迎提交问题、参与讨论和发起拉取请求——请参阅 CONTRIBUTING.md。如需报告漏洞,请使用 私密报告渠道, 而不是公开提交问题;相关政策见 SECURITY.md。

许可证

MIT © Willi Thiel

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。