Switzerland Parliament Mcp Server

io.github.cyanheads由 GitHub 帳號 cyanheads 發布v0.1.2更新於 Nov 2, 2026

Search Swiss parliamentary business, votes, debates, members, and declared interests.

已驗證Streamable HTTP可網頁執行位置與生活知識與記憶

概覽

AI 產生的概覽

以唯讀方式存取瑞士議會紀錄:議案、國民院點名表決、辯論紀錄、議員及申報利益。

可以做什麼
  • 檢索並讀取議會議案,包括原文、狀態沿革、法案、相關議案與辯論主題
  • 查詢國民院點名表決,分頁檢視議員個人投票,並讀取完整的表決與黨團計票
  • 依議案、主題、發言者、會期、議會或日期尋找《官方公報》中的辯論段落
  • 檢索現任及前任議員,並讀取其議會任期、委員會成員資格與申報利益
  • 解析識別碼、資料涵蓋範圍、語言、委員會、政黨與會期等參考代碼
適用情境
適合需要研究瑞士聯邦立法、投票行為或議會辯論的情境,讓助理直接調取原始紀錄並附上來源標註,而不是依賴一般知識作答。
執行需求
不需 API 金鑰或帳號,使用公開的 OData 服務。可連線託管端點,或以 npx(需 Node.js)或 Docker 在本機執行。傳輸方式、HTTP 埠、驗證模式、日誌等級與儲存等設定皆為選用,沒有必填項。
安裝前請注意
僅供唯讀,但結果是議會資料的非官方複製,來源內容適用議會的開放資料條款。涵蓋範圍有限:點名表決僅涵蓋 2003 年冬季會期起的國民院,辯論紀錄自 1999 年冬季會期起,因此空結果不能證明未發生表決或辯論。缺漏值維持未知,利益清單為空也不代表沒有利益衝突。

安裝

在 SourceWeft 中

  1. 開啟 儀表板中的 Switzerland Parliament Mcp Server,將其新增到工作區。
  2. 為需要使用其工具的對話啟用該服務。

Web executable,透過 Streamable HTTP。 遠端服務在工作區中設定後即可從網頁執行環境執行。

交給代理程式安裝

把這段提示詞貼上到 Claude Code、Codex、Cursor 等代理程式,或 SourceWeft 對話中。代理程式會讀取該伺服器的安裝指南,先向你展示發布者、端點和登入方式,經你同意後再把它新增到你的客戶端。金鑰不會寫進任何命令。

閱讀 https://sourceweft.com/mcp/io.github.cyanheads%2Fswitzerland-parliament-mcp-server/install.md,並按其中說明把這個 MCP 伺服器接入我的客戶端。修改任何設定之前,先告訴我它的發布者、端點和登入方式,等我確認。不要把 API 金鑰寫進命令或我會提交的檔案;問我金鑰應從哪裡取得。

檢視代理程式所依據的安裝指南

其他 MCP 客戶端

把它新增到你客戶端的 mcpServers 設定中。

{
  "mcpServers": {
    "switzerland-parliament": {
      "type": "http",
      "url": "https://switzerland-parliament.caseyjhand.com/mcp"
    }
  }
}

README

@cyanheads/switzerland-parliament-mcp-server

Search Swiss parliamentary business, votes, debates, members, and declared interests via MCP. STDIO or Streamable HTTP.

7 Tools • 0 Resources • 0 Prompts


Overview

Swiss Federal Assembly records from Curia Vista and the Amtliches Bulletin. Find parliamentary business, read its original texts and procedural history, follow the debate in either council, inspect Nationalrat roll calls, and look up members and declared interests. Uses the public OData service without an API key; runs as a stdio process, a local Streamable HTTP server, or the public hosted endpoint above.

Results credit Parlamentsdienste der Bundesversammlung, Bern, with source URLs and download dates. This is an unofficial reproduction. The Parliament's open-data conditions apply to source content; underlying author rights remain intact.

Tools

ToolDescription
chparl_search_businessFind business by title, submitter, type, status, submission session, dates, or committee role
chparl_get_businessRead business metadata, original texts, status history, bills, related business, committee consultations, or debate subjects
chparl_get_votesFind Nationalrat roll calls, page member decisions, or read complete vote and parliamentary-group counts
chparl_search_transcriptsFind debate passages by business, subject, speaker, session, council, or dates; retrieve original text
chparl_search_membersFind current or former parliamentary affiliation records by name, council, canton, party, or group
chparl_get_memberRead parliamentary identity, council terms, committee memberships, or declared interests
chparl_list_referenceResolve identifiers, coverage, languages, codes, committees, and sessions

