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 ADDED
@@ -0,0 +1,3 @@
1
+ # prqx-mcp-pricer-poc
2
+
3
+ A proof of concept for a ModelContextProtocol (MCP Server) to encapsulate the calls to the PRQX Pricer API.
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('[Setup] Initializing MCP server...');
22
+ console.error("[Setup] Initializing MCP server...");
22
23
  this.server = new index_js_1.Server({
23
- name: 'PrqxMcpServer',
24
- version: '1.0.0',
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: 'https://pricer-svc.dev.pricerqx.com/',
32
+ baseURL: "https://pricer-svc.dev.pricerqx.com/",
32
33
  headers: {
33
- 'Content-Type': 'application/json',
34
- 'Authorization': 'Bearer ' + process.env.TOKEN
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('[Error] MCP server error:', error);
46
+ console.error("[Error] MCP server error:", error);
45
47
  };
46
- process.on('SIGINT', async () => {
47
- console.error('[Info] MCP server shutting down...');
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('[Info] MCP server started !!');
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(`API error: ${response.statusText}`);
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 = 'DeletePricingGroups';
7
- description = 'Delete multiple pricing groups in bulk';
6
+ name = "DeletePricingGroups";
7
+ description = "Delete multiple pricing groups in bulk";
8
8
  inputSchema = {
9
- type: 'object',
9
+ type: "object",
10
10
  properties: {
11
11
  pricingGroupIds: {
12
- type: 'array',
13
- description: 'Array of IDs (numbers) of the pricing groups that will be deleted. They can belong to multiple productions.'
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: ['pricingGroupIds']
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('Missing argument pricingGroupIds');
22
+ throw new Error("Missing argument pricingGroupIds");
23
23
  }
24
- console.error('[API] Delete Pricing Group with arguments:', args);
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: 'text', text: 'Operation Completed!' }] };
26
+ return { content: [{ type: "text", text: "Operation Completed!" }] };
27
27
  }
28
28
  catch (error) {
29
29
  if (error instanceof Error) {
30
- console.error('Error in Delete Pricing Groups:', 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-prqx-pricer",
3
- "version": "1.0.12",
3
+ "version": "1.0.14",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -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
- CallToolRequest,
6
- CallToolRequestSchema,
7
- ErrorCode,
8
- ListToolsRequestSchema,
9
- McpError,
10
- } from '@modelcontextprotocol/sdk/types.js';
11
- import axios from 'axios';
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
- class PrqxMcpServer{
20
- private server: Server;
21
- private axiosInstance;
22
- private tools: McpTool[] = [];
20
+ class PrqxMcpServer {
21
+ private server: Server;
22
+ private axiosInstance;
23
+ private tools: McpTool[] = [];
23
24
 
24
- constructor() {
25
- console.error('[Setup] Initializing MCP server...');
26
- this.server = new Server({
27
- name: 'PrqxMcpServer',
28
- version: '1.0.0',
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
- tools:{}
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
- this.axiosInstance = axios.create({
37
- baseURL: 'https://pricer-svc.dev.pricerqx.com/',
38
- headers: {
39
- 'Content-Type': 'application/json',
40
- 'Authorization': 'Bearer ' + process.env.TOKEN
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
- this.tools.push(new GetProductionsTool());
45
- this.tools.push(new GetProductionInventoryTool());
46
- this.tools.push(new GetPricingGroupsTool());
47
- this.tools.push(new CreatePricingGroupTool());
48
- this.tools.push(new DeletePricingGroupsTool());
49
- this.setupToolHandlers();
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
- process.on('SIGINT', async () => {
55
- console.error('[Info] MCP server shutting down...');
56
- await this.server.close();
57
- process.exit(0);
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
- this.server.setRequestHandler(CallToolRequestSchema, async (request: CallToolRequest) => {
67
- const tool = this.tools.find(tool => tool.name === request.params.name);
68
- if(!tool) {
69
- throw new McpError(ErrorCode.MethodNotFound, `Tool name ${request.params.name} is not supported`);
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
- return await tool.toolHandler(request, this.axiosInstance);
73
- });
74
- }
83
+ return await tool.toolHandler(request, this.axiosInstance);
84
+ }
85
+ );
86
+ }
75
87
 
76
- async run() {
77
- const transport = new StdioServerTransport();
78
- await this.server.connect(transport);
79
- console.error('[Info] MCP server started !!');
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
- new PrqxMcpServer().run();
95
+ new PrqxMcpServer().run();