Swiss official gazettes (SHAB + cantonal) β procurement & notices, person-data rubrics excluded
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
We haven't yet run this listing's install command through our automated sandbox check. This isn't a red flag β we're steadily working through the catalog.
π‘ Paste the JSON block into your client's configuration file under mcpServers, then restart the application.
π¨π Part of the Swiss Public Data MCP Portfolio
MCP server for amtsblattportal.ch β the Swiss official gazette portal (SHAB + 27 cantonal gazettes). Public procurement and official notices, person-data rubrics excluded by design.
The Amtsblattportal publishes roughly 2.79 million official notices: public procurement, cantonal and communal announcements, enactments, spatial planning β and also bankruptcies, debt collection, inheritance calls and civil-status records naming natural persons.
This server exposes only the first group. Rubrics carrying systematic natural-person data are not queryable, and no tool accepts a person's name, birth date or address. That is a deliberate data-protection decision, explained in Data Protection & Scope.
Anchor demo query: "Which public tenders did canton Ticino publish this month?"
β
gazette_search_procurement(canton="TI", only_language=True, language="it") β gazette_get_publication(id=β¦)
For procurement in any other canton β including ZΓΌrich, Bern and Basel-Stadt β
use swiss-procurement-mcp;
see Boundary with swiss-procurement-mcp.
OB-ZG
was never filled after the simap switch, and that ZH routes everything through
simap.ch β so it explains instead of returning nothing. Activity is
measured, not read off the rubric labellanguage_mix rather than guessed at, and
only_language=True gives a single-language viewprovenanceFrom source:
The endpoint is /mcp.
Migrating from SSE. Until 0.18.0 this server spoke SSE only, on
/sse+/messages. MCP spec2026-07-28reclassifies HTTP+SSE as deprecated with a twelve-month removal window and removes protocol-level sessions, so streamable-http is now the default.MCP_TRANSPORT=ssestill works and still carries the full bearer-auth, rate-limit and CORS stack β it logs a warning at startup naming the deadline. Update the client URL when you switch: the path change is the part that breaks silently.
| Variable | Default | Purpose |
|---|---|---|
MCP_TRANSPORT | stdio | stdio, streamable-http (alias http), or the deprecated sse |
MCP_HOST | 127.0.0.1 | HTTP bind address. Defaults to loopback; set 0.0.0.0 to expose on all interfaces (the Docker image does this deliberately). |
MCP_STATELESS | (unset) | 1 runs streamable-http with no session tracking at all. Removes session hijacking and session affinity as questions rather than answering them (SEC-009, SCALE-002). Opt-in, because a stateless server cannot resume an interrupted stream or push server-initiated notifications. Ignored on sse, which has no stateless mode. |
MCP_CORS_ORIGINS | (unset) | Comma-separated origins allowed to call the endpoint from a browser. Unset means no cross-origin browser access at all β stdio and non-browser clients are unaffected. Mcp-Session-Id is exposed and accepted for the listed origins, so a browser client can hold a session. * is honoured but logs a warning and disables credentials, because browsers reject a wildcard origin together with credentials. |
MCP_API_KEY | β | Bearer token; required on every HTTP transport |
MCP_RATE_LIMIT / MCP_RATE_WINDOW | 60 / 60 | Sliding-window rate limit |
RUBRICS_TTL | 86400 | Taxonomy cache TTL (seconds) |
LOG_LEVEL | INFO | DEBUG | INFO | WARNING | ERROR. Structured JSON, one object per line, always on stderr β stdout carries the MCP protocol on a stdio transport. |
Built on structlog. Every event emitted during a
tool call carries that call's correlation_id, bound via contextvars β so a
retry or an egress denial logged deep in the HTTP path can be joined to the
request that caused it, without threading context through every signature.
| Level | Emitted when |
|---|---|
DEBUG | a tool call was entered (tool_call_started) β tells you whether a hung call ever started |
INFO | a tool call finished cleanly, with latency |
WARNING | upstream retry, egress denied, auth failure, rate limit |
ERROR | a tool call raised |
Records carry the exception type only β never its message and never an upstream response body.
Ship these to your SIEM and alert on auth_failed, rate_limited,
egress_denied, green_gate_violation and blocked_publication_requested β
the last two mean something tried to reach a rubric this server does not serve.
| Tool | Signature | Notes |
|---|---|---|
gazette_search_publications | (keyword?, rubric?, sub_rubric?, canton?, date_start?, date_end?, limit=20, page=0, language='de', only_language=False) | Green rubrics enforced. Without rubric, all green rubrics are injected β a keyword-only query can never reach a blocked one. |
gazette_search_detailed | same filters + top_n=3 | Aggregated. Search and full text for the top top_n hits in one call, fetched in parallel. Same green gate on every expanded document; blocked ones are withheld and counted, never rendered. |
gazette_search_procurement | (keyword?, canton?, date_start?, date_end?, include_inactive=False, limit=20, page=0, language='de', only_language=False) | OB-* rubrics plus the gazette-native sub-rubrics AR-VS40, AR-OW40, BA-SH40. A canton with neither gets a simap.ch explainer and no HTTP call. No CPV β the source has none. |
gazette_get_publication | (id, response_format='markdown') | Full official text from XML. Re-checks the rubric after fetching; content from a blocked rubric is discarded. |
gazette_list_rubrics | (language='de', rubric_class='green', response_format='markdown') | rubric_class='all' shows the full taxonomy with traffic-light classes and reasons β listed β queryable. |
gazette_source_status | (response_format='markdown') | Reachability, latency, cache age, scope metrics. |
All tools are readOnlyHint=True.
| Question | Tool chain |
|---|---|
| Tenders in Ticino this quarter | gazette_search_procurement(canton="TI", only_language=True, language="it") |
| Procurement simap.ch does not have | gazette_search_procurement(canton="VS") β 150 Valais awards, none on simap |
| Tenders in any other canton | β use swiss-procurement-mcp |
| What is even queryable here? | gazette_list_rubrics() |
| Why can't I search bankruptcies? | gazette_list_rubrics(rubric_class="all") |
| Zoning changes in Zurich | gazette_search_publications(rubric="RP-ZH") |
| Full text of a notice | gazette_get_publication(id="fbf0ff9e-β¦") |
| Everything published about one company | β use register-mcp |
No reviews yet β be the first to share how this listing worked for you.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/amtsblatt-mcp)<a href="https://allmcps.com/mcp/amtsblatt-mcp"><img src="https://allmcps.com/api/badge/amtsblatt-mcp?style=directory" alt="Amtsblatt MCP on AllMCPs" /></a>