@frihet/mcp-server 1.2.3 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +124 -40
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +10 -0
- package/dist/client.js.map +1 -1
- package/dist/index.js +17 -3
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts +46 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +90 -0
- package/dist/logger.js.map +1 -0
- package/dist/metrics.d.ts +28 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +81 -0
- package/dist/metrics.js.map +1 -0
- package/dist/tools/clients.d.ts.map +1 -1
- package/dist/tools/clients.js +36 -61
- package/dist/tools/clients.js.map +1 -1
- package/dist/tools/expenses.d.ts.map +1 -1
- package/dist/tools/expenses.js +36 -61
- package/dist/tools/expenses.js.map +1 -1
- package/dist/tools/invoices.d.ts.map +1 -1
- package/dist/tools/invoices.js +45 -75
- package/dist/tools/invoices.js.map +1 -1
- package/dist/tools/products.d.ts.map +1 -1
- package/dist/tools/products.js +36 -61
- package/dist/tools/products.js.map +1 -1
- package/dist/tools/quotes.d.ts.map +1 -1
- package/dist/tools/quotes.js +36 -61
- package/dist/tools/quotes.js.map +1 -1
- package/dist/tools/shared.d.ts +23 -1
- package/dist/tools/shared.d.ts.map +1 -1
- package/dist/tools/shared.js +54 -5
- package/dist/tools/shared.js.map +1 -1
- package/dist/tools/webhooks.d.ts.map +1 -1
- package/dist/tools/webhooks.js +36 -61
- package/dist/tools/webhooks.js.map +1 -1
- package/package.json +23 -14
package/README.md
CHANGED
|
@@ -8,37 +8,39 @@
|
|
|
8
8
|
</p>
|
|
9
9
|
|
|
10
10
|
<p align="center">
|
|
11
|
-
<a href="https://www.npmjs.com/package/@frihet/mcp-server"><img src="https://img.shields.io/npm/v/@frihet/mcp-server?style=flat&color=18181b&labelColor=09090b" alt="npm"></a>
|
|
11
|
+
<a href="https://www.npmjs.com/package/@frihet/mcp-server"><img src="https://img.shields.io/npm/v/@frihet/mcp-server?style=flat&color=18181b&labelColor=09090b" alt="npm version"></a>
|
|
12
|
+
<a href="https://www.npmjs.com/package/@frihet/mcp-server"><img src="https://img.shields.io/npm/dm/@frihet/mcp-server?style=flat&color=18181b&labelColor=09090b&label=downloads" alt="npm downloads"></a>
|
|
13
|
+
<a href="https://smithery.ai/server/frihet/frihet-mcp"><img src="https://smithery.ai/badge/frihet/frihet-mcp" alt="Smithery installs"></a>
|
|
14
|
+
<a href="https://registry.modelcontextprotocol.io/servers/io.github.berthelius/frihet"><img src="https://img.shields.io/badge/MCP-Registry-18181b?style=flat&labelColor=09090b" alt="MCP Registry"></a>
|
|
12
15
|
<a href="https://github.com/Frihet-io/frihet-mcp/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-18181b?style=flat&labelColor=09090b" alt="license"></a>
|
|
13
|
-
<
|
|
14
|
-
<
|
|
16
|
+
<img src="https://img.shields.io/badge/tools-31-18181b?style=flat&labelColor=09090b" alt="31 tools">
|
|
17
|
+
<img src="https://img.shields.io/badge/node-%3E%3D18-18181b?style=flat&labelColor=09090b" alt="node >=18">
|
|
18
|
+
<a href="https://www.typescriptlang.org/"><img src="https://img.shields.io/badge/TypeScript-18181b?style=flat&labelColor=09090b" alt="TypeScript"></a>
|
|
15
19
|
</p>
|
|
16
20
|
|
|
17
21
|
---
|
|
18
22
|
|
|
19
23
|
## What is this
|
|
20
24
|
|
|
21
|
-
An MCP server that connects your AI assistant to [Frihet
|
|
25
|
+
An MCP server that connects your AI assistant to [Frihet](https://frihet.io). Create invoices by talking. Query expenses in natural language. Manage your entire business from your IDE.
|
|
22
26
|
|
|
23
27
|
```
|
|
24
28
|
You: "Create an invoice for TechStart SL, 40 hours of consulting at 75 EUR/hour, due March 1st"
|
|
25
29
|
Claude: Done. Invoice INV-2026-089 created. Total: 3,000.00 EUR + 21% IVA = 3,630.00 EUR.
|
|
26
30
|
```
|
|
27
31
|
|
|
28
|
-
31 tools. 5 resources. 5 prompts. Structured output. Zero boilerplate.
|
|
32
|
+
31 tools. 5 resources. 5 prompts. Structured output on every tool. Zero boilerplate.
|
|
29
33
|
|
|
30
34
|
---
|
|
31
35
|
|
|
32
36
|
## Install
|
|
33
37
|
|
|
34
|
-
###
|
|
38
|
+
### One-line (Claude Code, Cursor, Copilot, Codex, Windsurf, Gemini CLI, and more)
|
|
35
39
|
|
|
36
40
|
```bash
|
|
37
41
|
npx skills add Frihet-io/frihet-mcp
|
|
38
42
|
```
|
|
39
43
|
|
|
40
|
-
### Per-tool configuration
|
|
41
|
-
|
|
42
44
|
### Claude Code / Claude Desktop
|
|
43
45
|
|
|
44
46
|
```json
|
|
@@ -68,7 +70,9 @@ The JSON config is identical for all tools. Only the file path changes.
|
|
|
68
70
|
|
|
69
71
|
### Remote (no install)
|
|
70
72
|
|
|
71
|
-
|
|
73
|
+
Use the hosted endpoint at `mcp.frihet.io` -- zero local dependencies, runs on Cloudflare Workers.
|
|
74
|
+
|
|
75
|
+
**With API key:**
|
|
72
76
|
|
|
73
77
|
```json
|
|
74
78
|
{
|
|
@@ -84,7 +88,9 @@ If you prefer not to install anything locally, use the hosted endpoint at `mcp.f
|
|
|
84
88
|
}
|
|
85
89
|
```
|
|
86
90
|
|
|
87
|
-
|
|
91
|
+
**With OAuth 2.0 + PKCE** (browser-based login, no API key needed):
|
|
92
|
+
|
|
93
|
+
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.
|
|
88
94
|
|
|
89
95
|
### Get your API key
|
|
90
96
|
|
|
@@ -140,9 +146,38 @@ Talk to your ERP. These are real prompts, not marketing copy.
|
|
|
140
146
|
|
|
141
147
|
---
|
|
142
148
|
|
|
143
|
-
##
|
|
149
|
+
## What to expect
|
|
150
|
+
|
|
151
|
+
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. All 31 tools are CRUD operations over the REST API.
|
|
152
|
+
|
|
153
|
+
**Works great:**
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
"Create an invoice for TechStart SL, 40h consulting at 75 EUR/h" --> creates the invoice
|
|
157
|
+
"Show unpaid invoices over 1,000 EUR" --> queries and filters
|
|
158
|
+
"Log a 120 EUR expense for the Madrid train, category: travel" --> records the expense
|
|
159
|
+
"Update client Acme's email to billing@acme.es" --> modifies the record
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**Does not do:**
|
|
144
163
|
|
|
145
|
-
|
|
164
|
+
- OCR or PDF scanning -- you cannot upload an invoice image and have it read
|
|
165
|
+
- File upload or attachment handling
|
|
166
|
+
- Image processing of any kind
|
|
167
|
+
|
|
168
|
+
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:
|
|
169
|
+
|
|
170
|
+
```
|
|
171
|
+
1. Scan/photograph the invoice
|
|
172
|
+
2. Use Claude Vision: "Read this invoice image and extract the vendor, items, amounts, and dates"
|
|
173
|
+
3. Then: "Create an expense in Frihet for [extracted data]"
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Tools (31)
|
|
179
|
+
|
|
180
|
+
### Invoices (6)
|
|
146
181
|
|
|
147
182
|
| Tool | What it does |
|
|
148
183
|
|------|-------------|
|
|
@@ -153,7 +188,7 @@ Talk to your ERP. These are real prompts, not marketing copy.
|
|
|
153
188
|
| `delete_invoice` | Permanently delete an invoice |
|
|
154
189
|
| `search_invoices` | Find invoices by client name |
|
|
155
190
|
|
|
156
|
-
### Expenses
|
|
191
|
+
### Expenses (5)
|
|
157
192
|
|
|
158
193
|
| Tool | What it does |
|
|
159
194
|
|------|-------------|
|
|
@@ -163,7 +198,7 @@ Talk to your ERP. These are real prompts, not marketing copy.
|
|
|
163
198
|
| `update_expense` | Modify an expense |
|
|
164
199
|
| `delete_expense` | Delete an expense |
|
|
165
200
|
|
|
166
|
-
### Clients
|
|
201
|
+
### Clients (5)
|
|
167
202
|
|
|
168
203
|
| Tool | What it does |
|
|
169
204
|
|------|-------------|
|
|
@@ -173,7 +208,7 @@ Talk to your ERP. These are real prompts, not marketing copy.
|
|
|
173
208
|
| `update_client` | Update client info |
|
|
174
209
|
| `delete_client` | Remove a client |
|
|
175
210
|
|
|
176
|
-
### Products
|
|
211
|
+
### Products (5)
|
|
177
212
|
|
|
178
213
|
| Tool | What it does |
|
|
179
214
|
|------|-------------|
|
|
@@ -183,7 +218,7 @@ Talk to your ERP. These are real prompts, not marketing copy.
|
|
|
183
218
|
| `update_product` | Update pricing or details |
|
|
184
219
|
| `delete_product` | Remove a product |
|
|
185
220
|
|
|
186
|
-
### Quotes
|
|
221
|
+
### Quotes (5)
|
|
187
222
|
|
|
188
223
|
| Tool | What it does |
|
|
189
224
|
|------|-------------|
|
|
@@ -193,7 +228,7 @@ Talk to your ERP. These are real prompts, not marketing copy.
|
|
|
193
228
|
| `update_quote` | Modify a quote |
|
|
194
229
|
| `delete_quote` | Delete a quote |
|
|
195
230
|
|
|
196
|
-
### Webhooks
|
|
231
|
+
### Webhooks (5)
|
|
197
232
|
|
|
198
233
|
| Tool | What it does |
|
|
199
234
|
|------|-------------|
|
|
@@ -203,6 +238,36 @@ Talk to your ERP. These are real prompts, not marketing copy.
|
|
|
203
238
|
| `update_webhook` | Modify events or URL |
|
|
204
239
|
| `delete_webhook` | Remove a webhook |
|
|
205
240
|
|
|
241
|
+
All 31 tools return **structured output** via `outputSchema` -- typed JSON, not raw text. List tools return paginated results (`{ data, total, limit, offset }`).
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Resources (5)
|
|
246
|
+
|
|
247
|
+
Static context the AI can read without making API calls.
|
|
248
|
+
|
|
249
|
+
| Resource | URI | What it provides |
|
|
250
|
+
|----------|-----|-----------------|
|
|
251
|
+
| API Schema | `frihet://api/schema` | OpenAPI summary: endpoints, auth, rate limits, pagination, error codes |
|
|
252
|
+
| Tax Rates | `frihet://tax/rates` | Tax rates by Spanish fiscal zone: IVA, IGIC, IPSI, EU reverse charge, IRPF |
|
|
253
|
+
| Tax Calendar | `frihet://tax/calendar` | Quarterly filing deadlines: Modelo 303, 130, 390, 420, VeriFactu timeline |
|
|
254
|
+
| Expense Categories | `frihet://config/expense-categories` | 8 categories with deductibility rules, IVA treatment, amortization |
|
|
255
|
+
| Invoice Statuses | `frihet://config/invoice-statuses` | Status flow (draft > sent > paid/overdue > cancelled), transition rules, webhook events |
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## Prompts (5)
|
|
260
|
+
|
|
261
|
+
Pre-built workflows the AI can execute as guided multi-step operations.
|
|
262
|
+
|
|
263
|
+
| Prompt | What it does | Arguments |
|
|
264
|
+
|--------|-------------|-----------|
|
|
265
|
+
| `monthly-close` | Close the month: review unpaid invoices, categorize expenses, check tax obligations, generate summary | `month?` (YYYY-MM) |
|
|
266
|
+
| `onboard-client` | Set up a new client with correct tax rates by location, optionally create a welcome quote | `clientName`, `country?`, `region?` |
|
|
267
|
+
| `quarterly-tax-prep` | Prepare quarterly tax filing: calculate IVA/IGIC, identify deductibles, preview Modelo 303/130/420 | `quarter?`, `fiscalZone?` |
|
|
268
|
+
| `overdue-followup` | Find overdue invoices, draft follow-up messages, suggest payment reminders | -- |
|
|
269
|
+
| `expense-batch` | Process expenses in bulk: categorize, apply tax rates, flag missing receipts | `fiscalZone?` |
|
|
270
|
+
|
|
206
271
|
---
|
|
207
272
|
|
|
208
273
|
## How it works
|
|
@@ -213,20 +278,22 @@ Your AI assistant frihet-mcp Frihet API
|
|
|
213
278
|
|-- "create invoice" --> | |
|
|
214
279
|
| |-- POST /invoices ->|
|
|
215
280
|
| |<-- 201 Created ----|
|
|
216
|
-
|<--
|
|
281
|
+
|<-- structured JSON --- | |
|
|
217
282
|
```
|
|
218
283
|
|
|
219
|
-
The
|
|
284
|
+
The server translates tool calls into REST API requests. It handles authentication, rate limiting (automatic retry with backoff on 429), pagination, and error mapping.
|
|
285
|
+
|
|
286
|
+
Two transports:
|
|
287
|
+
- **stdio** (local) -- `npx @frihet/mcp-server` with `FRIHET_API_KEY`
|
|
288
|
+
- **Streamable HTTP** (remote) -- `https://mcp.frihet.io/mcp` with Bearer token or OAuth 2.0+PKCE
|
|
220
289
|
|
|
221
290
|
### Environment variables
|
|
222
291
|
|
|
223
292
|
| Variable | Required | Default |
|
|
224
293
|
|----------|----------|---------|
|
|
225
|
-
| `FRIHET_API_KEY` | Yes | -- |
|
|
294
|
+
| `FRIHET_API_KEY` | Yes (stdio) | -- |
|
|
226
295
|
| `FRIHET_API_URL` | No | `https://api.frihet.io/v1` |
|
|
227
296
|
|
|
228
|
-
`FRIHET_API_URL` is useful if you self-host or want to point to a staging environment.
|
|
229
|
-
|
|
230
297
|
---
|
|
231
298
|
|
|
232
299
|
## API limits
|
|
@@ -239,22 +306,27 @@ The MCP server translates natural language tool calls into REST API requests. It
|
|
|
239
306
|
| Webhook payload | 100 KB max |
|
|
240
307
|
| Webhooks per account | 20 max |
|
|
241
308
|
|
|
242
|
-
Rate limiting is handled automatically with exponential backoff.
|
|
309
|
+
Rate limiting is handled automatically with exponential backoff.
|
|
243
310
|
|
|
244
311
|
---
|
|
245
312
|
|
|
246
313
|
## Claude Code Skill
|
|
247
314
|
|
|
248
|
-
Beyond raw MCP tools,
|
|
315
|
+
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.
|
|
249
316
|
|
|
250
317
|
### Install the skill
|
|
251
318
|
|
|
252
319
|
```bash
|
|
253
|
-
# Clone and symlink
|
|
254
320
|
git clone https://github.com/Frihet-io/frihet-mcp.git
|
|
255
321
|
ln -s "$(pwd)/frihet-mcp/skill" ~/.claude/skills/frihet
|
|
256
322
|
```
|
|
257
323
|
|
|
324
|
+
Or with the universal installer:
|
|
325
|
+
|
|
326
|
+
```bash
|
|
327
|
+
npx skills add Frihet-io/frihet-mcp
|
|
328
|
+
```
|
|
329
|
+
|
|
258
330
|
### Commands
|
|
259
331
|
|
|
260
332
|
| Command | What it does |
|
|
@@ -268,7 +340,7 @@ ln -s "$(pwd)/frihet-mcp/skill" ~/.claude/skills/frihet
|
|
|
268
340
|
| `/frihet webhooks` | Configure automation triggers |
|
|
269
341
|
| `/frihet setup` | Guided setup and connection test |
|
|
270
342
|
|
|
271
|
-
The skill knows about IVA rates, IRPF retention, Modelo 303 prep, expense deductibility rules, and
|
|
343
|
+
The skill knows about IVA rates, IRPF retention, Modelo 303 prep, expense deductibility rules, and VeriFactu compliance.
|
|
272
344
|
|
|
273
345
|
Full documentation: [docs.frihet.io/desarrolladores/skill-claude-code](https://docs.frihet.io/desarrolladores/skill-claude-code)
|
|
274
346
|
|
|
@@ -297,27 +369,39 @@ npx @modelcontextprotocol/inspector node dist/index.js
|
|
|
297
369
|
|
|
298
370
|
---
|
|
299
371
|
|
|
300
|
-
##
|
|
372
|
+
## Contributing
|
|
373
|
+
|
|
374
|
+
Contributions are welcome. Please open an issue first to discuss what you'd like to change.
|
|
375
|
+
|
|
376
|
+
```bash
|
|
377
|
+
git clone https://github.com/Frihet-io/frihet-mcp.git
|
|
378
|
+
cd frihet-mcp
|
|
379
|
+
npm install
|
|
380
|
+
npm run build # must pass before submitting
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
---
|
|
301
384
|
|
|
302
|
-
|
|
303
|
-
|---|:---:|:---:|:---:|:---:|:---:|
|
|
304
|
-
| Official MCP server | **Yes** | No (third-party) | No | No | No |
|
|
305
|
-
| Claude / Cursor / Windsurf | **Yes** | No | No | No | No |
|
|
306
|
-
| Public REST API | **Yes** | Yes | Limited | Yes | No |
|
|
307
|
-
| Webhooks with HMAC verification | **Yes** | No | No | No | No |
|
|
308
|
-
| AI assistant built-in | **Yes** | No | No | No | No |
|
|
309
|
-
| Open source tooling | **Yes** | No | No | No | No |
|
|
385
|
+
## Current limitations
|
|
310
386
|
|
|
311
|
-
|
|
387
|
+
- **No OCR or file upload** -- the MCP works with structured data, not images or PDFs. Planned for a future release.
|
|
388
|
+
- **Single company** -- one API key maps to one Frihet workspace. Multi-company support is not yet available.
|
|
389
|
+
- **Frihet account required** -- you need an active account at [app.frihet.io](https://app.frihet.io) and an API key (starts with `fri_`).
|
|
312
390
|
|
|
313
391
|
---
|
|
314
392
|
|
|
315
393
|
## Links
|
|
316
394
|
|
|
317
|
-
- [Frihet
|
|
318
|
-
- [
|
|
319
|
-
- [
|
|
395
|
+
- [Frihet](https://frihet.io) -- The product
|
|
396
|
+
- [Documentation](https://docs.frihet.io) -- Full docs
|
|
397
|
+
- [API reference](https://docs.frihet.io/desarrolladores/api-rest) -- REST API
|
|
398
|
+
- [MCP server docs](https://docs.frihet.io/desarrolladores/mcp-server) -- Setup guides, troubleshooting
|
|
399
|
+
- [Webhook docs](https://docs.frihet.io/desarrolladores/webhooks) -- Events, signatures, retries
|
|
400
|
+
- [npm](https://www.npmjs.com/package/@frihet/mcp-server) -- Package registry
|
|
401
|
+
- [MCP Registry](https://registry.modelcontextprotocol.io/servers/io.github.berthelius/frihet) -- Official MCP Registry
|
|
402
|
+
- [Smithery](https://smithery.ai/server/frihet/frihet-mcp) -- Smithery marketplace
|
|
320
403
|
- [Remote endpoint](https://mcp.frihet.io) -- Hosted MCP server (Cloudflare Workers)
|
|
404
|
+
- [OpenAPI spec](https://api.frihet.io/openapi.yaml) -- Machine-readable API definition
|
|
321
405
|
- [MCP specification](https://modelcontextprotocol.io) -- The protocol
|
|
322
406
|
|
|
323
407
|
---
|
|
@@ -326,4 +410,4 @@ The first business management platform with an official MCP server. No other ERP
|
|
|
326
410
|
|
|
327
411
|
MIT. See [LICENSE](./LICENSE).
|
|
328
412
|
|
|
329
|
-
Built by [
|
|
413
|
+
Built by [Frihet](https://frihet.io).
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAY,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Handles authentication, pagination, rate-limit retries, and error mapping.
|
|
5
5
|
*/
|
|
6
|
+
import { logApiCall, logRetry } from "./logger.js";
|
|
6
7
|
const BASE_URL = "https://api.frihet.io/v1";
|
|
7
8
|
const MAX_RETRIES = 3;
|
|
8
9
|
const DEFAULT_RETRY_DELAY_MS = 1000;
|
|
@@ -45,6 +46,7 @@ export class FrihetClient {
|
|
|
45
46
|
};
|
|
46
47
|
const controller = new AbortController();
|
|
47
48
|
const timeoutId = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
49
|
+
const startTime = Date.now();
|
|
48
50
|
let response;
|
|
49
51
|
try {
|
|
50
52
|
response = await fetch(url.toString(), {
|
|
@@ -55,16 +57,21 @@ export class FrihetClient {
|
|
|
55
57
|
});
|
|
56
58
|
}
|
|
57
59
|
catch (error) {
|
|
60
|
+
const durationMs = Math.round(Date.now() - startTime);
|
|
58
61
|
if (error instanceof Error && error.name === "AbortError") {
|
|
62
|
+
logApiCall(method, path, 408, durationMs);
|
|
59
63
|
throw new FrihetApiError(408, "request_timeout", `Request timed out after ${REQUEST_TIMEOUT_MS / 1000} seconds`);
|
|
60
64
|
}
|
|
65
|
+
logApiCall(method, path, 0, durationMs);
|
|
61
66
|
throw error;
|
|
62
67
|
}
|
|
63
68
|
finally {
|
|
64
69
|
clearTimeout(timeoutId);
|
|
65
70
|
}
|
|
71
|
+
const durationMs = Math.round(Date.now() - startTime);
|
|
66
72
|
// Rate limit handling
|
|
67
73
|
if (response.status === 429) {
|
|
74
|
+
logApiCall(method, path, 429, durationMs);
|
|
68
75
|
if (retryCount >= MAX_RETRIES) {
|
|
69
76
|
throw new FrihetApiError(429, "rate_limit_exceeded", "Rate limit exceeded after multiple retries. Please try again later.");
|
|
70
77
|
}
|
|
@@ -72,11 +79,13 @@ export class FrihetClient {
|
|
|
72
79
|
const delayMs = retryAfter
|
|
73
80
|
? parseInt(retryAfter, 10) * 1000
|
|
74
81
|
: DEFAULT_RETRY_DELAY_MS * Math.pow(2, retryCount);
|
|
82
|
+
logRetry(method, path, retryCount, delayMs);
|
|
75
83
|
await this.sleep(delayMs);
|
|
76
84
|
return this.request(method, path, body, query, retryCount + 1);
|
|
77
85
|
}
|
|
78
86
|
// Error responses
|
|
79
87
|
if (!response.ok) {
|
|
88
|
+
logApiCall(method, path, response.status, durationMs);
|
|
80
89
|
let errorBody;
|
|
81
90
|
try {
|
|
82
91
|
errorBody = (await response.json());
|
|
@@ -89,6 +98,7 @@ export class FrihetClient {
|
|
|
89
98
|
}
|
|
90
99
|
throw new FrihetApiError(response.status, errorBody.error, errorBody.message ?? errorBody.error);
|
|
91
100
|
}
|
|
101
|
+
logApiCall(method, path, response.status, durationMs);
|
|
92
102
|
// 204 No Content (e.g. DELETE)
|
|
93
103
|
if (response.status === 204) {
|
|
94
104
|
return undefined;
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -14,6 +14,8 @@ import { FrihetClient } from "./client.js";
|
|
|
14
14
|
import { registerAllTools } from "./tools/register-all.js";
|
|
15
15
|
import { registerAllResources } from "./resources/register-all.js";
|
|
16
16
|
import { registerAllPrompts } from "./prompts/register-all.js";
|
|
17
|
+
import { log } from "./logger.js";
|
|
18
|
+
import { registerShutdownHook } from "./metrics.js";
|
|
17
19
|
function main() {
|
|
18
20
|
const apiKey = process.env.FRIHET_API_KEY;
|
|
19
21
|
if (!apiKey) {
|
|
@@ -47,7 +49,7 @@ function main() {
|
|
|
47
49
|
const client = new FrihetClient(apiKey, baseUrl);
|
|
48
50
|
const server = new McpServer({
|
|
49
51
|
name: "frihet-erp",
|
|
50
|
-
version: "1.2.
|
|
52
|
+
version: "1.2.3",
|
|
51
53
|
description: "AI-native MCP server for Frihet ERP — invoices, expenses, clients, products, quotes, and webhooks. " +
|
|
52
54
|
"Provides 31 tools, 5 resources (tax rates, calendar, expense categories, invoice statuses, API schema), " +
|
|
53
55
|
"and 5 workflow prompts for business management with full Spanish tax compliance (IVA, IGIC, IPSI).",
|
|
@@ -58,12 +60,24 @@ function main() {
|
|
|
58
60
|
registerAllResources(server);
|
|
59
61
|
// Register 5 workflow prompts (monthly close, onboard client, tax prep, overdue follow-up, expense batch)
|
|
60
62
|
registerAllPrompts(server);
|
|
63
|
+
// Register shutdown hook to log final metrics summary
|
|
64
|
+
registerShutdownHook();
|
|
61
65
|
// Connect via stdio transport
|
|
62
66
|
const transport = new StdioServerTransport();
|
|
63
67
|
server.connect(transport).then(() => {
|
|
64
|
-
|
|
68
|
+
log({
|
|
69
|
+
level: "info",
|
|
70
|
+
message: "Frihet MCP server running on stdio",
|
|
71
|
+
operation: "startup",
|
|
72
|
+
metadata: { version: "1.2.4", transport: "stdio" },
|
|
73
|
+
});
|
|
65
74
|
}).catch((error) => {
|
|
66
|
-
|
|
75
|
+
log({
|
|
76
|
+
level: "error",
|
|
77
|
+
message: "Failed to start Frihet MCP server",
|
|
78
|
+
operation: "startup",
|
|
79
|
+
error: { message: error instanceof Error ? error.message : String(error) },
|
|
80
|
+
});
|
|
67
81
|
process.exit(1);
|
|
68
82
|
});
|
|
69
83
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured logging utility for the Frihet MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Outputs JSON to stderr (MCP protocol uses stdout for messages).
|
|
5
|
+
* Works in both Node.js (stdio) and Cloudflare Workers (fetch handler) environments.
|
|
6
|
+
*
|
|
7
|
+
* Set FRIHET_MCP_DEBUG=1 to enable debug-level logs.
|
|
8
|
+
*/
|
|
9
|
+
export interface LogEntry {
|
|
10
|
+
level: "debug" | "info" | "warn" | "error";
|
|
11
|
+
message: string;
|
|
12
|
+
service: "frihet-mcp";
|
|
13
|
+
timestamp: string;
|
|
14
|
+
tool?: string;
|
|
15
|
+
operation?: string;
|
|
16
|
+
durationMs?: number;
|
|
17
|
+
error?: {
|
|
18
|
+
message: string;
|
|
19
|
+
code?: string;
|
|
20
|
+
statusCode?: number;
|
|
21
|
+
};
|
|
22
|
+
metadata?: Record<string, unknown>;
|
|
23
|
+
}
|
|
24
|
+
type LogInput = Omit<LogEntry, "service" | "timestamp">;
|
|
25
|
+
/**
|
|
26
|
+
* Emit a structured log entry as JSON to stderr.
|
|
27
|
+
* In Cloudflare Workers, console.error automatically routes to Workers Logs.
|
|
28
|
+
*/
|
|
29
|
+
export declare function log(entry: LogInput): void;
|
|
30
|
+
/**
|
|
31
|
+
* Log the result of a tool call with timing.
|
|
32
|
+
*/
|
|
33
|
+
export declare function logToolCall(tool: string, startTime: number, success: boolean, error?: Error & {
|
|
34
|
+
statusCode?: number;
|
|
35
|
+
errorCode?: string;
|
|
36
|
+
}): void;
|
|
37
|
+
/**
|
|
38
|
+
* Log an outbound API call with timing.
|
|
39
|
+
*/
|
|
40
|
+
export declare function logApiCall(method: string, path: string, statusCode: number, durationMs: number): void;
|
|
41
|
+
/**
|
|
42
|
+
* Log a rate-limit retry.
|
|
43
|
+
*/
|
|
44
|
+
export declare function logRetry(method: string, path: string, retryCount: number, delayMs: number): void;
|
|
45
|
+
export {};
|
|
46
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,YAAY,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,KAAK,QAAQ,GAAG,IAAI,CAAC,QAAQ,EAAE,SAAS,GAAG,WAAW,CAAC,CAAC;AAiBxD;;;GAGG;AACH,wBAAgB,GAAG,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAiBzC;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,OAAO,EAChB,KAAK,CAAC,EAAE,KAAK,GAAG;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAC1D,IAAI,CAyBN;AAED;;GAEG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,IAAI,CAUN;AAED;;GAEG;AACH,wBAAgB,QAAQ,CACtB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd,IAAI,CAON"}
|
package/dist/logger.js
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structured logging utility for the Frihet MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Outputs JSON to stderr (MCP protocol uses stdout for messages).
|
|
5
|
+
* Works in both Node.js (stdio) and Cloudflare Workers (fetch handler) environments.
|
|
6
|
+
*
|
|
7
|
+
* Set FRIHET_MCP_DEBUG=1 to enable debug-level logs.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Returns true if debug logging is enabled.
|
|
11
|
+
* Checks env var in Node.js; always false in Workers unless overridden.
|
|
12
|
+
*/
|
|
13
|
+
function isDebugEnabled() {
|
|
14
|
+
// Node.js environment
|
|
15
|
+
if (typeof process !== "undefined" && process?.env) {
|
|
16
|
+
return process.env.FRIHET_MCP_DEBUG === "1" || process.env.FRIHET_MCP_DEBUG === "true";
|
|
17
|
+
}
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Emit a structured log entry as JSON to stderr.
|
|
22
|
+
* In Cloudflare Workers, console.error automatically routes to Workers Logs.
|
|
23
|
+
*/
|
|
24
|
+
export function log(entry) {
|
|
25
|
+
if (entry.level === "debug" && !isDebugEnabled()) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const full = {
|
|
29
|
+
...entry,
|
|
30
|
+
service: "frihet-mcp",
|
|
31
|
+
timestamp: new Date().toISOString(),
|
|
32
|
+
};
|
|
33
|
+
// Remove undefined fields for cleaner output
|
|
34
|
+
const cleaned = JSON.stringify(full, (_key, value) => value === undefined ? undefined : value);
|
|
35
|
+
console.error(cleaned);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Log the result of a tool call with timing.
|
|
39
|
+
*/
|
|
40
|
+
export function logToolCall(tool, startTime, success, error) {
|
|
41
|
+
const durationMs = Math.round(Date.now() - startTime);
|
|
42
|
+
if (!success && error) {
|
|
43
|
+
log({
|
|
44
|
+
level: "error",
|
|
45
|
+
message: `Tool ${tool} failed`,
|
|
46
|
+
tool,
|
|
47
|
+
operation: "tool_call",
|
|
48
|
+
durationMs,
|
|
49
|
+
error: {
|
|
50
|
+
message: error.message,
|
|
51
|
+
code: error.errorCode ?? error.name,
|
|
52
|
+
statusCode: error.statusCode,
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
log({
|
|
58
|
+
level: "info",
|
|
59
|
+
message: `Tool ${tool} completed`,
|
|
60
|
+
tool,
|
|
61
|
+
operation: "tool_call",
|
|
62
|
+
durationMs,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Log an outbound API call with timing.
|
|
68
|
+
*/
|
|
69
|
+
export function logApiCall(method, path, statusCode, durationMs) {
|
|
70
|
+
const level = statusCode >= 500 ? "error" : statusCode >= 400 ? "warn" : "info";
|
|
71
|
+
log({
|
|
72
|
+
level,
|
|
73
|
+
message: `${method} ${path} ${statusCode} ${durationMs}ms`,
|
|
74
|
+
operation: "api_call",
|
|
75
|
+
durationMs,
|
|
76
|
+
metadata: { method, path, statusCode },
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Log a rate-limit retry.
|
|
81
|
+
*/
|
|
82
|
+
export function logRetry(method, path, retryCount, delayMs) {
|
|
83
|
+
log({
|
|
84
|
+
level: "warn",
|
|
85
|
+
message: `Rate limited, retrying ${method} ${path} (attempt ${retryCount + 1}, delay ${delayMs}ms)`,
|
|
86
|
+
operation: "api_retry",
|
|
87
|
+
metadata: { method, path, retryCount: retryCount + 1, delayMs },
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAmBH;;;GAGG;AACH,SAAS,cAAc;IACrB,sBAAsB;IACtB,IAAI,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,EAAE,GAAG,EAAE,CAAC;QACnD,OAAO,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,MAAM,CAAC;IACzF,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,GAAG,CAAC,KAAe;IACjC,IAAI,KAAK,CAAC,KAAK,KAAK,OAAO,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;QACjD,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAa;QACrB,GAAG,KAAK;QACR,OAAO,EAAE,YAAY;QACrB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;IAEF,6CAA6C;IAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CACnD,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CACxC,CAAC;IAEF,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CACzB,IAAY,EACZ,SAAiB,EACjB,OAAgB,EAChB,KAA2D;IAE3D,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;IAEtD,IAAI,CAAC,OAAO,IAAI,KAAK,EAAE,CAAC;QACtB,GAAG,CAAC;YACF,KAAK,EAAE,OAAO;YACd,OAAO,EAAE,QAAQ,IAAI,SAAS;YAC9B,IAAI;YACJ,SAAS,EAAE,WAAW;YACtB,UAAU;YACV,KAAK,EAAE;gBACL,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,IAAI,EAAE,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,IAAI;gBACnC,UAAU,EAAE,KAAK,CAAC,UAAU;aAC7B;SACF,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,GAAG,CAAC;YACF,KAAK,EAAE,MAAM;YACb,OAAO,EAAE,QAAQ,IAAI,YAAY;YACjC,IAAI;YACJ,SAAS,EAAE,WAAW;YACtB,UAAU;SACX,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CACxB,MAAc,EACd,IAAY,EACZ,UAAkB,EAClB,UAAkB;IAElB,MAAM,KAAK,GAAG,UAAU,IAAI,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;IAEhF,GAAG,CAAC;QACF,KAAK;QACL,OAAO,EAAE,GAAG,MAAM,IAAI,IAAI,IAAI,UAAU,IAAI,UAAU,IAAI;QAC1D,SAAS,EAAE,UAAU;QACrB,UAAU;QACV,QAAQ,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE;KACvC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,QAAQ,CACtB,MAAc,EACd,IAAY,EACZ,UAAkB,EAClB,OAAe;IAEf,GAAG,CAAC;QACF,KAAK,EAAE,MAAM;QACb,OAAO,EAAE,0BAA0B,MAAM,IAAI,IAAI,aAAa,UAAU,GAAG,CAAC,WAAW,OAAO,KAAK;QACnG,SAAS,EAAE,WAAW;QACtB,QAAQ,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,GAAG,CAAC,EAAE,OAAO,EAAE;KAChE,CAAC,CAAC;AACL,CAAC"}
|