# TED MCP > Model Context Protocol server for Tenders Electronic Daily (TED), the European > Union's official public procurement journal. Gives AI agents structured access > to every procurement notice published across all 27 EU member states. Endpoint: https://ted-mcp.eu/mcp Transport: streamable HTTP Authentication: none for finding and reading notices — search_notices, get_notice, get_notices_by_buyer, search_upcoming_deadlines, list_cpv_codes and health need no account and no key. Everything else requires an active riigihanked.eu subscription: buyer profiles, market analytics and legal-basis lookup; the project tools; and the AI features (semantic_search, recommend_tenders, recommend_for_project, summarize_notice, and the site's Ask-TED chat). Those use standard OAuth 2.1, and signing in is one tool call: `authenticate`, which is open to everyone and answers 401 with a WWW-Authenticate header pointing at https://ted-mcp.eu/.well-known/oauth-protected-resource/mcp. Register dynamically (RFC 7591) and run the authorization-code flow with PKCE S256. No token is ever pasted by hand. A client without OAuth support surfaces that 401 as a generic authorization/transport error — that is the client discarding the response body, not an outage; the free tools keep working over the same connection. Operated by: riigihanked.eu (independent reuser of EU open data) ## Connect If MCP tools are not available in your session, do **not** reverse-engineer JSON-RPC against https://ted-mcp.eu/mcp and do not open it as a webpage. Use REST instead, or connect the client properly. Claude Code: claude mcp add --transport http ted-mcp https://ted-mcp.eu/mcp Codex: codex mcp add ted-mcp --url https://ted-mcp.eu/mcp Claude Desktop: Settings > Connectors > Add custom connector > https://ted-mcp.eu/mcp ChatGPT: enable Developer mode (Settings > Security and login), then chatgpt.com/plugins > + > paste https://ted-mcp.eu/mcp REST fallback (no MCP client needed), e.g. new open Estonia notices this week: https://ted-mcp.eu/api/v1/search?countries=EST&published_after=today(-7)&deadline_after=today&limit=50 GET https://ted-mcp.eu/mcp with Accept: text/markdown returns the same playbook. Cursor, in ~/.cursor/mcp.json: {"mcpServers": {"ted-mcp": {"url": "https://ted-mcp.eu/mcp"}}} VS Code, in .vscode/mcp.json: {"servers": {"ted-mcp": {"type": "http", "url": "https://ted-mcp.eu/mcp"}}} Windsurf uses the key `serverUrl`; Zed uses `context_servers`; Cline needs `"type": "streamableHttp"`; Goose uses `uri` with `type: streamable_http`. Full list: https://ted-mcp.eu/#install ## One endpoint, and signing in is one tool call https://ted-mcp.eu/mcp is the only address. It connects without any credential and serves the free tools immediately — it never demands a sign-in to reach them — and it advertises the sign-in anyway: every response it sends, including successful ones, carries a WWW-Authenticate header pointing at https://ted-mcp.eu/.well-known/oauth-protected-resource/mcp. So a client can offer a "Sign in" control from the moment it connects, without anyone first being refused anything. To sign in, call the `authenticate` tool. It is in the tool list of every connection, open to everyone, and without a token it answers 401 with a challenge asking for all three scopes at once, so one consent unlocks everything. Called with a token, it reports the account, its scopes and what is unlocked. There is no second URL to reconfigure with, and no token is ever pasted by hand. If you have nowhere to redirect to — a CLI, a container, a cron job — use the device grant (RFC 8628) instead, which is also the claim ceremony auth.md describes. POST client_id and scope to https://ted-mcp.eu/oauth/device_authorization, show the user the short user_code and the verification_uri you get back, then poll https://ted-mcp.eu/oauth/token with grant_type=urn:ietf:params:oauth:grant-type:device_code no faster than the interval you were given. authorization_pending and slow_down both mean carry on. The user signs in wherever they do have a browser; their phone will do. Full procedure: https://ted-mcp.eu/auth.md ## Every notice carries two links - view_url — https://ted-mcp.eu/view/{publication_number}. The notice rendered for reading: buyer, sectors, values with their own currencies, deadline. Use this when offering a person something to open, instead of pasting a whole notice into a conversation. - ted_url — the notice on ted.europa.eu. The authoritative record, and what to cite when the decision matters: a bid, a deadline, a legal question. Do not construct it yourself; `/en/notice/{n}/html` downloads a file rather than opening a page, and a bare `/en/notice/{n}` is a 404. Offer view_url to read, cite ted_url to rely on. ted-mcp.eu renders EU open data; it does not replace the Official Journal. ## Tools - search_notices — search notices by keyword, CPV sector code, country, contract value or date. Also accepts a raw TED expert query. Arguments: query, cpv_codes[], countries[] (ISO-3166 alpha-3; alpha-2 accepted), notice_types[], value_eur_min, value_eur_max, published_after, published_before, deadline_after, deadline_before, expert_query, scope (ACTIVE|LATEST|ALL), biddable (true = future deadline only), limit, page. Dates: YYYY-MM-DD, today(±N), this_week, this_month. ACTIVE includes notices with no deadline; use biddable=true for open-to-bid. - get_notice — full detail for one notice by publication number (00676595-2024 for eForms, 123456-2023 for legacy). Arguments: notice_id, lang, enrich, include_raw. - get_notices_by_buyer — every notice from one contracting authority. Arguments: buyer_name, limit. - get_buyer_profile — what a contracting authority buys, how often and how much: notice count and period, awards, total awarded value in EUR, breakdown by year and sector, and recent notices. Arguments: buyer_name. Subscriber feature. - search_upcoming_deadlines — tenders closing within N days, sorted by urgency. Arguments: days, cpv_codes[], countries[], limit. - list_cpv_codes — resolve a sector described in words into CPV codes. Labels in English, Estonian, French, German and Italian. Arguments: query, parent, lang, limit. - market_analytics — aggregate a market: notice counts, median and total value, top buyers, geographic spread, and the data_window actually aggregated. Arguments: cpv_codes[], countries[], months (up to 24). Subscriber feature. - explain_legal_basis — the EU directive a notice sits under, with EUR-Lex and national-law pointers. Arguments: notice_id or celex. Subscriber feature. - list_projects — the projects saved through TED by this account, with their keys. Subscriber feature; it is how a lost project key is recovered. These are this server's own storage, not the projects kept in the riigihanked.eu web application — separate systems, and neither lists the other's. - create_project / get_project / update_project / save_to_project — durable memory for an agent: save a company profile and a shortlist of notices, and come back to them in a later session. Subscriber feature. A project belongs to one account and opens for nobody else: the project_key names a project, it does not authorise access to it. Projects always cover Estonia (riigihanked.eu is an Estonian service); other countries can be added alongside. Saved items cannot be deleted through MCP — ask riigihanked.eu support. - semantic_search — find notices by meaning rather than words, across all 24 languages. Subscriber feature (see Authentication). - recommend_tenders — match open tenders to a company profile. Subscriber. - recommend_for_project — open tenders matching a saved project. Subscriber. - summarize_notice — plain-language summary of one notice. Subscriber. - health — service status and remaining upstream request budget. - authenticate — sign in to a riigihanked.eu subscription, or report which account this connection is signed in as and what it unlocks. Open to everyone; no arguments. This is the whole sign-in procedure. ## Delegate a task instead (A2A) There is also an A2A agent at https://ted-mcp.eu/a2a, described by its card at https://ted-mcp.eu/.well-known/agent-card.json. Use it when you would rather hand over a piece of research than drive the tools yourself: send one message, get a task id back immediately, and poll it while the work runs here. It speaks JSON-RPC — SendMessage, GetTask, CancelTask (the older message/send, tasks/get and tasks/cancel spellings are accepted too) — and answers with artifacts attached to the task. Four skills: tender-search, deadline-watch, market-brief and buyer-brief. Name one in the message metadata as `skill`, or just describe what you want. Pass structured parameters as a data part alongside the text. Unlike MCP, every A2A call needs a token, because a task keeps running after the request that made it returns. market-brief and buyer-brief additionally need the same subscription their MCP counterparts do. The card is public, so all of this is readable before you have a token. ## Markdown for agents Every HTML page on this site answers in markdown to a request that asks for it: curl -H 'Accept: text/markdown' https://ted-mcp.eu/ Those documents say what the page is for and where its data actually lives, rather than being the markup converted — three of the four pages fetch their content from the API after loading, so converting them would only hand you the word "Loading". A bare */* still gets HTML. ## Agent skill A skill teaching an agent to use these tools well — which tool answers which question, the CPV hierarchy, ISO-3166 alpha-3 country codes, what `scope` changes, how to read a missing value, and the pitfalls that silently return nothing: https://ted-mcp.eu/skill Also readable over MCP as the resource `ted://skill`. Install it as an Agent Skill by saving it to skills/ted-mcp/SKILL.md in your project. ## Resources - ted://skill — usage guidance for these tools - ted://notices/{publication_number} — one notice as JSON - ted://taxonomy/cpv — CPV vocabulary sample - ted://status/sync — data freshness and request budget ## Prompts - analyze_tender — analyse one notice from a supplier's point of view - bid_readiness_audit — assess a company against a tender's requirements - compare_notices — compare several notices side by side ## Conventions Publication numbers: 8 digits + year for eForms notices (mandatory since October 2023), 6 digits + year for legacy notices. Countries: ISO-3166 alpha-3 (EST, DEU, FRA, ITA). CPV: 8-digit Common Procurement Vocabulary codes; 45000000 is construction work, 72000000 is IT services. 9,454 codes are indexed. Dates: ISO YYYY-MM-DD, TED YYYYMMDD, or relative today(+30) / today(-7). ## REST API Also available without MCP, same data: https://ted-mcp.eu/api/v1/search?countries=EST&cpv=72000000&limit=10 https://ted-mcp.eu/api/v1/notices/{publication_number} https://ted-mcp.eu/api/v1/deadlines?days=14&countries=EST https://ted-mcp.eu/api/v1/buyers/{name}/profile https://ted-mcp.eu/api/v1/cpv?q=dental&lang=et Discovery documents: https://ted-mcp.eu/.well-known/mcp.json — MCP manifest https://ted-mcp.eu/.well-known/mcp/server-card.json — MCP Server Card (SEP-1649) https://ted-mcp.eu/.well-known/agent-card.json — A2A Agent Card https://ted-mcp.eu/.well-known/api-catalog — RFC 9727 linkset https://ted-mcp.eu/.well-known/oauth-protected-resource/mcp — RFC 9728 https://ted-mcp.eu/.well-known/oauth-authorization-server — RFC 8414 https://ted-mcp.eu/auth.md — how to enrol, in prose ## Data and licensing Notices originate from Tenders Electronic Daily, published by the Publications Office of the European Union, and are freely reusable for commercial and non-commercial purposes under Commission Decision 2011/833/EU. Around 520,000 notices are published each year. TED MCP is an independent service and is not affiliated with or endorsed by the European Union.