mcpField
P
Portugal Tenders

Portugal Tenders

远程服务
pipeworx.io法律与政务02 周前更新

关于 Portugal Tenders

Portugal Tenders 为采购团队、研究者及供应商提供葡萄牙招标公告和已授予合同的查询工具,数据来自监管机构 IMPIC 发布的开放数据。它支持公告与合同搜索及详情查询,并在结果中标明数据时间范围。

主要功能

  1. 01搜索招标公告
  2. 02按金额和供应商筛选合同
  3. 03查询公告与合同详情
  4. 04注明数据来源和时间范围

适用场景

  1. 01查找指定 CPV 的采购公告
  2. 02按采购方或供应商筛选合同
  3. 03核对合同金额、期限或地点

MCP 相关

MCP 服务提供公告搜索与详情、合同搜索与详情工具。数据来源为 IMPIC 开放数据,结果包含来源、许可和已加载数据窗口信息。

配置

远程服务无需本地安装。选择你使用的客户端,复制配置或使用一键安装。

服务地址https://gateway.pipeworx.io/portugal-tenders/mcp
一键复制安装命令
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

命令在终端中运行;JSON 粘贴到对应客户端的 MCP 配置后重启。需要授权的服务会在首次连接时提示登录。

工具

45
参数类型必填说明
qstring否question 的别名。
askstring否question 的别名。
textstring否question 的别名。
inputstring否question 的别名。
packsarray否可选。将路由限制为这些包的 slug(例如 ["sec-form-d","sec-13f"]),路由器随后只会从这些包中的工具进行选择。省略则使用默认的完整目录路由。Slug 可从 list_packs / search_packs / https://pipeworx.io/directory 获取;未列出或未知的 slug 会被忽略,并在 _meta.pack_scope.ignored 中列出。如果没有任何 slug 能匹配问题,则会在整个目录中路由,并设置 _meta.pack_scope.full_catalog:true(绝不会返回空答案)。
querystring否question 的别名。
promptstring否question 的别名。
messagestring否question 的别名。
questionstring是用自然语言表达的问题或请求。支持 query、q、prompt、text、input、ask、message 作为别名。

详细介绍

@pipeworx/portugal-tenders

来自 IMPIC(Instituto dos Mercados Públicos, do Imobiliário e da Construção,葡萄牙公共采购监管机构)的葡萄牙公共采购招标公告和中标合同。Fleet #3111。

这是 Pipeworx 的一部分——一个将 AI Agent 接入 1808+ 个实时数据源的 MCP 网关。这是独立的非官方集成,与上游提供方无关联、未获其认可,也非由其发布。

工具

  • pt_announcement_search(query?, cpv?, buyer?, date_from?, date_to?, limit?) -- 按自由文本关键词(公告标题)、CPV 分类代码/前缀、采购方名称子字符串以及发布日期范围搜索招标公告(默认为最近 90 天)。返回每条公告的内部 ID、IMPIC 公告 ID、采购方、标题、公告类型、合同类型、基础金额(EUR)、CPV、发布日期和投标截止日期。
  • pt_announcement_detail(id) -- 根据 pt_announcement_search 返回的内部 ID,获取一条公告的完整记录,包括采购方的 NIF 税号、采购程序模式、分包描述,以及官方公告文件的链接。
  • pt_contract_search(query?, buyer?, supplier?, amount_min?, amount_max?, date_from?, date_to?, limit?) -- 按自由文本关键词(合同标题)、采购方(adjudicante)名称子字符串、中标供应商(adjudicatário)名称子字符串、合同金额范围(EUR)和发布日期范围搜索中标合同。返回每份合同的 ID、标题、采购方、供应商、金额、合同类型、CPV、发布日期和签署日期。
  • pt_contract_detail(idcontrato) -- 根据合同 ID 获取一份合同的完整记录,包括采购方/供应商的 NIF 税号、完整描述、基础采购价格、履行期限和地点、采购程序类型以及所引用的法律制度。

