Skip to main content
Glama
AIWerk

@aiwerk/mcp-server-swiss-company

Official
by AIWerk
README.md
# @aiwerk/mcp-server-swiss-company

MCP server for Swiss company data from official public sources: the commercial register (Zefix open data via LINDAS), the UID register of the Federal Statistical Office, and the Swiss Official Gazette of Commerce (SHAB).

It answers questions about one company at a time: who is this, is it active, is it VAT registered, what changed in the register and when, which companies does this fiduciary act for, and which companies were newly registered in a canton this week. It never downloads a source in bulk. Every tool call runs under a hard request budget.

## Install

```bash
npx -y @aiwerk/mcp-server-swiss-company
```

Or add it to your MCP client configuration:

```json
{
  "mcpServers": {
    "swiss-company": {
      "command": "npx",
      "args": ["-y", "@aiwerk/mcp-server-swiss-company"]
    }
  }
}
```

No API key is needed.

## Tools

| Tool | What it answers | Requests |
|---|---|---|
| `ch_company_search` | Companies whose registered name contains a text, or whose statutory purpose contains a word (per canton). Candidates with UID, legal form, address and purpose. | 1 |
| `ch_company_profile` | One company by UID: name and translations, legal form, commercial register and UID register status, legal address, purpose, VAT registration (status, since when, VAT number), identifiers. | 2 |
| `ch_company_history` | The company's own register publications, newest first: registration, changes to officers, name, seat, address, purpose, capital, liquidation, bankruptcy, deletion. Full text plus the list of changed fields. | 2 + one per publication |
| `ch_company_mentions` | Publications about other companies that name this one, e.g. as auditor, liquidator or merger partner, with a text snippet and a role hint. | 2 + one per publication |
| `ch_register_publications` | New registrations, changes or deletions in one canton over up to 31 days. With `details=true` also name, UID, address, capital and purpose per row. | 1, or 1 + one per row |
| `ch_validate_uid` | Check digit of a UID or VAT number, and whether the UID register knows it and lists it as VAT registered. | 0 or 1 |

Start with `ch_company_search`. The name in the commercial register often differs from the one on a website, a letterhead or Google Maps (hyphens, "Dr." spacing, a different legal form), so search for a short, distinctive part of it and confirm the right candidate by address before using its UID.

## Configuration

| Variable | Default | Description |
|---|---|---|
| `SWISS_COMPANY_MAX_REQUESTS_PER_CALL` | `40` | Request budget per tool call, at most 200. A call that would need more fails and asks for a narrower question. |
| `SWISS_COMPANY_TIMEOUT_MS` | `20000` | Timeout per request. |
| `SWISS_COMPANY_ENABLE_ZEFIX_WEB_API` | off | Set to `1` to also use the API behind the zefix.ch search page. See below. |

## Sources and their terms

| Source | Used for | Terms relevant here |
|---|---|---|
| [LINDAS](https://lindas.admin.ch) Zefix dataset | Search, purpose, municipality | Open government data: "Open use. Must provide the source." |
| [UID register](https://www.uid.admin.ch) public services | Status, legal address, VAT registration | Free. The public services allow 20 requests per minute per caller and block temporarily when exceeded. |
| [Amtsblattportal](https://amtsblattportal.ch) (SHAB) | Register history, mentions, publications per canton | Public portal, used through its publication search. |
| Zefix web API (optional) | Register status, former names, auditors and audited companies, branches, takeovers, history before the portal's coverage | Not documented for third-party use, which is why it is off by default. The official Zefix REST API needs credentials from the Federal Office of Justice (zefix@bj.admin.ch). |

Every result carries a `sources` list with the attribution for the sources it used. Pass it on together with the data.

## How the server treats the sources

- **Request budget per call.** Default 40. When a question would need more, the call fails with a message asking for a smaller limit, a shorter date window or a canton.
- **Spacing per source.** At least 3.1 seconds between two UID register requests, 0.5 seconds for the others, per process.
- **Identifying User-Agent** with the package name, version and repository.
- **Caching.** Gazette publications do not change once published and are kept in memory for a day; register lookups for ten minutes.
- **Filter checks.** The gazette API ignores some filter combinations without an error (for example `subRubrics` next to `rubrics`, or a misspelled parameter) and then returns unfiltered data. The server checks every list response against the requested canton, type and date window and fails instead of reporting unfiltered data.
- **Subject check.** A search for a UID in the gazette also finds publications about other companies that merely name it. History and mentions are told apart by the UID in the publication's company block, not by the search hit.

## Limits

- The gazette portal returned no publications from before the second half of 2018 in testing. Older register history comes only from the optional Zefix web API.
- The name search matches a substring of the registered name. It does not find "Muster Aufzuege" for "Muster Aufzüge", or a name without its hyphen.
- A purpose search needs a canton; across all of Switzerland it takes ten seconds or more.
- The gazette search serves the first 10,000 hits of a query; the per-canton listing is therefore limited to 31 days per call.
- The UID register allows 20 requests per minute per caller. Several agents behind one IP address share that limit.
- The current list of officers is not a register field: it is only visible through the publications that changed it.

## What it deliberately does not do

- No bulk export or crawling of any source.
- No telephone directory data. The tel.search.ch terms forbid passing entries or the key on to third parties.
- No domain registration data. The SWITCH acceptable use policy excludes advertising and market research.
- No debt collection register (Betreibungsregister) data.

## Development

```bash
npm install
npm run build
npm test            # unit tests, no network
npm run smoke       # live test against the public sources, about 15 requests
```

Test fixtures are anonymized copies of real responses: the XML structure is kept, every company name, person, place and UID is replaced.

## License

MIT

TDQS

A4.4/5.0

Scored across 6 tools

Disambiguation5/5

Each tool targets a distinct operation: search, history, mentions, profile, register feed, and UID validation. Overlap between search and profile is clarified by UID-based lookup vs name-based candidate search, and history vs mentions explicitly separates own vs third-party publications.

Naming Consistency4/5

All tools share the ch_ prefix and snake_case, but verb placement varies: ch_company_search and ch_validate_uid are verb-focused while ch_company_history, ch_company_mentions, ch_company_profile, and ch_register_publications are noun-focused. This is mostly predictable and readable, with only minor stylistic inconsistency.

Tool Count5/5

Six tools cover search, detail, validation, and publication querying without redundancy. This is well within the ideal range and each tool earns its place for a focused Swiss company register server.

Completeness5/5

The set provides a complete lifecycle for company data: find candidates, validate identifiers, view the official profile, and inspect both own and third-party publications. There are no obvious dead ends, and references to related tools fill any potential gaps.

Maintenance

ActivityMaintained
ResponsivenessNo issues