|
1 | | -import { Server } from "@modelcontextprotocol/sdk/server/index.js"; |
| 1 | +import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; |
2 | 2 | import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; |
3 | | -import { |
4 | | - CallToolRequestSchema, |
5 | | - ListToolsRequestSchema, |
6 | | -} from "@modelcontextprotocol/sdk/types.js"; |
7 | 3 | import { z } from "zod"; |
8 | | - |
9 | | -const server = new Server( |
10 | | - { |
11 | | - name: "business-hotels-mcp", |
12 | | - version: "1.0.0", |
13 | | - }, |
14 | | - { |
15 | | - capabilities: { |
16 | | - tools: {}, |
17 | | - }, |
18 | | - } |
19 | | -); |
| 4 | +import axios from "axios"; |
20 | 5 |
|
21 | 6 | /** |
22 | | - * List available tools. |
| 7 | + * Initialize the BusinessHotels MCP Server |
| 8 | + * Version 2.0.0 aligned with Agentic Discovery Endpoints |
23 | 9 | */ |
24 | | -server.setRequestHandler(ListToolsRequestSchema, async () => { |
25 | | - return { |
26 | | - tools: [ |
27 | | - { |
28 | | - name: "search_hotels", |
29 | | - description: "Search for business hotels with real-time price verification", |
30 | | - inputSchema: { |
31 | | - type: "object", |
32 | | - properties: { |
33 | | - destination: { type: "string", description: "City or Airport code" }, |
34 | | - checkIn: { type: "string", description: "YYYY-MM-DD" }, |
35 | | - checkOut: { type: "string", description: "YYYY-MM-DD" }, |
36 | | - }, |
37 | | - required: ["destination", "checkIn", "checkOut"], |
38 | | - }, |
39 | | - }, |
40 | | - ], |
41 | | - }; |
| 10 | +const server = new McpServer({ |
| 11 | + name: "business-hotels-mcp", |
| 12 | + version: "2.0.0", |
42 | 13 | }); |
43 | 14 |
|
44 | 15 | /** |
45 | | - * Handle tool execution. |
| 16 | + * Tool: get_live_hotel_rates |
| 17 | + * Connects to the PHP tools route for real-time ARI data. |
46 | 18 | */ |
47 | | -server.setRequestHandler(CallToolRequestSchema, async (request) => { |
48 | | - if (request.params.name === "search_hotels") { |
49 | | - const { destination } = request.params.arguments as any; |
50 | | - |
51 | | - // Placeholder for your Priceline/PPS API logic |
52 | | - return { |
53 | | - content: [ |
54 | | - { |
55 | | - type: "text", |
56 | | - text: `Searching for premium business hotels in ${destination}... Connection to BusinessHotels.com API established.`, |
| 19 | +server.tool( |
| 20 | + "get_live_hotel_rates", |
| 21 | + { |
| 22 | + hotelName: z.string().describe("Hotel name only, NO COMMAS (e.g. Marriott Marquis San Francisco US)"), |
| 23 | + checkinDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).describe("Check-in date in YYYY-MM-DD format"), |
| 24 | + checkoutDate: z.string().regex(/^\d{4}-\d{2}-\d{2}$/).describe("Check-out date in YYYY-MM-DD format"), |
| 25 | + adults: z.number().min(1).max(4).optional().default(2), |
| 26 | + currency: z.string().length(3).optional().default("USD"), |
| 27 | + }, |
| 28 | + async ({ hotelName, checkinDate, checkoutDate, adults, currency }) => { |
| 29 | + try { |
| 30 | + // Connects to your unified PHP tools route |
| 31 | + const response = await axios.get("https://www.businesshotels.com/mcp-server.php", { |
| 32 | + params: { |
| 33 | + route: "tools", |
| 34 | + hotelName, |
| 35 | + checkinDate, |
| 36 | + checkoutDate, |
| 37 | + adults, |
| 38 | + currency, |
| 39 | + // Using the live test key from your tool-config.html |
| 40 | + apiKey: "test-live-hotel-rates2025" |
57 | 41 | }, |
58 | | - ], |
59 | | - }; |
| 42 | + timeout: 5000 // Optimized for your sub-2-second response goal |
| 43 | + }); |
| 44 | + |
| 45 | + return { |
| 46 | + content: [ |
| 47 | + { |
| 48 | + type: "text", |
| 49 | + text: JSON.stringify(response.data, null, 2), |
| 50 | + }, |
| 51 | + ], |
| 52 | + }; |
| 53 | + } catch (error: any) { |
| 54 | + return { |
| 55 | + isError: true, |
| 56 | + content: [ |
| 57 | + { |
| 58 | + type: "text", |
| 59 | + text: `API Error: ${error.message}`, |
| 60 | + }, |
| 61 | + ], |
| 62 | + }; |
| 63 | + } |
60 | 64 | } |
61 | | - throw new Error("Tool not found"); |
62 | | -}); |
| 65 | +); |
63 | 66 |
|
| 67 | +/** |
| 68 | + * Main execution block using Stdio transport |
| 69 | + */ |
64 | 70 | async function main() { |
65 | 71 | const transport = new StdioServerTransport(); |
66 | 72 | await server.connect(transport); |
67 | | - console.error("BusinessHotels MCP server running on stdio"); |
| 73 | + console.error("BusinessHotels Agentic MCP Server running on stdio"); |
68 | 74 | } |
69 | 75 |
|
70 | 76 | main().catch((error) => { |
71 | | - console.error("Server error:", error); |
| 77 | + console.error("Fatal Server Error:", error); |
72 | 78 | process.exit(1); |
73 | 79 | }); |
0 commit comments