Public Tenders Es Eu

io.github.nexus-mcp-infraPublished by GitHub account nexus-mcp-infrav1.0.0Updated Oct 24, 2026

Normalized search over public-sector tenders in TED (EU official procurement notices) -- Spain + EU

VerifiedStreamable HTTPWeb executableWeb Search & ScrapingBusiness & Commerce

Overview

AI-generated overview

Remote MCP server that lets an assistant search EU public procurement notices (TED), including Spain, by country, keyword, CPV code and date window.

What you can do
  • Search public-sector tender notices published in TED, the EU's official procurement notice platform, covering Spain and the rest of the EU.
  • Filter by buyer country, full-text keyword, CPV code prefix and how many days back to look, with a result limit.
  • Return notice details such as publication number, multilingual title and buyer name, buyer country, publication date, CPV classifications, total value where available, notice type and per-language detail links.
  • Report the total number of matching notices and flag when a response came from a one-hour cache.
When to use it
Useful when you want an assistant to look up current EU or Spanish public tenders, track what has been published recently in a sector or CPV area, or gather buyer and value details for procurement research without building your own TED client.
Requirements
A remote streamable HTTP endpoint; no package, account, API key or header is declared. Network access to the hosted service and to the upstream TED API is implied.
Before you install
The README states the HTTP search endpoint is billed at $0.01 per call, while MCP tool calls are currently not charged; check current pricing before relying on it. Coverage is limited to notices above the EU publication threshold, so Spanish sub-threshold tenders are absent. Results can be up to about an hour stale because of a one-hour query cache, and narrow CPV-prefix searches may return fewer matches than exist.

Installation

In SourceWeft

  1. Open Public Tenders Es Eu in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Web executable via Streamable HTTP. Remote servers run from the web runtime once configured in a workspace.

Use with an agent

Paste this prompt into Claude Code, Codex, Cursor or another agent — or into SourceWeft chat. The agent reads this server's install guide, shows you its publisher, endpoint and sign-in, and adds it to your client once you agree. Keys never go into a command.

Read https://sourceweft.com/mcp/io.github.nexus-mcp-infra%2Fpublic-tenders-es-eu/install.md and connect the MCP server it describes to my client. Before changing any config, show me its publisher, endpoint and sign-in method and wait for my OK. Never put an API key in a command or in a file I would commit; ask me where it should come from.

Read the install guide the agent follows

Other MCP clients

Add this to your client's mcpServers config.

{
  "mcpServers": {
    "public-tenders-es-eu": {
      "type": "http",
      "url": "https://public-tenders-es-eu-325572559480.us-central1.run.app/mcp"
    }
  }
}

README

Public Tenders ES/EU

