Distribution
Surface truth: the catalogue contains 156 canonical operations. The local full profile serves 161 tool names, 11 resources, and 10 prompts (156 canonical operations plus 5 fiscal aliases). The hosted grouped profile serves 164 tool names, 7 resources, and 10 prompts (the same names plus 3 discovery tools, with API-backed resources kept local-only). The separately reviewed OpenAI profile serves 33 tool names, 0 resources, and 0 prompts. Catalogue membership is not a promise that a backing API is enabled for every workspace.
What is this
An MCP server that connects your AI assistant to Frihet. Create invoices by talking. Query expenses in natural language. Manage your entire business from your IDE.
You: "Create an invoice for TechStart SL, 40 hours of consulting at 75 EUR/hour, due March 1st"
Claude: Done. Invoice INV-2026-089 created. Total: 3,000.00 EUR + 21% IVA = 3,630.00 EUR.
156 canonical operations. Five fiscal aliases. Ten prompts. The local package serves 11 resources; the hosted Worker deliberately serves the 7 static resources, while API-backed workspace resources remain local-profile only.
Try it instantly (no signup)
Kick the tires with zero setup — no account, no API key:
FRIHET_DEMO=1 npx -y @frihet/mcp-server
In demo mode the server answers from realistic example fixtures (Spanish invoices with IVA/IGIC, expenses, clients, products, a bank account, and more) — every record uses demo_-prefixed IDs and the server prints a DEMO MODE banner on startup. Nothing is persisted and no network call is ever made. Writes are simulated and fiscal actions (e-invoice, VeriFactu, TicketBAI, FACe, payroll) return a clearly-labeled simulation — never a real submission to any tax authority.
When you're ready for your real data, drop the flag and add your key (app.frihet.io → Settings → API keys). See Install below.
For AI agents
If you are an agent reading this repository rather than a person reading a page, everything you need is machine-readable and generated from the running server — you do not have to parse this README.
Three rules the contract encodes, in short:
- Orient before acting.
get_business_contextand thefrihet://tax/ratesresource decide the correct fiscal treatment. Do not recall a Spanish tax rate from memory. - Draft, show, stop.
create_invoice,create_quoteandcreate_credit_noteall default tostatus=draft— no fiscal number, no hash, nothing sent to a tax authority. Present the draft and hand back. - Human authority is not yours to assume. Any tool with a non-empty
externalSideEffectsreaches a client's inbox, a webhook, money, or AEAT / VeriFactu / TicketBAI / FACe. Several also takeconfirm=true; that flag records a human decision — never set it to satisfy your own plan.
docs/agent-onboarding.json is regenerated from the live surface by npm run generate:agent-onboarding and gated in CI by npm run gate:agent-onboarding, so its tool lists and counts cannot drift from the server.
Install
Local npm/stdio installs require Node 22.23.4+ (22.x), 24.22.1+ (24.x), or 26.12.1+ (26.x), covering the October 2026 Node security fixes. Node 20 is end-of-life: upgrade the Node runtime used by your MCP client before starting the server. CI uses Node 22.23.4.
This source change does not update previously published npm package metadata or users' installed Node runtimes. Updated package metadata requires a separate npm release; users can upgrade their runtime now. The remote Cloudflare Worker has a separate runtime and release process.
One-line (Claude Code, Cursor, Copilot, Codex, Windsurf, Gemini CLI, and more)
npx skills add Frihet-io/frihet-mcp
Claude Code plugin (skill + MCP server in one install)
This repository is also a Claude Code plugin (frihet-erp): installing it wires up both the business-management skill and the MCP server.
# Try it locally
claude --plugin-dir /path/to/frihet-mcp
Marketplace availability is pending. Use the local plugin command above or the Claude Code MCP command below to connect today.
Skill invocation: /frihet-erp:frihet-mcp. The bundled .mcp.json launches @frihet/mcp-server via npx — set FRIHET_API_KEY in your environment (get one at app.frihet.io → Settings → API keys).
The portable Claude plugin preview bundles
real receivables, document-drafting and monthly-review skills with the existing
public remote MCP. Load plugins/claude/frihet-erp in Claude Code or upload a ZIP
of that folder in chat/Cowork. Its skills guide behavior; they do not filter the
hosted catalogue or establish Directory approval. The root local MCP setup above
keeps its existing API-key configuration.
Claude Code — one command
claude mcp add frihet -s user -e FRIHET_API_KEY=fri_your_key_here -- npx -y @frihet/mcp-server
claude mcp list # verify: frihet ✓ Connected
The CLI owns the config file, so there is nothing to hand-edit and no path to get wrong. (User scope writes ~/.claude.json, not ~/.claude/mcp.json.)
Codex CLI — one command
codex mcp add frihet --env FRIHET_API_KEY=fri_your_key_here -- npx -y @frihet/mcp-server
codex mcp list # verify
Codex config is TOML, not JSON. codex mcp add writes:
[mcp_servers.frihet]
command = "npx"
args = ["-y", "@frihet/mcp-server"]
[mcp_servers.frihet.env]
FRIHET_API_KEY = "fri_your_key_here"
Pasting a JSON
mcpServersblock into~/.codex/config.tomlis a TOML parse error that takes down your whole Codex config, not just this server. Use the command above.
Claude Desktop, Cursor, Windsurf, Cline — JSON config
{
"mcpServers": {
"frihet": {
"command": "npx",
"args": ["-y", "@frihet/mcp-server"],
"env": {
"FRIHET_API_KEY": "fri_your_key_here"
}
}
}
}
The JSON above is identical for these four clients; only the file path changes. Claude Code and Codex are not in this table — they manage their own config through the CLI commands shown above.
Remote (no install)
Use the hosted endpoint at mcp.frihet.io -- zero local dependencies, runs on Cloudflare Workers.
With API key:
{
"mcpServers": {
"frihet": {
"type": "streamable-http",
"url": "https://mcp.frihet.io/mcp",
"headers": {
"Authorization": "Bearer fri_your_key_here"
}
}
}
}
With OAuth 2.0 + PKCE (browser-based login, no API key needed):
Clients that support OAuth (Claude Desktop, Smithery, etc.) can connect directly to https://mcp.frihet.io/mcp and authenticate via browser. The server implements the full OAuth 2.1 authorization code flow with PKCE.
Get your API key
- Log into app.frihet.io
- Go to Settings > API
- Click Create API key
- Copy the key (starts with
fri_) -- it's only shown once
What you can do
Talk to your ERP. These are real prompts, not marketing copy.
Invoicing
"Show me all unpaid invoices"
"Create an invoice for Acme SL with 10h of consulting at 95/hour"
"Mark invoice abc123 as paid"
"How much has ClientName been invoiced this year?"
Expenses
"Log a 59.99 EUR expense for Adobe Creative Cloud, category: software, tax-deductible"
"List all expenses from January"
"What did I spend on travel last quarter?"
Clients
"Add a new client: TechStart SL, NIF B12345678, email [email protected]"
"Show me all my clients"
"Update ClientName's address to Calle Mayor 1, Madrid 28001"
CRM
"Add a contact to Acme SL: Ana Garcia, CTO, [email protected]"
"Log a call with TechStart: discussed Q2 proposal, they're interested in upgrade"
"Add a note to ClientName: prefers invoices in English, payment NET 30"
"Show me all activities for Acme SL"
Quotes
"Create a quote for Design Studio: logo design (2000 EUR) + brand guidelines (3500 EUR)"
"Show me all pending quotes"
Webhooks
"Set up a webhook to notify https://my-app.com/hook when invoices are paid"
"List all my active webhooks"
What to expect
This MCP is a structured data interface -- you describe what you want in natural language, and the AI creates, queries, or modifies business records in Frihet. Most of the 156 canonical operations are CRUD operations over the REST API; the rest are read-only summaries and fiscal/e-invoice actions. Alias and discovery names are counted separately.
Works great:
"Create an invoice for TechStart SL, 40h consulting at 75 EUR/h" --> creates the invoice
"Show unpaid invoices over 1,000 EUR" --> queries and filters
"Log a 120 EUR expense for the Madrid train, category: travel" --> records the expense
"Update client Acme's email to [email protected]" --> modifies the record
Does not do:
- OCR or PDF scanning -- you cannot upload an invoice image and have it read
- File upload or attachment handling
- Image processing of any kind
If you need to digitize paper invoices or receipts, extract the data first (e.g., Claude Vision API, a dedicated OCR service, or manual entry), then use the MCP to create the record:
1. Scan/photograph the invoice
2. Use Claude Vision: "Read this invoice image and extract the vendor, items, amounts, and dates"
3. Then: "Create an expense in Frihet for [extracted data]"
Catalogue operations (156)
Invoices (12)
Expenses (5)
Clients (5)
CRM: Contacts (3)
CRM: Activities (2)
CRM: Notes (3)
Products (5)
Quotes (6)
Webhooks (6)
Intelligence (4)
E-Invoicing (10)
Time Tracking (6)
Recurring Invoices (8)
Team Management (4)
Gestoria — Accountants (5)
Audit GL (3)
White-label Portal Domain (3)
Self-onboard & VIES (2)
IGIC — Canary Islands Indirect Tax (4)
Impuesto sobre Sociedades — Corporate Tax (2)
Bank Categorization Rules (2)
Deposits (7)
Vendors (5)
Banking (5)
Fiscal — Spanish Tax Models (7)
Vacation Rentals / Stay (5)
POS — Point of Sale (4)
Kitchen / Restaurant (6)
HR — Human Resources (9)
Payroll (2)
Onboarding — withdrawn via #124
The onboarding_status and onboarding_persona_set tools were withdrawn because the Frihet-ERP /v1/onboarding/* family does not exist as of this release. See issue #124 for the audit and the precedent (src/tools/igic.ts shows the inline NOT_DEPLOYED stub pattern used for families whose backing API is not yet shipped; onboarding chose full withdrawal instead, because the catalogue should not over-promise tools that have no live handler).
If a future Frihet-ERP release ships the family, restore src/tools/onboarding.ts, the onboardingStatusOutput / onboardingPersonaResultOutput schemas in src/tools/shared.ts, the getOnboardingStatus / setOnboardingPersona methods on IFrihetClient, and the registration in src/tools/register-all.ts (the Onboarding tools — withdrawn via #124 test in src/__tests__/d4b-hr-payroll-onboarding-tools.test.ts is the gate that will fail and remind the next maintainer what was here).
Permissions (2)
Period Close (3)
All canonical operations (and their aliases) return structured output via outputSchema -- typed JSON, not raw text. List response shapes follow their API family; not every list endpoint is paginated.
Capability and side-effect truth
On the full MCP surfaces, every tools/list entry includes _meta["io.frihet/capability"]:
registeredmeans the name and handler exist in this server build;callabilityisapi_dependent(the handler calls the API; deployment, workspace enablement, and authorization still decide),runtime_checked(the handler explicitly distinguishes an absent backend from empty data),deferred,unavailable, orlocal—never an unconditional “available” claim;writesFrihet,externalInteraction, andexternalSideEffectsdistinguish state changes and calls to external entities/providers;- MCP action annotations remain the standard source for read-only, destructive, idempotent, and open-world hints.
The ChatGPT/OpenAI host is a separately reviewed surface: exactly 33 business operations with complete descriptions, 0 discovery meta-tools, 0 prompts, and 0 resources. Its 17 reads and 16 writes are deliberately narrow, and all writes require literal confirm=true. Ten writes may deliver full business events to active endpoints previously configured by the workspace owner; webhook administration itself remains excluded. Direct email delivery, the legacy monthly summary, raw invoice PDFs, invoice lifecycle transitions, updating an existing quote, regulated filing, deleting client parent records, deleting expenses with their linked files, deleting products, and deleting vendors are also excluded. This surface must not be inferred from the full catalogue.
Resources
Context the AI can read to make smarter decisions.
The local package serves 11 resources: 7 static references plus 4 API-backed workspace resources. The hosted Worker serves the 7 static resources. The OpenAI-reviewed host serves 0 resources.
Static (reference data, no API calls):
Dynamic (live data from your account):
Prompts (10)
Pre-built workflows the AI can execute as guided multi-step operations.
How it works
graph LR
AI["Your AI assistant"]
MCP["frihet-mcp"]
API["api.frihet.io"]
DB["Frihet ERP"]
AI -- "create_invoice()" --> MCP
MCP -- "POST /v1/invoices" --> API
API --> DB
DB -- "201 + invoice data" --> API
API -- "structured JSON" --> MCP
MCP -- "typed response + suggestions" --> AI
style AI fill:#09090b,stroke:#4ade80,color:#fafafa
style MCP fill:#09090b,stroke:#fafafa,color:#fafafa
style API fill:#09090b,stroke:#3f3f46,color:#a1a1aa
style DB fill:#09090b,stroke:#3f3f46,color:#a1a1aa
The server translates tool calls into REST API requests. It handles authentication, rate limiting (automatic retry with backoff on 429), pagination, and error mapping.
Two transports:
- stdio (local) --
npx @frihet/mcp-serverwithFRIHET_API_KEY - Streamable HTTP (remote) --
https://mcp.frihet.io/mcpwith Bearer token or OAuth 2.0+PKCE
Environment variables
The source-only Claude candidate requires building this checkout and running
dist/index.js; existing npm releases are not claimed to support the flag.
See candidate scope, exclusions and checks.
It cannot be combined with FRIHET_OPENAI_MODE=true and is not enabled in the deployed Worker.
Tool exposure: depth served on demand
Frihet's differentiator is depth — full ES/EU fiscal coverage plus native compliance (VeriFactu, TicketBAI, Facturae/FACe; KSeF Poland infra-ready, activation pending), banking, CRM, HR/payroll, stay/PMS and POS. But a flat list of every tool, loaded into an agent's context up front, is the 2026 context-rot problem: it crowds out the task and degrades tool selection before any work begins.
FRIHET_TOOL_MODE lets you choose how that depth is exposed.
In grouped mode operation names, input schemas and handlers are unchanged. Descriptors also expose the same conservative capability and action truth as the full profile. Discovery flows through three meta-tools:
list_tool_groups()— the domain map (invoicing, expenses, fiscal/compliance, banking, CRM, HR/payroll, stay/PMS, POS, intelligence, products, platform) with a one-line blurb and tool count for each.search_tools(query)— free-text search across tool name, title, summary and group; returns matching tools with their group, summary, read-only flag and input fields. Optionalgroupfilter andlimit.describe_tool(name)— the full original description and input fields for one tool, on demand, before you call it.
// claude_desktop_config.json — opt in to grouped mode
{
"mcpServers": {
"frihet": {
"command": "npx",
"args": ["@frihet/mcp-server"],
"env": {
"FRIHET_API_KEY": "fri_...",
"FRIHET_TOOL_MODE": "grouped"
}
}
}
}
Grouped exposure changes description density, not operation behavior. The versioned OpenAI-reviewed profile is composed separately and remains independently gated.
API limits
Rate limiting is handled automatically with exponential backoff.
Claude Code Skill
Beyond raw MCP tools, this repo includes a Claude Code skill that adds business context: Spanish tax rules, workflow recipes, financial reports, and natural language commands.
Install the skill
git clone https://github.com/Frihet-io/frihet-mcp.git
ln -s "$(pwd)/frihet-mcp/skills/frihet-mcp" ~/.claude/skills/frihet-mcp
Or with the universal installer:
npx skills add Frihet-io/frihet-mcp
The skill routes requests to the Frihet MCP tools (invoices, quotes, expenses, clients, monthly review) and tells the agent when to ask for confirmation before writes. It does not add standalone /frihet subcommands, and it does not ship VAT rates or deductibility rules: tax figures come from your Frihet data, not from the skill.
Full documentation: docs.frihet.io/desarrolladores/skill-claude-code
Development
git clone https://github.com/Frihet-io/frihet-mcp.git
cd frihet-mcp
npm install
npm run build
Run locally:
FRIHET_API_KEY=fri_xxx node dist/index.js
Test with the MCP Inspector:
npx @modelcontextprotocol/inspector node dist/index.js
Contributing
Contributions are welcome. Please open an issue first to discuss what you'd like to change.
git clone https://github.com/Frihet-io/frihet-mcp.git
cd frihet-mcp
npm install
npm run build # must pass before submitting
Current limitations
- No OCR or file upload -- the MCP works with structured data, not images or PDFs.
- Single company -- one API key maps to one Frihet workspace.
- Frihet account required -- you need an active account at app.frihet.io and an API key (starts with
fri_).
Ecosystem
Links
- Frihet -- The product
- Documentation -- Full docs
- API reference -- REST API
- MCP server docs -- Setup guides, troubleshooting
- npm -- Package registry
- Smithery -- Smithery marketplace
- MCP Registry -- Official Model Context Protocol registry
- GitHub MCP Registry -- Frihet listing on GitHub
- Remote endpoint -- Hosted MCP server (Cloudflare Workers)
- OpenAPI spec -- Machine-readable API definition
- Security policy -- Private vulnerability reporting guidance
License
MIT. See LICENSE.
Built by Frihet.