mcp-prqx-pricer 1.0.12 → 1.0.14
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 +3 -0
- package/build/index.js +16 -14
- package/build/tools/createPricingGroup.js +39 -21
- package/build/tools/deletePricingGroups.js +11 -11
- package/build/tools/updatePricingGroup.js +194 -0
- package/package.json +1 -1
- package/prompts/mcp-n8n-4.1-instructions.md +37 -0
- package/prompts/mcp-n8n-4.1-instructions.xml +20 -0
- package/src/index.ts +74 -62
- package/src/tools/createPricingGroup.ts +43 -22
- package/src/tools/deletePricingGroups.ts +44 -30
- package/src/tools/updatePricingGroup.ts +255 -0
- package/src/types/pricingGroup.ts +78 -1
- package/openapi/pricer.json +0 -7208
package/README.md
ADDED
package/build/index.js
CHANGED
@@ -13,25 +13,26 @@ const getProductionInventory_1 = require("./tools/getProductionInventory");
|
|
13
13
|
const getPricingGroups_1 = require("./tools/getPricingGroups");
|
14
14
|
const createPricingGroup_1 = require("./tools/createPricingGroup");
|
15
15
|
const deletePricingGroups_1 = require("./tools/deletePricingGroups");
|
16
|
+
const updatePricingGroup_1 = require("./tools/updatePricingGroup");
|
16
17
|
class PrqxMcpServer {
|
17
18
|
server;
|
18
19
|
axiosInstance;
|
19
20
|
tools = [];
|
20
21
|
constructor() {
|
21
|
-
console.error(
|
22
|
+
console.error("[Setup] Initializing MCP server...");
|
22
23
|
this.server = new index_js_1.Server({
|
23
|
-
name:
|
24
|
-
version:
|
24
|
+
name: "PrqxMcpServer",
|
25
|
+
version: "1.0.0",
|
25
26
|
}, {
|
26
27
|
capabilities: {
|
27
|
-
tools: {}
|
28
|
-
}
|
28
|
+
tools: {},
|
29
|
+
},
|
29
30
|
});
|
30
31
|
this.axiosInstance = axios_1.default.create({
|
31
|
-
baseURL:
|
32
|
+
baseURL: "https://pricer-svc.dev.pricerqx.com/",
|
32
33
|
headers: {
|
33
|
-
|
34
|
-
|
34
|
+
"Content-Type": "application/json",
|
35
|
+
Authorization: "Bearer " + process.env.TOKEN,
|
35
36
|
},
|
36
37
|
});
|
37
38
|
this.tools.push(new getProductions_1.GetProductionsTool());
|
@@ -39,22 +40,23 @@ class PrqxMcpServer {
|
|
39
40
|
this.tools.push(new getPricingGroups_1.GetPricingGroupsTool());
|
40
41
|
this.tools.push(new createPricingGroup_1.CreatePricingGroupTool());
|
41
42
|
this.tools.push(new deletePricingGroups_1.DeletePricingGroupsTool());
|
43
|
+
this.tools.push(new updatePricingGroup_1.UpdatePricingGroupTool());
|
42
44
|
this.setupToolHandlers();
|
43
45
|
this.server.onerror = (error) => {
|
44
|
-
console.error(
|
46
|
+
console.error("[Error] MCP server error:", error);
|
45
47
|
};
|
46
|
-
process.on(
|
47
|
-
console.error(
|
48
|
+
process.on("SIGINT", async () => {
|
49
|
+
console.error("[Info] MCP server shutting down...");
|
48
50
|
await this.server.close();
|
49
51
|
process.exit(0);
|
50
52
|
});
|
51
53
|
}
|
52
54
|
setupToolHandlers() {
|
53
55
|
this.server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({
|
54
|
-
tools: this.tools
|
56
|
+
tools: this.tools,
|
55
57
|
}));
|
56
58
|
this.server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
57
|
-
const tool = this.tools.find(tool => tool.name === request.params.name);
|
59
|
+
const tool = this.tools.find((tool) => tool.name === request.params.name);
|
58
60
|
if (!tool) {
|
59
61
|
throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, `Tool name ${request.params.name} is not supported`);
|
60
62
|
}
|
@@ -64,7 +66,7 @@ class PrqxMcpServer {
|
|
64
66
|
async run() {
|
65
67
|
const transport = new stdio_js_1.StdioServerTransport();
|
66
68
|
await this.server.connect(transport);
|
67
|
-
console.error(
|
69
|
+
console.error("[Info] MCP server started !!");
|
68
70
|
}
|
69
71
|
}
|
70
72
|
new PrqxMcpServer().run();
|
@@ -104,28 +104,34 @@ class CreatePricingGroupTool {
|
|
104
104
|
if (!request?.params?.arguments) {
|
105
105
|
throw new Error('Missing arguments');
|
106
106
|
}
|
107
|
+
const pricingGroupRequestRanks = request.params.arguments.pricingGroupRequestRanks;
|
108
|
+
const anchorTicketGroupId = pricingGroupRequestRanks.find(rank => rank.rank === 0)?.ticketGroupId;
|
109
|
+
if (!anchorTicketGroupId) {
|
110
|
+
throw new Error('Anchor ticket group ID is required');
|
111
|
+
}
|
112
|
+
const defaultsResponse = await httpClient.get('/v1/client/org-defaults/calculate-defaults/' + anchorTicketGroupId);
|
113
|
+
const defaults = defaultsResponse.data;
|
107
114
|
const productionId = request.params.arguments.productionId;
|
108
115
|
const name = request.params.arguments.name;
|
109
|
-
const ceilingPrice = request.params.arguments.ceilingPrice;
|
110
|
-
const floorPrice = request.params.arguments.floorPrice;
|
116
|
+
const ceilingPrice = request.params.arguments.ceilingPrice ?? defaults.ruleSet.ceiling;
|
117
|
+
const floorPrice = request.params.arguments.floorPrice ?? defaults.ruleSet.floor;
|
111
118
|
const pricingGroupRequestType = request.params.arguments.pricingGroupMode;
|
112
|
-
const amount = request.params.arguments.amount;
|
113
|
-
const increment = request.params.arguments.increment;
|
114
|
-
const incrementMethod = request.params.arguments.incrementMethod;
|
115
|
-
const offsetAmount = request.params.arguments.offsetAmount;
|
116
|
-
const offsetIncrement = request.params.arguments.offsetIncrement;
|
117
|
-
const offsetIncrementMethod = request.params.arguments.offsetIncrementMethod;
|
118
|
-
const enableShareOptions = request.params.arguments.enableShareOptions;
|
119
|
-
const shareOptionsType = request.params.arguments.shareOptionsType;
|
120
|
-
const shareAnchor = request.params.arguments.shareAnchor;
|
121
|
-
const customSharingAmount = request.params.arguments.customSharingAmount;
|
122
|
-
const customSharingMethod = request.params.arguments.customSharingMethod;
|
123
|
-
const applyCeilingOnlyToAnchor = request.params.arguments.applyCeilingOnlyToAnchor;
|
124
|
-
const applyFloorOnlyToAnchor = request.params.arguments.applyFloorOnlyToAnchor;
|
125
|
-
const floorPricingMethod = request.params.arguments.floorPricingMethod;
|
126
|
-
const ceilingPricingMethod = request.params.arguments.ceilingPricingMethod;
|
127
|
-
const noCompPricingMethod = request.params.arguments.noCompPricingMethod;
|
128
|
-
const pricingGroupRequestRanks = request.params.arguments.pricingGroupRequestRanks;
|
119
|
+
const amount = request.params.arguments.amount ?? defaults.ruleSet.amount;
|
120
|
+
const increment = request.params.arguments.increment ?? defaults.ruleSet.increment;
|
121
|
+
const incrementMethod = request.params.arguments.incrementMethod ?? defaults.ruleSet.incrementMethod;
|
122
|
+
const offsetAmount = request.params.arguments.offsetAmount ?? defaults.ruleSet.offsetAmount;
|
123
|
+
const offsetIncrement = request.params.arguments.offsetIncrement ?? defaults.ruleSet.offsetIncrement;
|
124
|
+
const offsetIncrementMethod = request.params.arguments.offsetIncrementMethod ?? defaults.ruleSet.offsetIncrementMethod;
|
125
|
+
const enableShareOptions = request.params.arguments.enableShareOptions ?? defaults.ruleSet.enableShareOptions;
|
126
|
+
const shareOptionsType = request.params.arguments.shareOptionsType ?? defaults.ruleSet.shareOptionsType;
|
127
|
+
const shareAnchor = request.params.arguments.shareAnchor ?? defaults.ruleSet.shareAnchor;
|
128
|
+
const customSharingAmount = request.params.arguments.customSharingAmount ?? defaults.ruleSet.customSharingAmount;
|
129
|
+
const customSharingMethod = request.params.arguments.customSharingMethod ?? defaults.ruleSet.customSharingMethod;
|
130
|
+
const applyCeilingOnlyToAnchor = request.params.arguments.applyCeilingOnlyToAnchor ?? defaults.ruleSet.applyCeilingOnlyToAnchor;
|
131
|
+
const applyFloorOnlyToAnchor = request.params.arguments.applyFloorOnlyToAnchor ?? defaults.ruleSet.applyFloorOnlyToAnchor;
|
132
|
+
const floorPricingMethod = request.params.arguments.floorPricingMethod ?? defaults.ruleSet.floorPricingMethod;
|
133
|
+
const ceilingPricingMethod = request.params.arguments.ceilingPricingMethod ?? defaults.ruleSet.ceilingPricingMethod;
|
134
|
+
const noCompPricingMethod = request.params.arguments.noCompPricingMethod ?? defaults.ruleSet.noCompPricingMethod;
|
129
135
|
const args = {
|
130
136
|
productionId: productionId,
|
131
137
|
name: name,
|
@@ -150,13 +156,25 @@ class CreatePricingGroupTool {
|
|
150
156
|
ceilingPricingMethod: ceilingPricingMethod,
|
151
157
|
noCompPricingMethod: noCompPricingMethod
|
152
158
|
},
|
153
|
-
marketGroupCriteria: {
|
159
|
+
marketGroupCriteria: {
|
160
|
+
sections: defaults?.marketGroupCriteria?.sections ?? [],
|
161
|
+
validSplitsIncludeV2: defaults?.marketGroupCriteria?.validSplitsIncludeV2,
|
162
|
+
validSplitsIncludeMax: defaults?.marketGroupCriteria?.validSplitsIncludeMax,
|
163
|
+
deliveryMethodInclude: defaults?.marketGroupCriteria?.deliveryMethodInclude,
|
164
|
+
attributesExclude: defaults?.marketGroupCriteria?.attributesExclude,
|
165
|
+
lowerOutlierMethod: defaults?.marketGroupCriteria?.lowerOutlierMethod,
|
166
|
+
lowerOutlierAmount: defaults?.marketGroupCriteria?.lowerOutlierAmount,
|
167
|
+
lowerOutlierThreshold: defaults?.marketGroupCriteria?.lowerOutlierThreshold,
|
168
|
+
includeSpeculativeTickets: defaults?.marketGroupCriteria?.includeSpeculativeTickets,
|
169
|
+
isSplitsDynamic: defaults?.marketGroupCriteria?.isSplitsDynamic,
|
170
|
+
rowRanges: defaults?.marketGroupCriteria?.rowRanges
|
171
|
+
},
|
154
172
|
pricingGroupRequestRanks: pricingGroupRequestRanks
|
155
173
|
};
|
156
174
|
console.error('[API] Create Pricing Group with arguments:', args);
|
157
175
|
const response = await httpClient.post(`/v2/client/pricing-group`, args);
|
158
176
|
if (response.status !== 200) {
|
159
|
-
throw new Error(
|
177
|
+
throw new Error("API error: " + response.statusText);
|
160
178
|
}
|
161
179
|
return { content: [{ type: 'text', text: JSON.stringify([response.data]) }] };
|
162
180
|
}
|
@@ -3,31 +3,31 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DeletePricingGroupsTool = void 0;
|
4
4
|
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
5
5
|
class DeletePricingGroupsTool {
|
6
|
-
name =
|
7
|
-
description =
|
6
|
+
name = "DeletePricingGroups";
|
7
|
+
description = "Delete multiple pricing groups in bulk";
|
8
8
|
inputSchema = {
|
9
|
-
type:
|
9
|
+
type: "object",
|
10
10
|
properties: {
|
11
11
|
pricingGroupIds: {
|
12
|
-
type:
|
13
|
-
description:
|
14
|
-
}
|
12
|
+
type: "array",
|
13
|
+
description: "Array of IDs (numbers) of the pricing groups that will be deleted. They can belong to multiple productions.",
|
14
|
+
},
|
15
15
|
},
|
16
|
-
required: [
|
16
|
+
required: ["pricingGroupIds"],
|
17
17
|
};
|
18
18
|
async toolHandler(request, axiosInstance) {
|
19
19
|
try {
|
20
20
|
const args = request.params.arguments;
|
21
21
|
if (!args) {
|
22
|
-
throw new Error(
|
22
|
+
throw new Error("Missing argument pricingGroupIds");
|
23
23
|
}
|
24
|
-
console.error(
|
24
|
+
console.error("[API] Delete Pricing Group with arguments:", args);
|
25
25
|
const response = await axiosInstance.delete(`/v2/client/pricing-group/bulk`, { data: args });
|
26
|
-
return { content: [{ type:
|
26
|
+
return { content: [{ type: "text", text: "Operation Completed!" }] };
|
27
27
|
}
|
28
28
|
catch (error) {
|
29
29
|
if (error instanceof Error) {
|
30
|
-
console.error(
|
30
|
+
console.error("Error in Delete Pricing Groups:", error);
|
31
31
|
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to delete pricing groups: ${error.message}`);
|
32
32
|
}
|
33
33
|
throw error;
|
@@ -0,0 +1,194 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.UpdatePricingGroupTool = void 0;
|
4
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
5
|
+
const pricingGroup_1 = require("../types/pricingGroup");
|
6
|
+
class UpdatePricingGroupTool {
|
7
|
+
name = "UpdatePricingGroup";
|
8
|
+
description = "Allows to update any individual property of an existing pricing group";
|
9
|
+
inputSchema = {
|
10
|
+
type: "object",
|
11
|
+
properties: {
|
12
|
+
pricingGroupId: {
|
13
|
+
type: "number",
|
14
|
+
description: "ID of the pricing group to modify",
|
15
|
+
},
|
16
|
+
name: {
|
17
|
+
type: "string",
|
18
|
+
description: "Name of the pricing group",
|
19
|
+
},
|
20
|
+
ceilingPrice: {
|
21
|
+
type: "number",
|
22
|
+
description: "Maximum price that the pricing group tickets can have",
|
23
|
+
},
|
24
|
+
floorPrice: {
|
25
|
+
type: "number",
|
26
|
+
description: "Minimum price that the pricing group tickets can have",
|
27
|
+
},
|
28
|
+
pricingGroupMode: {
|
29
|
+
type: "string",
|
30
|
+
description: "(AutoPrice or SimulationOnly) Mode of the pricing group",
|
31
|
+
},
|
32
|
+
amount: {
|
33
|
+
type: "number",
|
34
|
+
description: "Amount used to price the anchor ticket of the pricing group based on the first market comparable",
|
35
|
+
},
|
36
|
+
increment: {
|
37
|
+
type: "string",
|
38
|
+
description: "(increase or decrease) Decides if the amount is applied to increase or decrease the price of the anchor ticket of the pricing group based on the first market comparable",
|
39
|
+
},
|
40
|
+
incrementMethod: {
|
41
|
+
type: "string",
|
42
|
+
description: "( % or $ ) Decides if the amount is applied as a percentage or a dollar amount",
|
43
|
+
},
|
44
|
+
offsetAmount: {
|
45
|
+
type: "number",
|
46
|
+
description: "Offset amount used to price the other tickets in the group based of the previously ranked ticket",
|
47
|
+
},
|
48
|
+
offsetIncrement: {
|
49
|
+
type: "string",
|
50
|
+
description: "(increase or decrease) Decides if the offset amount is applied to increase or decrease the price of the other tickets in the group based of the previously ranked ticket",
|
51
|
+
},
|
52
|
+
offsetIncrementMethod: {
|
53
|
+
type: "string",
|
54
|
+
description: "( % or $ ) Decides if the offset amount is applied as a percentage or a dollar amount",
|
55
|
+
},
|
56
|
+
enableShareOptions: {
|
57
|
+
type: "boolean",
|
58
|
+
description: "Decides if the pricing group will control the sharing of tickets in a marketplace or not",
|
59
|
+
},
|
60
|
+
shareOptionsType: {
|
61
|
+
type: "string",
|
62
|
+
description: "(all or custom) Decides if we use custom parameters to share the tickets in the group or if we share them all. Default all.",
|
63
|
+
},
|
64
|
+
shareAnchor: {
|
65
|
+
type: "boolean",
|
66
|
+
description: "Controls if the anchor ticket of the pricing group will be shared or not",
|
67
|
+
},
|
68
|
+
customSharingAmount: {
|
69
|
+
type: "number",
|
70
|
+
description: "Custom sharing amount use to determine which tickets to share of this pricing group",
|
71
|
+
},
|
72
|
+
customSharingMethod: {
|
73
|
+
type: "string",
|
74
|
+
description: "( $ or % ) Decides if the custom sharing amount is applied as a percentage or a dollar amount.",
|
75
|
+
},
|
76
|
+
applyCeilingOnlyToAnchor: {
|
77
|
+
type: "boolean",
|
78
|
+
description: "Decides if the ceiling price will be applied only to the anchor ticket of the pricing group",
|
79
|
+
},
|
80
|
+
applyFloorOnlyToAnchor: {
|
81
|
+
type: "boolean",
|
82
|
+
description: "Decides if the floor price will be applied only to the anchor ticket of the pricing group",
|
83
|
+
},
|
84
|
+
floorPricingMethod: {
|
85
|
+
type: "string",
|
86
|
+
description: "(standard, variable, useFloor or floorRandomize) Decides what method to apply for pricing when the market comparable for the pricing group hits the floor price",
|
87
|
+
},
|
88
|
+
ceilingPricingMethod: {
|
89
|
+
type: "string",
|
90
|
+
description: "(standard, variable, useCeiling or ceilingRandomize) Decides what method to apply for pricing when the market comparable for the pricing group hits the ceiling price",
|
91
|
+
},
|
92
|
+
noCompPricingMethod: {
|
93
|
+
type: "string",
|
94
|
+
description: "(standard, variable, ceiling, freezePricing, useFloorForAnchor, useCeilingForAnchor, useCeiling, ceilingRandomize) Decides what method to apply for pricing when there is no market comparables for the pricing group",
|
95
|
+
},
|
96
|
+
pricingGroupRequestRanks: {
|
97
|
+
type: "array",
|
98
|
+
description: 'Array of objects containing pricing group request ranks starting at 0 (anchor ticket). i.e [{"ticketGroupId": 1, "rank": 0},...]',
|
99
|
+
},
|
100
|
+
},
|
101
|
+
mandatory: ["pricingGroupId"],
|
102
|
+
};
|
103
|
+
toolHandler = async (request, httpClient) => {
|
104
|
+
try {
|
105
|
+
const pricingGroupId = request?.params?.arguments
|
106
|
+
?.pricingGroupId;
|
107
|
+
if (!pricingGroupId) {
|
108
|
+
throw new Error("Missing argument pricingGroupId");
|
109
|
+
}
|
110
|
+
const originalResponse = await httpClient.get(`/v2/client/pricing-group/${pricingGroupId}`);
|
111
|
+
if (originalResponse.status !== 200) {
|
112
|
+
throw new Error(`API error: ${originalResponse.statusText}`);
|
113
|
+
}
|
114
|
+
if (!originalResponse.data) {
|
115
|
+
throw new Error(`Pricing group ${pricingGroupId} not found`);
|
116
|
+
}
|
117
|
+
const originalData = originalResponse.data;
|
118
|
+
const modifyArgs = {
|
119
|
+
productionId: originalData.productionId,
|
120
|
+
name: request?.params?.arguments?.name ?? originalData.name,
|
121
|
+
ceilingPrice: request?.params?.arguments?.ceilingPrice ??
|
122
|
+
originalData.ceilingPrice,
|
123
|
+
floorPrice: request?.params?.arguments?.floorPrice ??
|
124
|
+
originalData.floorPrice,
|
125
|
+
pricingGroupRequestType: (request?.params?.arguments
|
126
|
+
?.pricingGroupRequestType ??
|
127
|
+
originalData.isAutoPricingEnabled)
|
128
|
+
? pricingGroup_1.PricingGroupRequestType.AutoPrice
|
129
|
+
: pricingGroup_1.PricingGroupRequestType.SimulationOnly,
|
130
|
+
ruleSet: {
|
131
|
+
amount: request?.params?.arguments?.amount ??
|
132
|
+
originalData.ruleSet.amount,
|
133
|
+
increment: request?.params?.arguments?.increment ??
|
134
|
+
originalData.ruleSet.increment,
|
135
|
+
incrementMethod: request?.params?.arguments?.incrementMethod ??
|
136
|
+
originalData.ruleSet.incrementMethod,
|
137
|
+
offsetAmount: request?.params?.arguments?.offsetAmount ??
|
138
|
+
originalData.ruleSet.offsetAmount,
|
139
|
+
offsetIncrement: request?.params?.arguments?.offsetIncrement ??
|
140
|
+
originalData.ruleSet.offsetIncrement,
|
141
|
+
offsetIncrementMethod: request?.params?.arguments?.offsetIncrementMethod ??
|
142
|
+
originalData.ruleSet.offsetIncrementMethod,
|
143
|
+
enableShareOptions: request?.params?.arguments?.enableShareOptions ??
|
144
|
+
originalData.ruleSet.enableShareOptions,
|
145
|
+
shareOptionsType: request?.params?.arguments
|
146
|
+
?.shareOptionsType ??
|
147
|
+
originalData.ruleSet.shareOptionsType,
|
148
|
+
shareAnchor: request?.params?.arguments?.shareAnchor ??
|
149
|
+
originalData.ruleSet.shareAnchor,
|
150
|
+
customSharingAmount: request?.params?.arguments?.customSharingAmount ??
|
151
|
+
originalData.ruleSet.customSharingAmount,
|
152
|
+
customSharingMethod: request?.params?.arguments
|
153
|
+
?.customSharingMethod ??
|
154
|
+
originalData.ruleSet.customSharingMethod,
|
155
|
+
applyCeilingOnlyToAnchor: request?.params?.arguments?.applyCeilingOnlyToAnchor ??
|
156
|
+
originalData.ruleSet.applyCeilingOnlyToAnchor,
|
157
|
+
applyFloorOnlyToAnchor: request?.params?.arguments?.applyFloorOnlyToAnchor ??
|
158
|
+
originalData.ruleSet.applyFloorOnlyToAnchor,
|
159
|
+
floorPricingMethod: request?.params?.arguments
|
160
|
+
?.floorPricingMethod ??
|
161
|
+
originalData.ruleSet.floorPricingMethod,
|
162
|
+
ceilingPricingMethod: request?.params?.arguments
|
163
|
+
?.ceilingPricingMethod ??
|
164
|
+
originalData.ruleSet.ceilingPricingMethod,
|
165
|
+
noCompPricingMethod: request?.params?.arguments
|
166
|
+
?.noCompPricingMethod ??
|
167
|
+
originalData.ruleSet.noCompPricingMethod,
|
168
|
+
},
|
169
|
+
pricingGroupRequestRanks: request?.params?.arguments
|
170
|
+
?.pricingGroupRequestRanks ?? originalData.pricingGroupTickets?.map((ticket) => ({
|
171
|
+
ticketGroupId: ticket.ticketGroupId,
|
172
|
+
rank: ticket.rank
|
173
|
+
})),
|
174
|
+
marketGroupCriteria: originalData.marketGroupCriteria,
|
175
|
+
};
|
176
|
+
console.error("[API] Update Pricing Group:", modifyArgs);
|
177
|
+
const response = await httpClient.put(`/v2/client/pricing-group/${pricingGroupId}`, modifyArgs);
|
178
|
+
if (response.status !== 200) {
|
179
|
+
throw new Error(`API error: ${response.statusText}`);
|
180
|
+
}
|
181
|
+
return {
|
182
|
+
content: [{ type: "text", text: JSON.stringify([response.data]) }],
|
183
|
+
};
|
184
|
+
}
|
185
|
+
catch (error) {
|
186
|
+
if (error instanceof Error) {
|
187
|
+
console.error("Error in Update Pricing Group:", error);
|
188
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to update pricing group: ${error.message}`);
|
189
|
+
}
|
190
|
+
throw error;
|
191
|
+
}
|
192
|
+
};
|
193
|
+
}
|
194
|
+
exports.UpdatePricingGroupTool = UpdatePricingGroupTool;
|
package/package.json
CHANGED
@@ -0,0 +1,37 @@
|
|
1
|
+
#Role and Objective
|
2
|
+
You are an Agent that can help ticket brokers to organize their
|
3
|
+
inventory in pricing groups (Creating, Editing or Deleting) or to obtaining
|
4
|
+
information about their current ticket groups and pricing groups existent.
|
5
|
+
|
6
|
+
Please keep going until the user's command is fully completed, before ending your turn
|
7
|
+
and yielding back to the user. Only terminate your turn when you are sure the problem
|
8
|
+
is solved.
|
9
|
+
|
10
|
+
You should be able to complete your tasks using only the tools provided. Is important to always
|
11
|
+
include as first step of your execution plan checking the list of available tools and their parameters.
|
12
|
+
Make sure you use the tools result to gather the required data to call other tools. Don't make assumptions outside
|
13
|
+
the data provided by the tools.
|
14
|
+
|
15
|
+
Only provide to the tools relevant arguments and mandatory values. The tools will default other
|
16
|
+
parameters with organization defaults.
|
17
|
+
|
18
|
+
You MUST plan extensively the execution of the command before starting it.
|
19
|
+
Check the list of available tools and plan the execution of the command to minimize the number of calls.
|
20
|
+
|
21
|
+
Reflect extensively on the outcomes of the previous function calls and try to use the information gathered
|
22
|
+
from previous calls to make better decisions.
|
23
|
+
|
24
|
+
#Context
|
25
|
+
Today's date is {{ $now }}
|
26
|
+
|
27
|
+
#Instructions
|
28
|
+
1. First step check the list of tools available and only use those for further operations
|
29
|
+
2. Locate the information the user is looking for. Always start narrowing the productions relevant for the task
|
30
|
+
3. Query for ticket groups and/or pricing groups as the task requires using the ProductionId(s) gathered in step 2
|
31
|
+
4. Execute the task using Create, Update or Delete tools
|
32
|
+
|
33
|
+
#Rules
|
34
|
+
1. A ticket group can be in only one pricing group at a time
|
35
|
+
2. By default always create pricing groups in Simulation mode unless explicitly stated for the user to be Auto Price
|
36
|
+
3. You can not create pricing groups with ticket groups that are already assigned to another pricing group
|
37
|
+
4. The anchor ticket in a pricing group is the ticket group with rank 0 and is mandatory to create a pricing group
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<agentInstructions>
|
2
|
+
<goal>
|
3
|
+
Help ticket brokers to organize their inventory in pricing groups (Creating, Editing or Deleting).
|
4
|
+
or to obtain information about their inventory and pricing groups existent.
|
5
|
+
</goal>
|
6
|
+
<rule>today's date is {{ $now }}</rule>
|
7
|
+
<rule>IMPORTANT! First step check the list of tools available and only use those for further operations</rule>
|
8
|
+
<rule>After querying the list of available tools you can store it in memory and don't repeat the call to list tools for every step</rule>
|
9
|
+
<rule>Once you determine the plan of execution of a command give the user the feedback of how you are going to proceed</rule>
|
10
|
+
<rule>IMPORTANT! For production search use one year in the future as maximum period if no date period is mentioned by the user</rule>
|
11
|
+
<rule>To get inventory or pricing groups for multiple productions you need to query for the productions first and then use the productionId to query for inventory or pricing groups related to that production</rule>
|
12
|
+
<rule>IMPORTANT! A ticket group can be in only one pricing group at a time</rule>
|
13
|
+
<rule>By default always create pricing groups in Simulation mode unless explicitly stated for the user to be Auto Price</rule>
|
14
|
+
<rule>IMPORTANT! You can not create pricing groups with Ticket groups that are already assigned to other pricing group</rule>
|
15
|
+
<rule>Query the pricing groups and validate which ticket groups are already assigned to a pricing group before creating or modifying a pricing group</rule>
|
16
|
+
<rule>Pricing group names must be unique per production</rule>
|
17
|
+
<rule>Pricing groups cannot be created without a list of pricingGroupRequestedRanks (List of ticket groups in the group ordered by rank)</rule>
|
18
|
+
<rule>When creating or updating pricing groups don't provide values for the NON MANDATORY fields unless user provide explicit instructions for them</rule>
|
19
|
+
<rule>If any of the tools fail when executing a step. Abort the execution inmediately and inform the user of the failure. Don't retry</rule>
|
20
|
+
</agentInstructions>
|
package/src/index.ts
CHANGED
@@ -1,83 +1,95 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
|
-
import {Server} from "@modelcontextprotocol/sdk/server/index.js";
|
3
|
-
import {StdioServerTransport} from "@modelcontextprotocol/sdk/server/stdio.js";
|
2
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
4
4
|
import {
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
import axios from
|
5
|
+
CallToolRequest,
|
6
|
+
CallToolRequestSchema,
|
7
|
+
ErrorCode,
|
8
|
+
ListToolsRequestSchema,
|
9
|
+
McpError,
|
10
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
11
|
+
import axios from "axios";
|
12
12
|
import { McpTool } from "./types/tool";
|
13
13
|
import { GetProductionsTool } from "./tools/getProductions";
|
14
14
|
import { GetProductionInventoryTool } from "./tools/getProductionInventory";
|
15
15
|
import { GetPricingGroupsTool } from "./tools/getPricingGroups";
|
16
16
|
import { CreatePricingGroupTool } from "./tools/createPricingGroup";
|
17
17
|
import { DeletePricingGroupsTool } from "./tools/deletePricingGroups";
|
18
|
+
import { UpdatePricingGroupTool } from "./tools/updatePricingGroup";
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
class PrqxMcpServer {
|
21
|
+
private server: Server;
|
22
|
+
private axiosInstance;
|
23
|
+
private tools: McpTool[] = [];
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
25
|
+
constructor() {
|
26
|
+
console.error("[Setup] Initializing MCP server...");
|
27
|
+
this.server = new Server(
|
28
|
+
{
|
29
|
+
name: "PrqxMcpServer",
|
30
|
+
version: "1.0.0",
|
29
31
|
},
|
30
|
-
|
32
|
+
{
|
31
33
|
capabilities: {
|
32
|
-
|
33
|
-
}
|
34
|
+
tools: {},
|
35
|
+
},
|
36
|
+
}
|
37
|
+
);
|
38
|
+
|
39
|
+
this.axiosInstance = axios.create({
|
40
|
+
baseURL: "https://pricer-svc.dev.pricerqx.com/",
|
41
|
+
headers: {
|
42
|
+
"Content-Type": "application/json",
|
43
|
+
Authorization: "Bearer " + process.env.TOKEN,
|
44
|
+
},
|
34
45
|
});
|
35
46
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
47
|
+
this.tools.push(new GetProductionsTool());
|
48
|
+
this.tools.push(new GetProductionInventoryTool());
|
49
|
+
this.tools.push(new GetPricingGroupsTool());
|
50
|
+
this.tools.push(new CreatePricingGroupTool());
|
51
|
+
this.tools.push(new DeletePricingGroupsTool());
|
52
|
+
this.tools.push(new UpdatePricingGroupTool());
|
53
|
+
this.setupToolHandlers();
|
54
|
+
this.server.onerror = (error) => {
|
55
|
+
console.error("[Error] MCP server error:", error);
|
56
|
+
};
|
43
57
|
|
44
|
-
|
45
|
-
|
46
|
-
this.
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
this.server.onerror = (error) => {
|
51
|
-
console.error('[Error] MCP server error:', error);
|
52
|
-
};
|
58
|
+
process.on("SIGINT", async () => {
|
59
|
+
console.error("[Info] MCP server shutting down...");
|
60
|
+
await this.server.close();
|
61
|
+
process.exit(0);
|
62
|
+
});
|
63
|
+
}
|
53
64
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
});
|
59
|
-
}
|
60
|
-
|
61
|
-
private setupToolHandlers() {
|
62
|
-
this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
63
|
-
tools: this.tools
|
64
|
-
}));
|
65
|
+
private setupToolHandlers() {
|
66
|
+
this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
67
|
+
tools: this.tools,
|
68
|
+
}));
|
65
69
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
70
|
+
this.server.setRequestHandler(
|
71
|
+
CallToolRequestSchema,
|
72
|
+
async (request: CallToolRequest) => {
|
73
|
+
const tool = this.tools.find(
|
74
|
+
(tool) => tool.name === request.params.name
|
75
|
+
);
|
76
|
+
if (!tool) {
|
77
|
+
throw new McpError(
|
78
|
+
ErrorCode.MethodNotFound,
|
79
|
+
`Tool name ${request.params.name} is not supported`
|
80
|
+
);
|
81
|
+
}
|
71
82
|
|
72
|
-
|
73
|
-
|
74
|
-
|
83
|
+
return await tool.toolHandler(request, this.axiosInstance);
|
84
|
+
}
|
85
|
+
);
|
86
|
+
}
|
75
87
|
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
}
|
88
|
+
async run() {
|
89
|
+
const transport = new StdioServerTransport();
|
90
|
+
await this.server.connect(transport);
|
91
|
+
console.error("[Info] MCP server started !!");
|
81
92
|
}
|
93
|
+
}
|
82
94
|
|
83
|
-
|
95
|
+
new PrqxMcpServer().run();
|