Capability reference

chparl_search_business tool

  • query (title substring), author (published submitter label, not every co-signatory), typeId, statusId, sessionId (submission session), committeeId, and inclusive submittedFrom / submittedTo. Newest business IDs first, default 20/max 100
  • Continue with nextCursor and unchanged filters; a cursor from other filters fails as invalid_cursor. totalCount is reported only without author or committee filters. Author searches use an extra matching row to establish continuation; committee searches page role candidates, so pages can be short

chparl_get_business tool

  • Canonical eight-digit businessId or an exact published short number such as 99.1234. A short number matching several businesses fails as ambiguous_business_number, and a miss returns found: false
  • overview (default) returns metadata and availableTextFields with UTF-8 sizes. texts returns textDocument.kind: "full" | "outline": several large fields become an outline, and named textFields always return whole
  • status_history, bills, related_business, preconsultations, and subjects page independently, default 20/max 100 with nextOffset. subjects IDs narrow chparl_search_transcripts; linked bills are parliamentary records, not enacted law

chparl_get_votes tool

  • mode: "votes" with businessId, sessionId, or both lists roll calls (default 10/max 50). A returned voteId feeds mode: "members" (default 50/max 100, optional personNumber) or mode: "groups" (unpaged). Paged modes continue with nextOffset
  • mode: "members" with personNumber and no voteId pages that member's voting history, optionally narrowed by businessId and sessionId. Each history row carries its published vote, business, session, and time fields; selected-vote pages carry that context once in vote. cantonId uses the canton reference's numbering; votingCantonId preserves the source Voting identifier
  • members counts carry decisionCounts.scope: "page". groups reads every published member row and returns scope: "vote", complete: true, and per-group totals by the affiliation recorded on the vote. Count buckets retain every distinct published label in decisionTexts. Decision codes: 1 yes, 2 no, 3 abstention, 4 present, 5 did not participate, 6 excused under Art. 57 para. 4, 7 president does not vote, 8 resigned
  • Nationalrat only, from the 2003 winter session. An empty result does not establish that no vote occurred

chparl_search_transcripts tool

  • Both councils from the 1999 winter session. Scope with businessId or subjectId (exclusive), personNumber, sessionId, or a date bound; council only narrows. query (original-text substring) also needs sessionId or a closed range of at most 31 calendar days
  • Metadata with textSizeBytes by default (20/max 100); includeText: true returns whole passages (3/max 10); an exact transcriptId defaults to full text. Continue with nextOffset
  • A business search covers up to 20 debate subjects; more fails as business_scope_too_broad, so page chparl_get_business section subjects and pass one subjectId. found marks exact-ID misses, scopeFound a missing business

chparl_search_members tool

  • query (first, last, or official name substring), membership (current default, former, all), council (N/S or the German, French, or Italian council name), cantonId, partyId, groupId. Default 20/max 100, nextOffset
  • Rows are MemberCouncil affiliation records, not deduplicated people. Their personNumber, which need not equal Person.ID, feeds chparl_get_member, chparl_get_votes, and chparl_search_transcripts

chparl_get_member tool

  • Requires personNumber. overview (default) returns identity and every MemberCouncil affiliation, unpaged; a miss returns found: false
  • council_terms, committees, and interests page independently, default 20/max 100 with nextOffset. Committee rows are published memberships, not a historical ledger. A missing paid flag means unknown, and empty interests do not establish the absence of conflicts

chparl_list_reference tool

  • Static topics identifiers, coverage, languages, and statuses (the official vocabulary effective 1 July 2023, each code tagged era: "legacy" | "current"). Live dictionaries business_types, councils, cantons, parties, groups, committees, and sessions
  • Default 50/max 100, nextOffset. Only sessions accepts dates: dateFrom bounds the start and dateTo the end, inclusively

Features

Built on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.

Swiss Parliament-specific:

  • Keyless, read-only access to business, procedural relationships, Nationalrat roll calls, debate passages, members, and declared interests
  • de (default), fr, and it metadata with no translation fallback; Italian completeness is not established. Bulletin text stays in the language the speaker used
  • Published text and HTML are returned unchanged, with an index of their links and images carrying absolute HTTP(S) URLs where the source supplies one
  • One 45-second deadline per complete workflow, covering joins and retries