每个响应都包含 source、source_url、licence、data_as_of,而搜索/未匹配响应还会包含相关的 *_window_from/*_window_to 日期范围——即此数据包目前覆盖的数据集时间跨度——让调用方能够区分“没有相关主题的数据”和“该日期范围尚未加载”。

身份验证

无需密钥。工具只通过持有数据的 Pipeworx 网关响应;独立安装没有可读取的数据,每个工具在此情况下都会返回清晰的“此运行时未绑定存储”错误,而不是空列表。

数据来源

  • IMPIC(Instituto dos Mercados Públicos, do Imobiliário e da Construção) -- 葡萄牙公共采购监管机构,负责运营国家招标登记平台 Portal BASE。Fleet #3088 曾尝试直接访问 BASE,发现有两条可用路径,但都需要进一步处理:BASE 自有的旧版 REST API 会在响应过程中重置每个连接;IMPIC 较新的 API 则需要注册账户并获取令牌(Bruce 于 2026-10-15 决定“注册葡萄牙”以处理此事——这是单独且仍在进行的工作,本工具包不会等待它)。IMPIC 自身的文档称,较新的 API 返回的字段与其已作为开放数据发布的文件完全相同。这些文件由 IMPIC 发布在葡萄牙国家开放数据门户上 (https://dados.gov.pt/organizations/impic-i-p-instituto-dos-mercados-publicos-do) ——一个招标公告数据集和一个已授予合同数据集,每个数据集按日历年拆分为文件,每周更新。由于这两个数据集都不支持服务器端搜索,本工具包会根据它们构建存储库(scripts/portugal-tenders/load-data.mjs),而不是代理每个请求。这遵循 Bruce 于 2026-09-23 制定的长期规则:如果实时服务无法满足需求,就自行构建存储库,并提供刷新路径,且在每个响应中包含 data_as_of。

    **许可证(引自 dados.gov.pt 自身数据集 API,已于 2026-10-15 实时核验):**两个数据集均报告 "license": "other-pd"、"license_title": "Outra (Domínio Público)"——即公共领域,明确允许重复使用和再分发。这不属于适用“镜像需要再利用授权,但代理服务不需要”规则(mirror-needs-grant-proxy-does-not,Bruce,2026-09-08)的情况;许可证已包含所需授权。每个响应的 source/source_url 字段中均包含出处信息。

已知缺口——扩展此工具包前请先阅读

**此工具包仅保存滚动两年窗口(当年和上一日历年)的数据,而非 IMPIC 从 2012 年至 2026 年的完整历史记录。**仅已授予合同的数据,一整年就约有 190,000 行,未压缩的 JSON 约为 340MB(根据 2026 年部分年度数据于 2026-10-15 实时测得);若包含 15 年的数据,规模将达数 GB,远超单个工具包的 D1 数据库应承载的容量。 pt_announcement_search / pt_contract_search 每次返回无匹配结果时,都会报告已加载的数据窗口(ann_window_from/ann_window_to、contract_window_from/ contract_window_to),因此调用方可以区分确实没有结果,还是查询日期超出了已加载的数据范围。

buyer / supplier / query 筛选条件不会进行重音符号/变音符号折叠。 搜索 buyer: "camara" 不会匹配 “Câmara Municipal de Lisboa”——匹配方式是普通的、不区分大小写的子字符串匹配,不会将 “a” 视为等同于 “â”/“ã”。使用带重音符号的拼写(与 IMPIC 记录一致)即可搜索。以后可以通过添加规范化/折叠列来解决,前提是这确实导致了重要结果遗漏。

IMPIC 自身的公告 ID(IdIncm)并非始终唯一——“-1”哨兵值表示公告仅通过地方公报发布(例如亚速尔群岛的 JORAA),而非通过 Diário da República 发布;单一年份内就有数百条记录使用此哨兵值。因此,pt_announcement_detail 使用本工具包分配的合成内部 ID 作为键,该 ID 会通过 pt_announcement_search 作为 id 返回,而不是使用 IdIncm 本身(后者仍会返回供参考,且只要底层值为“-1”哨兵值,响应中就会将其设为 null)。

**目前仅构建了公告和已授予合同数据。**IMPIC 还在同一开放数据门户上发布合同修订数据集和采购方目录数据集;为使本工具包范围仅涵盖 fleet #3111 要求的功能(公告搜索、合同搜索、详情),这里未构建这两类数据。后续可添加其中任一类,而无需更改上述架构。

刷新数据

node scripts/portugal-tenders/load-data.mjs --years 2025,2026 [--retain-from-year 2025] [--init-schema on the very first run] -- 通过 dados.gov.pt 自身的数据集 API,实时解析每个请求年份的公告和合同资源(绝不使用写死的日期路径——底层存储 URL 包含一个时间戳片段,每次 IMPIC 每周刷新时都会变化),下载并流式传输数据,然后加载到 D1:公告按整年清空并重新加载(没有可靠的自然键——见“已知缺口”);合同则以 idcontrato 为键执行 upsert(INSERT OR REPLACE),因此重新加载已有年份只会刷新 IMPIC 更新过的行。需要已登录 Pipeworx Cloudflare 账户的 wrangler,以及 unzip CLI。

GitHub 工作流 .github/workflows/portugal-tenders-refresh.yml 每周运行一次,重新拉取当前和上一日历年,并滚动更新 --retain-from-year,避免表无限增长。

预部署冒烟测试(无需生产 D1)
node --experimental-strip-types scripts/portugal-tenders/build-local-sqlite.mjs \
  --year 2026 --ann <a downloaded anuncios2026.json> --contract <its extracted Contratos2026.json> \
  --out /tmp/portugal-tenders.sqlite
node --experimental-strip-types scripts/portugal-tenders/smoke-local.mjs /tmp/portugal-tenders.sqlite

通过基于真实 IMPIC 年度文件构建的本地 SQLite 文件和 D1Like 适配器,调用此工具包真正的 callTool() 进行测试——结构与 scripts/italy-tenders/{build-local-sqlite,smoke-local}.mjs 相同。

快速开始

添加到你的 MCP 客户端(Claude Desktop、Cursor、Windsurf 等):

{
  "mcpServers": {
    "portugal-tenders": {
      "url": "https://gateway.pipeworx.io/portugal-tenders/mcp"
    }
  }
}
此端点实际提供的内容

https://gateway.pipeworx.io/portugal-tenders/mcp 上的 tools/list 会返回上表中的工具,以及 Pipeworx 共享元工具——ask_pipeworx、discover_tools、search_within、remember/recall 和网关范围内的其他工具。因此,你看到的工具数量会多于此表:目前,单个工具包端点除了列出该工具包自己的工具外,还会列出大约 30 个共享工具。连接的 initialize 响应会说明其确切范围,是当天情况的权威依据。

这是有意设计的,并非意外进行的多路复用。元工具可以让限定范围的连接通过 ask_pipeworx 跨整个目录路由,从而回答此工具包无法涵盖的问题,无需你再添加第二个 MCP 服务。目前无法挂载不含这些元工具的工具包端点;如果额外的架构信息占用的上下文比路由带来的价值更大,请连接一次完整网关,而不是连接多个工具包端点。

或者连接完整的 Pipeworx 网关,以直接获取列出所有工具包的工具,而不只是此工具包的工具:

{
  "mcpServers": {
    "pipeworx": {
      "url": "https://gateway.pipeworx.io/mcp"
    }
  }
}

两个 URL 都会连接到同一个网关和同一组 1808 多个数据源。唯一的区别是哪个工具包的工具会被直接列出;无论连接哪个 URL,ask_pipeworx 都可以访问所有工具。

没有 MCP 客户端?通过 HTTP 调用

curl -X POST https://gateway.pipeworx.io/v1/tools/pt_announcement_search \
  -H 'Content-Type: application/json' \
  -d '{"query":"seguros","date_from":"2026-01-01","date_to":"2026-01-31","limit":5}'

首次调用无需账户。查看任意工具:GET https://gateway.pipeworx.io/v1/tools/pt_announcement_search。查找工具:POST https://gateway.pipeworx.io/v1/tools/search_packs,并传入 {"query":"..."}。

独立运行(无需网关账户)

此软件包也可以作为本地 stdio MCP 服务运行——无需 Pipeworx 账户,也无需通过网关往返:

{
  "mcpServers": {
    "portugal-tenders": {
      "command": "npx",
      "args": ["-y", "@pipeworx/mcp-portugal-tenders"]
    }
  }
}

或者直接运行,以确认服务可以启动:

npx -y @pipeworx/mcp-portugal-tenders

它通过 stdin/stdout 使用 MCP 协议,并仅为此工具包的工具响应 initialize/tools/list/tools/call——不包含上述网关连接提供的任何共享元工具。代码和工具相同,不提供 ask_pipeworx 路由。

与 ask_pipeworx 搭配使用

你也可以用通俗英文提问,而不是直接调用工具——此方式既适用于上面的工具包端点,也适用于完整网关:

ask_pipeworx({ question: "your question about Portugal Tenders data" })

网关会选择合适的工具并自动填写参数。

更多信息

许可证

MIT

评论

支持 Markdown

第一次接触 MCP?

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

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