@frihet/mcp-server 1.1.0 → 1.2.1
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 +11 -5
- package/dist/index.js +30 -1
- package/dist/index.js.map +1 -1
- package/dist/prompts/register-all.d.ts +10 -0
- package/dist/prompts/register-all.d.ts.map +1 -0
- package/dist/prompts/register-all.js +271 -0
- package/dist/prompts/register-all.js.map +1 -0
- package/dist/resources/register-all.d.ts +12 -0
- package/dist/resources/register-all.d.ts.map +1 -0
- package/dist/resources/register-all.js +345 -0
- package/dist/resources/register-all.js.map +1 -0
- package/dist/tools/clients.d.ts.map +1 -1
- package/dist/tools/clients.js +16 -6
- package/dist/tools/clients.js.map +1 -1
- package/dist/tools/expenses.d.ts.map +1 -1
- package/dist/tools/expenses.js +16 -6
- package/dist/tools/expenses.js.map +1 -1
- package/dist/tools/invoices.d.ts.map +1 -1
- package/dist/tools/invoices.js +19 -10
- package/dist/tools/invoices.js.map +1 -1
- package/dist/tools/products.d.ts.map +1 -1
- package/dist/tools/products.js +16 -6
- package/dist/tools/products.js.map +1 -1
- package/dist/tools/quotes.d.ts.map +1 -1
- package/dist/tools/quotes.js +16 -6
- package/dist/tools/quotes.js.map +1 -1
- package/dist/tools/shared.d.ts +120 -6
- package/dist/tools/shared.d.ts.map +1 -1
- package/dist/tools/shared.js +146 -5
- package/dist/tools/shared.js.map +1 -1
- package/dist/tools/webhooks.d.ts.map +1 -1
- package/dist/tools/webhooks.js +16 -6
- package/dist/tools/webhooks.js.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
<p align="center">
|
|
11
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>
|
|
12
|
-
<a href="https://github.com/
|
|
12
|
+
<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
13
|
<a href="https://smithery.ai/server/@frihet/mcp-server"><img src="https://img.shields.io/badge/smithery-listed-18181b?style=flat&labelColor=09090b" alt="smithery"></a>
|
|
14
14
|
<a href="https://frihet.io"><img src="https://img.shields.io/badge/frihet.io-ERP-18181b?style=flat&labelColor=09090b" alt="frihet"></a>
|
|
15
15
|
</p>
|
|
@@ -25,13 +25,19 @@ You: "Create an invoice for TechStart SL, 40 hours of consulting at 75 EUR/h
|
|
|
25
25
|
Claude: Done. Invoice INV-2026-089 created. Total: 3,000.00 EUR + 21% IVA = 3,630.00 EUR.
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
31 tools.
|
|
28
|
+
31 tools. 5 resources. 5 prompts. Structured output. Zero boilerplate.
|
|
29
29
|
|
|
30
30
|
---
|
|
31
31
|
|
|
32
32
|
## Install
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
### Universal (30+ agents — Claude Code, Cursor, Copilot, Codex, Windsurf, Gemini CLI, and more)
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
npx skills add Frihet-io/frihet-mcp
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Per-tool configuration
|
|
35
41
|
|
|
36
42
|
### Claude Code / Claude Desktop
|
|
37
43
|
|
|
@@ -245,7 +251,7 @@ Beyond raw MCP tools, Frihet ships a **Claude Code skill** that adds business in
|
|
|
245
251
|
|
|
246
252
|
```bash
|
|
247
253
|
# Clone and symlink
|
|
248
|
-
git clone https://github.com/
|
|
254
|
+
git clone https://github.com/Frihet-io/frihet-mcp.git
|
|
249
255
|
ln -s "$(pwd)/frihet-mcp/skill" ~/.claude/skills/frihet
|
|
250
256
|
```
|
|
251
257
|
|
|
@@ -271,7 +277,7 @@ Full documentation: [docs.frihet.io/desarrolladores/skill-claude-code](https://d
|
|
|
271
277
|
## Development
|
|
272
278
|
|
|
273
279
|
```bash
|
|
274
|
-
git clone https://github.com/
|
|
280
|
+
git clone https://github.com/Frihet-io/frihet-mcp.git
|
|
275
281
|
cd frihet-mcp
|
|
276
282
|
npm install
|
|
277
283
|
npm run build
|
package/dist/index.js
CHANGED
|
@@ -12,6 +12,8 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
12
12
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
13
13
|
import { FrihetClient } from "./client.js";
|
|
14
14
|
import { registerAllTools } from "./tools/register-all.js";
|
|
15
|
+
import { registerAllResources } from "./resources/register-all.js";
|
|
16
|
+
import { registerAllPrompts } from "./prompts/register-all.js";
|
|
15
17
|
function main() {
|
|
16
18
|
const apiKey = process.env.FRIHET_API_KEY;
|
|
17
19
|
if (!apiKey) {
|
|
@@ -22,13 +24,40 @@ function main() {
|
|
|
22
24
|
process.exit(1);
|
|
23
25
|
}
|
|
24
26
|
const baseUrl = process.env.FRIHET_API_URL;
|
|
27
|
+
if (baseUrl !== undefined) {
|
|
28
|
+
let parsed;
|
|
29
|
+
try {
|
|
30
|
+
parsed = new URL(baseUrl);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
console.error(`Error: FRIHET_API_URL is not a valid URL: "${baseUrl}"\n` +
|
|
34
|
+
"It must be a valid https:// URL with a frihet.io hostname.\n");
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
if (parsed.protocol !== "https:") {
|
|
38
|
+
console.error(`Error: FRIHET_API_URL must use https:// (got "${parsed.protocol}").\n`);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
if (!parsed.hostname.endsWith("frihet.io")) {
|
|
42
|
+
console.error(`Error: FRIHET_API_URL hostname must be under frihet.io (got "${parsed.hostname}").\n` +
|
|
43
|
+
"This prevents redirection to untrusted servers.\n");
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
25
47
|
const client = new FrihetClient(apiKey, baseUrl);
|
|
26
48
|
const server = new McpServer({
|
|
27
49
|
name: "frihet-erp",
|
|
28
|
-
version: "1.
|
|
50
|
+
version: "1.2.0",
|
|
51
|
+
description: "AI-native MCP server for Frihet ERP — invoices, expenses, clients, products, quotes, and webhooks. " +
|
|
52
|
+
"Provides 31 tools, 5 resources (tax rates, calendar, expense categories, invoice statuses, API schema), " +
|
|
53
|
+
"and 5 workflow prompts for business management with full Spanish tax compliance (IVA, IGIC, IPSI).",
|
|
29
54
|
});
|
|
30
55
|
// Register all 31 tools
|
|
31
56
|
registerAllTools(server, client);
|
|
57
|
+
// Register 5 static resources (tax rates, calendar, categories, statuses, API schema)
|
|
58
|
+
registerAllResources(server);
|
|
59
|
+
// Register 5 workflow prompts (monthly close, onboard client, tax prep, overdue follow-up, expense batch)
|
|
60
|
+
registerAllPrompts(server);
|
|
32
61
|
// Connect via stdio transport
|
|
33
62
|
const transport = new StdioServerTransport();
|
|
34
63
|
server.connect(transport).then(() => {
|
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;
|
|
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;AAE/D,SAAS,IAAI;IACX,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAE1C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CACX,2DAA2D;YACzD,kEAAkE;YAClE,YAAY;YACZ,mDAAmD,CACtD,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAE3C,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,IAAI,MAAW,CAAC;QAChB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;QAC5B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,KAAK,CACX,8CAA8C,OAAO,KAAK;gBACxD,8DAA8D,CACjE,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACjC,OAAO,CAAC,KAAK,CACX,iDAAiD,MAAM,CAAC,QAAQ,OAAO,CACxE,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;YAC3C,OAAO,CAAC,KAAK,CACX,gEAAgE,MAAM,CAAC,QAAQ,OAAO;gBACpF,mDAAmD,CACtD,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEjD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,YAAY;QAClB,OAAO,EAAE,OAAO;QAChB,WAAW,EACT,qGAAqG;YACrG,0GAA0G;YAC1G,oGAAoG;KACvG,CAAC,CAAC;IAEH,wBAAwB;IACxB,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjC,sFAAsF;IACtF,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAE7B,0GAA0G;IAC1G,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAE3B,8BAA8B;IAC9B,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;QAClC,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;QAC1B,OAAO,CAAC,KAAK,CAAC,oCAAoC,EAAE,KAAK,CAAC,CAAC;QAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,IAAI,EAAE,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Prompts for the Frihet ERP server.
|
|
3
|
+
*
|
|
4
|
+
* Prompts are pre-built templates that guide common business workflows.
|
|
5
|
+
* They return structured messages that an LLM can follow step-by-step,
|
|
6
|
+
* using the available Frihet tools to complete each action.
|
|
7
|
+
*/
|
|
8
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
9
|
+
export declare function registerAllPrompts(server: McpServer): void;
|
|
10
|
+
//# sourceMappingURL=register-all.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register-all.d.ts","sourceRoot":"","sources":["../../src/prompts/register-all.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA+S1D"}
|
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Prompts for the Frihet ERP server.
|
|
3
|
+
*
|
|
4
|
+
* Prompts are pre-built templates that guide common business workflows.
|
|
5
|
+
* They return structured messages that an LLM can follow step-by-step,
|
|
6
|
+
* using the available Frihet tools to complete each action.
|
|
7
|
+
*/
|
|
8
|
+
import { z } from "zod/v4";
|
|
9
|
+
export function registerAllPrompts(server) {
|
|
10
|
+
// -- monthly-close --
|
|
11
|
+
server.registerPrompt("monthly-close", {
|
|
12
|
+
title: "Monthly Close",
|
|
13
|
+
description: "Guide through closing the month: review unpaid invoices, categorize uncategorized expenses, " +
|
|
14
|
+
"check tax obligations, and generate a financial summary. " +
|
|
15
|
+
"/ Guía para el cierre mensual: revisar facturas impagadas, categorizar gastos, " +
|
|
16
|
+
"verificar obligaciones fiscales y generar resumen.",
|
|
17
|
+
argsSchema: {
|
|
18
|
+
month: z
|
|
19
|
+
.string()
|
|
20
|
+
.optional()
|
|
21
|
+
.describe("Month to close in YYYY-MM format (defaults to previous month) / Mes a cerrar"),
|
|
22
|
+
},
|
|
23
|
+
}, async ({ month }) => {
|
|
24
|
+
const targetMonth = month || "the previous month";
|
|
25
|
+
return {
|
|
26
|
+
messages: [
|
|
27
|
+
{
|
|
28
|
+
role: "user",
|
|
29
|
+
content: {
|
|
30
|
+
type: "text",
|
|
31
|
+
text: `Perform the monthly close for ${targetMonth}. Follow these steps in order:\n\n` +
|
|
32
|
+
`1. UNPAID INVOICES\n` +
|
|
33
|
+
` - Use list_invoices to find all invoices with status "sent" or "overdue"\n` +
|
|
34
|
+
` - For each overdue invoice, note the client name, amount, and days overdue\n` +
|
|
35
|
+
` - Summarize total outstanding receivables\n\n` +
|
|
36
|
+
`2. EXPENSE REVIEW\n` +
|
|
37
|
+
` - Use list_expenses to get all expenses for the period\n` +
|
|
38
|
+
` - Identify any expenses without a category — suggest categories based on the description\n` +
|
|
39
|
+
` - Flag any unusually large expenses that might need review\n` +
|
|
40
|
+
` - Calculate total expenses by category\n\n` +
|
|
41
|
+
`3. REVENUE SUMMARY\n` +
|
|
42
|
+
` - List all invoices with status "paid" for the period\n` +
|
|
43
|
+
` - Calculate total revenue, total tax collected (IVA/IGIC)\n` +
|
|
44
|
+
` - Compare with expenses to get net profit/loss\n\n` +
|
|
45
|
+
`4. TAX CHECK\n` +
|
|
46
|
+
` - Read frihet://tax/calendar to check if any tax filings are due\n` +
|
|
47
|
+
` - Calculate preliminary IVA/IGIC balance (output tax - input tax)\n` +
|
|
48
|
+
` - Flag if quarterly filing deadline is approaching\n\n` +
|
|
49
|
+
`5. SUMMARY REPORT\n` +
|
|
50
|
+
` - Total invoiced (draft/sent/paid/overdue/cancelled counts)\n` +
|
|
51
|
+
` - Total revenue (paid invoices)\n` +
|
|
52
|
+
` - Total expenses by category\n` +
|
|
53
|
+
` - Net position\n` +
|
|
54
|
+
` - Action items (overdue follow-ups, uncategorized expenses, upcoming tax deadlines)`,
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
],
|
|
58
|
+
};
|
|
59
|
+
});
|
|
60
|
+
// -- onboard-client --
|
|
61
|
+
server.registerPrompt("onboard-client", {
|
|
62
|
+
title: "Onboard New Client",
|
|
63
|
+
description: "Set up a new client: create the client record, determine correct tax rates based on their location, " +
|
|
64
|
+
"and optionally create a welcome quote. " +
|
|
65
|
+
"/ Dar de alta un nuevo cliente: crear ficha, determinar impuestos según ubicación y crear presupuesto de bienvenida.",
|
|
66
|
+
argsSchema: {
|
|
67
|
+
clientName: z.string().describe("Client or company name / Nombre del cliente o empresa"),
|
|
68
|
+
country: z
|
|
69
|
+
.string()
|
|
70
|
+
.optional()
|
|
71
|
+
.describe("Client country ISO code (e.g. ES, DE, US) / Código de país"),
|
|
72
|
+
region: z
|
|
73
|
+
.string()
|
|
74
|
+
.optional()
|
|
75
|
+
.describe("Spanish region if applicable (peninsula, canarias, ceuta, melilla) / Región española"),
|
|
76
|
+
},
|
|
77
|
+
}, async ({ clientName, country, region }) => {
|
|
78
|
+
const locationContext = country
|
|
79
|
+
? `The client is located in ${country}${region ? ` (${region})` : ""}.`
|
|
80
|
+
: "Ask the client for their country and region to determine the correct tax rate.";
|
|
81
|
+
return {
|
|
82
|
+
messages: [
|
|
83
|
+
{
|
|
84
|
+
role: "user",
|
|
85
|
+
content: {
|
|
86
|
+
type: "text",
|
|
87
|
+
text: `Onboard a new client: "${clientName}". ${locationContext}\n\n` +
|
|
88
|
+
`Follow these steps:\n\n` +
|
|
89
|
+
`1. DETERMINE TAX RATE\n` +
|
|
90
|
+
` - Read frihet://tax/rates to look up the correct rate\n` +
|
|
91
|
+
` - Peninsula Spain → IVA 21% (general)\n` +
|
|
92
|
+
` - Canary Islands → IGIC 7% (general)\n` +
|
|
93
|
+
` - Ceuta/Melilla → IPSI 10%\n` +
|
|
94
|
+
` - EU B2B → 0% reverse charge (need their VAT number)\n` +
|
|
95
|
+
` - Outside EU → 0% export exempt\n` +
|
|
96
|
+
` - Confirm the rate with the user before proceeding\n\n` +
|
|
97
|
+
`2. CREATE CLIENT RECORD\n` +
|
|
98
|
+
` - Use create_client with the client name\n` +
|
|
99
|
+
` - Ask for: email, phone, taxId (NIF/CIF/VAT number), address\n` +
|
|
100
|
+
` - Set the country in the address based on location\n\n` +
|
|
101
|
+
`3. WELCOME QUOTE (optional)\n` +
|
|
102
|
+
` - Ask if the user wants to create an initial quote for this client\n` +
|
|
103
|
+
` - If yes, ask for the services/products and prices\n` +
|
|
104
|
+
` - Use create_quote with the correct tax rate\n` +
|
|
105
|
+
` - Set validUntil to 30 days from now\n\n` +
|
|
106
|
+
`4. SUMMARY\n` +
|
|
107
|
+
` - Confirm the client record was created\n` +
|
|
108
|
+
` - State the tax rate that should be used for this client\n` +
|
|
109
|
+
` - List any missing information that should be filled in later`,
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
],
|
|
113
|
+
};
|
|
114
|
+
});
|
|
115
|
+
// -- quarterly-tax-prep --
|
|
116
|
+
server.registerPrompt("quarterly-tax-prep", {
|
|
117
|
+
title: "Quarterly Tax Preparation",
|
|
118
|
+
description: "Prepare for quarterly tax filing: list all invoices and expenses for the quarter, calculate IVA/IGIC totals, " +
|
|
119
|
+
"identify deductible expenses, and generate a Modelo 303/130/420 preview. " +
|
|
120
|
+
"/ Preparar la declaración trimestral: facturas, gastos, cálculo de IVA/IGIC, gastos deducibles y vista previa del modelo.",
|
|
121
|
+
argsSchema: {
|
|
122
|
+
quarter: z
|
|
123
|
+
.string()
|
|
124
|
+
.optional()
|
|
125
|
+
.describe("Quarter in format Q1-Q4 and year, e.g. 'Q1 2026' (defaults to current quarter) / Trimestre"),
|
|
126
|
+
fiscalZone: z
|
|
127
|
+
.enum(["peninsula", "canarias", "ceuta", "melilla"])
|
|
128
|
+
.optional()
|
|
129
|
+
.describe("Fiscal zone for tax calculation / Zona fiscal"),
|
|
130
|
+
},
|
|
131
|
+
}, async ({ quarter, fiscalZone }) => {
|
|
132
|
+
const targetQuarter = quarter || "the current quarter";
|
|
133
|
+
const zone = fiscalZone || "peninsula";
|
|
134
|
+
const taxType = zone === "canarias" ? "IGIC" : zone === "peninsula" ? "IVA" : "IPSI";
|
|
135
|
+
const modelo = zone === "canarias" ? "420" : "303";
|
|
136
|
+
return {
|
|
137
|
+
messages: [
|
|
138
|
+
{
|
|
139
|
+
role: "user",
|
|
140
|
+
content: {
|
|
141
|
+
type: "text",
|
|
142
|
+
text: `Prepare the quarterly tax filing for ${targetQuarter} (fiscal zone: ${zone}, tax: ${taxType}).\n\n` +
|
|
143
|
+
`Follow these steps:\n\n` +
|
|
144
|
+
`1. GATHER INVOICES\n` +
|
|
145
|
+
` - Use list_invoices to get all invoices for the quarter\n` +
|
|
146
|
+
` - Filter by date range for the quarter period\n` +
|
|
147
|
+
` - Separate by status: paid, sent, overdue, cancelled\n` +
|
|
148
|
+
` - Calculate total revenue (base imponible) and total ${taxType} collected (${taxType} repercutido)\n\n` +
|
|
149
|
+
`2. GATHER EXPENSES\n` +
|
|
150
|
+
` - Use list_expenses to get all expenses for the quarter\n` +
|
|
151
|
+
` - Read frihet://config/expense-categories for deductibility rules\n` +
|
|
152
|
+
` - Categorize expenses and calculate deductible ${taxType} (${taxType} soportado)\n` +
|
|
153
|
+
` - Flag any expenses missing receipts or with questionable deductibility\n\n` +
|
|
154
|
+
`3. TAX CALCULATION\n` +
|
|
155
|
+
` - Read frihet://tax/rates to confirm the applicable rates\n` +
|
|
156
|
+
` - ${taxType} to pay = ${taxType} repercutido (collected) - ${taxType} soportado (deductible)\n` +
|
|
157
|
+
` - If negative, it is a refund (a compensar o devolver)\n\n` +
|
|
158
|
+
`4. MODELO ${modelo} PREVIEW\n` +
|
|
159
|
+
` - Base imponible (taxable base): sum of invoice subtotals\n` +
|
|
160
|
+
` - ${taxType} devengado (output tax): sum of tax on invoices\n` +
|
|
161
|
+
` - ${taxType} deducible (input tax): sum of deductible tax on expenses\n` +
|
|
162
|
+
` - Resultado (result): output - input = amount to pay or refund\n\n` +
|
|
163
|
+
`5. MODELO 130 PREVIEW (IRPF advance)\n` +
|
|
164
|
+
` - Net income = Revenue - Deductible expenses\n` +
|
|
165
|
+
` - Advance payment = 20% of net income\n` +
|
|
166
|
+
` - Subtract any previous quarterly payments already made\n\n` +
|
|
167
|
+
`6. FILING REMINDER\n` +
|
|
168
|
+
` - Read frihet://tax/calendar for the filing deadline\n` +
|
|
169
|
+
` - Note: this is a PREVIEW only — actual filing must be done through AEAT/ATC\n` +
|
|
170
|
+
` - List any issues that need resolution before filing`,
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
],
|
|
174
|
+
};
|
|
175
|
+
});
|
|
176
|
+
// -- overdue-followup --
|
|
177
|
+
server.registerPrompt("overdue-followup", {
|
|
178
|
+
title: "Overdue Invoice Follow-up",
|
|
179
|
+
description: "Find all overdue invoices, draft follow-up messages for each client, and suggest payment reminders. " +
|
|
180
|
+
"/ Buscar facturas vencidas, redactar mensajes de seguimiento y sugerir recordatorios de pago.",
|
|
181
|
+
}, async () => ({
|
|
182
|
+
messages: [
|
|
183
|
+
{
|
|
184
|
+
role: "user",
|
|
185
|
+
content: {
|
|
186
|
+
type: "text",
|
|
187
|
+
text: `Help me follow up on overdue invoices.\n\n` +
|
|
188
|
+
`Follow these steps:\n\n` +
|
|
189
|
+
`1. FIND OVERDUE INVOICES\n` +
|
|
190
|
+
` - Use list_invoices to find all invoices with status "overdue" or "sent" past their due date\n` +
|
|
191
|
+
` - For each, note: invoice ID, client name, amount, due date, days overdue\n` +
|
|
192
|
+
` - Sort by days overdue (most overdue first)\n\n` +
|
|
193
|
+
`2. GROUP BY CLIENT\n` +
|
|
194
|
+
` - Group overdue invoices by client\n` +
|
|
195
|
+
` - Calculate total outstanding per client\n` +
|
|
196
|
+
` - Use get_client to get contact details for each client\n\n` +
|
|
197
|
+
`3. DRAFT FOLLOW-UP MESSAGES\n` +
|
|
198
|
+
` For each client, draft a professional payment reminder:\n` +
|
|
199
|
+
` - Tone: Firm but polite. Maintain the business relationship.\n` +
|
|
200
|
+
` - Include: Invoice number(s), amount(s), original due date(s)\n` +
|
|
201
|
+
` - 1-15 days overdue: Friendly reminder, assume it was overlooked\n` +
|
|
202
|
+
` - 16-30 days overdue: Firmer tone, request confirmation of payment date\n` +
|
|
203
|
+
` - 31-60 days overdue: Escalation notice, mention potential late fees\n` +
|
|
204
|
+
` - 60+ days overdue: Final notice, mention potential debt collection\n` +
|
|
205
|
+
` - Provide both English and Spanish versions\n\n` +
|
|
206
|
+
`4. SUGGEST ACTIONS\n` +
|
|
207
|
+
` - Recommend which invoices to update to "overdue" status if still "sent"\n` +
|
|
208
|
+
` - Suggest setting up webhook notifications for future overdue invoices\n` +
|
|
209
|
+
` - Flag any clients with multiple overdue invoices (potential bad debt risk)\n\n` +
|
|
210
|
+
`5. SUMMARY\n` +
|
|
211
|
+
` - Total overdue amount\n` +
|
|
212
|
+
` - Number of clients affected\n` +
|
|
213
|
+
` - Oldest unpaid invoice\n` +
|
|
214
|
+
` - Recommended priority order for follow-up`,
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
],
|
|
218
|
+
}));
|
|
219
|
+
// -- expense-batch --
|
|
220
|
+
server.registerPrompt("expense-batch", {
|
|
221
|
+
title: "Batch Expense Processing",
|
|
222
|
+
description: "Process a batch of expenses: help categorize each one, apply correct tax rates, flag items needing receipts. " +
|
|
223
|
+
"/ Procesar lote de gastos: categorizar, aplicar impuestos correctos, marcar los que necesitan justificante.",
|
|
224
|
+
argsSchema: {
|
|
225
|
+
fiscalZone: z
|
|
226
|
+
.enum(["peninsula", "canarias", "ceuta", "melilla"])
|
|
227
|
+
.optional()
|
|
228
|
+
.describe("Fiscal zone for tax deduction rules / Zona fiscal"),
|
|
229
|
+
},
|
|
230
|
+
}, async ({ fiscalZone }) => {
|
|
231
|
+
const zone = fiscalZone || "peninsula";
|
|
232
|
+
const taxType = zone === "canarias" ? "IGIC" : zone === "peninsula" ? "IVA" : "IPSI";
|
|
233
|
+
return {
|
|
234
|
+
messages: [
|
|
235
|
+
{
|
|
236
|
+
role: "user",
|
|
237
|
+
content: {
|
|
238
|
+
type: "text",
|
|
239
|
+
text: `Help me process a batch of expenses (fiscal zone: ${zone}, tax: ${taxType}).\n\n` +
|
|
240
|
+
`Before we start, read frihet://config/expense-categories to understand the 8 categories and their deductibility rules.\n\n` +
|
|
241
|
+
`For each expense I describe, do the following:\n\n` +
|
|
242
|
+
`1. CATEGORIZE\n` +
|
|
243
|
+
` - Assign one of the 8 categories: office, travel, software, marketing, professional, equipment, insurance, other\n` +
|
|
244
|
+
` - Explain why this category fits\n\n` +
|
|
245
|
+
`2. TAX TREATMENT\n` +
|
|
246
|
+
` - Determine if ${taxType} is deductible on this expense\n` +
|
|
247
|
+
` - Calculate the deductible ${taxType} amount\n` +
|
|
248
|
+
` - Note any special rules (e.g., vehicles 50%, meals with limits)\n\n` +
|
|
249
|
+
`3. DEDUCTIBILITY CHECK\n` +
|
|
250
|
+
` - Is this expense fully deductible, partially deductible, or not deductible?\n` +
|
|
251
|
+
` - If equipment >€300, note amortization period\n` +
|
|
252
|
+
` - Flag if the expense seems personal (not deductible)\n\n` +
|
|
253
|
+
`4. RECEIPT STATUS\n` +
|
|
254
|
+
` - Does this expense need an official invoice (factura) for ${taxType} deduction?\n` +
|
|
255
|
+
` - A simplified invoice (ticket) works for amounts <€400\n` +
|
|
256
|
+
` - International purchases may need a different document\n\n` +
|
|
257
|
+
`5. CREATE THE EXPENSE\n` +
|
|
258
|
+
` - Use create_expense with the suggested category, amount, date, and vendor\n` +
|
|
259
|
+
` - Set taxDeductible based on the analysis\n` +
|
|
260
|
+
` - Wait for my confirmation before creating each one\n\n` +
|
|
261
|
+
`I will now describe the expenses one by one. After processing all of them, provide a summary with:\n` +
|
|
262
|
+
`- Total expenses by category\n` +
|
|
263
|
+
`- Total deductible ${taxType}\n` +
|
|
264
|
+
`- Any items flagged for review`,
|
|
265
|
+
},
|
|
266
|
+
},
|
|
267
|
+
],
|
|
268
|
+
};
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
//# sourceMappingURL=register-all.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register-all.js","sourceRoot":"","sources":["../../src/prompts/register-all.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static MCP Resources for the Frihet ERP server.
|
|
3
|
+
*
|
|
4
|
+
* Resources are read-only reference data that LLMs can access without making
|
|
5
|
+
* API calls. They encode domain knowledge (tax rates, deadlines, categories)
|
|
6
|
+
* that would otherwise require the user to explain every time.
|
|
7
|
+
*
|
|
8
|
+
* All resources use the `frihet://` URI scheme.
|
|
9
|
+
*/
|
|
10
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
11
|
+
export declare function registerAllResources(server: McpServer): void;
|
|
12
|
+
//# sourceMappingURL=register-all.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register-all.d.ts","sourceRoot":"","sources":["../../src/resources/register-all.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAiRzE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAwG5D"}
|