Agent-friendly output:

  • Provenance on every result: attribution to Parlamentsdienste der Bundesversammlung, plus the source URL and retrieval time of each upstream response
  • Whole-record pages: replies fit a 24,000-byte budget by returning fewer records, never shorter fields, and report returnedCount, hasMore, totalCount when known, and the continuation
  • One record on both surfaces: content[] carries every structuredContent field, with multiline text and HTML in JSON-encoded fenced blocks that decode back losslessly
  • Unknown stays unknown: absent source values are omitted rather than defaulted, empty results carry next-step guidance, and failures carry typed reasons such as upstream_rate_limited

Getting started

Connect to the hosted instance, no install:

sh
claude mcp add --transport http switzerland-parliament-mcp-server https://switzerland-parliament.caseyjhand.com/mcp

Or run it locally:

sh
claude mcp add switzerland-parliament-mcp-server -- npx -y @cyanheads/switzerland-parliament-mcp-server

For other clients, add this to the MCP config file:

json
{  "mcpServers": {    "switzerland-parliament-mcp-server": {      "command": "npx",      "args": ["-y", "@cyanheads/switzerland-parliament-mcp-server"]    }  }}

For Docker or a source build, see Running the server.

Configuration

No server-specific environment variables are required.

VariableDescriptionDefault
MCP_TRANSPORT_TYPETransport: stdio or http.stdio
MCP_HTTP_PORTHTTP server port.3010
MCP_SESSION_MODEHTTP session mode: stateless, stateful, or auto.stateless
MCP_AUTH_MODEAuthentication: none, jwt, or oauth.none
MCP_LOG_LEVELLog level (debug, info, warning, error, etc.).info
LOGS_DIRDirectory for log files (Node.js only).<app-root>/logs
STORAGE_PROVIDER_TYPEStorage backend: in-memory, filesystem, supabase, cloudflare-kv/r2/d1.in-memory
OTEL_ENABLEDEnable OpenTelemetry.false

See .env.example for the common framework overrides.

Running the server

Local development

Requires Bun v1.4.0 or higher (or Node.js v24+).

sh
git clone https://github.com/cyanheads/switzerland-parliament-mcp-server.gitcd switzerland-parliament-mcp-serverbun installcp .env.example .env
  • Build and run the production version:

    sh
    # One-time buildbun run rebuild
    # Run the built serverbun run start:http# orbun run start:stdio
  • Run checks and tests:

    sh
    bun run devcheck  # Lints, formats, type-checks, and morebun run test      # Runs the test suite

Docker

sh
docker run --rm -p 3010:3010 ghcr.io/cyanheads/switzerland-parliament-mcp-server:latest

The image defaults to HTTP transport, stateless sessions, and logs to /var/log/switzerland-parliament-mcp-server. For stdio, use "command": "docker" with "args": ["run", "-i", "--rm", "-e", "MCP_TRANSPORT_TYPE=stdio", "ghcr.io/cyanheads/switzerland-parliament-mcp-server:latest"]. Build locally with docker build -t switzerland-parliament-mcp-server .; --build-arg OTEL_ENABLED=false omits OpenTelemetry peers.

Project structure

DirectoryPurpose
src/index.tscreateApp() entry point and service setup; seven tools, no resources or prompts.
src/mcp-server/toolsTool definitions, shared lossless rendering, and whole-record page fitting.
src/services/parliamentOData client, workflow deadlines, domain schemas and services, provenance, and reference snapshots.
tests/Unit and integration tests, mirroring the src/ structure.

Development guide

See CLAUDE.md for development guidelines and architectural rules. The short version:

  • Handlers throw, framework catches — no try/catch in tool logic
  • Use ctx.log for logging, ctx.state for storage
  • Register new tools and resources in the createApp() arrays in src/index.ts
  • Wrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields

Contributing

Issues are welcome. Run checks and tests before submitting:

sh
bun run devcheckbun run test

License

This project is licensed under the Apache 2.0 License. See the LICENSE file for details.

來源:README.md,提交 72ea577

工具

7

chparl_search_business

Chparl Search Business

Search Swiss parliamentary business by title substring, published submitter label, type, current status, submission session, inclusive submission dates, or committee role. Use chparl_list_reference to resolve codes and chparl_get_business to read a returned businessId. Follow nextCursor with unchanged filters; newest canonical business IDs appear first. Author searches omit the business total. Committee searches page role candidates and may return short pages without a distinct business total. Metadata labels remain in de, fr, or it without translation fallback.

