Lucius has always had two halves. One is an index of public procurement notices, pulled from the official portals of the United States, the European Union, the United Kingdom, Australia, Canada, Ireland, New Zealand, Singapore, India, the UN agencies and the World Bank. The other is a verification engine that reads a tender pack and returns every requirement with the page it came from. Until today both lived behind our own screens. From today the index is open to agents.
If you run an agent, a copilot or a workflow that has to answer "is there a tender for this, and when does it close", you can now ask Lucius directly. Three tools, one key, two transports: plain REST, and an MCP server so Claude Code, Claude Desktop, Cursor and any other MCP client can use the index as a tool with one line of configuration. This post says what is in the index, what an agent gets back, how a search runs, and the rules.
What is in the index
On 23 September 2026 the catalog held 235,415 notices from 15 feeds on 14 official portals (AusTender arrives as two feeds), tagged with 181 country and region codes. 42,572 of them were still open by deadline. 13,374 were added in the previous seven days, which is the pace the portals publish at. 235,278 rows carry a 3,072-dimension embedding, so the whole catalog is searchable by meaning as well as by words. The Grants.gov rows are funding opportunities rather than contracts; they stay in because the agents we talk to ask for both.
Each row is what a bid manager needs before deciding whether to open the pack: title, buyer, country, deadline, value where the buyer published one, CPV codes, the source portal and a link to the notice there. The full notice text is not part of the index we serve. The portals publish it, and the link takes you to it. More on that under the rules.
Three tools
search_tenders. Send a query, optional countries, a source, a CPV prefix, a closing window, a limit up to 25 and a cursor. Get ranked notices with their metadata, a snippet of up to 700 characters and a relevance score, plus a cursor for the next page. Spends one embedding call.
get_tender. Send a notice id. Get the notice's metadata, and if your own workspace has analysed that notice, its summary and bid verdict too. Spends no model time.
similar_tenders. Send a notice id, optional countries and a limit up to 25. Get the nearest notices by stored embedding. Spends no model time.
The same three tools sit behind both transports. Over REST they are three GET endpoints. Over MCP they are three tools with the same names and the same arguments, so a prompt that says "find open solar pumping tenders in East Africa closing in the next sixty days" turns into one call, and the agent reads the rows back as a tool result.
One request, end to end
A key looks like lk_live_ followed by 32 characters and travels in the Authorization header. Each key belongs to a company workspace, so what an agent can see is exactly what a person in that workspace can see: the public catalog, plus that workspace's own analysed copies. The defaults are 60 requests a minute and 2,000 results a day, both adjustable per partner without a deploy. Usage is one row per key per day in the database, and the cap check and the count are one statement, so two calls racing each other cannot both slip through.
How a search runs
Search is hybrid. The query is embedded once. A full-text leg runs over a stored tsvector of the title and text and ranks by term match. A vector leg runs over the ScaNN index by cosine distance, and for a market with fewer than 2,000 rows it takes an exact scan instead, because at that size exact is cheaper than approximate. Rank fusion merges the two lists into one, the catalog scope and the filters run on the merged list, and each row is cut to a snippet. On production on 22 September the vector leg averaged 141 milliseconds on the exact path and 180 milliseconds on the ScaNN path, measured from the database's own statement statistics. One end-to-end REST search over the public internet on 23 September, five results, took 0.7 seconds. That last number is a single call, not a benchmark; the two means are thousands of calls.
Quick start
MCP, from Claude Code, one line:
claude mcp add --transport http lucius-tenders https://api.ailucius.com/api/v1/mcp \
--header "Authorization: Bearer lk_live_..."
Any MCP client that takes a JSON config:
{
"mcpServers": {
"lucius-tenders": {
"type": "http",
"url": "https://api.ailucius.com/api/v1/mcp",
"headers": { "Authorization": "Bearer lk_live_..." }
}
}
}
REST, the same three tools:
curl -H "Authorization: Bearer lk_live_..." \
"https://api.ailucius.com/api/v1/ext/tenders/search?query=solar+water+pumping&countries=NE,KE,UG,ET&closing_within_days=60&limit=5"
curl -H "Authorization: Bearer lk_live_..." \
"https://api.ailucius.com/api/v1/ext/tenders/{id}"
curl -H "Authorization: Bearer lk_live_..." \
"https://api.ailucius.com/api/v1/ext/tenders/{id}/similar?countries=DE&limit=5"
What a search returns, shortened to one row:
{
"results": [
{
"id": "…",
"title": "Procurement of Solar Powered Water Pump under UNJP/ETH/140/UNJ project",
"buyer": "FAO",
"country": "ET",
"deadline_at": "2026-09-30T…",
"value": null,
"cpv_codes": [],
"source": "UNGM",
"source_url": "https://www.ungm.org/Public/Notice/…",
"snippet": "…",
"relevance": 0.83
}
],
"mode": "hybrid",
"next_cursor": "NToyOTc3N2FlMThh"
}
The full reference, with every argument and limit, is at ailucius.com/developers.
The rules
- Keys are issued by hand. There is no self-serve key page yet. Write to davor@ailucius.com with the company name and what you are building, and a key comes back with the limits set for that use.
- Read only. This release exposes the index. Nothing an agent does through it changes a row.
- Metadata, a snippet and a link. The response never carries the full notice text. Every row links to the notice on the portal that published it, and the portals' own terms apply to what you do with it from there.
- Limits are real. 60 requests a minute and 2,000 results a day by default. A key that hits its cap gets a clear refusal, not a degraded answer.
- Your workspace, your data. A key sees the public catalog and its own workspace's analysed copies. It never sees another workspace.
Why open it
Two reasons. The first is that every agent builder we talk to who touches procurement data has written the same thing: a scraper for one portal, then another, then a cron job that breaks when the portal changes its HTML. The index is the part of Lucius that gets more useful the more people query it, and it is already the part that costs the least to serve. The second is that most of the funded tools in this market are single-country or drafting-first, and an agent that can qualify tenders across fourteen portals is a better front door for the verification engine than a person who has to paste a PDF.
The engineering behind the index, AlloyDB with a ScaNN index and an MCP agent on the operations side, is written up on the Google Cloud blog under my byline. The companion piece on this blog, Let the Vector Index Drive, is the long version of the one query that made the vector leg fast enough to serve to strangers.
What is next
The verification engine is the second release: hand the API a pack, get back the page-cited requirement matrix and a bid or no-bid verdict. It goes to design partners first, because every call spends real model time and the quotas need to be prepaid and hard before it is public. If you are building on procurement data and want a key, or you want to be one of the partners who tries the verification tools before anyone else, write to davor@ailucius.com and say what you are building.
Questions
Does the API return the full text of a notice?
No. Each row carries title, buyer, country, deadline, value, CPV codes, the source portal, a link to the notice on that portal, and a snippet of up to 700 characters. The full text and the documents live on the portal, and the link takes the agent there.
What does a call cost?
Nothing to start. Keys are issued by hand to design partners, read only, with a per-minute and a per-day limit. A search spends one embedding call on our side; fetching a notice or finding similar ones spends no model time at all.
Can an agent analyse a tender pack through the API?
Not in this release. The page-cited requirement matrix and the bid verdict are the second release and go to design partners first. Write to davor@ailucius.com if you want to be one of them.
More from Lucius AI
Let the Vector Index Drive: ScaNN on AlloyDB
Our tender similarity search never used its ScaNN index because a join sat between the ORDER BY and the index. The rewrite, measured on production, and the two things it broke.
What Breaks When You Ingest Every Public Tender
Every tender platform claims to track everything. This is what that actually costs: the TLS pin, the watermark that froze at :59, the taxonomy that filed 65% of US contracts under medical, and the deploy that killed our customers' uploads.
Making an AI Bid Writer Refuse to Lie
This week our AI opened a bid draft with a warning that it could not evidence 11 of 45 requirements. That banner took a year of failures to build. These are the postmortems.
Get help with your bid