#!/usr/bin/env node // MCP Server - exposes dalidou tools to Claude Code on Windows import "dotenv/config"; import { Server } from "@modelcontextprotocol/sdk/server/index.js"; import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js"; import weather from "../tools/weather.js"; import gitea from "../tools/gitea.js"; import siemensDocs from "../tools/siemens-docs.js"; const server = new Server( { name: "dalidou-assistant", version: "1.3.0", }, { capabilities: { tools: {}, }, } ); // List available tools server.setRequestHandler(ListToolsRequestSchema, async () => { return { tools: [ // Weather tools { name: "get_current_weather", description: "Get current weather conditions in Rouyn-Noranda (temperature, wind, conditions)", inputSchema: { type: "object", properties: {}, required: [] } }, { name: "get_hourly_forecast", description: "Get hourly weather forecast for planning activities", inputSchema: { type: "object", properties: { days: { type: "number", description: "Days to forecast (1-7)" } } } }, { name: "get_daily_forecast", description: "Get daily weather forecast (highs, lows, conditions)", inputSchema: { type: "object", properties: { days: { type: "number", description: "Days to forecast (1-14)" } } } }, { name: "find_best_activity_windows", description: "Find best time windows for outdoor activities based on weather", inputSchema: { type: "object", properties: { activity: { type: "string", description: "Activity: skiing, cross-country-skiing, hiking, mushroom-hunting" }, days: { type: "number", description: "Days to search (1-7)" } }, required: ["activity"] } }, { name: "check_skiing_conditions", description: "Check if current conditions are good for cross-country skiing", inputSchema: { type: "object", properties: {} } }, // Gitea tools { name: "get_today_commits", description: "Get all git commits made today from Gitea", inputSchema: { type: "object", properties: {} } }, { name: "get_recent_activity", description: "Get recent git activity across all Gitea repos", inputSchema: { type: "object", properties: { days: { type: "number", description: "Days of history (default 7)" } } } }, { name: "list_repos", description: "List all repositories on Gitea", inputSchema: { type: "object", properties: {} } }, // Siemens Documentation tools { name: "siemens_docs_list", description: "List available Siemens documentation categories, NX Open class IDs, and usage info", inputSchema: { type: "object", properties: {} } }, { name: "siemens_docs_search", description: "Search Siemens Support Center documentation for a specific topic", inputSchema: { type: "object", properties: { query: { type: "string", description: "Search query (e.g., 'NXOpen Body.GetFaces', 'sketch constraints')" }, product: { type: "string", description: "Product to search: nx, teamcenter, simcenter, nastran (default: nx)" } }, required: ["query"] } }, { name: "siemens_docs_fetch", description: "Fetch a specific Siemens documentation page by URL", inputSchema: { type: "object", properties: { url: { type: "string", description: "Full URL of the documentation page to fetch" } }, required: ["url"] } }, { name: "siemens_auth_status", description: "Check Siemens Support Center authentication status", inputSchema: { type: "object", properties: {} } }, { name: "siemens_login", description: "Login to Siemens Support Center (use if session expired)", inputSchema: { type: "object", properties: {} } }, // NX Open Python Reference tools { name: "nxopen_get_class", description: "Get NX Open Python class documentation. Known classes: Session, Part, BasePart, PdmSession, CaeSession", inputSchema: { type: "object", properties: { className: { type: "string", description: "Class name (e.g., 'Session', 'Part', 'BasePart')" } }, required: ["className"] } }, { name: "nxopen_get_index", description: "Get NX Open Python Reference index pages (class list, functions, hierarchy)", inputSchema: { type: "object", properties: { indexType: { type: "string", description: "Index type: classes, annotated, hierarchy, functions, main (default: classes)" } } } }, { name: "nxopen_fetch_page", description: "Fetch any NX Open Python Reference page by page ID (e.g., 'a03318.html' for Session)", inputSchema: { type: "object", properties: { pagePath: { type: "string", description: "Page path (e.g., 'a03318.html', 'classes.html', 'functions_s.html')" } }, required: ["pagePath"] } } ] }; }); // Handle tool calls server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; try { let result; switch (name) { // Weather tools case "get_current_weather": result = await weather.getCurrentWeather(); break; case "get_hourly_forecast": result = await weather.getHourlyForecast(args?.days || 2); break; case "get_daily_forecast": result = await weather.getDailyForecast(args?.days || 7); break; case "find_best_activity_windows": result = await weather.findBestTimeWindows(args.activity, args?.days || 2); break; case "check_skiing_conditions": const current = await weather.getCurrentWeather(); const skiCheck = weather.isGoodForSkiing(current); result = { current_weather: current, good_for_skiing: skiCheck.good, assessment: skiCheck.reasons }; break; // Gitea tools case "get_today_commits": result = await gitea.getAllTodayCommits(); break; case "get_recent_activity": result = await gitea.getRepoActivity(args?.days || 7); break; case "list_repos": result = await gitea.listRepos(); break; // Siemens Documentation tools case "siemens_docs_list": result = await siemensDocs.listAvailableDocs(); break; case "siemens_docs_search": result = await siemensDocs.searchDocs(args.query, args.product || "nx"); break; case "siemens_docs_fetch": result = await siemensDocs.fetchDocPage(args.url); break; case "siemens_auth_status": result = await siemensDocs.checkAuthStatus(); break; case "siemens_login": result = await siemensDocs.performLogin(); break; // NX Open Python Reference tools case "nxopen_get_class": result = await siemensDocs.fetchNXOpenClass(args.className); break; case "nxopen_get_index": result = await siemensDocs.getNXOpenIndex(args?.indexType || "classes"); break; case "nxopen_fetch_page": result = await siemensDocs.fetchNXOpenPythonRef(args.pagePath); break; default: return { content: [{ type: "text", text: `Unknown tool: ${name}` }], isError: true }; } return { content: [{ type: "text", text: typeof result === "string" ? result : JSON.stringify(result, null, 2) }] }; } catch (error) { return { content: [{ type: "text", text: `Error: ${error.message}` }], isError: true }; } }); // Cleanup on exit process.on("SIGINT", async () => { await siemensDocs.closeBrowser(); process.exit(0); }); process.on("SIGTERM", async () => { await siemensDocs.closeBrowser(); process.exit(0); }); // Start server async function main() { const transport = new StdioServerTransport(); await server.connect(transport); console.error("Dalidou MCP Server v1.3.0 running on stdio (with NX Open Python Reference)"); } main().catch(console.error);