mcp-prqx-pricer 1.0.1 → 1.0.2
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/build/index.js +10 -46
- package/build/tools/getProductionInventory.js +36 -0
- package/build/tools/getProductions.js +54 -0
- package/build/types/productionInventory.js +4 -0
- package/build/types/tool.js +2 -0
- package/package.json +1 -1
- package/src/index.ts +14 -58
- package/src/tools/getProductionInventory.ts +35 -0
- package/src/tools/getProductions.ts +67 -0
- package/src/types/productionInventory.ts +56 -0
- package/src/types/tool.ts +12 -0
package/build/index.js
CHANGED
@@ -8,9 +8,12 @@ const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
|
|
8
8
|
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
9
9
|
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
10
10
|
const axios_1 = __importDefault(require("axios"));
|
11
|
+
const getProductions_1 = require("./tools/getProductions");
|
12
|
+
const getProductionInventory_1 = require("./tools/getProductionInventory");
|
11
13
|
class PrqxMcpServer {
|
12
14
|
server;
|
13
15
|
axiosInstance;
|
16
|
+
tools = [];
|
14
17
|
constructor() {
|
15
18
|
console.error('[Setup] Initializing MCP server...');
|
16
19
|
this.server = new index_js_1.Server({
|
@@ -28,6 +31,8 @@ class PrqxMcpServer {
|
|
28
31
|
'Authorization': 'Bearer ' + process.env.TOKEN
|
29
32
|
},
|
30
33
|
});
|
34
|
+
this.tools.push(new getProductions_1.GetProductionsTool());
|
35
|
+
this.tools.push(new getProductionInventory_1.GetProductionInventoryTool());
|
31
36
|
this.setupToolHandlers();
|
32
37
|
this.server.onerror = (error) => {
|
33
38
|
console.error('[Error] MCP server error:', error);
|
@@ -40,55 +45,14 @@ class PrqxMcpServer {
|
|
40
45
|
}
|
41
46
|
setupToolHandlers() {
|
42
47
|
this.server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({
|
43
|
-
tools:
|
44
|
-
{
|
45
|
-
name: 'Get Productions',
|
46
|
-
description: 'Get productions by production name, venue, performer, city. Within a range of dates (StartDate, EndDate). Only retrieves a maximum of 10 items',
|
47
|
-
inputSchema: {
|
48
|
-
type: 'object',
|
49
|
-
properties: {
|
50
|
-
filter: {
|
51
|
-
type: 'string',
|
52
|
-
description: 'Filter to be applied to the production search (Name, Venue, Performer or City) separated by spaces'
|
53
|
-
},
|
54
|
-
startDate: {
|
55
|
-
type: 'string',
|
56
|
-
description: 'Start date of the production search (YYYY-MM-DD)'
|
57
|
-
},
|
58
|
-
endDate: {
|
59
|
-
type: 'string',
|
60
|
-
description: 'End date of the production search (YYYY-MM-DD)'
|
61
|
-
}
|
62
|
-
}
|
63
|
-
}
|
64
|
-
}
|
65
|
-
]
|
48
|
+
tools: this.tools
|
66
49
|
}));
|
67
50
|
this.server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
}
|
72
|
-
const args = request.params.arguments;
|
73
|
-
args.pageSize = 10;
|
74
|
-
args.pageNumber = 1;
|
75
|
-
console.error('[API] Get Productions with arguments:', args);
|
76
|
-
const response = await this.axiosInstance.get('/v2/client/production', { params: args });
|
77
|
-
if (response.status !== 200) {
|
78
|
-
throw new Error(`API error: ${response.statusText}`);
|
79
|
-
}
|
80
|
-
if (response.data.totalFilteredRecords === 0) {
|
81
|
-
return { content: [{ type: "text", text: "No results found" }] };
|
82
|
-
}
|
83
|
-
return { content: [{ type: "text", text: JSON.stringify(response.data) }] };
|
84
|
-
}
|
85
|
-
catch (error) {
|
86
|
-
if (error instanceof Error) {
|
87
|
-
console.error('Error in Get Productions:', error);
|
88
|
-
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to fetch data: ${error.message}`);
|
89
|
-
}
|
90
|
-
throw error;
|
51
|
+
const tool = this.tools.find(tool => tool.name === request.params.name);
|
52
|
+
if (!tool) {
|
53
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.MethodNotFound, `Tool name ${request.params.name} is not supported`);
|
91
54
|
}
|
55
|
+
return await tool.toolHandler(request, this.axiosInstance);
|
92
56
|
});
|
93
57
|
}
|
94
58
|
async run() {
|
@@ -0,0 +1,36 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.GetProductionInventoryTool = void 0;
|
4
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
5
|
+
class GetProductionInventoryTool {
|
6
|
+
name = 'Get Production Inventory';
|
7
|
+
description = 'Get all the organization inventory (ticket groups) for a single production';
|
8
|
+
inputSchema = {
|
9
|
+
type: 'object',
|
10
|
+
properties: {
|
11
|
+
productionId: {
|
12
|
+
type: 'number',
|
13
|
+
description: 'ID of the production'
|
14
|
+
}
|
15
|
+
}
|
16
|
+
};
|
17
|
+
toolHandler = async (request, httpClient) => {
|
18
|
+
try {
|
19
|
+
const args = request.params.arguments;
|
20
|
+
console.error('[API] Get Production Inventory with arguments:', args);
|
21
|
+
const response = await httpClient.get(`/v2/client/production/${args.productionId}/inventory`);
|
22
|
+
if (response.status !== 200) {
|
23
|
+
throw new Error(`API error: ${response.statusText}`);
|
24
|
+
}
|
25
|
+
return { content: [{ type: 'text', text: JSON.stringify(response.data) }] };
|
26
|
+
}
|
27
|
+
catch (error) {
|
28
|
+
if (error instanceof Error) {
|
29
|
+
console.error('Error in Get Production Inventory:', error);
|
30
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to fetch data: ${error.message}`);
|
31
|
+
}
|
32
|
+
throw error;
|
33
|
+
}
|
34
|
+
};
|
35
|
+
}
|
36
|
+
exports.GetProductionInventoryTool = GetProductionInventoryTool;
|
@@ -0,0 +1,54 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.GetProductionsTool = void 0;
|
4
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
5
|
+
class GetProductionsTool {
|
6
|
+
name = 'Get Productions';
|
7
|
+
description = 'Get productions by production name, venue, performer, city. Within a range of dates (StartDate, EndDate). Only retrieves a maximum of 10 items';
|
8
|
+
inputSchema = {
|
9
|
+
type: 'object',
|
10
|
+
properties: {
|
11
|
+
filter: {
|
12
|
+
type: 'string',
|
13
|
+
description: 'Filter to be applied to the production search (Name, Venue, Performer or City) separated by spaces'
|
14
|
+
},
|
15
|
+
startDate: {
|
16
|
+
type: 'string',
|
17
|
+
description: 'Start date of the production search (YYYY-MM-DD)'
|
18
|
+
},
|
19
|
+
endDate: {
|
20
|
+
type: 'string',
|
21
|
+
description: 'End date of the production search (YYYY-MM-DD)'
|
22
|
+
},
|
23
|
+
productionStatus: {
|
24
|
+
type: 'string',
|
25
|
+
description: 'Status of the production ("Active","Inactive","Cancelled","Postponed", "All") - Include only Active if not specified'
|
26
|
+
}
|
27
|
+
}
|
28
|
+
};
|
29
|
+
toolHandler = async (request, httpClient) => {
|
30
|
+
try {
|
31
|
+
const args = request.params.arguments;
|
32
|
+
args.pageSize = 10;
|
33
|
+
args.pageNumber = 1;
|
34
|
+
args.productionStatus = args.productionStatus === "All" ? undefined : args.productionStatus || 'Active';
|
35
|
+
console.error('[API] Get Productions with arguments:', args);
|
36
|
+
const response = await httpClient.get('/v2/client/production', { params: args });
|
37
|
+
if (response.status !== 200) {
|
38
|
+
throw new Error(`API error: ${response.statusText}`);
|
39
|
+
}
|
40
|
+
if (response.data.totalFilteredRecords === 0) {
|
41
|
+
return { content: [{ type: "text", text: "No results found" }] };
|
42
|
+
}
|
43
|
+
return { content: [{ type: "text", text: JSON.stringify(response.data) }] };
|
44
|
+
}
|
45
|
+
catch (error) {
|
46
|
+
if (error instanceof Error) {
|
47
|
+
console.error('Error in Get Productions:', error);
|
48
|
+
throw new types_js_1.McpError(types_js_1.ErrorCode.InternalError, `Failed to fetch data: ${error.message}`);
|
49
|
+
}
|
50
|
+
throw error;
|
51
|
+
}
|
52
|
+
};
|
53
|
+
}
|
54
|
+
exports.GetProductionsTool = GetProductionsTool;
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
@@ -2,17 +2,21 @@
|
|
2
2
|
import {Server} from "@modelcontextprotocol/sdk/server/index.js";
|
3
3
|
import {StdioServerTransport} from "@modelcontextprotocol/sdk/server/stdio.js";
|
4
4
|
import {
|
5
|
+
CallToolRequest,
|
5
6
|
CallToolRequestSchema,
|
6
7
|
ErrorCode,
|
7
8
|
ListToolsRequestSchema,
|
8
9
|
McpError,
|
9
10
|
} from '@modelcontextprotocol/sdk/types.js';
|
10
11
|
import axios from 'axios';
|
11
|
-
import {
|
12
|
+
import { McpTool } from "./types/tool";
|
13
|
+
import { GetProductionsTool } from "./tools/getProductions";
|
14
|
+
import { GetProductionInventoryTool } from "./tools/getProductionInventory";
|
12
15
|
|
13
16
|
class PrqxMcpServer{
|
14
17
|
private server: Server;
|
15
18
|
private axiosInstance;
|
19
|
+
private tools: McpTool[] = [];
|
16
20
|
|
17
21
|
constructor() {
|
18
22
|
console.error('[Setup] Initializing MCP server...');
|
@@ -34,6 +38,8 @@ import { PagedProductionResponseDto } from "./types/production";
|
|
34
38
|
},
|
35
39
|
});
|
36
40
|
|
41
|
+
this.tools.push(new GetProductionsTool());
|
42
|
+
this.tools.push(new GetProductionInventoryTool());
|
37
43
|
this.setupToolHandlers();
|
38
44
|
|
39
45
|
this.server.onerror = (error) => {
|
@@ -49,66 +55,16 @@ import { PagedProductionResponseDto } from "./types/production";
|
|
49
55
|
|
50
56
|
private setupToolHandlers() {
|
51
57
|
this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
52
|
-
tools:
|
53
|
-
{
|
54
|
-
name: 'Get Productions',
|
55
|
-
description: 'Get productions by production name, venue, performer, city. Within a range of dates (StartDate, EndDate). Only retrieves a maximum of 10 items',
|
56
|
-
inputSchema: {
|
57
|
-
type: 'object',
|
58
|
-
properties: {
|
59
|
-
filter: {
|
60
|
-
type: 'string',
|
61
|
-
description: 'Filter to be applied to the production search (Name, Venue, Performer or City) separated by spaces'
|
62
|
-
},
|
63
|
-
startDate: {
|
64
|
-
type: 'string',
|
65
|
-
description: 'Start date of the production search (YYYY-MM-DD)'
|
66
|
-
},
|
67
|
-
endDate: {
|
68
|
-
type: 'string',
|
69
|
-
description: 'End date of the production search (YYYY-MM-DD)'
|
70
|
-
}
|
71
|
-
}
|
72
|
-
}
|
73
|
-
}
|
74
|
-
]
|
58
|
+
tools: this.tools
|
75
59
|
}));
|
76
60
|
|
77
|
-
this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
}
|
82
|
-
const args = request.params.arguments as {
|
83
|
-
filter?: string;
|
84
|
-
startDate?: string;
|
85
|
-
endDate?: string;
|
86
|
-
pageSize?: number;
|
87
|
-
pageNumber?: number;
|
88
|
-
};
|
89
|
-
|
90
|
-
args.pageSize = 10;
|
91
|
-
args.pageNumber = 1;
|
92
|
-
|
93
|
-
console.error('[API] Get Productions with arguments:', args);
|
94
|
-
const response = await this.axiosInstance.get<PagedProductionResponseDto>('/v2/client/production', {params: args});
|
95
|
-
|
96
|
-
if (response.status !== 200) {
|
97
|
-
throw new Error(`API error: ${response.statusText}`);
|
98
|
-
}
|
99
|
-
|
100
|
-
if(response.data.totalFilteredRecords === 0) {
|
101
|
-
return {content: [{type: "text", text: "No results found"}]};
|
102
|
-
}
|
103
|
-
|
104
|
-
return {content: [{type: "text", text: JSON.stringify(response.data)}]};
|
105
|
-
} catch (error) {
|
106
|
-
if(error instanceof Error) {
|
107
|
-
console.error('Error in Get Productions:', error);
|
108
|
-
throw new McpError(ErrorCode.InternalError, `Failed to fetch data: ${error.message}`);
|
109
|
-
}
|
110
|
-
throw error;
|
61
|
+
this.server.setRequestHandler(CallToolRequestSchema, async (request: CallToolRequest) => {
|
62
|
+
const tool = this.tools.find(tool => tool.name === request.params.name);
|
63
|
+
if(!tool) {
|
64
|
+
throw new McpError(ErrorCode.MethodNotFound, `Tool name ${request.params.name} is not supported`);
|
111
65
|
}
|
66
|
+
|
67
|
+
return await tool.toolHandler(request, this.axiosInstance);
|
112
68
|
});
|
113
69
|
}
|
114
70
|
|
@@ -0,0 +1,35 @@
|
|
1
|
+
import { CallToolRequest, ErrorCode, McpError } from "@modelcontextprotocol/sdk/types.js";
|
2
|
+
import { AxiosInstance } from "axios";
|
3
|
+
import { McpTool } from "../types/tool";
|
4
|
+
import { GetProductionInventoryResponse } from "../types/productionInventory";
|
5
|
+
|
6
|
+
export class GetProductionInventoryTool implements McpTool {
|
7
|
+
name = 'Get Production Inventory';
|
8
|
+
description = 'Get all the organization inventory (ticket groups) for a single production';
|
9
|
+
inputSchema = {
|
10
|
+
type: 'object',
|
11
|
+
properties: {
|
12
|
+
productionId: {
|
13
|
+
type: 'number',
|
14
|
+
description: 'ID of the production'
|
15
|
+
}
|
16
|
+
}
|
17
|
+
};
|
18
|
+
toolHandler = async (request: CallToolRequest, httpClient: AxiosInstance) => {
|
19
|
+
try {
|
20
|
+
const args = request.params.arguments as { productionId: number };
|
21
|
+
console.error('[API] Get Production Inventory with arguments:', args);
|
22
|
+
const response = await httpClient.get<GetProductionInventoryResponse>(`/v2/client/production/${args.productionId}/inventory`);
|
23
|
+
if (response.status !== 200) {
|
24
|
+
throw new Error(`API error: ${response.statusText}`);
|
25
|
+
}
|
26
|
+
return { content: [{ type: 'text', text: JSON.stringify(response.data) }] };
|
27
|
+
} catch (error) {
|
28
|
+
if (error instanceof Error) {
|
29
|
+
console.error('Error in Get Production Inventory:', error);
|
30
|
+
throw new McpError(ErrorCode.InternalError, `Failed to fetch data: ${error.message}`);
|
31
|
+
}
|
32
|
+
throw error;
|
33
|
+
}
|
34
|
+
};
|
35
|
+
}
|
@@ -0,0 +1,67 @@
|
|
1
|
+
import { CallToolRequest, ErrorCode, McpError } from "@modelcontextprotocol/sdk/types.js";
|
2
|
+
import { McpTool } from "../types/tool";
|
3
|
+
import { PagedProductionResponseDto } from "../types/production";
|
4
|
+
import axios from "axios";
|
5
|
+
|
6
|
+
export class GetProductionsTool implements McpTool {
|
7
|
+
name = 'Get Productions';
|
8
|
+
description = 'Get productions by production name, venue, performer, city. Within a range of dates (StartDate, EndDate). Only retrieves a maximum of 10 items';
|
9
|
+
inputSchema = {
|
10
|
+
type: 'object',
|
11
|
+
properties: {
|
12
|
+
filter: {
|
13
|
+
type: 'string',
|
14
|
+
description: 'Filter to be applied to the production search (Name, Venue, Performer or City) separated by spaces'
|
15
|
+
},
|
16
|
+
startDate: {
|
17
|
+
type: 'string',
|
18
|
+
description: 'Start date of the production search (YYYY-MM-DD)'
|
19
|
+
},
|
20
|
+
endDate: {
|
21
|
+
type: 'string',
|
22
|
+
description: 'End date of the production search (YYYY-MM-DD)'
|
23
|
+
},
|
24
|
+
productionStatus:{
|
25
|
+
type: 'string',
|
26
|
+
description: 'Status of the production ("Active","Inactive","Cancelled","Postponed", "All") - Include only Active if not specified'
|
27
|
+
}
|
28
|
+
}
|
29
|
+
};
|
30
|
+
|
31
|
+
toolHandler = async (request: CallToolRequest, httpClient: axios.AxiosInstance) => {
|
32
|
+
try{
|
33
|
+
const args = request.params.arguments as {
|
34
|
+
filter?: string;
|
35
|
+
startDate?: string;
|
36
|
+
endDate?: string;
|
37
|
+
pageSize?: number;
|
38
|
+
pageNumber?: number;
|
39
|
+
productionStatus?: string;
|
40
|
+
};
|
41
|
+
|
42
|
+
args.pageSize = 10;
|
43
|
+
args.pageNumber = 1;
|
44
|
+
args.productionStatus = args.productionStatus === "All" ? undefined : args.productionStatus || 'Active';
|
45
|
+
|
46
|
+
console.error('[API] Get Productions with arguments:', args);
|
47
|
+
const response = await httpClient.get<PagedProductionResponseDto>('/v2/client/production', {params: args});
|
48
|
+
|
49
|
+
if (response.status !== 200) {
|
50
|
+
throw new Error(`API error: ${response.statusText}`);
|
51
|
+
}
|
52
|
+
|
53
|
+
if(response.data.totalFilteredRecords === 0) {
|
54
|
+
return {content: [{type: "text", text: "No results found"}]};
|
55
|
+
}
|
56
|
+
|
57
|
+
return {content: [{type: "text", text: JSON.stringify(response.data)}]};
|
58
|
+
} catch (error) {
|
59
|
+
if(error instanceof Error) {
|
60
|
+
console.error('Error in Get Productions:', error);
|
61
|
+
throw new McpError(ErrorCode.InternalError, `Failed to fetch data: ${error.message}`);
|
62
|
+
}
|
63
|
+
throw error;
|
64
|
+
}
|
65
|
+
};
|
66
|
+
}
|
67
|
+
|
@@ -0,0 +1,56 @@
|
|
1
|
+
// Auto-generated interfaces for /v2/client/production/{ProductionId}/inventory
|
2
|
+
// Based on OpenAPI pricer.json
|
3
|
+
|
4
|
+
export interface GetProductionInventoryRequest {
|
5
|
+
ProductionId: number; // path param (int64)
|
6
|
+
showParking?: boolean; // query param
|
7
|
+
showSpeculation?: boolean; // query param
|
8
|
+
}
|
9
|
+
|
10
|
+
export type StockType = 'Pdf' | 'MobileTransfer' | 'Physical';
|
11
|
+
export type SeatType = 'Consecutive' | 'OddEven' | 'Piggyback' | 'GeneralAdmission';
|
12
|
+
export type SplitRule = 'Default' | 'NoSplit' | 'NeverLeaveOne' | 'AnySplit' | 'Custom';
|
13
|
+
export type InventoryStatus = 'Available' | 'Sold' | 'Held' | 'Deleted';
|
14
|
+
|
15
|
+
export interface InventoryResponseDtoV2 {
|
16
|
+
productionId: number;
|
17
|
+
section?: string | null;
|
18
|
+
row?: string | null;
|
19
|
+
quantity?: number | null;
|
20
|
+
validSplits?: number[] | null;
|
21
|
+
startSeat?: number | null;
|
22
|
+
endSeat?: number | null;
|
23
|
+
stockType: StockType;
|
24
|
+
attributes?: string[] | null;
|
25
|
+
inHandDate?: string | null; // YYYY-MM-DD
|
26
|
+
isParking?: boolean | null;
|
27
|
+
isInHand?: boolean | null;
|
28
|
+
isSpeculation?: boolean | null;
|
29
|
+
costPrice?: number | null;
|
30
|
+
listPrice?: number | null;
|
31
|
+
listPriceChange?: number | null;
|
32
|
+
suggestedPrice?: number | null;
|
33
|
+
retailPrice?: number | null;
|
34
|
+
retailPriceChange?: number | null;
|
35
|
+
suggestedRetailPrice?: number | null;
|
36
|
+
rank?: number | null;
|
37
|
+
pricingGroupId?: number | null;
|
38
|
+
pricingGroupName?: string | null;
|
39
|
+
isAutoPricingEnabled?: boolean | null;
|
40
|
+
seatType: SeatType;
|
41
|
+
splitRule: SplitRule;
|
42
|
+
internalNotes?: string | null;
|
43
|
+
externalNotes?: string | null;
|
44
|
+
isCeilingHit: boolean;
|
45
|
+
isFloorHit: boolean;
|
46
|
+
isNoActiveCompHit: boolean;
|
47
|
+
ticketGroupId: number;
|
48
|
+
isShared?: boolean | null;
|
49
|
+
inventoryStatus: InventoryStatus;
|
50
|
+
posOrganizationId?: number | null;
|
51
|
+
isPendingChange?: boolean | null;
|
52
|
+
inventoryTags?: string[] | null;
|
53
|
+
sourceKey?: string | null;
|
54
|
+
}
|
55
|
+
|
56
|
+
export type GetProductionInventoryResponse = InventoryResponseDtoV2[];
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import { CallToolRequest } from "@modelcontextprotocol/sdk/types.js";
|
2
|
+
import axios from "axios";
|
3
|
+
|
4
|
+
export interface McpTool {
|
5
|
+
name: string;
|
6
|
+
description: string;
|
7
|
+
inputSchema: {
|
8
|
+
type: string;
|
9
|
+
properties: object;
|
10
|
+
};
|
11
|
+
toolHandler: (request: CallToolRequest, httpClient: axios.AxiosInstance) => Promise<{content: {type: string; text: string}[]}>
|
12
|
+
}
|