vergabe-mcp
vergabe-mcp
一个用于 oeffentlichevergabe.de 的 MCP 服务器,后者是德国联邦公共招标门户。德国所有公共招标都会在此发布,并提供批量开放数据导出,但该导出会延迟一天,以每日 ZIP 形式提供,且无法筛选——你需要下载所有数据然后自行整理。门户自身的搜索 API 可以进行筛选(CPV 代码、地区、截止日期窗口、eForms 的“适合自由职业者”标志),并且在公告发布时即刻更新,但该 API 没有文档。此服务器对其进行了封装,因此任何 MCP 客户端都可以使用真实筛选条件搜索实时信息流,并以门户领域模型、eForms XML 或 OCDS 格式拉取公告。匿名使用,无需 API 密钥,无需账户。
逆向工程的 API 参考文档位于 docs/API.md —— 如果你想直接调用端点而非通过 MCP,它本身即可独立使用。
安装
无需安装;直接使用 npx 运行。
Claude Code
claude mcp add vergabe -- npx vergabe-mcpClaude Desktop —— 在 claude_desktop_config.json 中:
{
"mcpServers": {
"vergabe": {
"command": "npx",
"args": ["vergabe-mcp"]
}
}
}任何其他 stdio 客户端
npx vergabe-mcpStreamable HTTP,如果你的客户端需要 URL 而不是子进程:
npx vergabe-mcp --http --port 3000Related MCP server: germany-tenders
工具
工具 | 功能说明 |
| 使用平面参数搜索标段 —— 自由文本、CPV 前缀、 |
| 按 ID 获取一个公告,返回策划的 |
| 原生 |
| 将 CPV 或 NUTS 代码解析为德文或英文描述。 |
| 构建某天或某月的批量开放数据导出 URL,并附带相关说明。 |
所有五个工具均为只读;服务器不写入任何内容,不在磁盘上存储任何数据,也不持有任何凭证。
资源。 vergabe://api-reference 提供 API 文档,以便客户端在编写查询前了解后端实际支持的功能。模板涵盖单个公告 —— vergabe://notice/{noticeId}、.../eforms、.../ocds —— 以及 vergabe://codelist/{list}/{code}。
提示词。 find-solo-tenders(参数:keywords、cpv、maxDays)使用自由职业者/自雇标志进行搜索,然后引导模型进行候选筛选:描述中隐含的人日数、临近截止日期是参与请求还是报价本身、空值字段意味着什么。该筛选知识作为提示词提供,而非评分代码,以便你可以与之讨论。
示例
你: 查找标记为适合自由职业者的开放式 IT 招标。
模型调用 search_tenders,参数为 cpv: ["72"]、suitableFor: ["freelance"]、onlyActive: true。在 2026-08-17 这一天,结果是 30 个开放标段,其中有:
{
"noticeId": "7c70692d-dfb9-4b96-b777-4a5539eaee50",
"title": "Beschaffung einer Beratungsdienstleistung zur Fachberatung im Rahmen eines Identity and Access Management (IAM) Projektes für die Stadtwerke Bielefeld (SWB)",
"lotTitle": "Beratungsdienstleistung zur Fachberatung im Rahmen eines Identity and Access Management (IAM) Projektes",
"buyer": "Stadtwerke Bielefeld GmbH",
"cpv": "72260000",
"noticeType": "cn-standard",
"nature": "services",
"deadline": "2026-09-14T10:00:00+02:00",
"published": "2026-08-12T00:00:00+02:00"
}然后它对感兴趣的标段调用 get_tender 以读取描述、估计价值和排除理由,之后再告诉你哪些值得投标 —— 这一判断是模型的任务,服务器故意不进行任何评分。
注意该结果中数据的形状:这里的截止日期是 deadlineReceiptRequests,即参与请求,而非报价截止日期。find-solo-tenders 提示词之所以存在,正是因为这类区别决定了某个招标是否可供投标。
开发
Node 20 或更新版本。
npm install
npm test # vitest, no network
npm run typecheck
npm run lint # biome集成测试会访问实时门户,除非你要求,否则会被跳过:
VERGABE_LIVE=1 npm test提交遵循 Conventional Commits;release-please 将其转换为 main 分支上的发布 PR —— 合并该 PR 会标记发布、写入变更日志、发布到 npm,并将 tarball 附加到 GitHub 发布。提交类型决定版本号的提升。
许可证
MIT。
Available Tools
5 toolsget_export_urlBulk export URLARead-only
Builds the URL of the official bulk export for one day or month. The file is a large ZIP, so download it outside this server.
| Name | Required | Description | Default |
|---|---|---|---|
| day | No | YYYY-MM-DD, must already be closed. | |
| month | No | YYYY-MM. | |
| format | No | eforms.zip |
Output Schema
| Name | Required | Description |
|---|---|---|
| url | Yes | |
| note | Yes | |
| format | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint and openWorldHint. The description adds actionable advice: 'download it outside this server' due to the large ZIP size. This enhances transparency beyond the annotations, though it could mention rate limits or authentication requirements.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description consists of two efficient sentences: the first states the core purpose, and the second provides a critical behavioral caveat. No redundant information, every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers the main purpose and a key usage note. However, it is missing clarity on whether 'day' and 'month' are mutually exclusive or what happens when both are omitted (all parameters optional). Output schema may fill gaps, but a small clarification would make the description fully self-contained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is high (67%), with clear format descriptions for 'day' and 'month' and an enum for 'format'. The tool description adds no further parameter meaning beyond what the schema already provides, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb ('Builds the URL') and the resource ('official bulk export for one day or month'). It distinguishes the tool from sibling tools like 'search_tenders' and 'get_tender' by focusing on bulk export URL generation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not provide any guidance on when to use this tool versus alternatives or how to choose between the 'day' and 'month' parameters. It only mentions a precondition ('must already be closed') without explaining the use case for each parameter option.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_tenderGet one noticeARead-only
Fetches a single notice. 'summary' extracts the fields a bidder decides on (deadlines, lot values, suitableFor, document links); the other formats are returned verbatim.
| Name | Required | Description | Default |
|---|---|---|---|
| format | No | summary = curated extraction; domain/ocds = full JSON; eforms = original XML. | summary |
| noticeId | Yes | Notice identifier (UUID) from a search result. | |
| noticeVersion | No | Version like '01'; defaults to the latest published one. |
Output Schema
| Name | Required | Description |
|---|---|---|
| raw | No | Verbatim response body for the non-summary formats. |
| uri | Yes | Canonical resource URI for the same document. |
| format | Yes | |
| summary | No | Only for format 'summary'. |
| noticeId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint and openWorldHint, correctly indicating no side effects and external data mutability. The description adds value by detailing the behavioral difference between formats: summary is a curated extraction, while other formats are returned verbatim. This goes beyond what annotations offer.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences: the first states the core purpose, the second explains the critical format differentiation. No redundant information; every sentence earns its place. Highly front-loaded and efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has few parameters (all described in schema), an output schema, and comprehensive annotations, the description covers the essential behavioral nuance of formats. It could mention the default version behavior or error handling, but the agent has sufficient information for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so baseline is 3. The description adds meaningful context for the 'format' parameter by explaining what 'summary' extracts (deadlines, lot values, suitableFor, document links) and that other formats are verbatim. This enhances agent understanding beyond the schema's enum descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states it fetches a single notice, uses a specific verb ('fetches'), and explains the key distinction between the 'summary' format (curated extraction of bidder-relevant fields) and other verbatim formats. This effectively distinguishes it from sibling search tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
While the description implies the tool is for retrieving a single notice after obtaining an ID from a search, it does not explicitly state when to use it versus alternatives like search_tenders. No exclusion criteria or alternative tools are mentioned, leaving the agent to infer usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
lookup_codeLook up a CPV or NUTS codeBRead-only
Resolves a CPV or NUTS code to its official description.
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes | ||
| list | Yes | ||
| language | No | de |
Output Schema
| Name | Required | Description |
|---|---|---|
| code | Yes | |
| list | Yes | |
| description | No | |
| descriptionDefault | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true, indicating safe read-only operation with a known set of codes. The description adds no extra behavioral context beyond 'resolves to official description', which is consistent but not additional.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no wasted words, but it is under-specified rather than efficiently complete. It is concise but sacrifices necessary detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given three parameters (two required, with enums) and an output schema, the description lacks context about code format, case sensitivity, or the nature of the official description. The output schema is not shown, but even with it, the description should provide usage context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It mentions 'CPV or NUTS code' hinting at the 'list' and 'code' parameters, but does not explain the 'language' parameter or the expected format of the code. This is insufficient for three parameters with no schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the verb 'resolves' and the resource 'CPV or NUTS code' to its 'official description'. It is distinct from siblings like 'search_tenders' which deal with tenders, not code resolution.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives, no prerequisites, and no exclusions. The description only states what it does, not when or why to invoke it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_tendersSearch German public tendersARead-only
Searches lots on oeffentlichevergabe.de. Defaults to open lots of the competition notice types (cn-standard, cn-social, cn-desg, subco, qu-sy, pin-cfc-standard, pin-cfc-social), newest first. Use search_tenders_raw for anything this does not cover.
| Name | Required | Description | Default |
|---|---|---|---|
| cpv | No | CPV code prefixes, OR-ed, e.g. ['72', '7921']. | |
| nuts | No | NUTS codes of the place of performance. | |
| page | No | ||
| sort | No | publicationDate | |
| text | No | Free-text query across the whole notice (allFreeText). | |
| maxValue | No | Estimated value in EUR. Set on roughly 8.5% of lots. | |
| minValue | No | Estimated value in EUR. Set on roughly 8.5% of lots. | |
| pageSize | No | ||
| platform | No | Contracting platform host, e.g. 'evergabe-online.de'. | |
| textMode | No | How `text` is matched: all words, any word, or substring. | all |
| onlyActive | No | Restrict to lots that are still open. | |
| noticeTypes | No | eForms notice types; defaults to the competition set (cn-standard, qu-sy, …). | |
| suitableFor | No | BT-726 business types the buyer marked the lot suitable for. | |
| deadlineAfter | No | ISO date or datetime; keeps lots whose first deadline is later. | |
| sortDirection | No | DESC | |
| contractNature | No | ||
| publishedSince | No | ISO date or datetime, inclusive lower bound. | |
| publishedBefore | No | ISO date or datetime, inclusive upper bound. | |
| deadlineAtLeastDaysAway | No | Keep lots whose first deadline is at least N days out — bidding runway. |
Output Schema
| Name | Required | Description |
|---|---|---|
| page | Yes | |
| total | Yes | |
| results | Yes | |
| pageSize | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint and openWorldHint. Description adds default filtering and sorting behavior, as well as the specific website. No contradictions. Adds useful context beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with core action and defaults. Second sentence provides key alternative. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 19 optional parameters, an output schema that documents return values, and a sibling tool reference, the description is sufficiently complete. It covers the tool's purpose, defaults, and when to use an alternative.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 74%, so the schema already documents most parameters. The description mentions defaults for onlyActive, noticeTypes, and sort, but these are already in the schema. No new parameter semantics beyond what schema provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specifically states it searches lots on oeffentlichevergabe.de with defaults (open lots, competition notice types, newest first). Clearly distinguishes from sibling search_tenders_raw by saying 'use for anything this does not cover'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly provides default behavior and references an alternative tool for cases not covered. This gives clear when-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_tenders_rawSearch with the native DSLARead-only
Posts a WHERE/FROM/PAGE/ORDER query to /bkmk/searches unchanged. Operators: =, >, >=, <, <=, IN, STARTS_WITH, CONTAINS, MATCH_ALL, MATCH_ANY, RANGE_DAYS. Fields on lots: allFreeText, description, allCpvCodes, allContractNatures, active, noticeType, suitableFor (freelance|selbst|startup|other-sme), estimatedValue ('150000 EUR'), publicationDate, firstDeadline, allDeadlines, allPlacesOfPerformanceNutsCodes, contractingPlatform, procedureType, procedureLegalBasis, procedureIdentifier. Text and temporal operators take exactly one operand; IN and STARTS_WITH OR a list. RANGE_DAYS n means field >= midnight Europe/Berlin of today + n days, not a window. See the vergabe://api-reference resource for the full contract.
| Name | Required | Description | Default |
|---|---|---|---|
| FROM | No | 'notices' has a smaller field set, rejects active/suitableFor and ignores ORDER. | lots |
| PAGE | No | ||
| ORDER | No | Other fields answer HTTP 500. | |
| WHERE | No | ||
| SELECT | No | 'ALL' or a projection of field names. | ALL |
Output Schema
| Name | Required | Description |
|---|---|---|
| offset | Yes | |
| elements | Yes | |
| totalElements | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare readOnlyHint=true and openWorldHint=true. The description aligns: it describes a read operation ('posts a query ... unchanged') and adds behavioral nuances not covered by annotations, such as: 'RANGE_DAYS n means field >= midnight Europe/Berlin of today + n days, not a window', 'Other fields answer HTTP 500' for ORDER, and operator operand constraints. No contradiction.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single dense paragraph. It front-loads the core action and then dumps operators and fields. While every sentence adds value, the lack of bullet points or breaks may hinder quick scanning. However, it is not verbose and efficiently packs necessary information. Could be slightly more structured but still effective.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 5 parameters (0 required), nested objects, an output schema, and high complexity, the description covers query structure, operator semantics, field lists, FROM variations, ORDER limitations, and provides a reference to a full contract. It addresses pagination implicitly via PAGE parameter, and mentions error behavior for ORDER. No major gaps for a power-user tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 60%, but the description adds substantial meaning beyond the input schema. It enumerates all operators with their operand requirements (e.g., 'Text and temporal operators take exactly one operand; IN and STARTS_WITH OR a list'), lists all field names on lots with examples (e.g., 'estimatedValue (''150000 EUR'')'), and clarifies constraints like RANGE_DAYS behavior. This compensates for schema gaps and aids correct parameter construction.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific action: 'Posts a WHERE/FROM/PAGE/ORDER query to /bkmk/searches unchanged.' It names the HTTP method (POST), the endpoint, the query structure, and lists operators and fields. This clearly distinguishes it from the sibling 'search_tenders' tool, which likely provides a simpler search interface.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides extensive operator and field listings, guiding the agent on how to construct queries. It also notes that the 'notices' FROM value has a smaller field set. However, it does not explicitly compare with the sibling 'search_tenders' to state when to use this raw DSL version versus a simpler alternative. Missing explicit when-not or alternatives, but the detail implies usage for complex filtering.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v1.0.1- First observed
get_export_url - First observed
get_tender - First observed
lookup_code - First observed
search_tenders - First observed
search_tenders_raw
TDQS
Scored across 5 tools
Each tool targets a distinct operation: searching tenders, fetching details, raw querying, code lookup, and export URL generation. There is no overlap between their purposes.
All tool names follow a clear verb_noun pattern (search_tenders, get_tender, search_tenders_raw, lookup_code, get_export_url). The conventions are uniform and predictable.
Five tools are well-scoped for a public procurement domain. Each tool addresses a necessary function without being excessive or insufficient.
Core workflows for searching, fetching, raw querying, code lookup, and export are covered. Minor gaps like bulk export download instructions are handled via external guidance, which is acceptable.
Maintenance
Related MCP Connectors
Germany public procurement MCP — official German government tenders (keyless).
MCP server for French (BOAMP) + EU (TED) public procurement data via TenderAPI.
TED MCP Server: Real-time EU public tenders access. https://www.lexsocket.ai/
Search public procurement notices from 17 sources across Germany, the EU and the UK. Read-only.
Related MCP Servers
- AlicenseAqualityBmaintenanceMCP server for German public procurement data (OCDS). Semantic search, tender matching, and company profiles — all from your local LLM105MIT
- AlicenseNot gradedqualityBmaintenanceAccess official German government public procurement tenders via MCP, with keyless access.368 npmMIT
- AlicenseAqualityAmaintenanceMCP server providing read access to Swiss public procurement data via the official simap.ch API, covering all cantons and the Confederation with intraday updates. It enables searching tenders, awards, construction codes, and procurement offices through natural language queries.9160 PyPIMIT

vartoofficial
FlicenseNot gradedqualityBmaintenanceMCP server for Ukrainian public procurement (Prozorro) that exposes tools to search tenders, retrieve tender details and cards, list and read tender documents.-