@getcheddar/cheddar-mcp 2.0.0 → 2.0.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 CHANGED
@@ -5,20 +5,29 @@ Model Context Protocol server that calls the **legacy Cheddar merchant API** doc
5
5
  This package **does not** use `https://api.*` OAuth2 / Bearer REST.
6
6
 
7
7
  **Package:** `@getcheddar/cheddar-mcp`
8
- **Version:** 2.0.0
8
+ **Version:** 2.0.1
9
9
 
10
10
  ## Requirements
11
11
 
12
12
  - Node.js **18+**
13
- - A Cheddar **product site** base URL (same host you use for admin/checkout, e.g. `https://yoursubdomain.chargevault.com`)
13
+ - The **origin that serves legacy `/xml/…` routes** for your product (see [CHEDDAR_BASE_URL](#cheddar_base_url) below — it is **not** always the same host as hosted **ChargeVault** checkout pages).
14
14
  - **Product code** (`productCode` in URLs)
15
15
  - An **authorized user email** and **password** *or* the product **API key** (“secret key” from Configuration → Settings) as the Basic password ([auth docs](https://docs.getcheddar.com/#authentication))
16
16
 
17
+ ## CHEDDAR_BASE_URL
18
+
19
+ The MCP calls paths such as **`/xml/plans/get/productCode/{productCode}`** on whatever origin you set.
20
+
21
+ - **GetCheddar cloud** products often serve the legacy XML API from **`https://getcheddar.com`**, while **hosted signup / checkout** may live on **`https://{subdomain}.chargevault.com`**. Using only the ChargeVault host can return **404** for `/xml/…` because that host is for **hosted pages**, not the full legacy app.
22
+ - **Self-hosted** Cheddar may use your own domain (the same origin you use in the browser for product admin and legacy XML).
23
+
24
+ **How to verify:** with your credentials, `GET {CHEDDAR_BASE_URL}/xml/plans/get/productCode/{CHEDDAR_PRODUCT_CODE}` should return **200** and XML (or JSON if supported), not an HTML error page. On startup the server runs this check unless `CHEDDAR_SKIP_PREFLIGHT=1`.
25
+
17
26
  ## Environment variables
18
27
 
19
28
  | Variable | Required | Description |
20
29
  |----------|----------|-------------|
21
- | `CHEDDAR_BASE_URL` | **Yes** | Origin of your product app, no trailing slash (e.g. `https://cvences.chargevault.com`). |
30
+ | `CHEDDAR_BASE_URL` | **Yes** | Origin where **`/xml/…`** is available, no trailing slash (often `https://getcheddar.com` for cloud; use your real API host if self-hosted). |
22
31
  | `CHEDDAR_PRODUCT_CODE` | **Yes** | Your product’s `productCode` segment in legacy URLs. |
23
32
  | `CHEDDAR_USERNAME` | **Yes** | Email of an API-enabled user on that product. |
24
33
  | `CHEDDAR_PASSWORD` | One of | That user’s login password. |
@@ -34,12 +43,13 @@ npm run build
34
43
  ```
35
44
 
36
45
  ```bash
37
- export CHEDDAR_BASE_URL=https://your-product-host.example
46
+ export CHEDDAR_BASE_URL=https://getcheddar.com
38
47
  export CHEDDAR_PRODUCT_CODE=YOUR_PRODUCT_CODE
39
48
  export CHEDDAR_USERNAME=api-user@example.com
40
49
  export CHEDDAR_PRODUCT_API_KEY=your_secret_key
41
50
 
42
- node dist/index.js
51
+ npm run start
52
+ # or: node dist/index.js
43
53
  ```
44
54
 
45
55
  Or with `npx` after publish:
@@ -62,14 +72,16 @@ Responses are returned as **JSON text**: XML from the API is parsed to a plain o
62
72
 
63
73
  ## Claude Desktop example
64
74
 
75
+ **Recommended:** `npx` (no local build path):
76
+
65
77
  ```json
66
78
  {
67
79
  "mcpServers": {
68
80
  "cheddar": {
69
- "command": "node",
70
- "args": ["/absolute/path/to/cheddar-mcp/dist/index.js"],
81
+ "command": "npx",
82
+ "args": ["-y", "@getcheddar/cheddar-mcp"],
71
83
  "env": {
72
- "CHEDDAR_BASE_URL": "https://your-product-host.example",
84
+ "CHEDDAR_BASE_URL": "https://getcheddar.com",
73
85
  "CHEDDAR_PRODUCT_CODE": "YOUR_PRODUCT_CODE",
74
86
  "CHEDDAR_USERNAME": "api-user@example.com",
75
87
  "CHEDDAR_PRODUCT_API_KEY": "your_secret_key"
@@ -79,6 +91,8 @@ Responses are returned as **JSON text**: XML from the API is parsed to a plain o
79
91
  }
80
92
  ```
81
93
 
94
+ **Local dev:** point `command` / `args` at `node` and `./dist/index.js` (or `bin/cheddar-mcp.mjs`) under this package after `npm run build`.
95
+
82
96
  ## Development
83
97
 
84
98
  ```bash
package/dist/core.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
+ import { LegacyCheddarClient } from "./lib/legacy-client.js";
3
+ /** Keep in sync with package.json version. */
4
+ export declare const MCP_PACKAGE_VERSION = "2.0.1";
5
+ export type CheddarEnv = {
6
+ baseUrl: string;
7
+ productCode: string;
8
+ username: string;
9
+ password: string;
10
+ };
11
+ export declare function loadCheddarEnv(): CheddarEnv;
12
+ export declare function createCheddarMcpServer(version: string): {
13
+ server: Server;
14
+ client: LegacyCheddarClient;
15
+ };
16
+ export declare function runPreflight(client: LegacyCheddarClient): Promise<void>;
17
+ //# sourceMappingURL=core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAMnE,OAAO,EAAkB,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAI7E,8CAA8C;AAC9C,eAAO,MAAM,mBAAmB,UAAU,CAAC;AAE3C,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,wBAAgB,cAAc,IAAI,UAAU,CAc3C;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG;IACvD,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,mBAAmB,CAAC;CAC7B,CAiEA;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAK7E"}
package/dist/core.js ADDED
@@ -0,0 +1,79 @@
1
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
3
+ import { LegacyApiError, LegacyCheddarClient } from "./lib/legacy-client.js";
4
+ import { customerTools, handleCustomerTool } from "./tools/customers.js";
5
+ import { planTools, handlePlanTool } from "./tools/plans.js";
6
+ /** Keep in sync with package.json version. */
7
+ export const MCP_PACKAGE_VERSION = "2.0.1";
8
+ export function loadCheddarEnv() {
9
+ const baseUrl = (process.env.CHEDDAR_BASE_URL || "").replace(/\/+$/, "");
10
+ const productCode = process.env.CHEDDAR_PRODUCT_CODE || "";
11
+ const username = process.env.CHEDDAR_USERNAME || "";
12
+ const password = process.env.CHEDDAR_PASSWORD || process.env.CHEDDAR_PRODUCT_API_KEY || "";
13
+ if (!baseUrl || !productCode || !username || !password) {
14
+ throw new Error("Missing config. Set CHEDDAR_BASE_URL, CHEDDAR_PRODUCT_CODE, CHEDDAR_USERNAME, and CHEDDAR_PASSWORD or CHEDDAR_PRODUCT_API_KEY.");
15
+ }
16
+ return { baseUrl, productCode, username, password };
17
+ }
18
+ export function createCheddarMcpServer(version) {
19
+ const { baseUrl, productCode, username, password } = loadCheddarEnv();
20
+ const client = new LegacyCheddarClient({
21
+ baseUrl,
22
+ productCode,
23
+ username,
24
+ password,
25
+ });
26
+ const ALL_TOOLS = [...customerTools, ...planTools];
27
+ const server = new Server({
28
+ name: "cheddar-mcp",
29
+ version,
30
+ }, {
31
+ capabilities: {
32
+ tools: {},
33
+ },
34
+ });
35
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: ALL_TOOLS }));
36
+ function toolErrorMessage(error) {
37
+ if (error instanceof LegacyApiError) {
38
+ return `Cheddar API error (HTTP ${error.status}). See server logs for details.`;
39
+ }
40
+ if (error instanceof Error) {
41
+ return error.message;
42
+ }
43
+ return String(error);
44
+ }
45
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
46
+ const { name, arguments: args } = request.params;
47
+ try {
48
+ if (name.startsWith("cheddar_customer")) {
49
+ return await handleCustomerTool(client, name, args);
50
+ }
51
+ if (name.startsWith("cheddar_plans_")) {
52
+ return await handlePlanTool(client, name, args);
53
+ }
54
+ throw new Error(`Unknown tool: ${name}`);
55
+ }
56
+ catch (error) {
57
+ if (error instanceof LegacyApiError) {
58
+ console.error("[cheddar-mcp] LegacyApiError body:", typeof error.body === "string"
59
+ ? error.body.slice(0, 4000)
60
+ : JSON.stringify(error.body).slice(0, 4000));
61
+ }
62
+ else {
63
+ console.error("[cheddar-mcp] Tool error:", error);
64
+ }
65
+ return {
66
+ content: [{ type: "text", text: `Error: ${toolErrorMessage(error)}` }],
67
+ isError: true,
68
+ };
69
+ }
70
+ });
71
+ return { server, client };
72
+ }
73
+ export async function runPreflight(client) {
74
+ if (process.env.CHEDDAR_SKIP_PREFLIGHT) {
75
+ return;
76
+ }
77
+ await client.ping();
78
+ }
79
+ //# sourceMappingURL=core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"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"}
package/dist/http.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ /**
2
+ * MCP over Streamable HTTP + ALB-friendly GET /health (plain 200).
3
+ * Bind with MCP_ALLOWED_HOSTS (comma-separated hostnames) when not using 0.0.0.0 DNS-rebinding defaults.
4
+ */
5
+ import "dotenv/config";
6
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,eAAe,CAAC"}
package/dist/http.js ADDED
@@ -0,0 +1,65 @@
1
+ /**
2
+ * MCP over Streamable HTTP + ALB-friendly GET /health (plain 200).
3
+ * Bind with MCP_ALLOWED_HOSTS (comma-separated hostnames) when not using 0.0.0.0 DNS-rebinding defaults.
4
+ */
5
+ import "dotenv/config";
6
+ import { createMcpExpressApp } from "@modelcontextprotocol/sdk/server/express.js";
7
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
8
+ import { LegacyApiError } from "./lib/legacy-client.js";
9
+ import { createCheddarMcpServer, MCP_PACKAGE_VERSION, runPreflight, } from "./core.js";
10
+ const MCP_PATH = (process.env.MCP_HTTP_PATH || "/mcp").replace(/\/+$/, "") || "/mcp";
11
+ function parseAllowedHosts() {
12
+ const raw = process.env.MCP_ALLOWED_HOSTS?.trim();
13
+ if (!raw) {
14
+ return undefined;
15
+ }
16
+ return raw.split(",").map((h) => h.trim()).filter(Boolean);
17
+ }
18
+ async function main() {
19
+ let server;
20
+ let client;
21
+ try {
22
+ ({ server, client } = createCheddarMcpServer(MCP_PACKAGE_VERSION));
23
+ }
24
+ catch (e) {
25
+ console.error(e instanceof Error ? e.message : String(e));
26
+ process.exit(1);
27
+ }
28
+ try {
29
+ await runPreflight(client);
30
+ }
31
+ catch (err) {
32
+ const msg = err instanceof Error ? err.message : String(err);
33
+ console.error(`Cheddar legacy API preflight failed: ${msg}`);
34
+ if (err instanceof LegacyApiError) {
35
+ console.error("[cheddar-mcp] Preflight response body:", typeof err.body === "string"
36
+ ? err.body.slice(0, 4000)
37
+ : JSON.stringify(err.body).slice(0, 4000));
38
+ }
39
+ process.exit(1);
40
+ }
41
+ const allowedHosts = parseAllowedHosts();
42
+ const app = createMcpExpressApp(allowedHosts
43
+ ? { host: "0.0.0.0", allowedHosts }
44
+ : { host: "0.0.0.0" });
45
+ app.get("/health", (_req, res) => {
46
+ res.status(200).type("text/plain").send("ok");
47
+ });
48
+ const transport = new StreamableHTTPServerTransport({
49
+ sessionIdGenerator: undefined,
50
+ });
51
+ await server.connect(transport);
52
+ app.all(MCP_PATH, async (req, res) => {
53
+ await transport.handleRequest(req, res, req.body);
54
+ });
55
+ const port = Number(process.env.PORT || 3000);
56
+ const listenHost = process.env.MCP_HTTP_HOST || "0.0.0.0";
57
+ app.listen(port, listenHost, () => {
58
+ console.error(`Cheddar MCP Streamable HTTP on http://${listenHost}:${port}${MCP_PATH} (health: GET /health)`);
59
+ });
60
+ }
61
+ main().catch((error) => {
62
+ console.error("Fatal error:", error);
63
+ process.exit(1);
64
+ });
65
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,82 +1,29 @@
1
1
  import "dotenv/config";
2
- import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
2
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
- import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
5
- import { LegacyApiError, LegacyCheddarClient } from "./lib/legacy-client.js";
6
- import { customerTools, handleCustomerTool } from "./tools/customers.js";
7
- import { planTools, handlePlanTool } from "./tools/plans.js";
8
- const baseUrl = (process.env.CHEDDAR_BASE_URL || "").replace(/\/+$/, "");
9
- const productCode = process.env.CHEDDAR_PRODUCT_CODE || "";
10
- const username = process.env.CHEDDAR_USERNAME || "";
11
- const password = process.env.CHEDDAR_PASSWORD || process.env.CHEDDAR_PRODUCT_API_KEY || "";
12
- if (!baseUrl || !productCode || !username || !password) {
13
- console.error("Missing config. Set CHEDDAR_BASE_URL, CHEDDAR_PRODUCT_CODE, CHEDDAR_USERNAME, and CHEDDAR_PASSWORD or CHEDDAR_PRODUCT_API_KEY.");
14
- process.exit(1);
15
- }
16
- const client = new LegacyCheddarClient({
17
- baseUrl,
18
- productCode,
19
- username,
20
- password,
21
- });
22
- const ALL_TOOLS = [...customerTools, ...planTools];
23
- const server = new Server({
24
- name: "cheddar-mcp",
25
- version: "2.0.0",
26
- }, {
27
- capabilities: {
28
- tools: {},
29
- },
30
- });
31
- server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: ALL_TOOLS }));
32
- function toolErrorMessage(error) {
33
- if (error instanceof LegacyApiError) {
34
- return `Cheddar API error (HTTP ${error.status}). See server logs for details.`;
3
+ import { LegacyApiError } from "./lib/legacy-client.js";
4
+ import { createCheddarMcpServer, MCP_PACKAGE_VERSION, runPreflight, } from "./core.js";
5
+ async function main() {
6
+ let server;
7
+ let client;
8
+ try {
9
+ ({ server, client } = createCheddarMcpServer(MCP_PACKAGE_VERSION));
35
10
  }
36
- if (error instanceof Error) {
37
- return error.message;
11
+ catch (e) {
12
+ console.error(e instanceof Error ? e.message : String(e));
13
+ process.exit(1);
38
14
  }
39
- return String(error);
40
- }
41
- server.setRequestHandler(CallToolRequestSchema, async (request) => {
42
- const { name, arguments: args } = request.params;
43
15
  try {
44
- if (name.startsWith("cheddar_customer")) {
45
- return await handleCustomerTool(client, name, args);
46
- }
47
- if (name.startsWith("cheddar_plans_")) {
48
- return await handlePlanTool(client, name, args);
49
- }
50
- throw new Error(`Unknown tool: ${name}`);
51
- }
52
- catch (error) {
53
- if (error instanceof LegacyApiError) {
54
- console.error("[cheddar-mcp] LegacyApiError body:", typeof error.body === "string" ? error.body.slice(0, 4000) : JSON.stringify(error.body).slice(0, 4000));
55
- }
56
- else {
57
- console.error("[cheddar-mcp] Tool error:", error);
58
- }
59
- return {
60
- content: [{ type: "text", text: `Error: ${toolErrorMessage(error)}` }],
61
- isError: true,
62
- };
16
+ await runPreflight(client);
63
17
  }
64
- });
65
- async function main() {
66
- if (!process.env.CHEDDAR_SKIP_PREFLIGHT) {
67
- try {
68
- await client.ping();
69
- }
70
- catch (err) {
71
- const msg = err instanceof Error ? err.message : String(err);
72
- console.error(`Cheddar legacy API preflight failed: ${msg}`);
73
- if (err instanceof LegacyApiError) {
74
- console.error("[cheddar-mcp] Preflight response body:", typeof err.body === "string"
75
- ? err.body.slice(0, 4000)
76
- : JSON.stringify(err.body).slice(0, 4000));
77
- }
78
- process.exit(1);
18
+ catch (err) {
19
+ const msg = err instanceof Error ? err.message : String(err);
20
+ console.error(`Cheddar legacy API preflight failed: ${msg}`);
21
+ if (err instanceof LegacyApiError) {
22
+ console.error("[cheddar-mcp] Preflight response body:", typeof err.body === "string"
23
+ ? err.body.slice(0, 4000)
24
+ : JSON.stringify(err.body).slice(0, 4000));
79
25
  }
26
+ process.exit(1);
80
27
  }
81
28
  const transport = new StdioServerTransport();
82
29
  await server.connect(transport);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAC;AACvB,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EACL,sBAAsB,EACtB,mBAAmB,EACnB,YAAY,GACb,MAAM,WAAW,CAAC;AAEnB,KAAK,UAAU,IAAI;IACjB,IAAI,MAAM,CAAC;IACX,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,sBAAsB,CAAC,mBAAmB,CAAC,CAAC,CAAC;IACrE,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,OAAO,CAAC,KAAK,CAAC,wCAAwC,GAAG,EAAE,CAAC,CAAC;QAC7D,IAAI,GAAG,YAAY,cAAc,EAAE,CAAC;YAClC,OAAO,CAAC,KAAK,CACX,wCAAwC,EACxC,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ;gBAC1B,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;gBACzB,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAC5C,CAAC;QACJ,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;AACpE,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getcheddar/cheddar-mcp",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "Model Context Protocol server for Cheddar Payment Platform integration",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -21,6 +21,7 @@
21
21
  "build": "tsc",
22
22
  "dev": "tsc --watch",
23
23
  "start": "node dist/index.js",
24
+ "start:http": "node dist/http.js",
24
25
  "test": "vitest",
25
26
  "lint": "eslint src/**/*.ts",
26
27
  "format": "prettier --write src/**/*.ts"
@@ -44,6 +45,7 @@
44
45
  "fast-xml-parser": "^4.5.0"
45
46
  },
46
47
  "devDependencies": {
48
+ "@types/express": "^5.0.6",
47
49
  "@types/node": "^20.10.0",
48
50
  "eslint": "^8.55.0",
49
51
  "prettier": "^3.1.0",