Skip to main content
Glama

scb-mcp

An MCP server over Statistics Sweden's business register. Point an assistant at it and it can search, count and read Swedish workplaces and legal entities without knowing anything about cursors, path versions or API keys.

No dependencies. The protocol is implemented against the specification rather than wrapped, which is the point: the handshake, the framing and the error codes are all in src/, in about three hundred lines you can read.

Use it

// Claude Desktop, claude_desktop_config.json
{
  "mcpServers": {
    "scb": {
      "command": "npx",
      "args": ["-y", "scb-mcp"],
      "env": { "SCB_API_KEY": "the key you were given" }
    }
  }
}

The key goes in the environment, never on the command line and never in a path. It travels in the X-API-Key header that the register's contract asks for, and it is not written to the log.

Related MCP server: SCB MCP Server

The tools

tool

what it does

search_workplaces

Workplaces, filtered on one of kommun, län, näringsgren or size class

count_workplaces

The same filters, but only the number

get_workplace

One workplace by its CFAR number

search_legal_entities

The same, over legal entities

count_legal_entities

get_legal_entity

One legal entity by organisation number

Every search takes limit and follows the register's cursor until it has that many. full: true asks for every available variable instead of the usual selection.

See it work

node --experimental-strip-types examples/handshake.ts

A stubbed register, the real protocol:

-> {"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05"}}
<- {"protocolVersion":"2024-11-05","capabilities":{"tools":{"listChanged":false}},"serverInfo":{"name":"scb-mcp","version":"0.1.0"}}
-> {"jsonrpc":"2.0","method":"notifications/initialized"}
   (notification, nothing to answer)
-> {"jsonrpc":"2.0","id":2,"method":"tools/list"}
<- 6 tools: search_workplaces, count_workplaces, get_workplace, search_legal_entities, count_legal_entities, get_legal_entity
-> {"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"count_workplaces","arguments":{"...
<- ok: { "count": 1403 }
-> {"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"search_workplaces","arguments":{...
<- ok: { "count": 2, "hasMore": true, "items": [ { "cfarNr": "10000001", "namn": "Nordvik Bygg AB", "kommun": "0486",
-> {"jsonrpc":"2.0","id":5,"method":"tools/call","params":{"name":"get_workplace","arguments":{"cfa...
<- tool error: no such resource in the register: {"message":"unknown path"}

Three decisions

A tool that fails is a result, not a protocol error. The last line above is a 404 from the register, and it comes back inside tools/call with isError: true. A model reads that and tries a different identifier. A JSON-RPC error would take the whole turn down for something the model could have handled.

Paging is not the model's problem. The register hands out pages with limit and cursorId and says hasMore when there is more. The search tools follow that until they have what was asked for and report whether anything was left, so a model never has to hold a cursor across turns.

The register filters on one thing at a time. That is the API's restriction, not this server's, and giving two filters comes back as the register filters on one thing at a time; kommun and lan were both given rather than one of them being dropped quietly.

Development

npm run check    # types
npm test         # 56 tests, no network, no key
npm run build

fetch is injected into the client, which is why every test runs offline. The register's own contract is at apiafr.scb.se; the paths here follow it, including the /v1 segment and the /count and /full variants.

MIT licensed.

Available Tools

6 tools
count_workplacesA

Count workplaces in the register, with the same filters as the search. Cheaper than listing them.

Inputs: lan, kommun, naringsgren, anstalldaklass.

get_workplaceB

Read one entry from the register by its cfarNr.

Inputs: cfarNr (required), full.

search_workplacesA

Search workplaces in Statistics Sweden's business register. Filter on one of kommun, lan, naringsgren, anstalldaklass, or leave the filters out to read from the top of the register.

Inputs: lan, full, limit, kommun, +2 more.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.9/5.0

    Scored across 6 tools

    Disambiguation5/5

    The set factorizes cleanly into two resources (workplaces, legal entities) × three operations (get, search, count), and each tool name states both explicitly. The descriptions reinforce this, including a clear note that count is a cheaper alternative to search and that get uses a distinct identifier (cfarNr vs peOrgNr). No two tools can be reasonably confused.

    Naming Consistency5/5

    Every tool follows the same snake_case verb_noun pattern (get_/search_/count_ plus the resource), with parallel naming across the two entity types. The pattern is fully predictable, so an agent can infer tool names for a resource without reading descriptions.

    Tool Count5/5

    Six tools is tightly scoped: exactly the three read operations needed for each of the two register resources, with no redundant or filler tools. The count/search pairing is justified by an explicit cost tradeoff rather than duplication.

    Completeness4/5

    For a read-only statistical register, the surface covers the core lifecycle: filtered search, cheap counting, and single-record retrieval by key. The notable gap is discoverability of filter vocabularies (valid kommun/lan/naringsgren/anstalldaklass codes) and pagination semantics, which agents must currently guess at.

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      Not graded
      quality
      Not graded
      maintenance
      Enables searching and retrieving detailed information about Swedish companies, including financial data and annual reports from Bolagsverket (Swedish Companies Registration Office), with intelligent caching for fast responses.
      -
    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables LLMs to search, access, and retrieve official Swedish statistics from Statistics Sweden (SCB), providing access to 1,200+ tables covering demographics, economy, environment, labor market, and education with 75+ years of historical data.
      9
      MIT
    • A
      license
      B
      quality
      D
      maintenance
      Enables interaction with the Norwegian Business Registry (Brønnøysundregistrene) API to search and retrieve detailed information about Norwegian companies, subunits, roles, organization forms, municipalities, and NACE industry codes.
      18
      11 npm
      1
      MIT
    • A
      license
      A
      quality
      D
      maintenance
      Query Swedish public data from AI tools. Includes company data, SCB statistics, weather, transport, public agencies, and more through the Apiverket API.
      2
      53 npm
      2
      MIT