@frihet/mcp-server 1.6.0 → 1.6.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/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/observability.d.ts +56 -0
- package/dist/observability.d.ts.map +1 -0
- package/dist/observability.js +212 -0
- package/dist/observability.js.map +1 -0
- package/dist/tools/register-all.d.ts +4 -0
- package/dist/tools/register-all.d.ts.map +1 -1
- package/dist/tools/register-all.js +30 -0
- package/dist/tools/register-all.js.map +1 -1
- package/dist/tools/stay.d.ts +86 -0
- package/dist/tools/stay.d.ts.map +1 -0
- package/dist/tools/stay.js +422 -0
- package/dist/tools/stay.js.map +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -17,6 +17,7 @@ import { registerAllPrompts } from "./prompts/register-all.js";
|
|
|
17
17
|
import { applyOpenAIProfile, OPENAI_EXCLUDED_COUNT, OPENAI_EXCLUDED_RESOURCE_COUNT } from "./openai-profile.js";
|
|
18
18
|
import { log } from "./logger.js";
|
|
19
19
|
import { registerShutdownHook } from "./metrics.js";
|
|
20
|
+
import { setTraceContext } from "./observability.js";
|
|
20
21
|
function main() {
|
|
21
22
|
const apiKey = process.env.FRIHET_API_KEY;
|
|
22
23
|
if (!apiKey) {
|
|
@@ -50,6 +51,12 @@ function main() {
|
|
|
50
51
|
}
|
|
51
52
|
}
|
|
52
53
|
const client = new FrihetClient(apiKey, baseUrl);
|
|
54
|
+
// Set trace context for Langfuse (reads LANGFUSE_* from process.env automatically).
|
|
55
|
+
// clientName can be overridden via FRIHET_CLIENT_NAME env var by the MCP host.
|
|
56
|
+
setTraceContext({
|
|
57
|
+
mcpVersion: "mcp/1.0",
|
|
58
|
+
clientName: process.env.FRIHET_CLIENT_NAME,
|
|
59
|
+
});
|
|
53
60
|
const server = new McpServer({
|
|
54
61
|
name: "frihet-erp",
|
|
55
62
|
version: "1.5.2",
|
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,kBAAkB,EAAE,qBAAqB,EAAE,8BAA8B,EAAE,MAAM,qBAAqB,CAAC;AAChH,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Langfuse observability for Frihet MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Uses direct HTTP POST to the Langfuse ingestion API (no SDK dependency)
|
|
5
|
+
* so it works identically in Node.js (stdio) and Cloudflare Workers (edge).
|
|
6
|
+
*
|
|
7
|
+
* Design:
|
|
8
|
+
* - Fail-open: any Langfuse error logs a warning and lets the tool proceed.
|
|
9
|
+
* - PII: tool input content is passed as-is (business data is fine to trace).
|
|
10
|
+
* userId / apiKey metadata are hashed with a simple SHA-256 fingerprint.
|
|
11
|
+
* - Fire-and-forget: traces are sent via waitUntil (Workers) or unref'd promise
|
|
12
|
+
* (Node.js) so they never block tool responses.
|
|
13
|
+
*
|
|
14
|
+
* Environment variables (both Node.js stdio and Cloudflare Worker):
|
|
15
|
+
* LANGFUSE_PUBLIC_KEY — pk-lf-...
|
|
16
|
+
* LANGFUSE_SECRET_KEY — sk-lf-...
|
|
17
|
+
* LANGFUSE_BASE_URL — https://langfuse.frihet.io (no trailing slash)
|
|
18
|
+
*
|
|
19
|
+
* Docs: https://langfuse.com/docs/api/reference/overview
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* Called once from FrihetMCP.init() in the Worker to inject env vars.
|
|
23
|
+
* Not needed in Node.js stdio mode (reads from process.env directly).
|
|
24
|
+
*/
|
|
25
|
+
export declare function initLangfuse(config: {
|
|
26
|
+
publicKey?: string;
|
|
27
|
+
secretKey?: string;
|
|
28
|
+
baseUrl?: string;
|
|
29
|
+
}): void;
|
|
30
|
+
interface TraceContext {
|
|
31
|
+
/** User-Agent from MCP client or other client identifier */
|
|
32
|
+
clientName?: string;
|
|
33
|
+
/** MCP protocol version */
|
|
34
|
+
mcpVersion?: string;
|
|
35
|
+
/** Frihet workspace/user ID — will be hashed */
|
|
36
|
+
userId?: string;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Set session-level context (client identity, MCP version).
|
|
40
|
+
* Call once from server init; applies to all subsequent traces.
|
|
41
|
+
*/
|
|
42
|
+
export declare function setTraceContext(ctx: TraceContext): void;
|
|
43
|
+
/**
|
|
44
|
+
* Wraps a tool handler fn and sends a Langfuse trace+span for the call.
|
|
45
|
+
*
|
|
46
|
+
* Fail-open: if Langfuse is not configured or errors, fn runs unchanged.
|
|
47
|
+
* Fire-and-forget: Langfuse POST never blocks the tool response.
|
|
48
|
+
*
|
|
49
|
+
* @param toolName Tool name (e.g. "create_invoice")
|
|
50
|
+
* @param input Raw tool input args
|
|
51
|
+
* @param fn Async tool handler to wrap
|
|
52
|
+
* @returns Result of fn
|
|
53
|
+
*/
|
|
54
|
+
export declare function traceMCPTool<T>(toolName: string, input: unknown, fn: () => Promise<T>): Promise<T>;
|
|
55
|
+
export {};
|
|
56
|
+
//# sourceMappingURL=observability.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observability.d.ts","sourceRoot":"","sources":["../src/observability.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAkCH;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,IAAI,CAQP;AA8FD,UAAU,YAAY;IACpB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2BAA2B;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAKD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,YAAY,GAAG,IAAI,CAEvD;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CAAC,CAAC,EAClC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,OAAO,EACd,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CAoGZ"}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Langfuse observability for Frihet MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Uses direct HTTP POST to the Langfuse ingestion API (no SDK dependency)
|
|
5
|
+
* so it works identically in Node.js (stdio) and Cloudflare Workers (edge).
|
|
6
|
+
*
|
|
7
|
+
* Design:
|
|
8
|
+
* - Fail-open: any Langfuse error logs a warning and lets the tool proceed.
|
|
9
|
+
* - PII: tool input content is passed as-is (business data is fine to trace).
|
|
10
|
+
* userId / apiKey metadata are hashed with a simple SHA-256 fingerprint.
|
|
11
|
+
* - Fire-and-forget: traces are sent via waitUntil (Workers) or unref'd promise
|
|
12
|
+
* (Node.js) so they never block tool responses.
|
|
13
|
+
*
|
|
14
|
+
* Environment variables (both Node.js stdio and Cloudflare Worker):
|
|
15
|
+
* LANGFUSE_PUBLIC_KEY — pk-lf-...
|
|
16
|
+
* LANGFUSE_SECRET_KEY — sk-lf-...
|
|
17
|
+
* LANGFUSE_BASE_URL — https://langfuse.frihet.io (no trailing slash)
|
|
18
|
+
*
|
|
19
|
+
* Docs: https://langfuse.com/docs/api/reference/overview
|
|
20
|
+
*/
|
|
21
|
+
function getConfig() {
|
|
22
|
+
let publicKey;
|
|
23
|
+
let secretKey;
|
|
24
|
+
let baseUrl;
|
|
25
|
+
// Node.js
|
|
26
|
+
if (typeof process !== "undefined" && process?.env) {
|
|
27
|
+
publicKey = process.env.LANGFUSE_PUBLIC_KEY;
|
|
28
|
+
secretKey = process.env.LANGFUSE_SECRET_KEY;
|
|
29
|
+
baseUrl = process.env.LANGFUSE_BASE_URL;
|
|
30
|
+
}
|
|
31
|
+
if (!publicKey || !secretKey || !baseUrl)
|
|
32
|
+
return null;
|
|
33
|
+
return { publicKey, secretKey, baseUrl: baseUrl.replace(/\/$/, "") };
|
|
34
|
+
}
|
|
35
|
+
// ── Worker env injection (for Cloudflare Workers) ───────────────────────────
|
|
36
|
+
let workerEnv = null;
|
|
37
|
+
/**
|
|
38
|
+
* Called once from FrihetMCP.init() in the Worker to inject env vars.
|
|
39
|
+
* Not needed in Node.js stdio mode (reads from process.env directly).
|
|
40
|
+
*/
|
|
41
|
+
export function initLangfuse(config) {
|
|
42
|
+
if (config.publicKey && config.secretKey && config.baseUrl) {
|
|
43
|
+
workerEnv = {
|
|
44
|
+
publicKey: config.publicKey,
|
|
45
|
+
secretKey: config.secretKey,
|
|
46
|
+
baseUrl: config.baseUrl.replace(/\/$/, ""),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
function resolveConfig() {
|
|
51
|
+
return workerEnv ?? getConfig();
|
|
52
|
+
}
|
|
53
|
+
// ── PII helpers ──────────────────────────────────────────────────────────────
|
|
54
|
+
/**
|
|
55
|
+
* One-way fingerprint for PII values (apiKey, userId, email).
|
|
56
|
+
* Uses Web Crypto API (available in both Node.js ≥18 and Workers).
|
|
57
|
+
*/
|
|
58
|
+
async function hashPii(value) {
|
|
59
|
+
try {
|
|
60
|
+
const encoder = new TextEncoder();
|
|
61
|
+
const data = encoder.encode(value);
|
|
62
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
|
|
63
|
+
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
64
|
+
return hashArray.map((b) => b.toString(16).padStart(2, "0")).join("").slice(0, 16);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
return "[hash-error]";
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
// ── ID generation ────────────────────────────────────────────────────────────
|
|
71
|
+
function newId() {
|
|
72
|
+
// crypto.randomUUID() available in Node.js ≥18 and all Workers
|
|
73
|
+
return crypto.randomUUID();
|
|
74
|
+
}
|
|
75
|
+
// ── HTTP send ────────────────────────────────────────────────────────────────
|
|
76
|
+
async function sendBatch(config, batch) {
|
|
77
|
+
const credentials = btoa(`${config.publicKey}:${config.secretKey}`);
|
|
78
|
+
const resp = await fetch(`${config.baseUrl}/api/public/ingestion`, {
|
|
79
|
+
method: "POST",
|
|
80
|
+
headers: {
|
|
81
|
+
"Content-Type": "application/json",
|
|
82
|
+
"Authorization": `Basic ${credentials}`,
|
|
83
|
+
},
|
|
84
|
+
body: JSON.stringify(batch),
|
|
85
|
+
signal: AbortSignal.timeout(5000),
|
|
86
|
+
});
|
|
87
|
+
if (!resp.ok) {
|
|
88
|
+
// Log but don't throw — fail-open
|
|
89
|
+
const body = await resp.text().catch(() => "");
|
|
90
|
+
console.error(JSON.stringify({
|
|
91
|
+
service: "frihet-mcp",
|
|
92
|
+
level: "warn",
|
|
93
|
+
message: `Langfuse ingestion failed: ${resp.status} ${body.slice(0, 200)}`,
|
|
94
|
+
operation: "langfuse_send",
|
|
95
|
+
timestamp: new Date().toISOString(),
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// Module-level context set once per session (Workers: per DO init, Node.js: startup)
|
|
100
|
+
let _sessionContext = {};
|
|
101
|
+
/**
|
|
102
|
+
* Set session-level context (client identity, MCP version).
|
|
103
|
+
* Call once from server init; applies to all subsequent traces.
|
|
104
|
+
*/
|
|
105
|
+
export function setTraceContext(ctx) {
|
|
106
|
+
_sessionContext = { ..._sessionContext, ...ctx };
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Wraps a tool handler fn and sends a Langfuse trace+span for the call.
|
|
110
|
+
*
|
|
111
|
+
* Fail-open: if Langfuse is not configured or errors, fn runs unchanged.
|
|
112
|
+
* Fire-and-forget: Langfuse POST never blocks the tool response.
|
|
113
|
+
*
|
|
114
|
+
* @param toolName Tool name (e.g. "create_invoice")
|
|
115
|
+
* @param input Raw tool input args
|
|
116
|
+
* @param fn Async tool handler to wrap
|
|
117
|
+
* @returns Result of fn
|
|
118
|
+
*/
|
|
119
|
+
export async function traceMCPTool(toolName, input, fn) {
|
|
120
|
+
const config = resolveConfig();
|
|
121
|
+
// No config — pass through silently
|
|
122
|
+
if (!config) {
|
|
123
|
+
return fn();
|
|
124
|
+
}
|
|
125
|
+
const traceId = newId();
|
|
126
|
+
const spanId = newId();
|
|
127
|
+
const startTime = new Date();
|
|
128
|
+
let result;
|
|
129
|
+
let isError = false;
|
|
130
|
+
let errorMessage;
|
|
131
|
+
let output;
|
|
132
|
+
try {
|
|
133
|
+
result = await fn();
|
|
134
|
+
output = result;
|
|
135
|
+
return result;
|
|
136
|
+
}
|
|
137
|
+
catch (err) {
|
|
138
|
+
isError = true;
|
|
139
|
+
errorMessage = err instanceof Error ? err.message : String(err);
|
|
140
|
+
throw err;
|
|
141
|
+
}
|
|
142
|
+
finally {
|
|
143
|
+
const endTime = new Date();
|
|
144
|
+
// Fire-and-forget — build and send async, never awaited
|
|
145
|
+
void (async () => {
|
|
146
|
+
try {
|
|
147
|
+
// Hash PII fields
|
|
148
|
+
const userIdRaw = _sessionContext.userId;
|
|
149
|
+
const userIdHashed = userIdRaw ? await hashPii(userIdRaw) : undefined;
|
|
150
|
+
const traceBody = {
|
|
151
|
+
id: traceId,
|
|
152
|
+
name: "mcp_request",
|
|
153
|
+
timestamp: startTime.toISOString(),
|
|
154
|
+
input: { tool: toolName, args: input },
|
|
155
|
+
output: isError ? { error: errorMessage } : output,
|
|
156
|
+
metadata: {
|
|
157
|
+
tool: toolName,
|
|
158
|
+
clientName: _sessionContext.clientName,
|
|
159
|
+
mcpVersion: _sessionContext.mcpVersion,
|
|
160
|
+
success: !isError,
|
|
161
|
+
},
|
|
162
|
+
tags: [`mcp.tool.${toolName}`],
|
|
163
|
+
...(userIdHashed ? { userId: userIdHashed } : {}),
|
|
164
|
+
};
|
|
165
|
+
const spanBody = {
|
|
166
|
+
id: spanId,
|
|
167
|
+
traceId,
|
|
168
|
+
name: `tool.${toolName}`,
|
|
169
|
+
startTime: startTime.toISOString(),
|
|
170
|
+
endTime: endTime.toISOString(),
|
|
171
|
+
input,
|
|
172
|
+
output: isError ? { error: errorMessage } : output,
|
|
173
|
+
metadata: {
|
|
174
|
+
durationMs: endTime.getTime() - startTime.getTime(),
|
|
175
|
+
clientName: _sessionContext.clientName,
|
|
176
|
+
mcpVersion: _sessionContext.mcpVersion,
|
|
177
|
+
},
|
|
178
|
+
level: isError ? "ERROR" : "DEFAULT",
|
|
179
|
+
...(isError && errorMessage ? { statusMessage: errorMessage } : {}),
|
|
180
|
+
};
|
|
181
|
+
const batch = {
|
|
182
|
+
batch: [
|
|
183
|
+
{
|
|
184
|
+
type: "trace-create",
|
|
185
|
+
id: newId(),
|
|
186
|
+
timestamp: startTime.toISOString(),
|
|
187
|
+
body: traceBody,
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
type: "span-create",
|
|
191
|
+
id: newId(),
|
|
192
|
+
timestamp: startTime.toISOString(),
|
|
193
|
+
body: spanBody,
|
|
194
|
+
},
|
|
195
|
+
],
|
|
196
|
+
};
|
|
197
|
+
await sendBatch(config, batch);
|
|
198
|
+
}
|
|
199
|
+
catch (langfuseErr) {
|
|
200
|
+
// Fail-open: log warn only
|
|
201
|
+
console.error(JSON.stringify({
|
|
202
|
+
service: "frihet-mcp",
|
|
203
|
+
level: "warn",
|
|
204
|
+
message: `Langfuse trace failed (non-blocking): ${langfuseErr instanceof Error ? langfuseErr.message : String(langfuseErr)}`,
|
|
205
|
+
operation: "langfuse_trace",
|
|
206
|
+
timestamp: new Date().toISOString(),
|
|
207
|
+
}));
|
|
208
|
+
}
|
|
209
|
+
})();
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=observability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observability.js","sourceRoot":"","sources":["../src/observability.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Used by both the local (stdio) and remote (Cloudflare Workers) servers
|
|
5
5
|
* so tool definitions stay in sync — one source of truth.
|
|
6
|
+
*
|
|
7
|
+
* Langfuse observability is injected by patching server.registerTool once
|
|
8
|
+
* before any tool registration. This wraps every tool callback with
|
|
9
|
+
* traceMCPTool so all 62 tools are instrumented at zero per-tool cost.
|
|
6
10
|
*/
|
|
7
11
|
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
8
12
|
import type { IFrihetClient } from "../client-interface.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register-all.d.ts","sourceRoot":"","sources":["../../src/tools/register-all.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"register-all.d.ts","sourceRoot":"","sources":["../../src/tools/register-all.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AA0C5D,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CAc/E"}
|
|
@@ -3,7 +3,12 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Used by both the local (stdio) and remote (Cloudflare Workers) servers
|
|
5
5
|
* so tool definitions stay in sync — one source of truth.
|
|
6
|
+
*
|
|
7
|
+
* Langfuse observability is injected by patching server.registerTool once
|
|
8
|
+
* before any tool registration. This wraps every tool callback with
|
|
9
|
+
* traceMCPTool so all 62 tools are instrumented at zero per-tool cost.
|
|
6
10
|
*/
|
|
11
|
+
import { traceMCPTool } from "../observability.js";
|
|
7
12
|
import { registerInvoiceTools } from "./invoices.js";
|
|
8
13
|
import { registerExpenseTools } from "./expenses.js";
|
|
9
14
|
import { registerClientTools } from "./clients.js";
|
|
@@ -14,7 +19,32 @@ import { registerWebhookTools } from "./webhooks.js";
|
|
|
14
19
|
import { registerIntelligenceTools } from "./intelligence.js";
|
|
15
20
|
import { registerCrmTools } from "./crm.js";
|
|
16
21
|
import { registerDepositTools } from "./deposits.js";
|
|
22
|
+
/**
|
|
23
|
+
* Patches server.registerTool to wrap every tool callback with Langfuse tracing.
|
|
24
|
+
*
|
|
25
|
+
* The patch is applied once before tool registration so all 62 tools are
|
|
26
|
+
* instrumented without per-tool edits. Tool call signatures are unchanged —
|
|
27
|
+
* existing MCP clients continue to work identically.
|
|
28
|
+
*
|
|
29
|
+
* traceMCPTool is fail-open: any Langfuse error → warn log, tool proceeds.
|
|
30
|
+
*/
|
|
31
|
+
function patchServerWithTracing(server) {
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
33
|
+
const originalRegisterTool = server.registerTool.bind(server);
|
|
34
|
+
// We override registerTool to wrap the callback (cb) with Langfuse tracing.
|
|
35
|
+
// The override preserves full TypeScript compatibility via a broad signature
|
|
36
|
+
// cast — the runtime types are identical; we only intercept the callback.
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
38
|
+
server.registerTool = function patchedRegisterTool(name, config, cb) {
|
|
39
|
+
const tracedCb = async (args, extra) => {
|
|
40
|
+
return traceMCPTool(name, args, () => cb(args, extra));
|
|
41
|
+
};
|
|
42
|
+
return originalRegisterTool(name, config, tracedCb);
|
|
43
|
+
};
|
|
44
|
+
}
|
|
17
45
|
export function registerAllTools(server, client) {
|
|
46
|
+
// Inject Langfuse tracing into all subsequent registerTool calls (fail-open)
|
|
47
|
+
patchServerWithTracing(server);
|
|
18
48
|
registerIntelligenceTools(server, client);
|
|
19
49
|
registerInvoiceTools(server, client);
|
|
20
50
|
registerExpenseTools(server, client);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register-all.js","sourceRoot":"","sources":["../../src/tools/register-all.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"register-all.js","sourceRoot":"","sources":["../../src/tools/register-all.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAErD;;;;;;;;GAQG;AACH,SAAS,sBAAsB,CAAC,MAAiB;IAC/C,6DAA6D;IAC7D,MAAM,oBAAoB,GAAG,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAE9D,4EAA4E;IAC5E,6EAA6E;IAC7E,0EAA0E;IAC1E,8DAA8D;IAC7D,MAAc,CAAC,YAAY,GAAG,SAAS,mBAAmB,CACzD,IAAY,EACZ,MAA+B,EAC/B,EAA8C;QAE9C,MAAM,QAAQ,GAAG,KAAK,EAAE,IAAa,EAAE,KAAc,EAAoB,EAAE;YACzE,OAAO,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,CAAqB,CAAC,CAAC;QAC7E,CAAC,CAAC;QACF,OAAO,oBAAoB,CAAC,IAAI,EAAE,MAAoD,EAAE,QAAsD,CAAC,CAAC;IAClJ,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAiB,EAAE,MAAqB;IACvE,6EAA6E;IAC7E,sBAAsB,CAAC,MAAM,CAAC,CAAC;IAE/B,yBAAyB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stay tools for the Frihet MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Covers property management, reservations, operations (cleaning, occupancy),
|
|
5
|
+
* iCal channel sync, and guest compliance — all routed to api.frihet.io/v1/stay/*.
|
|
6
|
+
*/
|
|
7
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
8
|
+
import { z } from "zod/v4";
|
|
9
|
+
import type { IFrihetClient } from "../client-interface.js";
|
|
10
|
+
export declare const propertyItemOutput: z.ZodObject<{
|
|
11
|
+
id: z.ZodString;
|
|
12
|
+
name: z.ZodString;
|
|
13
|
+
type: z.ZodOptional<z.ZodString>;
|
|
14
|
+
address: z.ZodOptional<z.ZodString>;
|
|
15
|
+
maxGuests: z.ZodOptional<z.ZodNumber>;
|
|
16
|
+
bedrooms: z.ZodOptional<z.ZodNumber>;
|
|
17
|
+
bathrooms: z.ZodOptional<z.ZodNumber>;
|
|
18
|
+
active: z.ZodOptional<z.ZodBoolean>;
|
|
19
|
+
licenseNumber: z.ZodOptional<z.ZodString>;
|
|
20
|
+
createdAt: z.ZodOptional<z.ZodString>;
|
|
21
|
+
updatedAt: z.ZodOptional<z.ZodString>;
|
|
22
|
+
}, z.core.$loose>;
|
|
23
|
+
export declare const reservationItemOutput: z.ZodObject<{
|
|
24
|
+
id: z.ZodString;
|
|
25
|
+
propertyId: z.ZodString;
|
|
26
|
+
propertyName: z.ZodOptional<z.ZodString>;
|
|
27
|
+
guestName: z.ZodString;
|
|
28
|
+
guestEmail: z.ZodOptional<z.ZodString>;
|
|
29
|
+
guestPhone: z.ZodOptional<z.ZodString>;
|
|
30
|
+
checkIn: z.ZodString;
|
|
31
|
+
checkOut: z.ZodString;
|
|
32
|
+
status: z.ZodOptional<z.ZodString>;
|
|
33
|
+
totalAmount: z.ZodOptional<z.ZodNumber>;
|
|
34
|
+
nightlyRate: z.ZodOptional<z.ZodNumber>;
|
|
35
|
+
numGuests: z.ZodOptional<z.ZodNumber>;
|
|
36
|
+
channel: z.ZodOptional<z.ZodString>;
|
|
37
|
+
notes: z.ZodOptional<z.ZodString>;
|
|
38
|
+
createdAt: z.ZodOptional<z.ZodString>;
|
|
39
|
+
updatedAt: z.ZodOptional<z.ZodString>;
|
|
40
|
+
}, z.core.$loose>;
|
|
41
|
+
export declare const cleaningTaskItemOutput: z.ZodObject<{
|
|
42
|
+
id: z.ZodString;
|
|
43
|
+
propertyId: z.ZodString;
|
|
44
|
+
propertyName: z.ZodOptional<z.ZodString>;
|
|
45
|
+
reservationId: z.ZodOptional<z.ZodString>;
|
|
46
|
+
status: z.ZodOptional<z.ZodString>;
|
|
47
|
+
scheduledAt: z.ZodOptional<z.ZodString>;
|
|
48
|
+
completedAt: z.ZodOptional<z.ZodString>;
|
|
49
|
+
assignedTo: z.ZodOptional<z.ZodString>;
|
|
50
|
+
notes: z.ZodOptional<z.ZodString>;
|
|
51
|
+
createdAt: z.ZodOptional<z.ZodString>;
|
|
52
|
+
updatedAt: z.ZodOptional<z.ZodString>;
|
|
53
|
+
}, z.core.$loose>;
|
|
54
|
+
export declare const occupancyStatsOutput: z.ZodObject<{
|
|
55
|
+
from: z.ZodString;
|
|
56
|
+
to: z.ZodString;
|
|
57
|
+
occupancyRate: z.ZodOptional<z.ZodNumber>;
|
|
58
|
+
totalRevenue: z.ZodOptional<z.ZodNumber>;
|
|
59
|
+
adr: z.ZodOptional<z.ZodNumber>;
|
|
60
|
+
revPAR: z.ZodOptional<z.ZodNumber>;
|
|
61
|
+
totalNights: z.ZodOptional<z.ZodNumber>;
|
|
62
|
+
occupiedNights: z.ZodOptional<z.ZodNumber>;
|
|
63
|
+
reservationsCount: z.ZodOptional<z.ZodNumber>;
|
|
64
|
+
byProperty: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
65
|
+
propertyId: z.ZodString;
|
|
66
|
+
propertyName: z.ZodOptional<z.ZodString>;
|
|
67
|
+
occupancyRate: z.ZodOptional<z.ZodNumber>;
|
|
68
|
+
revenue: z.ZodOptional<z.ZodNumber>;
|
|
69
|
+
adr: z.ZodOptional<z.ZodNumber>;
|
|
70
|
+
}, z.core.$loose>>>;
|
|
71
|
+
}, z.core.$loose>;
|
|
72
|
+
export declare const complianceStatusOutput: z.ZodObject<{
|
|
73
|
+
total: z.ZodNumber;
|
|
74
|
+
verified: z.ZodNumber;
|
|
75
|
+
pending: z.ZodNumber;
|
|
76
|
+
expired: z.ZodOptional<z.ZodNumber>;
|
|
77
|
+
byProperty: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
78
|
+
propertyId: z.ZodString;
|
|
79
|
+
propertyName: z.ZodOptional<z.ZodString>;
|
|
80
|
+
verified: z.ZodNumber;
|
|
81
|
+
pending: z.ZodNumber;
|
|
82
|
+
total: z.ZodNumber;
|
|
83
|
+
}, z.core.$loose>>>;
|
|
84
|
+
}, z.core.$loose>;
|
|
85
|
+
export declare function registerStayTools(server: McpServer, client: IFrihetClient): void;
|
|
86
|
+
//# sourceMappingURL=stay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stay.d.ts","sourceRoot":"","sources":["../../src/tools/stay.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAC3B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAoB5D,eAAO,MAAM,kBAAkB;;;;;;;;;;;;iBAYf,CAAC;AAEjB,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;iBAiBlB,CAAC;AAEjB,eAAO,MAAM,sBAAsB;;;;;;;;;;;;iBAYnB,CAAC;AAEjB,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;iBAiBjB,CAAC;AAEjB,eAAO,MAAM,sBAAsB;;;;;;;;;;;;iBAYnB,CAAC;AAMjB,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,GAAG,IAAI,CAiZhF"}
|
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stay tools for the Frihet MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Covers property management, reservations, operations (cleaning, occupancy),
|
|
5
|
+
* iCal channel sync, and guest compliance — all routed to api.frihet.io/v1/stay/*.
|
|
6
|
+
*/
|
|
7
|
+
import { z } from "zod/v4";
|
|
8
|
+
import { withToolLogging, formatPaginatedResponse, formatRecord, listContent, getContent, mutateContent, enrichResponse, READ_ONLY_ANNOTATIONS, CREATE_ANNOTATIONS, UPDATE_ANNOTATIONS, paginatedOutput, actionResultOutput, } from "./shared.js";
|
|
9
|
+
/* ------------------------------------------------------------------ */
|
|
10
|
+
/* Output schemas */
|
|
11
|
+
/* ------------------------------------------------------------------ */
|
|
12
|
+
export const propertyItemOutput = z.object({
|
|
13
|
+
id: z.string(),
|
|
14
|
+
name: z.string(),
|
|
15
|
+
type: z.string().optional(),
|
|
16
|
+
address: z.string().optional(),
|
|
17
|
+
maxGuests: z.number().optional(),
|
|
18
|
+
bedrooms: z.number().optional(),
|
|
19
|
+
bathrooms: z.number().optional(),
|
|
20
|
+
active: z.boolean().optional(),
|
|
21
|
+
licenseNumber: z.string().optional(),
|
|
22
|
+
createdAt: z.string().optional(),
|
|
23
|
+
updatedAt: z.string().optional(),
|
|
24
|
+
}).passthrough();
|
|
25
|
+
export const reservationItemOutput = z.object({
|
|
26
|
+
id: z.string(),
|
|
27
|
+
propertyId: z.string(),
|
|
28
|
+
propertyName: z.string().optional(),
|
|
29
|
+
guestName: z.string(),
|
|
30
|
+
guestEmail: z.string().optional(),
|
|
31
|
+
guestPhone: z.string().optional(),
|
|
32
|
+
checkIn: z.string(),
|
|
33
|
+
checkOut: z.string(),
|
|
34
|
+
status: z.string().optional(),
|
|
35
|
+
totalAmount: z.number().optional(),
|
|
36
|
+
nightlyRate: z.number().optional(),
|
|
37
|
+
numGuests: z.number().optional(),
|
|
38
|
+
channel: z.string().optional(),
|
|
39
|
+
notes: z.string().optional(),
|
|
40
|
+
createdAt: z.string().optional(),
|
|
41
|
+
updatedAt: z.string().optional(),
|
|
42
|
+
}).passthrough();
|
|
43
|
+
export const cleaningTaskItemOutput = z.object({
|
|
44
|
+
id: z.string(),
|
|
45
|
+
propertyId: z.string(),
|
|
46
|
+
propertyName: z.string().optional(),
|
|
47
|
+
reservationId: z.string().optional(),
|
|
48
|
+
status: z.string().optional(),
|
|
49
|
+
scheduledAt: z.string().optional(),
|
|
50
|
+
completedAt: z.string().optional(),
|
|
51
|
+
assignedTo: z.string().optional(),
|
|
52
|
+
notes: z.string().optional(),
|
|
53
|
+
createdAt: z.string().optional(),
|
|
54
|
+
updatedAt: z.string().optional(),
|
|
55
|
+
}).passthrough();
|
|
56
|
+
export const occupancyStatsOutput = z.object({
|
|
57
|
+
from: z.string(),
|
|
58
|
+
to: z.string(),
|
|
59
|
+
occupancyRate: z.number().optional(),
|
|
60
|
+
totalRevenue: z.number().optional(),
|
|
61
|
+
adr: z.number().optional(),
|
|
62
|
+
revPAR: z.number().optional(),
|
|
63
|
+
totalNights: z.number().optional(),
|
|
64
|
+
occupiedNights: z.number().optional(),
|
|
65
|
+
reservationsCount: z.number().optional(),
|
|
66
|
+
byProperty: z.array(z.object({
|
|
67
|
+
propertyId: z.string(),
|
|
68
|
+
propertyName: z.string().optional(),
|
|
69
|
+
occupancyRate: z.number().optional(),
|
|
70
|
+
revenue: z.number().optional(),
|
|
71
|
+
adr: z.number().optional(),
|
|
72
|
+
}).passthrough()).optional(),
|
|
73
|
+
}).passthrough();
|
|
74
|
+
export const complianceStatusOutput = z.object({
|
|
75
|
+
total: z.number(),
|
|
76
|
+
verified: z.number(),
|
|
77
|
+
pending: z.number(),
|
|
78
|
+
expired: z.number().optional(),
|
|
79
|
+
byProperty: z.array(z.object({
|
|
80
|
+
propertyId: z.string(),
|
|
81
|
+
propertyName: z.string().optional(),
|
|
82
|
+
verified: z.number(),
|
|
83
|
+
pending: z.number(),
|
|
84
|
+
total: z.number(),
|
|
85
|
+
}).passthrough()).optional(),
|
|
86
|
+
}).passthrough();
|
|
87
|
+
/* ------------------------------------------------------------------ */
|
|
88
|
+
/* Tool registration */
|
|
89
|
+
/* ------------------------------------------------------------------ */
|
|
90
|
+
export function registerStayTools(server, client) {
|
|
91
|
+
// -- list_properties --
|
|
92
|
+
server.registerTool("list_properties", {
|
|
93
|
+
title: "List Properties (Stay)",
|
|
94
|
+
description: "List all Stay properties with optional filters. " +
|
|
95
|
+
"Returns properties the authenticated user manages, sorted by name. " +
|
|
96
|
+
"Use active=true to list only active rentals. " +
|
|
97
|
+
"/ Lista todas las propiedades de Stay con filtros opcionales. " +
|
|
98
|
+
"Devuelve las propiedades del usuario autenticado, ordenadas por nombre. " +
|
|
99
|
+
"Usa active=true para listar solo alquileres activos.",
|
|
100
|
+
annotations: READ_ONLY_ANNOTATIONS,
|
|
101
|
+
inputSchema: {
|
|
102
|
+
active: z
|
|
103
|
+
.boolean()
|
|
104
|
+
.optional()
|
|
105
|
+
.describe("Filter by active/inactive status / Filtrar por estado activo/inactivo"),
|
|
106
|
+
type: z
|
|
107
|
+
.string()
|
|
108
|
+
.optional()
|
|
109
|
+
.describe("Filter by property type (apartment, house, room, villa...) / Filtrar por tipo de propiedad"),
|
|
110
|
+
limit: z
|
|
111
|
+
.number().int().min(1).max(100)
|
|
112
|
+
.optional()
|
|
113
|
+
.describe("Max results per page (1-100, default 50) / Resultados por pagina"),
|
|
114
|
+
offset: z
|
|
115
|
+
.number().int().min(0)
|
|
116
|
+
.optional()
|
|
117
|
+
.describe("Number of results to skip / Resultados a saltar"),
|
|
118
|
+
after: z
|
|
119
|
+
.string()
|
|
120
|
+
.optional()
|
|
121
|
+
.describe("Cursor for cursor-based pagination / Cursor de paginacion"),
|
|
122
|
+
},
|
|
123
|
+
outputSchema: paginatedOutput(propertyItemOutput),
|
|
124
|
+
}, async ({ active, type, limit, offset, after }) => withToolLogging("list_properties", async () => {
|
|
125
|
+
const result = await client.listStayProperties({ active, type, limit, offset, after });
|
|
126
|
+
const hints = enrichResponse("stay_properties", "list", result.data);
|
|
127
|
+
return {
|
|
128
|
+
content: [listContent(formatPaginatedResponse("properties", result))],
|
|
129
|
+
structuredContent: { ...result, ...hints },
|
|
130
|
+
};
|
|
131
|
+
}));
|
|
132
|
+
// -- get_property --
|
|
133
|
+
server.registerTool("get_property", {
|
|
134
|
+
title: "Get Property (Stay)",
|
|
135
|
+
description: "Get full details of a Stay property by its ID. " +
|
|
136
|
+
"Returns address, capacity, license number, pricing, and active status. " +
|
|
137
|
+
"/ Obtiene los detalles completos de una propiedad de Stay por su ID. " +
|
|
138
|
+
"Devuelve direccion, capacidad, numero de licencia, precios y estado activo.",
|
|
139
|
+
annotations: READ_ONLY_ANNOTATIONS,
|
|
140
|
+
inputSchema: {
|
|
141
|
+
id: z.string().describe("Property ID / ID de la propiedad"),
|
|
142
|
+
},
|
|
143
|
+
outputSchema: propertyItemOutput,
|
|
144
|
+
}, async ({ id }) => withToolLogging("get_property", async () => {
|
|
145
|
+
const result = await client.getStayProperty(id);
|
|
146
|
+
return {
|
|
147
|
+
content: [getContent(formatRecord("Property", result))],
|
|
148
|
+
structuredContent: result,
|
|
149
|
+
};
|
|
150
|
+
}));
|
|
151
|
+
// -- list_reservations --
|
|
152
|
+
server.registerTool("list_reservations", {
|
|
153
|
+
title: "List Reservations (Stay)",
|
|
154
|
+
description: "List Stay reservations with optional filters by date range, property, status, or channel. " +
|
|
155
|
+
"Sorted by check-in date descending. " +
|
|
156
|
+
"Example: propertyId='abc', from='2026-06-01', to='2026-06-30', status='confirmed' " +
|
|
157
|
+
"/ Lista reservas de Stay con filtros opcionales por fecha, propiedad, estado o canal. " +
|
|
158
|
+
"Ordenadas por fecha de entrada descendente.",
|
|
159
|
+
annotations: READ_ONLY_ANNOTATIONS,
|
|
160
|
+
inputSchema: {
|
|
161
|
+
propertyId: z
|
|
162
|
+
.string()
|
|
163
|
+
.optional()
|
|
164
|
+
.describe("Filter by property ID / Filtrar por ID de propiedad"),
|
|
165
|
+
from: z
|
|
166
|
+
.string()
|
|
167
|
+
.optional()
|
|
168
|
+
.describe("Check-in on or after this date (YYYY-MM-DD) / Fecha de entrada desde"),
|
|
169
|
+
to: z
|
|
170
|
+
.string()
|
|
171
|
+
.optional()
|
|
172
|
+
.describe("Check-in on or before this date (YYYY-MM-DD) / Fecha de entrada hasta"),
|
|
173
|
+
status: z
|
|
174
|
+
.enum(["pending", "confirmed", "checked_in", "checked_out", "cancelled", "no_show"])
|
|
175
|
+
.optional()
|
|
176
|
+
.describe("Filter by reservation status / Filtrar por estado"),
|
|
177
|
+
channel: z
|
|
178
|
+
.string()
|
|
179
|
+
.optional()
|
|
180
|
+
.describe("Filter by channel (airbnb, booking, direct...) / Filtrar por canal"),
|
|
181
|
+
limit: z
|
|
182
|
+
.number().int().min(1).max(100)
|
|
183
|
+
.optional()
|
|
184
|
+
.describe("Max results per page (1-100) / Resultados por pagina"),
|
|
185
|
+
offset: z
|
|
186
|
+
.number().int().min(0)
|
|
187
|
+
.optional()
|
|
188
|
+
.describe("Number of results to skip / Resultados a saltar"),
|
|
189
|
+
after: z
|
|
190
|
+
.string()
|
|
191
|
+
.optional()
|
|
192
|
+
.describe("Cursor for cursor-based pagination / Cursor de paginacion"),
|
|
193
|
+
},
|
|
194
|
+
outputSchema: paginatedOutput(reservationItemOutput),
|
|
195
|
+
}, async ({ propertyId, from, to, status, channel, limit, offset, after }) => withToolLogging("list_reservations", async () => {
|
|
196
|
+
const result = await client.listStayReservations({ propertyId, from, to, status, channel, limit, offset, after });
|
|
197
|
+
const hints = enrichResponse("stay_reservations", "list", result.data);
|
|
198
|
+
return {
|
|
199
|
+
content: [listContent(formatPaginatedResponse("reservations", result))],
|
|
200
|
+
structuredContent: { ...result, ...hints },
|
|
201
|
+
};
|
|
202
|
+
}));
|
|
203
|
+
// -- get_reservation --
|
|
204
|
+
server.registerTool("get_reservation", {
|
|
205
|
+
title: "Get Reservation (Stay)",
|
|
206
|
+
description: "Get full details of a Stay reservation by its ID. " +
|
|
207
|
+
"Returns guest info, dates, amounts, channel, and status. " +
|
|
208
|
+
"/ Obtiene los detalles completos de una reserva de Stay por su ID. " +
|
|
209
|
+
"Devuelve datos del huesped, fechas, importes, canal y estado.",
|
|
210
|
+
annotations: READ_ONLY_ANNOTATIONS,
|
|
211
|
+
inputSchema: {
|
|
212
|
+
id: z.string().describe("Reservation ID / ID de la reserva"),
|
|
213
|
+
},
|
|
214
|
+
outputSchema: reservationItemOutput,
|
|
215
|
+
}, async ({ id }) => withToolLogging("get_reservation", async () => {
|
|
216
|
+
const result = await client.getStayReservation(id);
|
|
217
|
+
return {
|
|
218
|
+
content: [getContent(formatRecord("Reservation", result))],
|
|
219
|
+
structuredContent: result,
|
|
220
|
+
};
|
|
221
|
+
}));
|
|
222
|
+
// -- create_reservation --
|
|
223
|
+
server.registerTool("create_reservation", {
|
|
224
|
+
title: "Create Reservation (Stay)",
|
|
225
|
+
description: "Create a new Stay reservation. Requires property ID, guest name, check-in and check-out dates. " +
|
|
226
|
+
"Check-in and check-out must be in YYYY-MM-DD format, check-out after check-in. " +
|
|
227
|
+
"/ Crea una nueva reserva de Stay. Requiere ID de propiedad, nombre del huesped y fechas. " +
|
|
228
|
+
"Las fechas deben estar en formato YYYY-MM-DD, check-out despues de check-in.",
|
|
229
|
+
annotations: CREATE_ANNOTATIONS,
|
|
230
|
+
inputSchema: {
|
|
231
|
+
propertyId: z.string().describe("Property ID / ID de la propiedad"),
|
|
232
|
+
guestName: z.string().describe("Guest full name / Nombre completo del huesped"),
|
|
233
|
+
guestEmail: z.string().optional().describe("Guest email / Email del huesped"),
|
|
234
|
+
guestPhone: z.string().optional().describe("Guest phone / Telefono del huesped"),
|
|
235
|
+
checkIn: z.string().describe("Check-in date (YYYY-MM-DD) / Fecha de entrada"),
|
|
236
|
+
checkOut: z.string().describe("Check-out date (YYYY-MM-DD) / Fecha de salida"),
|
|
237
|
+
numGuests: z.number().int().min(1).optional().describe("Number of guests / Numero de huespedes"),
|
|
238
|
+
nightlyRate: z.number().optional().describe("Nightly rate in EUR / Precio por noche en EUR"),
|
|
239
|
+
totalAmount: z.number().optional().describe("Total amount in EUR (override auto-calc) / Importe total en EUR"),
|
|
240
|
+
channel: z.string().optional().describe("Booking channel (airbnb, booking, direct...) / Canal de reserva"),
|
|
241
|
+
status: z
|
|
242
|
+
.enum(["pending", "confirmed"])
|
|
243
|
+
.optional()
|
|
244
|
+
.describe("Initial status (default: confirmed) / Estado inicial"),
|
|
245
|
+
notes: z.string().optional().describe("Internal notes / Notas internas"),
|
|
246
|
+
},
|
|
247
|
+
outputSchema: reservationItemOutput,
|
|
248
|
+
}, async (input) => withToolLogging("create_reservation", async () => {
|
|
249
|
+
const result = await client.createStayReservation(input);
|
|
250
|
+
const hints = enrichResponse("stay_reservations", "create", result);
|
|
251
|
+
return {
|
|
252
|
+
content: [mutateContent(formatRecord("Reservation created", result))],
|
|
253
|
+
structuredContent: { ...result, ...hints },
|
|
254
|
+
};
|
|
255
|
+
}));
|
|
256
|
+
// -- update_reservation --
|
|
257
|
+
server.registerTool("update_reservation", {
|
|
258
|
+
title: "Update Reservation (Stay)",
|
|
259
|
+
description: "Update an existing Stay reservation using PATCH semantics. Only provided fields are changed. " +
|
|
260
|
+
"Use status='cancelled' to cancel a reservation, or update dates, guest info, or amounts. " +
|
|
261
|
+
"/ Actualiza una reserva de Stay existente. Solo se modifican los campos proporcionados. " +
|
|
262
|
+
"Usa status='cancelled' para cancelar una reserva.",
|
|
263
|
+
annotations: UPDATE_ANNOTATIONS,
|
|
264
|
+
inputSchema: {
|
|
265
|
+
id: z.string().describe("Reservation ID / ID de la reserva"),
|
|
266
|
+
guestName: z.string().optional().describe("Guest name / Nombre del huesped"),
|
|
267
|
+
guestEmail: z.string().optional().describe("Guest email / Email del huesped"),
|
|
268
|
+
guestPhone: z.string().optional().describe("Guest phone / Telefono del huesped"),
|
|
269
|
+
checkIn: z.string().optional().describe("Check-in date (YYYY-MM-DD) / Fecha de entrada"),
|
|
270
|
+
checkOut: z.string().optional().describe("Check-out date (YYYY-MM-DD) / Fecha de salida"),
|
|
271
|
+
numGuests: z.number().int().min(1).optional().describe("Number of guests / Numero de huespedes"),
|
|
272
|
+
nightlyRate: z.number().optional().describe("Nightly rate in EUR / Precio por noche"),
|
|
273
|
+
totalAmount: z.number().optional().describe("Total amount in EUR / Importe total"),
|
|
274
|
+
status: z
|
|
275
|
+
.enum(["pending", "confirmed", "checked_in", "checked_out", "cancelled", "no_show"])
|
|
276
|
+
.optional()
|
|
277
|
+
.describe("Reservation status / Estado de la reserva"),
|
|
278
|
+
notes: z.string().optional().describe("Internal notes / Notas internas"),
|
|
279
|
+
},
|
|
280
|
+
outputSchema: reservationItemOutput,
|
|
281
|
+
}, async ({ id, ...data }) => withToolLogging("update_reservation", async () => {
|
|
282
|
+
const result = await client.updateStayReservation(id, data);
|
|
283
|
+
const hints = enrichResponse("stay_reservations", "update", result);
|
|
284
|
+
return {
|
|
285
|
+
content: [mutateContent(formatRecord("Reservation updated", result))],
|
|
286
|
+
structuredContent: { ...result, ...hints },
|
|
287
|
+
};
|
|
288
|
+
}));
|
|
289
|
+
// -- list_cleaning_tasks --
|
|
290
|
+
server.registerTool("list_cleaning_tasks", {
|
|
291
|
+
title: "List Cleaning Tasks (Stay)",
|
|
292
|
+
description: "List cleaning tasks for Stay properties, optionally filtered by status or property. " +
|
|
293
|
+
"Useful for operations management and cleaning schedule overview. " +
|
|
294
|
+
"Statuses: pending, in_progress, done, skipped. " +
|
|
295
|
+
"/ Lista tareas de limpieza para propiedades de Stay, con filtro opcional por estado o propiedad. " +
|
|
296
|
+
"Estados: pending, in_progress, done, skipped.",
|
|
297
|
+
annotations: READ_ONLY_ANNOTATIONS,
|
|
298
|
+
inputSchema: {
|
|
299
|
+
status: z
|
|
300
|
+
.enum(["pending", "in_progress", "done", "skipped"])
|
|
301
|
+
.optional()
|
|
302
|
+
.describe("Filter by task status / Filtrar por estado de la tarea"),
|
|
303
|
+
propertyId: z
|
|
304
|
+
.string()
|
|
305
|
+
.optional()
|
|
306
|
+
.describe("Filter by property ID / Filtrar por ID de propiedad"),
|
|
307
|
+
from: z
|
|
308
|
+
.string()
|
|
309
|
+
.optional()
|
|
310
|
+
.describe("Scheduled on or after this date (YYYY-MM-DD) / Fecha programada desde"),
|
|
311
|
+
to: z
|
|
312
|
+
.string()
|
|
313
|
+
.optional()
|
|
314
|
+
.describe("Scheduled on or before this date (YYYY-MM-DD) / Fecha programada hasta"),
|
|
315
|
+
limit: z
|
|
316
|
+
.number().int().min(1).max(100)
|
|
317
|
+
.optional()
|
|
318
|
+
.describe("Max results per page / Resultados por pagina"),
|
|
319
|
+
offset: z
|
|
320
|
+
.number().int().min(0)
|
|
321
|
+
.optional()
|
|
322
|
+
.describe("Results to skip / Resultados a saltar"),
|
|
323
|
+
after: z
|
|
324
|
+
.string()
|
|
325
|
+
.optional()
|
|
326
|
+
.describe("Cursor for cursor-based pagination / Cursor de paginacion"),
|
|
327
|
+
},
|
|
328
|
+
outputSchema: paginatedOutput(cleaningTaskItemOutput),
|
|
329
|
+
}, async ({ status, propertyId, from, to, limit, offset, after }) => withToolLogging("list_cleaning_tasks", async () => {
|
|
330
|
+
const result = await client.listStayCleaningTasks({ status, propertyId, from, to, limit, offset, after });
|
|
331
|
+
return {
|
|
332
|
+
content: [listContent(formatPaginatedResponse("cleaning tasks", result))],
|
|
333
|
+
structuredContent: result,
|
|
334
|
+
};
|
|
335
|
+
}));
|
|
336
|
+
// -- get_occupancy_stats --
|
|
337
|
+
server.registerTool("get_occupancy_stats", {
|
|
338
|
+
title: "Get Occupancy Stats (Stay)",
|
|
339
|
+
description: "Get occupancy rate, total revenue, ADR (average daily rate), and RevPAR for a date range. " +
|
|
340
|
+
"Optionally filtered to a specific property. " +
|
|
341
|
+
"Returns per-property breakdown when propertyId is not specified. " +
|
|
342
|
+
"/ Obtiene tasa de ocupacion, ingresos totales, ADR y RevPAR para un rango de fechas. " +
|
|
343
|
+
"Filtro opcional por propiedad. Devuelve desglose por propiedad si no se especifica.",
|
|
344
|
+
annotations: READ_ONLY_ANNOTATIONS,
|
|
345
|
+
inputSchema: {
|
|
346
|
+
from: z.string().describe("Start date (YYYY-MM-DD) / Fecha de inicio"),
|
|
347
|
+
to: z.string().describe("End date (YYYY-MM-DD) / Fecha de fin"),
|
|
348
|
+
propertyId: z
|
|
349
|
+
.string()
|
|
350
|
+
.optional()
|
|
351
|
+
.describe("Limit to a specific property / Limitar a una propiedad especifica"),
|
|
352
|
+
},
|
|
353
|
+
outputSchema: occupancyStatsOutput,
|
|
354
|
+
}, async ({ from, to, propertyId }) => withToolLogging("get_occupancy_stats", async () => {
|
|
355
|
+
const result = await client.getStayOccupancyStats({ from, to, propertyId });
|
|
356
|
+
return {
|
|
357
|
+
content: [getContent(formatRecord("Occupancy stats", result))],
|
|
358
|
+
structuredContent: result,
|
|
359
|
+
};
|
|
360
|
+
}));
|
|
361
|
+
// -- sync_ical_channel --
|
|
362
|
+
server.registerTool("sync_ical_channel", {
|
|
363
|
+
title: "Sync iCal Channel (Stay)",
|
|
364
|
+
description: "Trigger an iCal feed sync for a property channel (Airbnb, Booking.com, etc.). " +
|
|
365
|
+
"The channel must already be configured in the property settings. " +
|
|
366
|
+
"Returns the result of the sync including new/updated/deleted reservations count. " +
|
|
367
|
+
"/ Dispara la sincronizacion del feed iCal para un canal de propiedad. " +
|
|
368
|
+
"El canal debe estar configurado en los ajustes de la propiedad. " +
|
|
369
|
+
"Devuelve el resultado incluyendo el numero de reservas nuevas/actualizadas/eliminadas.",
|
|
370
|
+
annotations: UPDATE_ANNOTATIONS,
|
|
371
|
+
inputSchema: {
|
|
372
|
+
propertyId: z.string().describe("Property ID / ID de la propiedad"),
|
|
373
|
+
channelId: z.string().describe("Channel ID to sync / ID del canal a sincronizar"),
|
|
374
|
+
},
|
|
375
|
+
outputSchema: actionResultOutput,
|
|
376
|
+
}, async ({ propertyId, channelId }) => withToolLogging("sync_ical_channel", async () => {
|
|
377
|
+
const result = await client.syncStayIcalChannel(propertyId, channelId);
|
|
378
|
+
return {
|
|
379
|
+
content: [mutateContent(formatRecord("iCal sync result", result))],
|
|
380
|
+
structuredContent: result,
|
|
381
|
+
};
|
|
382
|
+
}));
|
|
383
|
+
// -- get_compliance_status --
|
|
384
|
+
server.registerTool("get_compliance_status", {
|
|
385
|
+
title: "Get Guest Compliance Status (Stay)",
|
|
386
|
+
description: "Get an overview of guest compliance status across properties. " +
|
|
387
|
+
"Returns counts of verified, pending, and expired guest documents. " +
|
|
388
|
+
"Critical for Spanish STR legal compliance (SES.HOSPEDAJES / parte de viajeros). " +
|
|
389
|
+
"Optionally scope to a single property. " +
|
|
390
|
+
"/ Obtiene un resumen del estado de cumplimiento de huespedes en las propiedades. " +
|
|
391
|
+
"Devuelve conteos de documentos verificados, pendientes y caducados. " +
|
|
392
|
+
"Critico para cumplimiento legal STR espanol (SES.HOSPEDAJES / parte de viajeros).",
|
|
393
|
+
annotations: READ_ONLY_ANNOTATIONS,
|
|
394
|
+
inputSchema: {
|
|
395
|
+
propertyId: z
|
|
396
|
+
.string()
|
|
397
|
+
.optional()
|
|
398
|
+
.describe("Scope to a specific property / Limitar a una propiedad especifica"),
|
|
399
|
+
from: z
|
|
400
|
+
.string()
|
|
401
|
+
.optional()
|
|
402
|
+
.describe("Check-in on or after this date (YYYY-MM-DD) / Fecha de entrada desde"),
|
|
403
|
+
to: z
|
|
404
|
+
.string()
|
|
405
|
+
.optional()
|
|
406
|
+
.describe("Check-in on or before this date (YYYY-MM-DD) / Fecha de entrada hasta"),
|
|
407
|
+
},
|
|
408
|
+
outputSchema: complianceStatusOutput,
|
|
409
|
+
}, async ({ propertyId, from, to }) => withToolLogging("get_compliance_status", async () => {
|
|
410
|
+
const result = await client.getStayComplianceStatus({ propertyId, from, to });
|
|
411
|
+
const warnings = [];
|
|
412
|
+
const rec = result;
|
|
413
|
+
if (typeof rec.pending === "number" && rec.pending > 0) {
|
|
414
|
+
warnings.push(`${rec.pending} guest(s) with pending compliance documents — submit to SES.HOSPEDAJES before check-in`);
|
|
415
|
+
}
|
|
416
|
+
return {
|
|
417
|
+
content: [getContent(formatRecord("Compliance status", result))],
|
|
418
|
+
structuredContent: { ...result, ...(warnings.length > 0 ? { _warnings: warnings } : {}) },
|
|
419
|
+
};
|
|
420
|
+
}));
|
|
421
|
+
}
|
|
422
|
+
//# sourceMappingURL=stay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stay.js","sourceRoot":"","sources":["../../src/tools/stay.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@frihet/mcp-server",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.1",
|
|
4
4
|
"description": "AI-native MCP server for business management — invoices, expenses, deposits, clients, products, quotes, webhooks, CRM. 62 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",
|