How-to guides · Getting one task done
Call the gateway
Two-stage discovery, one call, and what a refusal means — locally today, publicly once the endpoint is served.
On this page
One gateway, two functions: policy (rate, session budget, typed refusals) and aggregation (flat names, deterministic tool list, two-stage discovery). Behind it two interfaces to federal infrastructure: fedlex over the public Fedlex SPARQL endpoint, lindas over the 44 political data cubes of the Federal Chancellery.
State: mcp.openhelvetia.swiss/mcp is prepared and not served. Everything here describes the built state as the tests prove it. It runs locally today; how is in Run, test and call the MCP gateway.
The three doors
| Door | For whom | Note |
|---|---|---|
| MCP over stdio | local hosts and tests | the machine door; the process is the session |
MCP streamable HTTP /mcp | agents and hosts over the network | the intended public door (revision 2026-07-28) |
JSON shell GET /tools, POST /tool/<id> | simple clients, this website's chat | local; not a production transport; same tools, same refusals |
Relay /relay/infomaniak/<product>/… | this website's chat, for a provider whose API refuses browser calls | forwards chat/completions and models with the visitor's own key to Infomaniak and nowhere else; stores and logs nothing of it; open only where the operator sets --relay (E16, revision 05.09.2026) |
Two-stage discovery
- meta.tools. Every tool with id, domain, one-liner and weight, without input schemas. Costs 1.
- meta.schemas. The full input schemas only of the named ids, typically three to five.
- Call. Both stages and
tools/listread the same router; the schemas are byte-identical.
One row from stage one, verbatim from the tool inventory:
{
"id": "fedlex.resolve_sr",
"domain": "fedlex",
"summary": "Resolve an SR number (e.g. 832.10) to the act's ELI, titles and in-force status: use when a question names an SR; predecessors stay visible. norm.",
"weight": 2
}
A call through the JSON shell
curl -s http://127.0.0.1:8700/tools
curl -s -X POST http://127.0.0.1:8700/tool/meta.schemas -H 'content-type: application/json' -d '{"names": ["fedlex.resolve_sr", "fedlex.read_article"]}'
curl -s -X POST http://127.0.0.1:8700/tool/lindas.list_cubes -H 'content-type: application/json' -d '{}'
The first message over MCP streamable HTTP
POST https://mcp.openhelvetia.swiss/mcp
Accept: application/json, text/event-stream
Content-Type: application/json
MCP-Protocol-Version: 2026-07-28
MCP-Method: server/discover
{
"jsonrpc": "2.0",
"id": 1,
"method": "server/discover",
"params": {
"protocolVersion": "2026-07-28",
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientCapabilities": {}
}
}
}
Both Accept types, version and method headers, params._meta with both keys: if one is missing, a conforming server refuses the request before any MCP logic runs.
Limits
Session budget: a weighted hard limit (register read 1, domain call 2), it does not recover. Rate: default 60 weight units per minute, burst 20, per client. A refusal costs nothing. The six refusals are in the reference.