关于 나라장터 낙찰정보
这是将 data.go.kr 나라장터 낙찰信息 Open API 封装为本地 MCP 服务的工具,面向需要检索公共采购开标和中标数据的用户。它支持按条件搜索,也可按复合标识整合单个公告的中标、投标排名和预备价格信息。
主要功能
- 01搜索中标结果和开标记录
- 02按四类采购业务并行查询
- 03宽日期范围自动分段查询
- 04整合单个公告的多类结果
- 05部分失败时返回可用结果
适用场景
- 01按地区和日期查找物品中标结果
- 02查看公告的中标者及投标排名
- 03筛选流标或重新投标记录
- 04分析企业的历史中标情况
MCP 相关
本地 MCP 服务向客户端提供三个只读工具,用于搜索中标和开标记录,以及查询单个公告的详细结果。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
3收录的工具列表 · 更新于 3 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| bizno | string | 否 | 供应商企业注册号。仅查询该供应商的中标项目(不包括参与但未中标的项目) |
| region | string | 否 | 投标参与限制地区名称(prtcptLmtRgnNm) |
| bidKind | array | 否 | 业务类别数组(cnstwk=工程·servc=服务·thng=货物·frgcpt=外资)。未指定时并行查询所有类别,API 请求将增至 4 倍。已知业务类别时请指定,以节省认证密钥的每日流量 |
| endDate | string | 否 | 查询结束日期 YYYYMMDD |
| keyword | string | 否 | 按公告名称进行部分匹配(bidNtceNm) |
| dateType | enum | 否 | 日期 기준。posted=公告发布(默认),opened=开标posted | opened |
| industry | string | 否 | 行业名称(indstrytyNm) |
| maxPages | integer | 否 | 每个时间窗口的最大页数(默认为 10) |
| maxPrice | number | 否 | 추정가격 상한(presmptPrceEnd) |
| minPrice | number | 否 | 추정가격 하한(presmptPrceBgn) |
| pageSize | integer | 否 | 每窗口页大小(默认 100) |
| startDate | string | 否 | 查询开始日期 YYYYMMDD |
| institution | string | 否 | 公告机构名称 |
| demandInstitution | string | 否 | 수요기관명(dminsttNm) |
| detailProductCode | string | 否 | 세부품명번호(dtilPrdctClsfcNo) |
| demandInstitutionCode | string | 否 | 需求机构代码。用于稳定的终端标识 |
详细介绍
@opendata-kr/narajangteo-opening-mcp
나라장터 낙찰정보서비스(공공데이터포털 data.go.kr) Open API를 감싼 로컬 MCP 서버.
MCP 클라이언트에서 나라장터 낙찰정보(개찰결과·최종낙찰자·투찰업체별 순위·예비가격·유찰/재입찰)를 자연어로 검색하고 조회한다. 예를 들어 이렇게 물어볼 수 있다.
- "R25BK00965123 공고 개찰결과 보여줘. 낙찰자랑 투찰업체별 순위·금액."
- "인천 지역 물품 낙찰 결과 최근 것 검색해줘."
- "이 공고 유찰됐는지 확인해줘."
특징
- 4계열 데이터를 3개 도구로 노출: 낙찰자(A)·개찰진행(B)·예비가격상세(C)·투찰업체별(D) 오퍼레이션을 검색용 2개(
search_awards·search_openings)와 단건 심층조회 1개(get_bid_result)로 묶어 사용성을 단순화했다. - 4개 업무구분 병렬 검색: 공사/용역/물품/외자를 한 번에 조회한다. 업무구분 미지정 시 전 구분을 동시 검색한다.
- 넓은 기간 자동 분할:
startDate/endDate범위가 넓으면 내부에서 창 단위로 쪼개 순차 조회한다. - 부분 실패 표면화: 일부 구분·집행 조회가 실패해도 나머지 결과를 반환하고, 실패는 오류 메시지로 드러낸다(조용한 누락 없음).
- 복합키 정합:
get_bid_result는 공고번호+차수+분류+재입찰번호로 A/B/C/D를 조인해 집행 단위로 묶는다. - data.go.kr 에러코드 한국어화: 인증키 만료, 트래픽 초과 등 결과코드를 조치 가능한 한국어 메시지로 정규화한다.
- 이중 인코딩 방어: Encoding 키를 잘못 넣으면 경고하고, 요청은 한 번만 인코딩한다.
- 타임아웃: API 호출에 타임아웃을 둔다.
준비물
- Node.js 24 이상 (
.nvmrc=lts/krypton). - data.go.kr 인증키:
- 공공데이터포털에서 나라장터 낙찰정보서비스(
ScsbidInfoService)를 활용신청해[승인]을 받는다. 인증키는 계정당 하나지만, 각 API는 저마다 활용신청 승인이 있어야 그 API에서 인증된다. 서비스키가 있어도 이 API를 활용신청하지 않으면 인증 오류(코드 30)가 난다. - 마이페이지 → 활용신청 현황 → 개발계정 상세에서 Decoding 서비스키를 복사한다.
- 같은
DATA_GO_KR_SERVICE_KEY는 같은 계정으로 활용신청한 다른 data.go.kr API에도 재사용된다.
- 공공데이터포털에서 나라장터 낙찰정보서비스(
提示
공공데이터포털이 처음이라면 활용신청부터 인증키 복사까지 그림으로 따라 하는 data.go.kr 인증키 발급 가이드를 참고한다.
서비스키는 반드시 Decoding(원본) 키를 넣는다. Encoding(
%2B등 포함) 키를 넣으면 이중 인코딩으로 인증 오류(코드 30)가 난다.
MCP 클라이언트 설정
MCP 클라이언트에 아래 config를 추가한다:
{
"mcpServers": {
"narajangteo-opening": {
"command": "npx",
"args": ["-y", "@opendata-kr/narajangteo-opening-mcp@latest"],
"env": { "DATA_GO_KR_SERVICE_KEY": "발급받은_Decoding_키" }
}
}
}
说明
@opendata-kr/narajangteo-opening-mcp@latest를 쓰면 클라이언트가 항상 최신 버전을 받는다.
重要
DATA_GO_KR_SERVICE_KEY(필수, Decoding 원본 키)가 없으면 첫 호출이 인증 오류(코드 30)로 실패한다. 위 config의env에 키를 넣는다. 원클릭 버튼이나 env를 config에 담지 못하는 클라이언트는 설치 후 셸 환경변수로DATA_GO_KR_SERVICE_KEY를 설정한다.
클라이언트별 설정
Amp
https://ampcode.com/manual#mcp 의 안내를 따르고 위 config를 사용한다. CLI로도 추가할 수 있다:amp mcp add narajangteo-opening -- npx -y @opendata-kr/narajangteo-opening-mcp@latest
이후 생성된 설정의 env(또는 셸 환경변수)에 DATA_GO_KR_SERVICE_KEY를 추가한다.
Antigravity
Antigravity 문서의 커스텀 MCP 서버 추가 방법을 따라 아래 config를 MCP servers 설정에 넣는다:
{
"mcpServers": {
"narajangteo-opening": {
"command": "npx",
"args": ["-y", "@opendata-kr/narajangteo-opening-mcp@latest"],
"env": { "DATA_GO_KR_SERVICE_KEY": "발급받은_Decoding_키" }
}
}
}
Claude Code
Claude Code CLI로 서버를 추가한다 (가이드):
claude mcp add narajangteo-opening --scope user --env DATA_GO_KR_SERVICE_KEY=발급받은_Decoding_키 -- npx -y @opendata-kr/narajangteo-opening-mcp@latest
Cline
https://docs.cline.bot/mcp/configuring-mcp-servers 의 안내를 따르고 위 config를 사용한다.Codex
MCP 설정 가이드를 따르고 위 config를 사용한다. Codex CLI로도 추가할 수 있다:codex mcp add narajangteo-opening --env DATA_GO_KR_SERVICE_KEY=발급받은_Decoding_키 -- npx -y @opendata-kr/narajangteo-opening-mcp@latest
Windows
~/.codex/config.toml에 cmd /c 래핑으로 추가한다:
[mcp_servers.narajangteo-opening]
command = "cmd"
args = ["/c", "npx", "-y", "@opendata-kr/narajangteo-opening-mcp@latest"]
env = { DATA_GO_KR_SERVICE_KEY = "발급받은_Decoding_키" }
Command Code
Command Code CLI로 서버를 추가한다 (MCP 가이드):
cmd mcp add narajangteo-opening --scope user npx -y @opendata-kr/narajangteo-opening-mcp@latest
이후 생성된 설정의 env(또는 셸 환경변수)에 DATA_GO_KR_SERVICE_KEY를 추가한다.
Continue
Continue의 MCP 가이드를 따른다. Continue는 mcpServers를 배열로 쓴다:
{
"mcpServers": [
{
"name": "narajangteo-opening",
"command": "npx",
"args": ["-y", "@opendata-kr/narajangteo-opening-mcp@latest"],
"env": { "DATA_GO_KR_SERVICE_KEY": "발급받은_Decoding_키" }
}
]
}
Copilot CLI
Copilot CLI를 시작한다:
copilot
MCP 서버 추가 대화를 연다:
/mcp add
다음 필드를 입력하고 CTRL+S로 저장한다:
- 服务名称:
narajangteo-opening - 服务类型:
[1] 本地 - 命令:
npx -y @opendata-kr/narajangteo-opening-mcp@latest - 环境变量:
DATA_GO_KR_SERVICE_KEY=발급받은_Decoding_키
Copilot / VS Code
通过按钮安装:
按钮无法包含密钥。安装后,在
.vscode/mcp.json(或用户设置)的env中添加DATA_GO_KR_SERVICE_KEY。
手动添加:
按照 VS Code MCP 配置指南操作,或使用 CLI。
macOS·Linux:
code --add-mcp '{"name":"narajangteo-opening","command":"npx","args":["-y","@opendata-kr/narajangteo-opening-mcp@latest"],"env":{"DATA_GO_KR_SERVICE_KEY":"발급받은_Decoding_키"}}'
Windows(PowerShell):
code --add-mcp '{"""name""":"""narajangteo-opening""","""command""":"""npx""","""args""":["""-y""","""@opendata-kr/narajangteo-opening-mcp@latest"""],"""env""":{"""DATA_GO_KR_SERVICE_KEY""":"""발급받은_Decoding_키"""}}'
Cursor
通过按钮安装:
按钮无法包含密钥。安装后,在 Cursor 的 MCP 设置中将
DATA_GO_KR_SERVICE_KEY添加到env。
手动添加:
在 Cursor Settings → MCP → New MCP Server 中使用上述 config。
Factory CLI
使用 Factory CLI 添加服务(指南):
droid mcp add narajangteo-opening "npx -y @opendata-kr/narajangteo-opening-mcp@latest"
之后,在生成的配置的 env 中(或通过 shell 环境变量)添加 DATA_GO_KR_SERVICE_KEY。
Gemini CLI
使用 Gemini CLI 添加服务。
项目范围:
gemini mcp add narajangteo-opening npx -y @opendata-kr/narajangteo-opening-mcp@latest
全局:
gemini mcp add -s user narajangteo-opening npx -y @opendata-kr/narajangteo-opening-mcp@latest
也可以按照 MCP 指南操作,并使用上述 config。在 ~/.gemini/settings.json 的服务定义 env 中添加 DATA_GO_KR_SERVICE_KEY。
Gemini Code Assist
按照 MCP 配置指南操作,并使用上述 config。Grok Build CLI
grok mcp add narajangteo-opening npx -y @opendata-kr/narajangteo-opening-mcp@latest
之后,在生成的配置的 env 中(或通过 shell 环境变量)添加 DATA_GO_KR_SERVICE_KEY。更多选项请参阅文档。
JetBrains AI Assistant & Junie
在 Settings | Tools | AI Assistant | Model Context Protocol (MCP) → Add 中使用上述 config。
Junie 也可用相同方式,在 Settings | Tools | Junie | MCP Settings → Add 中使用上述 config。
Katalon Studio
Katalon StudioAssist 通过 MCP 代理连接 stdio 服务。
**步骤 1:**按照MCP 代理配置指南安装代理。
**步骤 2:**通过代理启动服务(在同一个 shell 中已 export DATA_GO_KR_SERVICE_KEY):
DATA_GO_KR_SERVICE_KEY=발급받은_Decoding_키 mcp-proxy --transport streamablehttp --port 8080 -- npx -y @opendata-kr/narajangteo-opening-mcp@latest
**步骤 3:**使用以下设置将服务添加到 StudioAssist:
- 连接 URL:
http://127.0.0.1:8080/mcp - 传输类型:
HTTP
Kiro
在 Kiro Settings 中选择 Configure MCP → Open Workspace or User MCP Config,并使用上述 config。
也可以在 Activity Bar → Kiro → MCP Servers → Open MCP Config 中使用上述 config。
Mistral Vibe
添加到 `~/.vibe/config.toml`:[[mcp_servers]]
name = "narajangteo-opening"
transport = "stdio"
command = "npx"
args = ["-y", "@opendata-kr/narajangteo-opening-mcp@latest"]
env = { DATA_GO_KR_SERVICE_KEY = "발급받은_Decoding_키" }
OpenCode
添加到 opencode.json。如果文件不存在,则在 ~/.config/opencode/opencode.json 中创建(指南):
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"narajangteo-opening": {
"type": "local",
"command": ["npx", "-y", "@opendata-kr/narajangteo-opening-mcp@latest"],
"environment": { "DATA_GO_KR_SERVICE_KEY": "발급받은_Decoding_키" }
}
}
}
Qoder CLI
使用 Qoder CLI 添加服务(指南):
项目范围:
qodercli mcp add narajangteo-opening -- npx @opendata-kr/narajangteo-opening-mcp@latest
全局:
qodercli mcp add -s user narajangteo-opening -- npx @opendata-kr/narajangteo-opening-mcp@latest
然后在生成的配置中的 env(或 Shell 环境变量)中添加 DATA_GO_KR_SERVICE_KEY。
Warp
在 Settings | AI | Manage MCP Servers → + Add 中添加 MCP 服务,并使用上述 config。
Windsurf
按照 MCP 配置指南操作,并使用上述 config。Windsurf 使用 `mcpServers` 键(`~/.codeium/windsurf/mcp_config.json`)。Zed
添加到 ~/.config/zed/settings.json(架构可能因 Zed 版本而异,请查阅 Zed 官方文档):
{
"context_servers": {
"narajangteo-opening": {
"command": { "path": "npx", "args": ["-y", "@opendata-kr/narajangteo-opening-mcp@latest"] },
"env": { "DATA_GO_KR_SERVICE_KEY": "발급받은_Decoding_키" }
}
}
}
ChatGPT · 仅支持远程的客户端
像 ChatGPT Developer Mode 这样仅支持远程(HTTPS)MCP 的客户端,无法直接连接本地 stdio 服务。使用 stdio→HTTP 桥接工具(mcp-proxy)通过 HTTP 启动此服务,并通过公开的 HTTPS 端点(反向代理、隧道或托管服务)将其暴露,然后将该 URL 注册为连接器。
DATA_GO_KR_SERVICE_KEY=발급받은_Decoding_키 mcp-proxy --transport streamablehttp --port 8080 -- npx -y @opendata-kr/narajangteo-opening-mcp@latest
将 http://127.0.0.1:8080/mcp 暴露为公开 HTTPS 端点需由用户自行完成。(mcp-remote 用于将 stdio 客户端连接到远程服务,因此不适用于此处。)
发现
此服务在 MCP 注册表中的标识为 io.github.opendata-kr/narajangteo-opening。可在支持 registry.modelcontextprotocol.io 的客户端中搜索并安装。
环境变量
| 环境变量 | 必需 | 敏感 | 默认值 | 说明 |
|---|---|---|---|---|
DATA_GO_KR_SERVICE_KEY | 是 | 是 | (无) | 公共数据门户 **Decoding(原始)**认证密钥 |
DATA_GO_KR_BASE_URL | 否 | 否 | https://apis.data.go.kr/1230000/as/ScsbidInfoService | 包含服务路径的完整 URL 覆盖值 |
工具
3 个工具均为只读查询(readOnlyHint)。业务类别(bidKind)数组:cnstwk(工程)servc(服务)thng(物品)frgcpt(外资)。未指定时,将并行查询所有类别(API 请求会按类别数量成倍消耗,因此请指定已知类别)。startDate/endDate(YYYYMMDD)必须同时指定;较大的日期范围会在内部拆分为多个窗口并依次查询。
search_awards
按公告名称、机构、需求机构(代码)、地区、行业、估算价格、企业注册号和日期范围搜索国家综合电子采购系统的中标结果(最终中标人)。可用于查询“谁以多少金额中标”、竞争对手(企业注册号)的中标记录,以及追踪重复项目的完整历程。仅返回中标人,不包含该企业参与但未中标的投标。若要查看特定公告的开标情况、投标企业和预备价格详情,请使用 get_bid_result;若要查找正在开标或流标的项目,请使用 search_openings。
| 参数 | 类型 | 说明 |
|---|---|---|
bidKind | string[] | 业务类别数组。未指定时并行查询所有类别(消耗 4 倍 API 请求) |
keyword | string | 公告名称模糊搜索(bidNtceNm) |
institution | string | 公告机构名称(ntceInsttNm) |
demandInstitution | string | 需求机构名称(dminsttNm) |
demandInstitutionCode | string | 需求机构代码(dminsttCd)。适合稳定地追踪项目完整历程 |
detailProductCode | string | 细分产品编号(dtilPrdctClsfcNo) |
region | string | 参与限制地区名称(prtcptLmtRgnNm) |
industry | string | 行业名称(indstrytyNm) |
minPrice | number | 估算价格下限(presmptPrceBgn) |
maxPrice | number | 估算价格上限(presmptPrceEnd) |
bizno | string | 企业注册号。仅查询该企业的中标项目(不包含未中标的投标) |
startDate | string | 查询开始日期 YYYYMMDD |
endDate | string | 查询结束日期 YYYYMMDD |
dateType | string | 日期 기준:posted(公告发布,默认)opened(开标) |
pageSize | number | 每个窗口的页面大小(默认 100,最大 100) |
maxPages | number | 每个窗口的最大页数(默认 10,最大 50) |
search_openings
搜索国家综合电子采购系统的开标结果列表,并按进展状态(开标完成/流标/重新投标)筛选。可用于查找流标或重新投标的公告。status 并非 API 参数,而是根据响应进行的客户端筛选,因此响应较慢;建议按机构、行业和日期范围缩小搜索范围(若 truncated: true,表示扫描未完成)。重新投标是同一公告下的再次投标,并非重新公告(重新公告属于招标公告服务的范围)。若要搜索最终中标人,请使用 search_awards;若要查看单个公告的详情,请使用 get_bid_result。
| 参数 | 类型 | 说明 |
|---|---|---|
bidKind | string[] | 业务类别数组。未指定时并行查询所有类别(消耗 4 倍 API 请求) |
keyword | string | 公告名称(bidNtceNm) |
institution | string | 公告机构名称 |
demandInstitution | string | 需求机构名称(dminsttNm) |
region | string | 参与限制地区名称(prtcptLmtRgnNm,例如:仁川广域市) |
industry | string | 行业名称(indstrytyNm) |
status | string | 进展状态筛选:개찰완료 유찰 재입찰(根据响应中的 progrsDivCdNm 进行客户端筛选) |
startDate | string | 查询开始日期 YYYYMMDD(需与 endDate 一起指定) |
endDate | string | 查询结束日期 YYYYMMDD(需与 startDate 一起指定) |
dateType | string | 日期 기준:posted(公告发布,默认)opened(开标) |
pageSize | number | 每个窗口的页面大小(默认 20;开标结果响应较慢,建议设置较小值) |
maxPages | number | 每个窗口的最大页数(默认 5) |
开标结果查询的响应较慢(基于实时数据:20 行需 0.6 秒,50 行需 9 秒,100 行会超时)。请保持较小的页面大小,并缩小搜索范围。
get_bid_result
根据招标公告编号,通过复合键(公告编号+轮次+分类+重新投标编号)准确查询该公告的中标人、开标进度、预备价格详情(调整率),以及各投标企业的排名/金额/分数。可用于项目事后分析和参考投标价格。多分类、多轮次公告会拆分为执行单元数组。中标方式为估算(仅协商合同提供技术和价格分数,资格审查仅提供金额和排名);若提供 myBizno,则会在本企业的投标记录中标记 isOurs。若要按条件查找多个公告,请使用 search_awards 或 search_openings。
| 参数 | 类型 | 说明 |
|---|---|---|
bidNtceNo | string | 招标公告编号(必填) |
bidKind | string | 业务类别。未指定时会在所有类别中查询 A/B/C(12 次 API 请求;指定时为 3 次) |
status | string | D(各投标企业)状态:completed failing rebid all(默认,并行查询已完成、流标和重新投标的项目) |
bidNtceOrd | string | 招标公告轮次。缩小到特定执行单元 |
bidClsfcNo | string | 招标分类编号。缩小到特定执行单元 |
rbidNo | string | 重新投标编号。缩小到特定执行单元 |
myBizno | string | 本企业注册号。在匹配的投标记录中添加 isOurs 标记 |
所有工具的返回结果中,search_awards/search_openings 返回 { query, results }(按业务类别返回 { totalCount, invalidCount, items },或失败时返回 { error }),get_bid_result 返回 { bidNtceNo, executions, errors, invalidCount, notes }。invalidCount 是因未通过响应架构验证而从 items 中排除的记录数。如果该值不为 0,说明 API 响应字段可能发生了意外变化;请通过问题反馈告知,我们会进行处理。
响应字段
搜索工具(search_awards、search_openings)会返回按业务类别划分的 results 映射。每个类别的值为 { totalCount(BeforeFilter), invalidCount, items, truncated, failedWindows } | { error }。指定日期范围时,会按日历月份边界划分窗口并依次查询;即使部分窗口查询失败,也会返回其余成功结果,并将失败的窗口及原因放入 failedWindows,以表明结果不完整。
AwardResult(A 系列,最终中标人)
bidNtceNo(招标公告编号)、bidNtceNm(公告名称)、participants(参与企业数)、winner(中标人)、winnerBizno(中标人企业注册号)、winnerCeo(中标人代表)、awardAmount(中标金额)、awardRate(中标率)、realOpeningDt(实际开标日期时间)、demandInstitution(需求机构)、finalAwardDate(最终中标日期)。
OpeningSummary (계열 B, 개찰진행)
bidNtceNo, bidNtceNm, openingDt(개찰일시), participants(참가업체수), progress(진행상태: 개찰완료/유찰/재입찰), topBidder(1위 업체 { name, bizno, ceo, amount, rate } 또는 null), reservePriceFileExists(예비가격 파일 존재 여부), noticeInstitution(공고기관), demandInstitution(수요기관), failReasonHint(유찰 시 참가업체수 기반 추정 사유, 선택).
PreparPriceDetail (계열 C, 예비가격상세·집행 단위 집약)
planPrice(예정가격), baseAmount(기초금액), saJeongRate(사정률, 숫자 또는 null), totalReserveCount(총 복수예가수), drawn(추첨번호), reserves(복수예가 배열: seq·basePlanPrice).
BidderDetail (계열 D, 투찰업체별)
rank(순위), name(업체명), bizno(사업자번호), ceo(대표자), amount(투찰금액), rate(투찰율), remark(비고), priceScore(가격점수), techScore(기술점수), techRawScore(기술평점), totalScore(합산점수), bidDt(투찰일시), isOurs(자사 여부, myBizno 일치 시 true).
개발
nvm use # Node 24
pnpm install
pnpm test # vitest
pnpm typecheck # tsc --noEmit
pnpm build # tsup, dist/ 생성
문제 해결
-
인증 오류(코드 30): Encoding 키를 넣으면 이중 인코딩으로 실패한다. Decoding(원본) 키를 쓴다. 서버가 시작 시 Encoding 키로 보이면 경고 로그를 남긴다.
-
개찰결과 조회가 느리거나 타임아웃:
search_openings는 응답이 무겁다.pageSize를 기본값(20) 이하로 유지하고 기관·업종·기간으로 조건을 좁힌다.truncated: true가 보이면 스캔이 끝나지 않은 것이다. -
결과코드 메시지: 트래픽 초과, 인증키 만료 등 data.go.kr 결과코드는 한국어 메시지로 정규화되어 반환된다.
-
도구 동작 점검: MCP inspector로 직접 호출해 볼 수 있다.
npx @modelcontextprotocol/inspector npx -y @opendata-kr/narajangteo-opening-mcp
라이선스
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。