mcp-anac-crawler
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-anac-crawlerFind recent pubblicità legale notices for lavori."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-anac-crawler
MCP stdio server for crawling the Italian ANAC Pubblicità Legale tender platform
(pubblicitalegale.anticorruzione.it), built to the requirements in
docs/req-web-crawel.
The finding that shaped the design
The requirements assume an HTML crawler ("analizzare pagina web"). The target is not an
HTML site: /bandi is an Angular single-page application. The served HTML is a 37 KB
shell containing no tender data at all — scraping it returns nothing.
All data is delivered by a JSON API that the SPA's own BackendService calls. That API is
undocumented, so the contract was reverse-engineered from the production bundle
(main.<hash>.js) and verified against live responses. See
endpoints.py for the full contract.
Two consequences that drive most of this codebase:
Two incompatible pagination models coexist.
/avvisiis offset-based (SpringPage, with totals);/avvisi-full-textis cursor-based — page N+1 requires the token returned with page N. Conflating them silently returns page 0 forever.Documents are not on ANAC's domain.
documenti_di_gara_linkpoints at arbitrary third-party contracting-authority portals, and never directly at a file — verified across a full day of notices, zero links end in.pdf. Reaching a PDF therefore needs an HTML hop, and every such fetch is an untrusted-URL fetch (SSRF surface).
Related MCP server: Kontur.Zakupki MCP
Quick start
python -m venv .venv && .venv/Scripts/pip install -e ".[dev]"
.venv/Scripts/python -m anac_crawler # speaks MCP over stdioRegister with an MCP client:
{
"mcpServers": {
"anac-crawler": {
"command": "C:/path/to/.venv/Scripts/python.exe",
"args": ["-m", "anac_crawler"],
"env": { "ANAC_LOG_LEVEL": "INFO", "ANAC_RATELIMIT_REQUESTS_PER_SECOND": "4" }
}
}
}Tools
Tool | Purpose | Notes |
| Taxonomies, value bands, publication dates, categories, news | Call first to build valid filters |
| Search with offset pagination | Reports totals; use for page jumps |
| Full-text search with cursor pagination | Pass |
| Multi-page traversal in one call | Hard record/page ceilings |
| Single notice by | Flattened record |
| Revision chronology | Upstream 404 → empty list |
| Fetch an HTML landing page, discover PDF links | Untrusted third-party content |
| Download a document | Not read-only; writes to disk, egress-guarded |
| Breaker state, cache stats, latency percentiles, schema-drift signal |
Typical flow: anac_reference_data → anac_search_notices → anac_inspect_page on a
documenti_di_gara_link → anac_download_document on a discovered PDF.
Requirements coverage
Requirement | Where |
Python | 3.11+, |
stdio | mcp_server/server.py + stdout guard |
HTTP GET/POST | http/client.py ( |
Cookies | Persistent JSON jar + Azure |
Sessions | One pooled, keep-alive |
Web protocol | HTTP/2, conditional requests, |
Page analysis | documents/html.py (selectolax) |
Caching | http/cache.py — 2-tier, ETag revalidation, single-flight, stale-if-error |
Navigation | Unified pagination + bounded traversal in repository.py |
Targeted file access + PDF download |
Configuration
Everything is env-driven and validated at startup (ANAC_ prefix) — see
.env.example and config.py.
The knobs that matter most in production:
ANAC_RATELIMIT_REQUESTS_PER_SECOND=4 # politeness toward a public service
ANAC_RATELIMIT_MAX_CONCURRENCY=4
ANAC_DOWNLOAD_HOST_ALLOWLIST= # pin the egress surface (strongly recommended)
ANAC_DOWNLOAD_MAX_BYTES=67108864
ANAC_CA_BUNDLE= # for corporate TLS interception
ANAC_LOG_FORMAT=json # structured logs on stderrTLS note
Document downloads default to the OS trust store (via truststore), not certifi.
This is functional, not cosmetic: many Italian PA portals serve an incomplete certificate
chain, which OpenSSL cannot resolve but the Windows/macOS verifiers can (via AIA).
Verified against a live portal — certifi fails, the OS store completes TLS 1.3. Details in
http/tls.py.
Verification
.venv/Scripts/python -m pytest -q # 241 tests, no network
.venv/Scripts/python -m mypy src # strict, clean
.venv/Scripts/python -m ruff check src tests scripts
.venv/Scripts/python scripts/smoke_live.py # live API contract check
.venv/Scripts/python scripts/smoke_stdio.py # real JSON-RPC handshake over stdiosmoke_stdio.py is the one that matters most: it spawns the server as a subprocess and
drives it exactly as a client would, which is the only way to catch a stray byte on stdout.
Further reading
docs/ARCHITECTURE.md — layering, request lifecycle, design decisions
docs/ENTERPRISE.md — what is production-ready, what is not, and the recommended roadmap with known limitations stated explicitly
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Alicense-qualityDmaintenanceEnables search and analysis of European public procurement tenders, including EU above-threshold (TED) and below-threshold from 11 national sources, with hybrid search and filtering.Last updatedMIT
- Flicense-qualityCmaintenanceEnables searching and retrieving Russian tenders (закупки) through the Kontur.Zakupki API. Supports filtering by date, text, laws, procedures, statuses, and more.Last updated
- Flicense-qualityCmaintenanceProvides tools to search and retrieve French public procurement data (tenders, awarded contracts) and company information from official open APIs.Last updated
- Alicense-qualityCmaintenanceEnables searching Korean procurement notices from the public data portal, with support for integrated search across categories, flexible date ranges, and attachment extraction.Last updatedMIT
Related MCP Connectors
Israel Government Procurement MCP — public tenders & exemption contracts (keyless).
UK public procurement data for AI agents: tenders, contracts, buyer and supplier profiles.
dati.gov.it MCP — Italy's national open-data portal (CKAN API).
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/AndreaC3p0/mcp-anac-crawler'
If you have feedback or need assistance with the MCP directory API, please join our Discord server