@frihet/mcp-server 1.5.3 → 1.5.5
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 +8 -6
- package/dist/index.js +18 -5
- package/dist/index.js.map +1 -1
- package/dist/openai-profile.d.ts +49 -0
- package/dist/openai-profile.d.ts.map +1 -0
- package/dist/openai-profile.js +273 -0
- package/dist/openai-profile.js.map +1 -0
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
<a href="https://smithery.ai/server/frihet/frihet-mcp"><img src="https://smithery.ai/badge/frihet/frihet-mcp" alt="Smithery installs"></a>
|
|
18
18
|
<a href="https://registry.modelcontextprotocol.io/?q=io.frihet"><img src="https://img.shields.io/badge/MCP_Registry-io.frihet%2Ferp-4A90D9?style=flat&logo=anthropic&logoColor=white" alt="MCP Registry"></a>
|
|
19
19
|
<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>
|
|
20
|
-
<img src="https://img.shields.io/badge/tools-
|
|
20
|
+
<img src="https://img.shields.io/badge/tools-55-18181b?style=flat&labelColor=09090b" alt="55 tools">
|
|
21
21
|
<img src="https://img.shields.io/badge/node-%3E%3D18-18181b?style=flat&labelColor=09090b" alt="node >=18">
|
|
22
22
|
<a href="https://www.typescriptlang.org/"><img src="https://img.shields.io/badge/TypeScript-18181b?style=flat&labelColor=09090b" alt="TypeScript"></a>
|
|
23
23
|
</p>
|
|
@@ -33,7 +33,7 @@ You: "Create an invoice for TechStart SL, 40 hours of consulting at 75 EUR/h
|
|
|
33
33
|
Claude: Done. Invoice INV-2026-089 created. Total: 3,000.00 EUR + 21% IVA = 3,630.00 EUR.
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
55 tools. 8 resources. 7 prompts. Structured output on every tool. Zero boilerplate.
|
|
37
37
|
|
|
38
38
|
---
|
|
39
39
|
|
|
@@ -161,7 +161,7 @@ Talk to your ERP. These are real prompts, not marketing copy.
|
|
|
161
161
|
|
|
162
162
|
## What to expect
|
|
163
163
|
|
|
164
|
-
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
|
|
164
|
+
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 55 tools are CRUD operations over the REST API.
|
|
165
165
|
|
|
166
166
|
**Works great:**
|
|
167
167
|
|
|
@@ -188,7 +188,7 @@ If you need to digitize paper invoices or receipts, extract the data first (e.g.
|
|
|
188
188
|
|
|
189
189
|
---
|
|
190
190
|
|
|
191
|
-
## Tools (
|
|
191
|
+
## Tools (55)
|
|
192
192
|
|
|
193
193
|
### Invoices (6)
|
|
194
194
|
|
|
@@ -283,7 +283,7 @@ If you need to digitize paper invoices or receipts, extract the data first (e.g.
|
|
|
283
283
|
| `get_quarterly_taxes` | Quarterly tax prep: Modelo 303/130 fields, collected vs deductible, liability |
|
|
284
284
|
| `duplicate_invoice` | Clone an invoice for recurring billing (copies items/client/tax, starts as draft) |
|
|
285
285
|
|
|
286
|
-
All
|
|
286
|
+
All 55 tools return **structured output** via `outputSchema` -- typed JSON, not raw text. List tools return paginated results (`{ data, total, limit, offset }`).
|
|
287
287
|
|
|
288
288
|
---
|
|
289
289
|
|
|
@@ -462,10 +462,12 @@ npm run build # must pass before submitting
|
|
|
462
462
|
|
|
463
463
|
| Package | What it is |
|
|
464
464
|
|---------|-----------|
|
|
465
|
-
| [`@frihet/mcp-server`](https://www.npmjs.com/package/@frihet/mcp-server) | This MCP server (
|
|
465
|
+
| [`@frihet/mcp-server`](https://www.npmjs.com/package/@frihet/mcp-server) | This MCP server (55 tools, 8 resources, 7 prompts) |
|
|
466
466
|
| [`@frihet/sdk`](https://github.com/Frihet-io/frihet-sdk) | TypeScript SDK (`frihet.invoices.create()`) |
|
|
467
467
|
| [`frihet`](https://www.npmjs.com/package/frihet) | CLI (`frihet invoices list --status overdue`) |
|
|
468
|
+
| [`n8n-nodes-frihet`](https://www.npmjs.com/package/n8n-nodes-frihet) | n8n community node for workflow automation |
|
|
468
469
|
| [REST API](https://docs.frihet.io/desarrolladores/api-rest) | OpenAPI 3.1 at `api.frihet.io/v1` |
|
|
470
|
+
| [Remote MCP](https://mcp.frihet.io) | Hosted endpoint on Cloudflare Workers (zero install) |
|
|
469
471
|
| [Webhooks](https://docs.frihet.io/desarrolladores/webhooks) | Real-time events with HMAC-SHA256 |
|
|
470
472
|
|
|
471
473
|
## Links
|
package/dist/index.js
CHANGED
|
@@ -14,15 +14,18 @@ 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 { applyOpenAIProfile, OPENAI_EXCLUDED_COUNT, OPENAI_EXCLUDED_RESOURCE_COUNT } from "./openai-profile.js";
|
|
17
18
|
import { log } from "./logger.js";
|
|
18
19
|
import { registerShutdownHook } from "./metrics.js";
|
|
19
20
|
function main() {
|
|
20
21
|
const apiKey = process.env.FRIHET_API_KEY;
|
|
21
22
|
if (!apiKey) {
|
|
22
|
-
console.error("Error: FRIHET_API_KEY environment variable is required.\n" +
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
|
|
23
|
+
console.error("Error: FRIHET_API_KEY environment variable is required.\n\n" +
|
|
24
|
+
"Get your API key:\n" +
|
|
25
|
+
" 1. Create a free account at https://app.frihet.io\n" +
|
|
26
|
+
" 2. Go to Settings > Developers > API Keys\n" +
|
|
27
|
+
" 3. Create a key and add it to your MCP configuration\n\n" +
|
|
28
|
+
"Documentation: https://docs.frihet.io/desarrolladores/mcp-server\n");
|
|
26
29
|
process.exit(1);
|
|
27
30
|
}
|
|
28
31
|
const baseUrl = process.env.FRIHET_API_URL;
|
|
@@ -55,7 +58,17 @@ function main() {
|
|
|
55
58
|
"11 resources (8 static + 3 live), and 10 workflow prompts for business management " +
|
|
56
59
|
"with full Spanish tax compliance (IVA, IGIC, IPSI).",
|
|
57
60
|
});
|
|
58
|
-
//
|
|
61
|
+
// Apply OpenAI-safe profile if enabled (strips sensitive fields, fixes annotations)
|
|
62
|
+
const openaiMode = process.env.FRIHET_OPENAI_MODE === "true";
|
|
63
|
+
if (openaiMode) {
|
|
64
|
+
applyOpenAIProfile(server);
|
|
65
|
+
log({
|
|
66
|
+
level: "info",
|
|
67
|
+
message: `OpenAI safety profile active — ${OPENAI_EXCLUDED_COUNT} tools + ${OPENAI_EXCLUDED_RESOURCE_COUNT} resources excluded, gov IDs + credentials redacted`,
|
|
68
|
+
operation: "startup",
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
// Register tools (55 full / 53 in OpenAI mode)
|
|
59
72
|
registerAllTools(server, client);
|
|
60
73
|
// Register 11 resources (8 static + 3 dynamic via API)
|
|
61
74
|
registerAllResources(server, client);
|
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;AAC/D,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEpD,SAAS,IAAI;IACX,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAE1C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CACX,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI-safe profile for the Frihet MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Activated by FRIHET_OPENAI_MODE=true (env var or Worker binding).
|
|
5
|
+
*
|
|
6
|
+
* Applies transformations to every tool registration to comply with
|
|
7
|
+
* OpenAI's ChatGPT Apps submission requirements:
|
|
8
|
+
*
|
|
9
|
+
* 1. Excludes tools that return highly sensitive fiscal data
|
|
10
|
+
* 2. Corrects openWorldHint for tools that trigger external communication
|
|
11
|
+
* 3. Removes government IDs and credentials from input schemas
|
|
12
|
+
* 4. Redacts sensitive fields from all tool outputs
|
|
13
|
+
* 5. Updates descriptions to reflect modified behavior + openWorldHint justifications
|
|
14
|
+
*
|
|
15
|
+
* The full MCP server (55 tools) remains available for Claude, Cursor,
|
|
16
|
+
* Windsurf, Cline, Codex, and all other MCP clients.
|
|
17
|
+
*
|
|
18
|
+
* OpenAI-safe mode: 53 tools (2 excluded), 0 government IDs in I/O.
|
|
19
|
+
*
|
|
20
|
+
* @see https://developers.openai.com/apps-sdk/app-submission-guidelines
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Content-Security-Policy for the OpenAI-safe MCP endpoint.
|
|
24
|
+
* OpenAI requires CSP specifying the exact domains the app fetches from.
|
|
25
|
+
*/
|
|
26
|
+
export declare const OPENAI_CSP: string;
|
|
27
|
+
/**
|
|
28
|
+
* Applies the OpenAI-safe profile to an MCP server.
|
|
29
|
+
*
|
|
30
|
+
* Must be called BEFORE registerAllTools() and registerAllResources().
|
|
31
|
+
* Intercepts both registerTool() and registerResource() to apply
|
|
32
|
+
* the profile transformations.
|
|
33
|
+
*
|
|
34
|
+
* @example
|
|
35
|
+
* ```ts
|
|
36
|
+
* const server = new McpServer({ name: "Frihet", version: "1.5.4" });
|
|
37
|
+
* if (process.env.FRIHET_OPENAI_MODE === "true") {
|
|
38
|
+
* applyOpenAIProfile(server);
|
|
39
|
+
* }
|
|
40
|
+
* registerAllTools(server, client);
|
|
41
|
+
* registerAllResources(server, client);
|
|
42
|
+
* ```
|
|
43
|
+
*/
|
|
44
|
+
export declare function applyOpenAIProfile(server: any): void;
|
|
45
|
+
/** Number of tools excluded in OpenAI mode (for logging). */
|
|
46
|
+
export declare const OPENAI_EXCLUDED_COUNT: number;
|
|
47
|
+
/** Number of resources excluded in OpenAI mode (for logging). */
|
|
48
|
+
export declare const OPENAI_EXCLUDED_RESOURCE_COUNT: number;
|
|
49
|
+
//# sourceMappingURL=openai-profile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-profile.d.ts","sourceRoot":"","sources":["../src/openai-profile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AA2LH;;;GAGG;AACH,eAAO,MAAM,UAAU,QAQkB,CAAC;AAM1C;;;;;;;;;;;;;;;;GAgBG;AAEH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,GAAG,GAAG,IAAI,CAiGpD;AAED,6DAA6D;AAC7D,eAAO,MAAM,qBAAqB,QAA4B,CAAC;AAE/D,iEAAiE;AACjE,eAAO,MAAM,8BAA8B,QAAyB,CAAC"}
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI-safe profile for the Frihet MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Activated by FRIHET_OPENAI_MODE=true (env var or Worker binding).
|
|
5
|
+
*
|
|
6
|
+
* Applies transformations to every tool registration to comply with
|
|
7
|
+
* OpenAI's ChatGPT Apps submission requirements:
|
|
8
|
+
*
|
|
9
|
+
* 1. Excludes tools that return highly sensitive fiscal data
|
|
10
|
+
* 2. Corrects openWorldHint for tools that trigger external communication
|
|
11
|
+
* 3. Removes government IDs and credentials from input schemas
|
|
12
|
+
* 4. Redacts sensitive fields from all tool outputs
|
|
13
|
+
* 5. Updates descriptions to reflect modified behavior + openWorldHint justifications
|
|
14
|
+
*
|
|
15
|
+
* The full MCP server (55 tools) remains available for Claude, Cursor,
|
|
16
|
+
* Windsurf, Cline, Codex, and all other MCP clients.
|
|
17
|
+
*
|
|
18
|
+
* OpenAI-safe mode: 53 tools (2 excluded), 0 government IDs in I/O.
|
|
19
|
+
*
|
|
20
|
+
* @see https://developers.openai.com/apps-sdk/app-submission-guidelines
|
|
21
|
+
*/
|
|
22
|
+
const PROFILE = {
|
|
23
|
+
// ── Tools excluded entirely ─────────────────────────────────────────
|
|
24
|
+
// Return restricted data categories that cannot be adequately redacted.
|
|
25
|
+
excludeTools: new Set([
|
|
26
|
+
"get_quarterly_taxes", // Modelo 303/130 tax filing data — sensitive fiscal PII
|
|
27
|
+
"get_invoice_einvoice", // EN16931 XML mandatorily contains seller+buyer NIF/CIF
|
|
28
|
+
]),
|
|
29
|
+
// ── Annotation corrections ──────────────────────────────────────────
|
|
30
|
+
// openWorldHint MUST be true for tools that cause external side effects.
|
|
31
|
+
annotationOverrides: {
|
|
32
|
+
send_invoice: { openWorldHint: true },
|
|
33
|
+
send_quote: { openWorldHint: true },
|
|
34
|
+
create_webhook: { openWorldHint: true },
|
|
35
|
+
update_webhook: { openWorldHint: true },
|
|
36
|
+
},
|
|
37
|
+
// ── Description overrides ───────────────────────────────────────────
|
|
38
|
+
// Remove references to stripped fields (taxId, secret, to) and include
|
|
39
|
+
// openWorldHint justifications as required by OpenAI review guidelines.
|
|
40
|
+
descriptionOverrides: {
|
|
41
|
+
list_clients: "List all clients/customers with optional pagination. " +
|
|
42
|
+
"Returns contact info and addresses. " +
|
|
43
|
+
"/ Lista todos los clientes con paginacion opcional. " +
|
|
44
|
+
"Devuelve informacion de contacto y direcciones.",
|
|
45
|
+
create_client: "Create a new client/customer. Requires at minimum a name. " +
|
|
46
|
+
"Clients are used when creating invoices and quotes. " +
|
|
47
|
+
"Example: name='Acme Corp', email='billing@acme.com', " +
|
|
48
|
+
"address={street:'Main St 1', city:'Madrid', country:'ES'} " +
|
|
49
|
+
"/ Crea un nuevo cliente. Requiere como minimo un nombre.",
|
|
50
|
+
update_client: "Update an existing client using PATCH semantics. Only the provided fields will be changed. " +
|
|
51
|
+
"Example: id='abc123', email='new@acme.com', phone='+34600123456' " +
|
|
52
|
+
"/ Actualiza un cliente existente. Solo se modifican los campos proporcionados.",
|
|
53
|
+
list_vendors: "List all vendors/suppliers with optional pagination and search. " +
|
|
54
|
+
"Returns contact info and addresses. " +
|
|
55
|
+
"/ Lista todos los proveedores con paginacion y busqueda opcional. " +
|
|
56
|
+
"Devuelve informacion de contacto y direcciones.",
|
|
57
|
+
create_vendor: "Create a new vendor/supplier. Requires at minimum a name. " +
|
|
58
|
+
"Vendors are used when tracking expenses and purchase orders. " +
|
|
59
|
+
"Example: name='Office Supplies Ltd', email='billing@office.com', " +
|
|
60
|
+
"address={street:'Gran Via 1', city:'Madrid', country:'ES'} " +
|
|
61
|
+
"/ Crea un nuevo proveedor. Requiere como minimo un nombre.",
|
|
62
|
+
update_vendor: "Update an existing vendor using PATCH semantics. Only the provided fields will be changed. " +
|
|
63
|
+
"Example: id='abc123', email='new@supplier.com', phone='+34600123456' " +
|
|
64
|
+
"/ Actualiza un proveedor existente. Solo se modifican los campos proporcionados.",
|
|
65
|
+
send_invoice: "Send an invoice to the client via email using the client's stored email address. " +
|
|
66
|
+
"The invoice must exist and should not already be cancelled. " +
|
|
67
|
+
"[openWorldHint: true — triggers email delivery to the client's external email address " +
|
|
68
|
+
"via Frihet's transactional email service] " +
|
|
69
|
+
"/ Envia una factura al cliente por email usando el email almacenado del cliente.",
|
|
70
|
+
send_quote: "Send a quote to the client via email using the client's stored email address. " +
|
|
71
|
+
"The quote must exist and should not already be expired or rejected. " +
|
|
72
|
+
"[openWorldHint: true — triggers email delivery to the client's external email address " +
|
|
73
|
+
"via Frihet's transactional email service] " +
|
|
74
|
+
"/ Envia un presupuesto al cliente por email usando el email almacenado del cliente.",
|
|
75
|
+
create_webhook: "Register a new webhook endpoint. Specify the URL and events to subscribe to. " +
|
|
76
|
+
"Available events: invoice.created, invoice.updated, invoice.paid, invoice.deleted, " +
|
|
77
|
+
"expense.created, expense.updated, expense.deleted, client.created, client.updated, " +
|
|
78
|
+
"quote.created, quote.updated, quote.accepted. " +
|
|
79
|
+
"Example: url='https://example.com/webhook', events=['invoice.created','invoice.paid'] " +
|
|
80
|
+
"[openWorldHint: true — configures Frihet to POST event data to the specified external URL] " +
|
|
81
|
+
"/ Registra un nuevo endpoint de webhook.",
|
|
82
|
+
update_webhook: "Update an existing webhook configuration using PATCH semantics. " +
|
|
83
|
+
"Example: id='abc123', active=false to disable a webhook. " +
|
|
84
|
+
"[openWorldHint: true — can modify the external URL that receives webhook notifications] " +
|
|
85
|
+
"/ Actualiza la configuracion de un webhook.",
|
|
86
|
+
},
|
|
87
|
+
// ── Input fields stripped ──────────────────────────────────────────
|
|
88
|
+
// Government IDs (NIF/CIF/VAT), auth credentials, and unsolicited
|
|
89
|
+
// email address collection removed from input schemas.
|
|
90
|
+
stripInputFields: {
|
|
91
|
+
create_client: ["taxId"], // NIF/CIF/VAT — government-issued identifier
|
|
92
|
+
update_client: ["taxId"],
|
|
93
|
+
create_vendor: ["taxId"],
|
|
94
|
+
update_vendor: ["taxId"],
|
|
95
|
+
send_invoice: ["to"], // Don't solicit email — use client's stored email
|
|
96
|
+
send_quote: ["to"],
|
|
97
|
+
create_webhook: ["secret"], // Signing credential — manage via Frihet web app
|
|
98
|
+
update_webhook: ["secret"],
|
|
99
|
+
},
|
|
100
|
+
// ── Output fields redacted ─────────────────────────────────────────
|
|
101
|
+
// Stripped from structuredContent and text in ALL tool responses.
|
|
102
|
+
// Includes synonyms that the Frihet API may return via .passthrough() schemas.
|
|
103
|
+
redactOutputFields: [
|
|
104
|
+
"taxId", "tax_id", // Primary field name + snake_case variant
|
|
105
|
+
"nif", "cif", "vatNumber", // Spanish/EU synonyms for government tax ID
|
|
106
|
+
"vat_number", "vatId", "vat_id",
|
|
107
|
+
"secret", // Webhook signing credential
|
|
108
|
+
"iban", "bankAccount", // Banking identifiers (if exposed via passthrough)
|
|
109
|
+
"bank_account", "accountNumber",
|
|
110
|
+
],
|
|
111
|
+
};
|
|
112
|
+
/* ------------------------------------------------------------------ */
|
|
113
|
+
/* Deep field redaction */
|
|
114
|
+
/* ------------------------------------------------------------------ */
|
|
115
|
+
/** Recursively removes named fields from an object/array tree. */
|
|
116
|
+
function deepRedact(obj, fields) {
|
|
117
|
+
if (obj === null || typeof obj !== "object")
|
|
118
|
+
return;
|
|
119
|
+
if (Array.isArray(obj)) {
|
|
120
|
+
for (const item of obj)
|
|
121
|
+
deepRedact(item, fields);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const record = obj;
|
|
125
|
+
for (const field of fields) {
|
|
126
|
+
if (field in record)
|
|
127
|
+
delete record[field];
|
|
128
|
+
}
|
|
129
|
+
for (const value of Object.values(record)) {
|
|
130
|
+
deepRedact(value, fields);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/** Best-effort redaction of JSON field patterns from display text. */
|
|
134
|
+
function redactText(text, fields) {
|
|
135
|
+
let result = text;
|
|
136
|
+
for (const field of fields) {
|
|
137
|
+
// Remove "field": "value", or "field": value patterns
|
|
138
|
+
result = result.replace(new RegExp(`\\s*"${field}"\\s*:\\s*(?:"[^"]*"|null|true|false|\\d+(?:\\.\\d+)?)\\s*,?`, "g"), "");
|
|
139
|
+
}
|
|
140
|
+
// Clean up trailing commas before } or ] left by removals
|
|
141
|
+
return result.replace(/,(\s*[}\]])/g, "$1");
|
|
142
|
+
}
|
|
143
|
+
/* ------------------------------------------------------------------ */
|
|
144
|
+
/* Resources excluded / redacted in OpenAI mode */
|
|
145
|
+
/* ------------------------------------------------------------------ */
|
|
146
|
+
/** Dynamic resources excluded — return too much raw PII to safely redact. */
|
|
147
|
+
const EXCLUDE_RESOURCES = new Set([
|
|
148
|
+
"overdue-invoices", // Returns up to 100 raw invoice objects with client NIF/CIF
|
|
149
|
+
]);
|
|
150
|
+
/* ------------------------------------------------------------------ */
|
|
151
|
+
/* CSP for the OpenAI Worker */
|
|
152
|
+
/* ------------------------------------------------------------------ */
|
|
153
|
+
/**
|
|
154
|
+
* Content-Security-Policy for the OpenAI-safe MCP endpoint.
|
|
155
|
+
* OpenAI requires CSP specifying the exact domains the app fetches from.
|
|
156
|
+
*/
|
|
157
|
+
export const OPENAI_CSP = "default-src 'self'; " +
|
|
158
|
+
"script-src 'self' 'unsafe-inline' https://www.gstatic.com https://apis.google.com; " +
|
|
159
|
+
"style-src 'self' 'unsafe-inline'; " +
|
|
160
|
+
"connect-src 'self' https://api.frihet.io https://us-central1-gen-lang-client-0335716041.cloudfunctions.net " +
|
|
161
|
+
"https://identitytoolkit.googleapis.com https://securetoken.googleapis.com https://www.googleapis.com https://www.gstatic.com; " +
|
|
162
|
+
"frame-src https://accounts.google.com https://github.com https://login.microsoftonline.com; " +
|
|
163
|
+
"img-src 'self' data: https:; " +
|
|
164
|
+
"font-src 'self' https://www.frihet.io";
|
|
165
|
+
/* ------------------------------------------------------------------ */
|
|
166
|
+
/* Profile applicator */
|
|
167
|
+
/* ------------------------------------------------------------------ */
|
|
168
|
+
/**
|
|
169
|
+
* Applies the OpenAI-safe profile to an MCP server.
|
|
170
|
+
*
|
|
171
|
+
* Must be called BEFORE registerAllTools() and registerAllResources().
|
|
172
|
+
* Intercepts both registerTool() and registerResource() to apply
|
|
173
|
+
* the profile transformations.
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* ```ts
|
|
177
|
+
* const server = new McpServer({ name: "Frihet", version: "1.5.4" });
|
|
178
|
+
* if (process.env.FRIHET_OPENAI_MODE === "true") {
|
|
179
|
+
* applyOpenAIProfile(server);
|
|
180
|
+
* }
|
|
181
|
+
* registerAllTools(server, client);
|
|
182
|
+
* registerAllResources(server, client);
|
|
183
|
+
* ```
|
|
184
|
+
*/
|
|
185
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
186
|
+
export function applyOpenAIProfile(server) {
|
|
187
|
+
const fieldsToRedact = PROFILE.redactOutputFields;
|
|
188
|
+
/* ── Intercept registerTool ─────────────────────────────────────── */
|
|
189
|
+
const originalRegisterTool = server.registerTool.bind(server);
|
|
190
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
191
|
+
server.registerTool = (name, config, handler) => {
|
|
192
|
+
// 1. Skip excluded tools entirely
|
|
193
|
+
if (PROFILE.excludeTools.has(name))
|
|
194
|
+
return;
|
|
195
|
+
// 2. Merge annotation overrides
|
|
196
|
+
const annOverrides = PROFILE.annotationOverrides[name];
|
|
197
|
+
if (annOverrides) {
|
|
198
|
+
config.annotations = { ...config.annotations, ...annOverrides };
|
|
199
|
+
}
|
|
200
|
+
// 3. Replace descriptions
|
|
201
|
+
const descOverride = PROFILE.descriptionOverrides[name];
|
|
202
|
+
if (descOverride) {
|
|
203
|
+
config.description = descOverride;
|
|
204
|
+
}
|
|
205
|
+
// 4. Strip sensitive input fields
|
|
206
|
+
const inputStrip = PROFILE.stripInputFields[name];
|
|
207
|
+
if (inputStrip && config.inputSchema) {
|
|
208
|
+
for (const field of inputStrip) {
|
|
209
|
+
delete config.inputSchema[field];
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
// 5. Wrap handler to redact sensitive output fields
|
|
213
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
214
|
+
const wrappedHandler = async (input) => {
|
|
215
|
+
const result = await handler(input);
|
|
216
|
+
// Redact structuredContent (programmatic output)
|
|
217
|
+
if (result.structuredContent) {
|
|
218
|
+
deepRedact(result.structuredContent, fieldsToRedact);
|
|
219
|
+
}
|
|
220
|
+
// Best-effort redact text content (display output)
|
|
221
|
+
if (Array.isArray(result.content)) {
|
|
222
|
+
for (const block of result.content) {
|
|
223
|
+
if (block.type === "text" && typeof block.text === "string") {
|
|
224
|
+
block.text = redactText(block.text, fieldsToRedact);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return result;
|
|
229
|
+
};
|
|
230
|
+
return originalRegisterTool(name, config, wrappedHandler);
|
|
231
|
+
};
|
|
232
|
+
/* ── Intercept registerResource ─────────────────────────────────── */
|
|
233
|
+
const originalRegisterResource = server.registerResource.bind(server);
|
|
234
|
+
// registerResource(name, uri, config, handler) — 4 args
|
|
235
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
236
|
+
server.registerResource = (name, ...rest) => {
|
|
237
|
+
// Skip resources that expose too much raw PII
|
|
238
|
+
if (EXCLUDE_RESOURCES.has(name))
|
|
239
|
+
return;
|
|
240
|
+
// Find the handler (last argument) and wrap it
|
|
241
|
+
const handler = rest[rest.length - 1];
|
|
242
|
+
if (typeof handler === "function") {
|
|
243
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
244
|
+
rest[rest.length - 1] = async (...args) => {
|
|
245
|
+
const result = await handler(...args);
|
|
246
|
+
// Resources return { contents: [{ uri, text?, blob? }] }
|
|
247
|
+
if (result?.contents && Array.isArray(result.contents)) {
|
|
248
|
+
for (const content of result.contents) {
|
|
249
|
+
if (typeof content.text === "string") {
|
|
250
|
+
// Parse JSON, redact, re-serialize for clean removal
|
|
251
|
+
try {
|
|
252
|
+
const parsed = JSON.parse(content.text);
|
|
253
|
+
deepRedact(parsed, fieldsToRedact);
|
|
254
|
+
content.text = JSON.stringify(parsed, null, 2);
|
|
255
|
+
}
|
|
256
|
+
catch {
|
|
257
|
+
// Not JSON — fall back to regex redaction
|
|
258
|
+
content.text = redactText(content.text, fieldsToRedact);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return result;
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
return originalRegisterResource(name, ...rest);
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
/** Number of tools excluded in OpenAI mode (for logging). */
|
|
270
|
+
export const OPENAI_EXCLUDED_COUNT = PROFILE.excludeTools.size;
|
|
271
|
+
/** Number of resources excluded in OpenAI mode (for logging). */
|
|
272
|
+
export const OPENAI_EXCLUDED_RESOURCE_COUNT = EXCLUDE_RESOURCES.size;
|
|
273
|
+
//# sourceMappingURL=openai-profile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-profile.js","sourceRoot":"","sources":["../src/openai-profile.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frihet/mcp-server",
|
|
3
|
-
"version": "1.5.
|
|
4
|
-
"description": "AI-native MCP server for business management — invoices, expenses, clients, products, quotes, webhooks, CRM. 55 tools
|
|
3
|
+
"version": "1.5.5",
|
|
4
|
+
"description": "AI-native MCP server for business management — invoices, expenses, clients, products, quotes, webhooks, CRM. 55 tools. Remote endpoint at mcp.frihet.io (zero install). Works with Claude, Cursor, Windsurf, Cline.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"bin": {
|
|
@@ -39,6 +39,10 @@
|
|
|
39
39
|
"quotes",
|
|
40
40
|
"saas",
|
|
41
41
|
"tax-compliance",
|
|
42
|
+
"gemini-cli",
|
|
43
|
+
"freelancer",
|
|
44
|
+
"small-business",
|
|
45
|
+
"business-automation",
|
|
42
46
|
"verifactu",
|
|
43
47
|
"webhooks",
|
|
44
48
|
"windsurf"
|