輸入參數limitqueryauthorcursortypeIdlanguagestatusIdsessionIdcommitteeIdsubmittedTosubmittedFrom

chparl_get_business

Chparl Get Business

Read a Swiss parliamentary business by canonical eight-digit businessId or exact published short number. Choose overview for metadata and available text sizes; texts for original published text, automatically outlined when several fields exceed the disclosure budget; or status_history, bills, related_business, preconsultations, or subjects for independently paged relationships. textFields selects complete original fields only in texts, even when large. Paging applies only to relationships. Use subjects to narrow chparl_search_transcripts; source text and HTML remain unchanged.

輸入參數limitoffsetsectionlanguagebusinessId必填textFields

chparl_get_votes

Chparl Get Votes

Find Nationalrat roll calls with mode votes and businessId, sessionId, or both. Use mode members with voteId for one paged roll call, or personNumber without voteId for member history optionally filtered by businessId and sessionId. Use mode groups with voteId for complete decision counts by parliamentary group. Member roll calls start in the 2003 winter session and exclude Ständerat member votes; an empty result does not prove no vote occurred. Member counts cover only delivered rows; groups mode reads all published member rows before reporting totals. Verbatim decisionTexts accompany code buckets when published. Code meanings include 1 yes, 2 no, 3 abstention, 4 present, 5 did not participate, 6 excused under Art. 57 para. 4, 7 president does not vote, and 8 resigned. Unknown codes and missing decisions are retained. Follow nextOffset with the same mode and filters.

輸入參數modelimitoffsetvoteIdlanguagesessionIdbusinessIdpersonNumber

chparl_search_transcripts

Chparl Search Transcripts

Find Amtliches Bulletin passages by business, debate subject, speaker, session, council, or inclusive meeting dates. Supply at least a business, subject, speaker, session, or date bound. A text substring query additionally requires sessionId or a closed date range of at most 31 calendar days. Searches return metadata by default; includeText returns whole original passages, and an exact transcriptId defaults to full text. Metadata language never translates the speaker text; missing LanguageOfText remains unknown. Business searches cover every associated subject up to 20; larger debates require selecting subjectId through chparl_get_business section subjects. Follow nextOffset with unchanged filters.

輸入參數limitquerydateTooffsetcouncildateFromlanguagesessionIdsubjectIdbusinessIdincludeTextpersonNumber另有 1 個

chparl_search_members

Chparl Search Members

Find current or former Swiss Parliament affiliation records by name, council, canton, party, or parliamentary group. membership defaults to current; former selects inactive records and all omits the activity filter. query matches a substring of a published first, last, or official name. Use each record’s personNumber with chparl_get_member for identity, full council terms, committees, and declared interests. Follow nextOffset with the same filters.

輸入參數limitqueryoffsetcouncilgroupIdpartyIdcantonIdlanguagemembership

chparl_get_member

Chparl Get Member

Read a Swiss Parliament member by PersonNumber, which need not equal Person.ID. overview returns identity and every base MemberCouncil affiliation without pagination. Select council_terms for historical council terms, committees for published MemberCommittee rows, or interests for declared interests; those sections accept limit and offset. Missing paid status means unknown, and empty interests do not establish absence of conflicts of interest. Metadata labels remain in the selected language.

輸入參數limitoffsetsectionlanguagepersonNumber必填

chparl_list_reference

Chparl List Reference

List Swiss Parliament reference entries and source coverage. Choose identifiers, coverage, or languages for server explanations; statuses for the official legacy/current status snapshot; or business_types, councils, cantons, parties, groups, committees, or sessions for live dictionaries. Date filters apply only to sessions. Follow nextOffset with the same topic, language, and dates; labels remain in the requested metadata language and missing labels stay unknown.

輸入參數limittopic必填dateTooffsetdateFromlanguage

版本歷史

2
  1. v0.1.2最新Oct 26, 2026
  2. v0.1.1Oct 25, 2026

評分

已滿足適用檢查項的 100%

該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。

  • 近 30 天內可連通必需25 分
  • 已宣告認證方式必需10 分
  • 已列出工具必需15 分
  • 描述必需15 分
  • 圖示10 分
  • 文件15 分
  • 授權條款10 分