UNPKG

yszl-mcp

Version:

Scenic Area Tourist Flow Query Server with official MCP SDK

214 lines (200 loc) 5.7 kB
/** * Startup file for SSE communication protocol mode */ import express from 'express'; import bodyParser from 'body-parser'; import dotenv from 'dotenv'; dotenv.config(); // Import tools import { TouristFlowTool } from '../tools/touristFlowTool.js'; import { CumulativeTouristFlowTool } from '../tools/cumulativeTouristFlowTool.js'; import { DailyTouristFlowTool } from '../tools/dailyTouristFlowTool.js'; import { ProvinceOriginTool } from '../tools/provinceOriginTool.js'; import { GenderPortraitTool } from '../tools/genderPortraitTool.js'; import { AgePortraitTool } from '../tools/agePortraitTool.js'; // Import SSE transport import { SseTransport } from '../transport/sse.js'; // Create Express application const app = express(); const port = process.env.PORT || 3000; // Enable CORS app.use((req, res, next) => { res.header('Access-Control-Allow-Origin', '*'); res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept'); res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS'); if (req.method === 'OPTIONS') { return res.sendStatus(200); } next(); }); // Use middleware to parse JSON app.use(bodyParser.json()); // Create tool instances const toolInstances = { touristFlowTool: new TouristFlowTool(), cumulativeTouristFlowTool: new CumulativeTouristFlowTool(), dailyTouristFlowTool: new DailyTouristFlowTool(), provinceOriginTool: new ProvinceOriginTool(), genderPortraitTool: new GenderPortraitTool(), agePortraitTool: new AgePortraitTool() }; // MCP manifest endpoint with SSE mode app.get('/manifest', (req, res) => { res.json({ schema_version: "v1", name_for_human: "Tourist Flow Query Service", name_for_model: "touristFlowQuery", description_for_human: "Provides real-time tourist flow and visitor profile query services for scenic areas", description_for_model: "A service for querying real-time tourist flow, cumulative flow, daily flow statistics and visitor profiles (origin, gender, age distribution) in scenic areas", auth: { type: "none" }, api: { type: "sse", sse: { enabled: true } }, tools_endpoint: "/api/tools" }); }); // Tool metadata endpoint app.get('/api/tools', (req, res) => { res.json({ tools: [ { name: 'TouristFlow', description: 'Get real-time tourist flow information', inputs: { type: 'object', properties: { scId: { type: 'string', description: 'Scenic Area ID' } }, required: ['scId'] } }, { name: 'CumulativeTouristFlow', description: 'Get cumulative tourist flow statistics', inputs: { type: 'object', properties: { scId: { type: 'string', description: 'Scenic Area ID' } }, required: ['scId'] } }, { name: 'DailyTouristFlow', description: 'Get daily tourist flow statistics', inputs: { type: 'object', properties: { scId: { type: 'string', description: 'Scenic Area ID' }, day: { type: 'string', description: 'Date in YYYYMMDD format, e.g. 20220101' } }, required: ['scId', 'day'] } }, { name: 'ProvinceOrigin', description: 'Get tourist province origin distribution', inputs: { type: 'object', properties: { scId: { type: 'string', description: 'Scenic Area ID' }, day: { type: 'string', description: 'Date in YYYYMMDD format, e.g. 20220101' } }, required: ['scId', 'day'] } }, { name: 'GenderPortrait', description: 'Get tourist gender distribution', inputs: { type: 'object', properties: { scId: { type: 'string', description: 'Scenic Area ID' }, day: { type: 'string', description: 'Date in YYYYMMDD format, e.g. 20220101' } }, required: ['scId', 'day'] } }, { name: 'AgePortrait', description: 'Get tourist age distribution', inputs: { type: 'object', properties: { scId: { type: 'string', description: 'Scenic Area ID' }, day: { type: 'string', description: 'Date in YYYYMMDD format, e.g. 20220101' } }, required: ['scId', 'day'] } } ] }); }); // Root endpoint app.get('/', (req, res) => { res.json({ name: 'Tourist Flow Query Service (SSE Mode)', version: '1.1.8', status: 'running', endpoints: [ '/manifest', '/api/tools', '/sse', '/sse/execute' ] }); }); // Health check app.get('/health', (req, res) => { res.json({ status: 'ok' }); }); // Error handling middleware app.use((err, req, res, next) => { console.error('Server error:', err); res.status(500).json({ status: 'error', message: 'Internal server error' }); }); // Initialize and start the SSE transport const sseTransport = new SseTransport(app, toolInstances); sseTransport.start(); // Start server const server = app.listen(port, () => { console.log(`Tourist Flow Query Service (SSE Mode) running on port ${port}`); });