MCP server
Connect any MCP-compatible agent to Apier's hosted Norwegian compliance tools — per-client config, a five-minute quickstart, and the full 13-tool reference.
[Cite this as: Apier.no Docs v0.1.0 — last updated 2026-06-05]
Apier ships a hosted Model Context Protocol (MCP) server so an AI agent can answer Norwegian compliance questions — what a company must file, who may act for it, and when obligations are due — without you teaching it Norwegian law or rebuilding the Altinn / Maskinporten / Brønnøysund integration. The agent discovers a set of deterministic tools and calls them; every answer is the same shape it would get over REST, plus a justification an agent can cite back to a user.
| Endpoint | https://www.apier.no/api/mcp |
| Transport | Streamable HTTP |
| Registry | no.apier/mcp (the official MCP registry) |
| npm package | @apier-no/mcp (a thin local proxy for stdio-only clients) |
| Auth | Bearer API key (discovery is keyless — see below) |
The same tool verdicts are available over plain REST — see the endpoint reference. MCP is the fastest path for an agent runtime; REST is the fallback for any HTTP client.
One-click install
The quickest way in: register the Apier MCP server with your client in a single click. Cursor uses a real install deep link; Claude Desktop has no install scheme yet, so the button copies a ready-to-paste config block. Both point at the same hosted endpoint — the detailed per-client configuration below is the manual alternative, and the place to add your API key.
What you connect with
There are two ways to reach the server, and which one you use depends on your client:
- Direct streamable HTTP. Clients that speak remote MCP natively
(VS Code, the OpenAI Agents SDK, Azure AI Foundry, and recent
Cursor builds) connect straight to
https://www.apier.no/api/mcpand send the API key in anAuthorization: Bearerheader. - The
@apier-no/mcpstdio proxy. Clients that only speak stdio (Claude Desktop, older Cursor) launch the published npm package vianpx. It readsAPIER_API_KEYfrom the environment, scrubs it from the child process, and forwards it as the bearer header to the same hosted endpoint. No tool logic runs locally — everything resolves server-side.
Per-client configuration
Each block below is copy-paste ready. Replace the placeholder key with a real one from your dashboard — see getting a key — and keep it out of source control.
Claude Desktop
Edit claude_desktop_config.json (Settings → Developer → Edit Config):
{
"mcpServers": {
"apier": {
"command": "npx",
"args": ["-y", "@apier-no/mcp"],
"env": { "APIER_API_KEY": "apr_live_<your_key_here>" }
}
}
}Restart Claude Desktop; the Apier tools appear in the tool menu.
Windows: if Claude Desktop reports
spawn npx ENOENT, wrap the launcher — set"command": "cmd"and"args": ["/c", "npx", "-y", "@apier-no/mcp"], keeping the sameenv. The same applies to any stdio/npx-based client on Windows.
Cursor
Add the same server to ~/.cursor/mcp.json (global) or
.cursor/mcp.json (per-project):
{
"mcpServers": {
"apier": {
"command": "npx",
"args": ["-y", "@apier-no/mcp"],
"env": { "APIER_API_KEY": "apr_live_<your_key_here>" }
}
}
}VS Code
VS Code (Copilot agent mode) speaks remote MCP natively, so it
connects to the endpoint directly. Add .vscode/mcp.json:
{
"servers": {
"apier": {
"type": "http",
"url": "https://www.apier.no/api/mcp",
"headers": { "Authorization": "Bearer apr_live_<your_key_here>" }
}
}
}OpenAI Agents SDK
Wire the endpoint as a MCPServerStreamableHttp server and hand it to
an Agent (Python):
import asyncio
from agents import Agent, Runner
from agents.mcp import MCPServerStreamableHttp
async def main():
async with MCPServerStreamableHttp(
name="apier",
params={
"url": "https://www.apier.no/api/mcp",
"headers": {"Authorization": "Bearer apr_live_<your_key_here>"},
},
) as apier:
agent = Agent(
name="Compliance assistant",
instructions="Use Apier's tools for Norwegian compliance questions.",
mcp_servers=[apier],
)
result = await Runner.run(agent, "What does org 999999999 owe?")
print(result.final_output)
asyncio.run(main())Azure AI Foundry
Register the endpoint as an MCP tool on a Foundry agent. Auth headers are passed per run and are not persisted by Foundry (Python):
from azure.ai.agents.models import McpTool
apier = McpTool(
server_label="apier",
server_url="https://www.apier.no/api/mcp",
)
apier.update_headers("Authorization", "Bearer apr_live_<your_key_here>")
agent = project_client.agents.create_agent(
model="gpt-4o",
name="compliance-assistant",
instructions="Use Apier's tools for Norwegian compliance questions.",
tools=apier.definitions,
)Getting a key
Sign up and open your dashboard to
create a key. It is shown in full exactly once — store it
securely. Issued keys are prefixed apr_test_ (synthetic data) or
apr_live_ (production). See Authentication
for the full key model, tiers, and rate limits.
How bearer auth works
The MCP server splits a keyless discovery surface from an authenticated call surface:
- Keyless (no key needed) — the whole handshake and discovery
surface:
initialize,notifications/initialized,tools/list,ping,prompts/list,prompts/get,resources/list,resources/templates/list,resources/read(public rulebook resources only), andcompletion/complete. A client can complete the MCP handshake and read the full catalogue before presenting any credential; the discovery response is byte-identical for every caller. - Authenticated (key + scope) —
tools/call, andresources/readfor company-specific resources. A missing or invalid key returns a JSON-RPC-32001error with aWWW-Authenticate: Bearerchallenge, never a result. Each tool's required scope is in the tool reference below.
Every response also carries the negotiated MCP-Protocol-Version
header; the server supports 2025-06-18 (latest), 2025-03-26, and
2024-11-05.
The @apier-no/mcp proxy injects the bearer header for you from
APIER_API_KEY; the direct-HTTP clients above set it themselves.
OAuth is coming. Today authentication is a bearer API key. An OAuth 2.1 authorization-code flow — so an agent can obtain and refresh a key without copy-pasting one — is planned for a later release. The bearer key will keep working.
Five-minute quickstart
- Add the config for your client from the section above, using a
real key. (No key yet? You can still explore the tool catalogue —
tools/listis keyless — but calling a tool needs one.) - Restart the client so it picks up the new server.
- Ask a compliance question in natural language. The agent reads the tool catalogue, picks the right tool, and calls it:
You: What does org 999999999 owe?
Agent: (calls get_company_obligations with org_number "999999999")
Org 999999999 has these active obligations:
• MVA (VAT) return — filed per term — Merverdiavgiftsloven § 15-1
• A-melding — monthly employer/payroll report — A-opplysningsloven § 3
• Årsregnskap — annual accounts — Regnskapsloven § 8-2
Source: Brønnøysund + Apier Universal Rulebook. Each verdict
carries its legal_reference, so I can show you exactly which
rule applies.Under the hood the agent issued a single tools/call:
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get_company_obligations",
"arguments": { "org_number": "999999999" }
},
"id": 1
}Apier resolves it against the live Rulebook and returns the structured
obligation set. 999999999 is the documentation example org; to
rehearse the full authenticated surface — per-company context, dry-run
filings, receipts — with zero risk and no signup, point your agent at
the sandbox (it never calls a government system and tags
every response _meta.is_sandbox: true).
The response envelope
Every tool returns the same three-part envelope, so an agent parses results uniformly:
{
"result": { "...": "the normalised tool payload" },
"justification": {
"rules_applied": ["MVA_FILING_BIMONTHLY"],
"source_data": ["brreg", "rulebook"],
"valid_until": "2026-07-01T00:00:00Z"
},
"metadata": {
"query_id": "…",
"resolved_at": "2026-06-05T08:00:00Z",
"data_sources": ["brreg", "rulebook"],
"schema_version": "2026.6.0",
"tool_name": "get_company_obligations"
}
}justification is the audit signal — which rules and upstream sources
produced the answer, and when it goes stale. On failure, result is
null and metadata carries an error_code plus a safe
error_message (never a stack trace or raw upstream body).
Tool reference
Thirteen tools are live. Names are verb_noun, so an agent can read
the intent from the name alone. Twelve are read-only; one
(submit_vat_return) models a write and is locked to the sandbox.
Each tool also ships a longer description, a structured output schema,
truthful behaviour hints, and worked examples in its tools/list
entry — clients surface these automatically.
Company intelligence
| Tool | Title | What it does | Scope |
|---|---|---|---|
get_company_summary | Company compliance summary | One-shot identity and compliance verdict for an org number — the broadest single call. | read:brreg |
get_company_context | Company registry facts | Brønnøysund identity slice only (name, form, NACE, addresses, role codes) — no compliance verdict. | read:brreg |
get_company_profile | Company profile (Brønnøysund) | Structured Enhetsregisteret profile: name, form, NACE, addresses, status, MVA flag, role codes. | read:brreg |
get_company_obligations | Company regulatory obligations | Every applicable obligation with its current state and legal reference, evaluated against the live Rulebook. | read:brreg |
get_company_deadlines | Company filing calendar | Upcoming filing dates per obligation and period — Europe/Oslo, DST- and holiday-aware — over a horizon you choose. | read:brreg |
Public lookups (no org number required)
| Tool | Title | What it does | Scope |
|---|---|---|---|
get_public_obligations | Obligations by entity type | Baseline obligations an entity owes by being that form (AS, ENK, NUF, …), before per-company data. | read:rulebook |
get_public_deadlines | Norwegian filing calendar | The universal filing calendar for a year — MVA, A-melding, årsregnskap. | read:rulebook |
get_exchange_rate | Norges Bank exchange rate | The latest Norges Bank reference rate between two ISO-4217 currencies. | read:norgesbank |
Authorisation
| Tool | Title | What it does | Scope |
|---|---|---|---|
check_authorization | Authorisation snapshot | Your delegation status on an org: granted vs missing scopes and the delegation chain. | read:altinn |
list_acting_capacity | Acting capacity for a person | The actions a person may take for an org, derived from their Altinn roles, each with a legal citation. | read:altinn |
Actions
| Tool | Title | What it does | Scope |
|---|---|---|---|
validate_action | Validate a regulatory action (dry-run) | Run a proposed filing through the five prerequisite checks with zero upstream side effects. | read:actions |
submit_vat_return | Submit VAT return (sandbox) | Sandbox-only MVA filing — preview without an approval token, or file a mock receipt with one. Never contacts a real government system. | read:actions |
Errors
| Tool | Title | What it does | Scope |
|---|---|---|---|
explain_compliance_error | Explain a compliance error | Turn any Apier error_code into a Norwegian-bokmål explanation with fix steps and, where applicable, a legal basis. | read:rulebook |
Keys carry a scopes array (default read:*, which grants any
read: action). A call whose key lacks the required scope returns
SCOPE_INSUFFICIENT. Reserved prefixes (write:, act:, delegate:)
are not assignable — which is why submit_vat_return needs only
read:actions: the human approval gate, not the agent's key,
authorises the mock filing.
Next steps
Authentication
The full key model — formats, tiers, scopes, and rate limits.
Quick start
Zero-auth REST calls in under five minutes — no key required.
Endpoint reference
Every tool verdict is also a REST endpoint, backed by the OpenAPI spec.
SDKs
Official Python and MCP packages, plus spec-driven client generation.