#!/usr/bin/env node
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
import { z } from "zod";
import { DataverseClient } from "./dataverse-client.js";
// No dotenv/config needed; credentials come from process.env
import {
createTableTool,
getTableTool,
updateTableTool,
deleteTableTool,
listTablesTool
} from "./tools/table-tools.js";
import {
createColumnTool,
getColumnTool,
updateColumnTool,
deleteColumnTool,
listColumnsTool
} from "./tools/column-tools.js";
import {
createRelationshipTool,
getRelationshipTool,
deleteRelationshipTool,
listRelationshipsTool
} from "./tools/relationship-tools.js";
import {
createOptionSetTool,
getOptionSetTool,
updateOptionSetTool,
deleteOptionSetTool,
listOptionSetsTool,
getOptionSetOptionsTool
} from "./tools/optionset-tools.js";
import {
createPublisherTool,
createSolutionTool,
getSolutionTool,
getPublisherTool,
listSolutionsTool,
listPublishersTool,
setSolutionContextTool,
getSolutionContextTool,
clearSolutionContextTool
} from "./tools/solution-tools.js";
import {
createRoleTool,
getRoleTool,
updateRoleTool,
deleteRoleTool,
listRolesTool,
addPrivilegesToRoleTool,
removePrivilegeFromRoleTool,
replaceRolePrivilegesTool,
getRolePrivilegesTool,
assignRoleToUserTool,
removeRoleFromUserTool,
assignRoleToTeamTool,
removeRoleFromTeamTool
} from "./tools/role-tools.js";
import {
createTeamTool,
getTeamTool,
updateTeamTool,
deleteTeamTool,
listTeamsTool,
addMembersToTeamTool,
removeMembersFromTeamTool,
getTeamMembersTool,
convertOwnerTeamToAccessTeamTool
} from "./tools/team-tools.js";
import {
createBusinessUnitTool,
getBusinessUnitTool,
updateBusinessUnitTool,
deleteBusinessUnitTool,
listBusinessUnitsTool,
getBusinessUnitHierarchyTool,
setBusinessUnitParentTool,
getBusinessUnitUsersTool,
getBusinessUnitTeamsTool
} from "./tools/businessunit-tools.js";
import {
exportSolutionSchemaTool,
generateMermaidDiagramTool
} from "./tools/schema-tools.js";
import {
generateWebAPICallTool
} from "./tools/webapi-tools.js";
import {
generatePowerPagesWebAPICallTool
} from "./tools/powerpages-webapi-tools.js";
import {
managePowerPagesWebAPIConfigTool
} from "./tools/powerpages-config-tools.js";
import {
createAutoNumberColumnTool,
updateAutoNumberFormatTool,
setAutoNumberSeedTool,
getAutoNumberColumnTool,
listAutoNumberColumnsTool,
convertToAutoNumberTool
} from "./tools/autonumber-tools.js";
import {
registerWebAPIResources
} from "./resources/webapi-resources.js";
import {
registerPowerPagesResources
} from "./resources/powerpages-resources.js";
import {
registerWebResourceTools
} from "./tools/webresource-tools.js";
// Create MCP server
const server = new McpServer({
name: "dataverse-mcp",
version: "0.2.2"
});
// Register all tools (now using DataverseClient with process.env credentials)
createTableTool(server);
getTableTool(server);
updateTableTool(server);
deleteTableTool(server);
listTablesTool(server);
createColumnTool(server);
getColumnTool(server);
updateColumnTool(server);
deleteColumnTool(server);
listColumnsTool(server);
createRelationshipTool(server);
getRelationshipTool(server);
deleteRelationshipTool(server);
listRelationshipsTool(server);
createOptionSetTool(server);
getOptionSetTool(server);
updateOptionSetTool(server);
deleteOptionSetTool(server);
listOptionSetsTool(server);
getOptionSetOptionsTool(server);
createPublisherTool(server);
createSolutionTool(server);
getSolutionTool(server);
getPublisherTool(server);
listSolutionsTool(server);
listPublishersTool(server);
setSolutionContextTool(server);
getSolutionContextTool(server);
clearSolutionContextTool(server);
createRoleTool(server);
getRoleTool(server);
updateRoleTool(server);
deleteRoleTool(server);
listRolesTool(server);
addPrivilegesToRoleTool(server);
removePrivilegeFromRoleTool(server);
replaceRolePrivilegesTool(server);
getRolePrivilegesTool(server);
assignRoleToUserTool(server);
removeRoleFromUserTool(server);
assignRoleToTeamTool(server);
removeRoleFromTeamTool(server);
createTeamTool(server);
getTeamTool(server);
updateTeamTool(server);
deleteTeamTool(server);
listTeamsTool(server);
addMembersToTeamTool(server);
removeMembersFromTeamTool(server);
getTeamMembersTool(server);
convertOwnerTeamToAccessTeamTool(server);
createBusinessUnitTool(server);
getBusinessUnitTool(server);
updateBusinessUnitTool(server);
deleteBusinessUnitTool(server);
listBusinessUnitsTool(server);
getBusinessUnitHierarchyTool(server);
setBusinessUnitParentTool(server);
getBusinessUnitUsersTool(server);
getBusinessUnitTeamsTool(server);
exportSolutionSchemaTool(server);
generateMermaidDiagramTool(server);
generateWebAPICallTool(server);
generatePowerPagesWebAPICallTool(server);
managePowerPagesWebAPIConfigTool(server);
createAutoNumberColumnTool(server);
updateAutoNumberFormatTool(server);
setAutoNumberSeedTool(server);
getAutoNumberColumnTool(server);
listAutoNumberColumnsTool(server);
convertToAutoNumberTool(server);
registerWebAPIResources(server, {} as any);
registerPowerPagesResources(server, {} as any);
registerWebResourceTools(server);
// @ts-ignore
import cors from 'cors';
import express from "express";
const app = express();
app.use(cors());
// ΠΡΟΣΟΧΗ: Μην χρησιμοποιείς το app.use(express.json()) παγκόσμια!
// Το MCP SDK χρειάζεται το stream του /messages καθαρό.
// 1. Δήλωση στην κορυφή (έξω από τα app.get/post)
let transport: any = null;
// 2. Το SSE Endpoint
app.get("/sse", async (req, res) => {
console.log("🚀 New SSE Connection Attempt");
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
res.setHeader('X-Accel-Buffering', 'no');
// Εδώ δίνουμε τιμή στη μεταβλητή που δηλώσαμε πάνω
transport = new SSEServerTransport("/messages", res);
await server.connect(transport);
res.on('close', () => {
console.log("🔌 SSE connection closed");
// Μην το κάνεις null αμέσως για να προλάβει το POST
setTimeout(() => { transport = null; }, 5000);
});
});
// 3. Το Messages Endpoint
app.post("/messages", async (req, res) => {
if (transport) {
try {
await transport.handlePostMessage(req, res);
} catch (err) {
console.error("❌ Error handling message:", err);
res.status(500).send("Internal Server Error");
}
} else {
res.status(400).send("No active session");
}
});
const PORT = parseInt(process.env.PORT || "8000", 10);
app.listen(PORT, "0.0.0.0", () => {
console.error(`🚀 Dataverse MCP server running on port ${PORT}`);
});