Sweden Parliament MCP Server
This server has a remotely hosted endpoint. Open its connector listing for connection details, authentication requirements, and setup instructions:
Public Hosted Server: https://sweden-parliament.caseyjhand.com/mcp
Overview
Swedish parliamentary records from Riksdagen Open Data. Find proposals and committee reports, follow published decisions and main votes, read speeches, explore member assignments, and retrieve consolidated SFS statutes. Runs as a stdio process, a local Streamable HTTP server, or the public hosted endpoint above; no API key required.
Source: The Swedish Parliament. This independent service is not operated or endorsed by Sveriges riksdag. Swedish titles, labels, decisions, and text retain their source wording; English labels appear only where the source supplies them.
Tools
Tool | Description |
| Browse official document types, committees, parties, constituencies, sessions, and identifier and coverage guidance |
| Search parliamentary documents and consolidated SFS statutes by words, type, session, committee, party, member, or dates |
| Read publication metadata, decisions, reservations, activities, links, and paginated text |
| Find speeches within a session by debate heading, member, or party; retrieve full text through get mode |
| Read report decisions, party main-vote totals, individual ballots for a point, or one member's session main votes |
| Find register entries by name, party, constituency, and source service classification |
| Read an exact member IID and its published assignment history |
Related MCP server: mcp-riksdagen-se
Capability reference
riksdag_list_reference tool
topic:document_types,committees,parties,constituencies,speech_types,sessions,identifiers, orcoverageDated offline snapshot (
referenceVerifiedAt) with Swedish labels and source-supplied English labels; the session catalog can lag current sessions, and newer well-formed sessions are still acceptedSessions accept
YYYY/YY, consecutiveYYYY/YYYY, or a historical calendar year;1999/00retains the published1999/2000formoffsetpagination;limitdefaults to 20, clamped to 100, withtotalCountandnextCall
riksdag_search_documents tool
Optional
query,documentType,session,committee,party,memberId,dateFrom, anddateTo; dates useYYYY-MM-DD, and codes or exact reference labels are accepted.memberIdselects source-linked participants, without inferring authorshipsortisrelevancefor a nonblank query anddateotherwise; either can be selected explicitly. Source subtitles include available author and SFS consolidation labelsRemote
pagestarts at 1;pageSizedefaults to 10 and is clamped to 50. Large pages split into whole-row responses withoffsetandrevision; follownextCallto finish that remote page before advancing, keepingpageSizefixedUse
documentType: "sfs"for consolidated statutes; narrow slow full-text searches withsessionordocumentType
riksdag_get_document tool
Required
documentIdfrom search, or an SFS identifier (1974:152,SFS 1974:152,sfs-1974-152); misses returnfound: false. Omitsectionsfor metadata, the outline, and the first text page, or select frommetadata,decisions,reservations,activities,properties,attachments,references,stakeholders,text,source_htmlText and HTML page by Unicode code point (
textOffset/textLength,htmlOffset/htmlLength), starting at 8,000 by default and fitting the complete response. Explicit lengths are honored. Array sections usesectionOffset/sectionLimit(default 20, clamped to 100). FollownextTextCall,nextHtmlCall, orsectionPages[].nextCallwithrevision; a changed record fails withrevision_changedDecisions and notice properties expose readable Markdown alongside original HTML. Published summary tables retain every table and its totals; stakeholders retain source names, parties, roles, order, and available numeric member IDs
SFS text is the published consolidation (
versionKind: "consolidated") and can include future-effective provisions; it is not an as-enacted or point-in-time version. Attachments are returned as links, never downloaded
riksdag_search_speeches tool
mode: "search"(default) requiressession; optionalmemberId,party,speechType: "all" | "speech"(speechexcludes replies), andheadingContains, which matches all tokens in headings and subheadings, never body text.limitdefaults to 5 (max 20);textCountdefaults to 1 (max 5,0for metadata only)mode: "get"reads onespeechIdcopied from a search item (notsourceSpeechId) and pages the body withtextOffset/textLengthandnextTextCall. Default text pages start at 8,000 code points and fit the complete response; explicit lengths are honoredtextStateisincluded,not_requested,unavailable, orfailed, with recovery details on transient failures; retainrevisionon continuationsA missing detail, including an exact zero-byte HTTP 200 source response, returns
found: falsein get mode ortextState: "unavailable"during search hydration
riksdag_get_votes tool
Required
modeandsession.mode: "report"takesreport(FiU20or2024/25:FiU20) or a reportdocumentId, plus onepointorpointOffset/pointLimit(default 5, max 10);mode: "member"takesmemberId, optionalparty, andoffset/limit(default 20, max 500)Report points carry the authoritative decision and party aggregates separated by source
avser;rollCallStateisavailable,acclamation,not_published, orunknown, and acclamation requires explicit decision evidence, never just empty vote rows. Incomplete groups retain unknown counts and observed labels; extra vote labels land inotherVotesWith an explicit report
point,ballots: trueadds individualvotesand independentballotPagepagination usingoffset/limit. FollowballotPage.nextCallwith bothrevisionandballotRevision; report-point counts keep their existing meaningPublished main votes only, not every ballot round; follow
nextCallwithrevisionfor remaining points or rows
riksdag_search_members tool
register: "service"(default) searches current members plus recent former members, substitutes, and ministers;register: "all"includes earlier records. A cold all-register request is substantially larger and can reach the normal timeoutOptional
nameContainsmatches all tokens as substrings, ignoring case and diacritics.partyandconstituencyaccept codes or exact labels.sitting: "all" | "serving" | "not_serving"(defaultall) filters source service labels, including serving substitutes, without establishing elected membershipoffsetpagination;limitdefaults to 20, clamped to 100. Returns actualcandidateCount, filteredtotalCount,sourceReportedCount,revision, andnextCall. Source-reported hits can differ from returned all-register records; a notice discloses this, and neither count is an independent historical censusmemberIdkeeps leading zeros. Entries without an IID returndetailAvailable: false; theirsourceRecordIdis a different identifier and can't be passed toriksdag_get_member
riksdag_get_member tool
Required numeric-string
memberId, leading zeros included; copy it from a member search result withdetailAvailable: true. Misses returnfound: falsewith guidanceRegister metadata and assignments in source order;
assignmentOffset/assignmentLimitdefault to 0 / 20 (max 100), withassignmentTotal,nextCall, andrevisionAssignment dates keep source precision and don't establish historical sitting status; contact details and photographs are excluded
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.
Riksdag-specific:
Keyless access to official document, speech, vote, and member endpoints, plus dated official reference tables
Document text as canonical Markdown or SFS source text, with separately selectable original HTML
Shared upstream concurrency, bounded public-response caching, and one 55-second deadline across queueing, retries, and text hydration
Historical coverage varies by record type; speeches and votes start in 1993/94, with gaps in older vote data
Agent-friendly output:
Source attribution, retrieval time, effective filters, and source warnings on both
content[]andstructuredContentComplete continuation calls for rows, sections, and text, with revision checks on local continuations; a changing remote document search is not a frozen snapshot
Explicit misses, unavailable text, unknown counts, and source service classifications; candidate saturation fails as
candidate_limit_reachedinstead of returning an incomplete traversal
Getting started
Connect to the hosted instance, no install:
claude mcp add --transport http sweden-parliament-mcp-server https://sweden-parliament.caseyjhand.com/mcpOr run it locally:
claude mcp add sweden-parliament-mcp-server -- npx -y @cyanheads/sweden-parliament-mcp-serverFor other MCP clients, add this to your configuration:
{
"mcpServers": {
"sweden-parliament-mcp-server": {
"command": "npx",
"args": ["-y", "@cyanheads/sweden-parliament-mcp-server"]
}
}
}Riksdagen Open Data requires no API key or account. For Docker or a source build, see Running the server.
Configuration
Variable | Description | Default |
| Transport: |
|
| HTTP server port. |
|
| HTTP session mode: |
|
| Authentication: |
|
| Log level ( |
|
| Directory for log files (Node.js only). |
|
| Storage backend: |
|
| Enable OpenTelemetry. |
|
See .env.example for every server setting and the common framework overrides.
Running the server
Local development
Requires Bun v1.4.0 or higher (or Node.js v24+).
git clone https://github.com/cyanheads/sweden-parliament-mcp-server.git
cd sweden-parliament-mcp-server && bun install
cp .env.example .envThe environment file is optional; edit it for transport, authentication, or logging overrides.
Build and run the production version:
# One-time build bun run rebuild # Run the built server bun run start:http # or bun run start:stdioRun checks and tests:
bun run devcheck # Lints, formats, type-checks, and more bun run test # Runs the test suite
Docker
docker run --rm -p 3010:3010 ghcr.io/cyanheads/sweden-parliament-mcp-server:latestThe image uses stateless HTTP and writes logs to /var/log/sweden-parliament-mcp-server. For stdio, use docker run -i --rm -e MCP_TRANSPORT_TYPE=stdio ghcr.io/cyanheads/sweden-parliament-mcp-server:latest as the client launch command. Build locally with docker build -t sweden-parliament-mcp-server .; add --build-arg OTEL_ENABLED=false to omit the optional OpenTelemetry dependencies.
Project structure
Directory | Purpose |
| Registers seven tools, initializes the service, and selects stateless HTTP sessions. |
| Seven read-only tool definitions; no resources or prompts. |
| Riksdagen endpoint parsing, reference tables, transport, cache, text conversion, and continuation. |
| Unit and integration tests, mirroring the |
See docs/tree.md for the full file tree.
Development guide
See CLAUDE.md for development guidelines and architectural rules. The short version:
Handlers throw, framework catches — no
try/catchin tool logicUse
ctx.logfor logging,ctx.statefor storageRegister new tools and resources in the
createApp()arrays insrc/index.tsWrap 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:
bun run devcheck
bun run testLicense
Apache-2.0 — see LICENSE for details.
This server cannot be deployed
Maintenance
Related MCP Connectors
Riksdagen (Swedish Parliament) open data MCP.
Swedish public data as read-only tools: registries, statistics, domains, transport, energy.
Search Swiss parliamentary business, votes, debates, members, and declared interests.
Official EUR-Lex, UK, US, and gazette search, metadata fetch, and change-only watches.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables LLMs to query and retrieve real-time open data, documents, protocols, and records from the Swedish Parliament (Riksdag) and Government Offices through 32 specialized MCP tools.31MIT
- AlicenseNot gradedqualityBmaintenanceEnables AI agents to query Swedish Parliament open data through natural language.214 npmMIT
- AlicenseNot gradedqualityAmaintenanceEnables tracking of Canadian federal parliamentary records by searching bills, members, House divisions, and indexed Hansard speeches, then retrieving detailed dossiers, profiles, tallies, and full speech text from official public sources. Runs over STDIO or Streamable HTTP with no API key required.589 npm1Apache 2.0
- AlicenseNot gradedqualityAmaintenanceEnables discovery and retrieval of European Parliament procedures, MEPs, plenary votes, documents, speeches, and questions from the Open Data API over STDIO or Streamable HTTP.479 npm1Apache 2.0