Normalized search over public-sector tenders published in TED (Tenders Electronic Daily, the EU's official procurement notice platform) -- covers Spain plus the rest of the EU. NEXUS candidate #16 -- manual build, not FORGE-generated, same manual-Cloud-Run-asset pattern as candidates #3/#4/#6/#8/#9/#13.

  • POST /search-public-tenders {"country": "ESP", "keyword": null, "cpv_prefix": null, "days_back": 30, "limit": 20} -- $0.01/call.
  • MCP tool search_public_tenders at /mcp, same params -- currently free, see "Known limitations".
  • GET /health, GET /.well-known/agent-card.json, GET /openapi.json (has x-payment-info), GET /.well-known/402index-verify.txt (402index claim verification file).

Source: pivoted from the original brief, with explicit sign-off (2026-08-23)

The task brief named contrataciondelsectorpublico.gob.es/sindicacion/sindicacion_643/ (Spain's national PLACSP ATOM sindication feed) as "ya grounded de la sesión anterior". Verified live at the start of this session via two independent fetch paths (curl, WebFetch, with and without a browser User-Agent): 403 Forbidden, and the domain's own robots.txt is Disallow: / for the entire site -- a declared, site-wide block, not a rate limit. That would very likely also block Cloud Run (a datacenter IP range, the common target of this kind of WAF rule). Flagged to the user before writing any code (not silently substituted) -- user chose to pivot to TED.

TED (Tenders Electronic Daily, api.ted.europa.eu) is the EU Publications Office's own official public-procurement notice search API -- free, keyless, no documented auth. Verified live and field-by-field this session (a third-party README got query-field names wrong on the first pass -- e.g. claimed country-buyer where the real API only accepts buyer-country -- so every field/operator below was confirmed against the real API's own responses, not trusted secondhand):

  • POST https://api.ted.europa.eu/v3/notices/search with a JSON body of query (expert-search string), fields (array of eForms field names to return), limit, scope ("ACTIVE" or "ALL").
  • Query fields confirmed live: publication-date>=YYYYMMDD (8-digit, no dashes), buyer-country=ESP (ISO-3166 alpha-3), FT~"phrase" (full-text), AND, SORT BY publication-date DESC.
  • Output fields confirmed live: publication-number, notice-title (multilingual dict, keys like spa/ eng), buyer-name (multilingual dict of lists), buyer-country, publication-date, classification-cpv (list of CPV codes), total-value (not present on every notice type -- e.g. qualification-system notices don't carry one, this is normal, not an error), notice-type, links (per-language html/pdf/xml detail URLs).
  • Real query tested: buyer-country=ESP alone matched 26,314 notices in the ACTIVE scope at the time of this check; a publication-date + buyer-country combo matched 1,058 in an 8-day window -- real, current volume, not a stale/empty endpoint.

TED already covers Spain (any tender above the EU publication threshold appears with buyer-country=ESP) plus the rest of the EU, so it fits the "España/UE" framing of the original brief at least as well as the blocked national sub-threshold feed would have -- arguably better, since it's EU-wide by construction and not blocked. Scope difference from what the blocked source would have given: TED only carries notices above the EU publication threshold (a real, non-trivial floor -- Spain's own sub-threshold tenders, the ones PLACSP's national feed alone would have carried, are NOT in TED). This asset does not claim to cover those; total_matching_notices and each result's source: "TED" field make the actual coverage explicit to a buyer, not implied to be broader than it is.

State (db_constraint exception)

Every sibling manual asset (url-metadata-api, agent-verification-api, document-conversion-api, new-x402-listings-feed, onchain-activity-index, x402-receipt-verifier) is fully stateless -- each call hits its upstream fresh, no NEXUS-owned table beyond the standard traffic_events/revenue_events/ mcp_call_events telemetry trio. This is the first of the 8 manual/FORGE assets to need the case-by-case exception: a new table, tenders_query_cache (Supabase migration add_tenders_query_cache_candidate16, project ieduhdgfjdeffvzxvihf), read+written only by this asset.

Why: TED's own docs state there is no documented rate limit but ask callers to be reasonable with request volume on a shared public resource. Caching identical repeat queries (same country/keyword/ cpv_prefix/days_back/limit, bucketed to the hour) for 1 hour is being a good citizen of that guidance, not gratuitous state -- a cache hit is marked "cache_hit": true in the response so a buyer can see when this happened.

This is NOT the state the original PLACSP-scraping design would have needed. That design (walking an unfilterable ATOM feed, tracking "already seen" tender IDs to detect deltas -- the same shape as new-x402-listings-feed's catalog-walk cache) doesn't apply here: TED's own server-side publication-date>= filtering already answers "what's new since X" without this asset needing to remember anything about individual tenders itself. The only state kept is a short-lived response cache, not a tender index.

RLS: anon gets SELECT + INSERT on tenders_query_cache only -- no UPDATE/DELETE granted, same insert-append discipline as every other NEXUS telemetry table. A cache "overwrite" is really just a new row with a newer cached_at; the lookup query always picks the freshest row within the TTL window. Stale rows past the 1-hour TTL are never deleted -- unbounded growth over the 7-day probation window is negligible (one row per distinct query per hour) and accepted for now; a real cleanup would need either a scheduled job or a DELETE grant this asset doesn't otherwise need.

Deploy target: Cloud Run

Same pipeline as candidates #4/#3/#6/#8/#9/#13 -- see skills/infra-deploy-ops.

bash
# 1. First deploy -- PUBLIC_DOMAIN not known yet, every real request 421s until step 2../scripts/deploy_cloud_run.sh public-tenders-es-eu manual_assets/public-tenders-es-eu
# 2. Grab the printed *.run.app URL, then (only if it differs from env-vars.deploy.yaml's guess):gcloud run services update public-tenders-es-eu --region us-central1 --project nexus-505016 \    --update-env-vars PUBLIC_DOMAIN=<the-real-domain>

Known limitations (left unfixed on purpose -- CLAUDE.md SS3, no gate without evidence it's needed)

  • MCP tool calls are not charged. Same in-process-call pattern as every other manual asset in this codebase.
  • Only EU-publication-threshold tenders. See "Source" above -- Spain's sub-threshold national tenders are not in TED and not covered by this asset.
  • cpv_prefix is filtered client-side, after fetching. TED's query syntax doesn't support CPV-prefix matching server-side; this asset over-fetches (3x limit, capped at 50) when cpv_prefix is set, then filters in-process. A caller with a very narrow cpv_prefix against a broad days_back window could get fewer real matches than exist in TED's full result set beyond what was over-fetched.
  • Cache is a plain 1-hour TTL, not invalidated on new TED publications. A query repeated within the same hour bucket can return results that are up to ~1 hour stale relative to TED. Disclosed via cache_hit in every response.
  • No per-caller rate limiting. Fine for a 7-day disposable measurement window.
  • tenders_query_cache rows are never deleted. See "State" above.

Quality gate (2026-08-23, from design not retroactive)

Same 2-agent process as candidates #3/#4/#6/#8/#9/#13 (security lens; functional+quality+buyer-experience lens) -- results filled in below once run.

Measurement (candidate #16, 7-day window)

7-day window from 2026-08-23 (real deploy date) -> decision point 2026-08-30. Source of truth: traffic_events/revenue_events/mcp_call_events (asset_name = 'public-tenders-es-eu'), not Cloud Run logs. Day 7: if zero real traffic (filtering crawlers), pause/delete the Cloud Run service (gcloud run services delete public-tenders-es-eu --region us-central1 --project nexus-505016).

Source: README.md at commit 7a492dc

Tools

0
SourceWeft has not read this server's tools yet.

Version history

1
  1. v1.0.0LatestSep 16, 2026

Score

75% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 daysRequired25 pts
  • Auth declaredRequired10 pts
  • Tools listedRequired15 pts

    Answer tools/list without a credential, or ship a package that starts in a sandbox without one.

  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts

    Declare a license in the repository or the registry entry.