# MCP server

The MCP server gives an AI assistant read access to Swedish public procurement
data in Fentlig: notices, buyers, award results, contracts, tender documents
and the requirements extracted from them. It is a remote server, so there is
nothing to install. It is included in every Fentlig plan.

```
https://mcp.fentlig.se/mcp
```

## Signing in

When you connect, the client opens a Fentlig sign-in page. You sign in and
approve what the assistant may read. No key is needed.

The assistant reads what you see in Fentlig, limited to the markets your
account follows. An account that follows no markets gets no
results until an owner or admin chooses markets in Fentlig under
**Inställningar > Marknader** (Settings > Markets).

Any member of an account can connect an assistant.

## Connecting

### Claude (claude.ai and Claude Desktop)

1. Open **Settings > Connectors** and choose **Add custom connector**.
2. Enter a name, for example Fentlig, and paste `https://mcp.fentlig.se/mcp` as
   the URL.
3. Leave the OAuth client ID and client secret fields empty.
4. Choose **Connect**, then sign in to Fentlig and approve.

If your organisation manages Claude's connectors centrally, an administrator
may need to add it first.

### ChatGPT

1. Turn on developer mode under **Settings > Security and login > Developer
   mode**. Whether it is available depends on your ChatGPT plan and your
   workspace's settings.
2. Open **Plugins**, select the plus button, and enter a name and a
   description.
3. Under **Connection**, enter `https://mcp.fentlig.se/mcp` as the server URL.
4. Create the connection, then sign in to Fentlig and approve when ChatGPT asks
   you to.

### Claude Code

```bash
claude mcp add --transport http fentlig https://mcp.fentlig.se/mcp
```

Then run `/mcp` in Claude Code and choose to authenticate. A browser opens on
the Fentlig sign-in page.

### Other MCP clients

Clients such as Cursor and VS Code connect to a remote server over Streamable
HTTP with OAuth. Add `https://mcp.fentlig.se/mcp` as a remote (HTTP) server,
and the client opens the sign-in page when it first connects.

A client that can only send a fixed header can use an API key instead. Send it
as `Authorization: Bearer`. An account owner creates keys under
**Inställningar > API-nycklar** (Settings > API keys), on any plan; see
[Authentication](/utvecklare/authentication). In Claude Code:

```bash
claude mcp add --transport http fentlig https://mcp.fentlig.se/mcp \
  --header "Authorization: Bearer $FENTLIG_API_KEY"
```

Revoke the key under API-nycklar to stop it.

## Removing a connection

Your connected assistants are listed in the Fentlig app under **Inställningar >
Assistenter** (Settings > Assistants). Removing one there ends its access at
once.

## Tools

Every tool is read-only and offered to every connection. A tool whose data
your plan does not include answers that it is not included in your plan.
With an API key, a tool also needs the scope listed in
[Authentication](/utvecklare/authentication#scopes).

| Tool | Answers | Plans |
| --- | --- | --- |
| `search_notices` | Which procurements match, by keyword, buyer, status, region, CPV, deadline, value or words in the tender documents | Every plan |
| `get_notice` | One notice in full | Every plan |
| `find_similar_notices` | Procurements like a given one | Every plan |
| `search_buyers` | Which contracting authorities match a name, category or region | Every plan |
| `get_buyer` | How one contracting authority buys | Every plan |
| `get_market_stats` | Figures for a market: volumes, procedures, awarded values, suppliers per procurement | Every plan |
| `get_requirements` | The requirements and award criteria extracted from a procurement | Every plan |
| `read_document` | The tender documents of a procurement, listed and read in parts | Every plan |
| `lookup_codes` | CPV codes and NUTS region codes that match a few words | Every plan |
| `list_watches` | Your account's saved searches (bevakningar) | Every plan |
| `get_watch_matches` | The recent matches of a saved search | Every plan |
| `get_supplier_history` | One company's record as a supplier: procurements, wins and buyers | Team and Koncern |
| `get_competitors` | Which suppliers win in a market | Team and Koncern |
| `search_contracts` | Public contracts and when they end | Team and Koncern |
| `summarize_contracts` | Contract totals by buyer, supplier, year or category | Team and Koncern |

Tool arguments are in snake_case. Tool names and arguments change only by
addition; see [Versioning and changes](/utvecklare/versioning).

## Example prompts

- "Which open procurements for cleaning services in Västra Götaland close in
  the next month?" (`lookup_codes`, `search_notices`)
- "What are the requirements and award criteria in Region Sörmland's
  procurement of fruit and vegetables? Quote the tender documents where they
  set a minimum." (`get_requirements`, `read_document`)
- "How does Karlskrona kommun buy IT services, and how many bids do its
  procurements usually get?" (`get_buyer`, `get_market_stats`)
- "Who wins school meal contracts from municipalities in Skåne, and which of
  those contracts end next year?" (`get_competitors`, `search_contracts`)
- "Vilka nya träffar har mina bevakningar fått den här veckan?" ("What new
  matches have my saved searches had this week?") (`list_watches`,
  `get_watch_matches`)

## What to expect from the answers

The assistant is told:

- **Few procurements are open at any one time.** An empty search for live
  tenders is a normal result.
- **The answers cover part of the market.** The server answers from what your
  account sees in Fentlig, in the markets it follows. If a buyer does not
  appear, nothing is recorded for it here.
- **A concluded procurement has a published result.** The result is either an
  award or a discontinued procedure.
- **Buyer and market figures count the procurements recorded here**, not
  everything the buyer bought.
- **A supplier is recorded only where a notice names it.** A win rate counts
  the procurements the supplier is recorded in, and an empty competitor result
  means no supplier was named.
- **Every answer carries a `coverage` field** naming the sources and the
  attribution their licences require. See
  [Coverage and attribution](/utvecklare/coverage).

## Sole traders

A Swedish sole trader's registration number is the owner's personal identity
number, and the business name is often the owner's name. On those rows the name
and number are withheld, and the row is flagged as withheld. Every other field
is served, and the row counts in every ranking and total.

## Aggregates

Every aggregate carries a sample size. A value total sums the award lines that
state a positive amount, and its `sampleSize` is how many such lines there were.
Read it before quoting a total.

## Transport

The endpoint speaks Streamable HTTP and accepts `POST` only; `GET` and
`DELETE` answer `405`. See [Rate limits](/utvecklare/rate-limits).
