Skip to main content
Glama
bambinobino

mcp-skatteetaten

by bambinobino
README.md
# mcp-skatteetaten

A comprehensive [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server for [Skatteetaten](https://www.skatteetaten.no) — the Norwegian Tax Administration.

Exposes **35+ tools** covering all major Skatteetaten APIs so that LLM agents and AI assistants can query tax data, submit reports, look up population register information, validate VAT returns, and more — all authenticated via Maskinporten.

---

## Covered APIs

| API | Description |
|-----|-------------|
| **Inntekt** | Employer-reported income (monthly/yearly) |
| **Beregnet Skatt** | Calculated tax: trinnskatt, trygdeavgift, fellesskatt |
| **Summert Skattegrunnlag** | Aggregated tax basis (income, assets, deductions) |
| **Skattemelding** | Tax return retrieval and validation |
| **Restanse** | Outstanding tax debts and arrears |
| **Formuesobjekt Fast Eiendom** | Property ownership and classification |
| **Formuesgrunnlag Eiendomsskatt** | Property value basis for property tax |
| **Folkeregisteret** | Population register: lookup, search, event feed |
| **A-Melding** | Wage/personnel reporting (replaces Altinn A02) |
| **A-Melding Tilbakemelding** | Feedback for submitted A-meldinger |
| **MVA-Melding** | VAT return validation |
| **Skattekorttilarbeidsgiver** | Tax deduction cards for employers |
| **Krav og Betalinger** | Claims and payment history (Fremtidens innkreving) |
| **Tredjepartsopplysninger** | Third-party data reporting (banks, brokers, etc.) |

---

## Prerequisites

1. A Norwegian organisation with an organisation number
2. Access to [Maskinporten](https://docs.digdir.no/docs/Maskinporten) with a registered client and private key
3. Rights packages (rettighetspakker) granted by Skatteetaten for the APIs you need
4. Node.js 20+

### Getting Access

- Register your Maskinporten client at [Samarbeidsportalen](https://samarbeid.digdir.no/)
- Request the relevant scopes from Skatteetaten at [skatteetaten.no/deling](https://www.skatteetaten.no/en/deling/)
- For test environments, use [Tenor test data](https://www.skatteetaten.no/en/testdata/) to get synthetic identifiers

---

## Installation

```bash
npm install
npm run build
```

---

## Configuration

Copy `.env.example` to `.env` and fill in your credentials:

```bash
cp .env.example .env
```

| Variable | Required | Description |
|----------|----------|-------------|
| `MASKINPORTEN_CLIENT_ID` | Yes | Your Maskinporten client ID |
| `MASKINPORTEN_PRIVATE_KEY_PATH` | Yes* | Path to your RSA private key PEM file |
| `MASKINPORTEN_PRIVATE_KEY_JWK` | Yes* | Or provide the JWK as a JSON string |
| `SKATTEETATEN_ENV` | No | `test` (default) or `production` |
| `MASKINPORTEN_ISSUER` | No | Override Maskinporten issuer URL |
| `MASKINPORTEN_TOKEN_ENDPOINT` | No | Override token endpoint URL |
| `FOLKEREGISTERET_AUTH_PACKAGE` | No | `offentlig-med-hjemmel` (default), `offentlig-uten-hjemmel`, or `privat` |

*Either `MASKINPORTEN_PRIVATE_KEY_PATH` or `MASKINPORTEN_PRIVATE_KEY_JWK` is required.

---

## Usage

### With Claude Desktop

Add to your `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "skatteetaten": {
      "command": "node",
      "args": ["/path/to/mcp-skatteetaten/dist/index.js"],
      "env": {
        "MASKINPORTEN_CLIENT_ID": "your-client-id",
        "MASKINPORTEN_PRIVATE_KEY_PATH": "/path/to/private-key.pem",
        "SKATTEETATEN_ENV": "test"
      }
    }
  }
}
```

### With Claude Code

```bash
claude mcp add skatteetaten -- node /path/to/mcp-skatteetaten/dist/index.js
```

Or run directly:

```bash
MASKINPORTEN_CLIENT_ID=... MASKINPORTEN_PRIVATE_KEY_PATH=... npm start
```

---

## Available Tools

### Income (`inntekt`)

| Tool | Description |
|------|-------------|
| `get_inntekt` | Income for a person in a specific month |
| `get_inntekt_for_year` | All income across 12 months for a year |

### Tax (`skatt`)

| Tool | Description |
|------|-------------|
| `get_beregnet_skatt` | Calculated tax breakdown |
| `get_summert_skattegrunnlag` | Aggregated tax basis |
| `get_skattemelding` | Retrieve tax return document |
| `validate_skattemelding` | Validate a tax return XML |
| `get_restanse` | Outstanding tax debts |

### Property (`eiendom`)

| Tool | Description |
|------|-------------|
| `get_formuesobjekt_fast_eiendom` | Property assets for a person |
| `get_formuesgrunnlag_eiendomsskatt` | Property value for tax purposes |

### Population Register (`folkeregisteret`)

| Tool | Description |
|------|-------------|
| `get_person_folkeregisteret` | Full person record lookup |
| `search_personer_folkeregisteret` | Search by criteria |
| `get_folkeregisteret_hendelser` | Change event feed |
| `get_folkeregisteret_current_sekvens` | Current event feed position |

### Wage Reporting (`amelding`)

| Tool | Description |
|------|-------------|
| `submit_amelding` | Submit monthly A-melding |
| `get_amelding_status` | Check submission status |
| `get_amelding_tilbakemelding` | Get feedback on submitted report |
| `list_amelding_for_maaned` | List submissions for a month |

### VAT (`mva`)

| Tool | Description |
|------|-------------|
| `validate_mva_melding_xml` | Validate VAT return XML |
| `validate_mva_melding_json` | Validate VAT return JSON |
| `get_mva_koder` | List valid VAT codes |

### Tax Deduction Cards (`skattekort`)

| Tool | Description |
|------|-------------|
| `get_skattekort` | Get deduction card for an employee |
| `order_skattekort` | Bulk order deduction cards |
| `get_skattekort_ordre_status` | Check order status |
| `get_skattekort_resultat` | Retrieve completed order results |

### Claims & Payments (`krav-og-betalinger`)

| Tool | Description |
|------|-------------|
| `get_krav` | Outstanding claims |
| `get_betalinger` | Payment history |

### Third-Party Reporting (`tredjepartsopplysninger`)

| Tool | Description |
|------|-------------|
| `submit_tredjepartsopplysninger` | Submit third-party data |
| `get_tredjepartsopplysninger_status` | Check submission status |
| `get_tredjepartsopplysninger_oppgavetyper` | List valid report types |

---

## Authentication

All APIs use [Maskinporten](https://docs.digdir.no/docs/Maskinporten) for server-to-server OAuth2 authentication with enterprise certificates.

The client automatically:
- Creates signed JWT grants using your RSA private key
- Exchanges them for Maskinporten access tokens
- Caches tokens until 30 seconds before expiry
- Fetches per-scope tokens (different scopes for different APIs)

**Test environment:** `https://test.maskinporten.no/`
**Production:** `https://maskinporten.no/`

---

## API Documentation

- [Skatteetaten API Documentation](https://skatteetaten.github.io/api-dokumentasjon/en/)
- [Folkeregisteret API](https://skatteetaten.github.io/folkeregisteret-api-dokumentasjon/)
- [MVA-Meldingen](https://skatteetaten.github.io/mva-meldingen/english/api/)
- [Skattemeldingen](https://github.com/Skatteetaten/skattemeldingen)
- [Maskinporten Guide](https://docs.digdir.no/docs/Maskinporten/maskinporten_guide_apikonsument)
- [SwaggerHub — Skatteetaten](https://app.swaggerhub.com/apis/skatteetaten)

---

## Development

```bash
# Run in development mode
npm run dev

# Type check
npm run typecheck

# Build
npm run build
```

---

## License

MIT

TDQS

B3.4/5.0

Scored across 52 tools

Disambiguation4/5

Most tools have distinct purposes, but some near-overlaps exist: get_restanse and get_krav both relate to outstanding tax claims, and get_trinnskatt_satser overlaps with get_skattesatser. Descriptions are specific enough to guide selection, so agents are unlikely to misselect if they read carefully.

Naming Consistency5/5

All tools follow a consistent verb_noun pattern using lowercase with underscores, primarily get_*, with a few action verbs like submit_, validate_, order_, search_, and list_. No mixing of conventions such as camelCase, so the naming is highly predictable.

Tool Count1/5

At 52 tools, this server is excessively large, exceeding the 50-tool threshold for an extreme mismatch. While the Norwegian tax domain is broad, this many tools creates navigation overhead and suggests unnecessary granularity; many rate/deduction tools could be consolidated.

Completeness4/5

The server covers a wide range of tax-related operations: fetching rates, retrieving income/tax data, submitting A-melding and third-party reports, managing skattekort, and accessing the population register. However, there are notable gaps, such as no tool to submit a skattemelding (only validate) and no update/delete operations for several entity types.

Maintenance

ActivityInactive
ResponsivenessNo issues