microsoft-todo-mcp-server
Version:
Microsoft Todo MCP service for Claude and Cursor. Fork of @jhirono/todomcp
123 lines (122 loc) • 5.06 kB
JavaScript
// src/setup.ts
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
import { join } from "path";
import { homedir } from "os";
import { spawn } from "child_process";
import readline from "readline";
var rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
var question = (query) => {
return new Promise((resolve) => rl.question(query, resolve));
};
async function setup() {
console.log("\u{1F680} Microsoft To Do MCP Server Setup");
console.log("==================================\n");
const configDir = process.platform === "win32" ? join(process.env.APPDATA || join(homedir(), "AppData", "Roaming"), "microsoft-todo-mcp") : join(homedir(), ".config", "microsoft-todo-mcp");
const tokenPath = join(configDir, "tokens.json");
if (existsSync(tokenPath)) {
const answer = await question("Tokens already exist. Reconfigure? (y/N): ");
if (answer.toLowerCase() !== "y") {
console.log("Setup cancelled.");
process.exit(0);
}
}
let hasEnvFile = existsSync(".env");
if (!hasEnvFile) {
console.log("\n\u{1F4CB} Azure App Registration Required");
console.log("You need to create an app registration in Azure Portal first.");
console.log("\nSteps:");
console.log("1. Go to https://portal.azure.com");
console.log("2. Navigate to 'App registrations' and create a new registration");
console.log("3. Set redirect URI to: http://localhost:3000/callback");
console.log("4. Add these API permissions: Tasks.Read, Tasks.ReadWrite, User.Read");
console.log("5. Create a client secret\n");
const clientId = await question("Enter your CLIENT_ID: ");
const clientSecret = await question("Enter your CLIENT_SECRET: ");
const tenantId = await question("Enter your TENANT_ID (press Enter for 'organizations'): ") || "organizations";
const envContent = `CLIENT_ID=${clientId}
CLIENT_SECRET=${clientSecret}
TENANT_ID=${tenantId}
REDIRECT_URI=http://localhost:3000/callback
`;
writeFileSync(".env", envContent);
console.log("\u2705 Created .env file");
}
console.log("\n\u{1F510} Starting authentication flow...");
console.log("A browser window will open. Please sign in with your Microsoft account.\n");
const authProcess = spawn("node", ["dist/auth-server.js"], {
stdio: "inherit",
shell: true
});
authProcess.on("close", async (code) => {
var _a, _b, _c;
if (code === 0) {
console.log("\n\u2705 Authentication successful!");
const localTokens = join(process.cwd(), "tokens.json");
if (existsSync(localTokens)) {
const tokens = JSON.parse(readFileSync(localTokens, "utf8"));
const env = readFileSync(".env", "utf8");
const clientId = (_a = env.match(/CLIENT_ID=(.+)/)) == null ? void 0 : _a[1];
const clientSecret = (_b = env.match(/CLIENT_SECRET=(.+)/)) == null ? void 0 : _b[1];
const tenantId = ((_c = env.match(/TENANT_ID=(.+)/)) == null ? void 0 : _c[1]) || "organizations";
const enhancedTokens = {
...tokens,
clientId,
clientSecret,
tenantId
};
mkdirSync(configDir, { recursive: true });
writeFileSync(tokenPath, JSON.stringify(enhancedTokens, null, 2));
console.log(`
\u{1F4C1} Tokens saved to: ${tokenPath}`);
await updateClaudeConfig();
console.log("\n\u{1F389} Setup complete! Microsoft To Do MCP is ready to use.");
console.log("Restart Claude Desktop to activate the integration.");
}
} else {
console.error("\n\u274C Authentication failed. Please try again.");
}
rl.close();
});
}
async function updateClaudeConfig() {
const claudeConfigPath = process.platform === "win32" ? join(process.env.APPDATA || "", "Claude", "claude_desktop_config.json") : process.platform === "darwin" ? join(homedir(), "Library", "Application Support", "Claude", "claude_desktop_config.json") : join(homedir(), ".config", "Claude", "claude_desktop_config.json");
if (!existsSync(claudeConfigPath)) {
console.log("\n\u26A0\uFE0F Claude config not found. Add this to your Claude desktop config manually:");
console.log(
JSON.stringify(
{
"microsoft-todo": {
command: "npx",
args: ["microsoft-todo-mcp-server"],
env: {}
}
},
null,
2
)
);
return;
}
try {
const config = JSON.parse(readFileSync(claudeConfigPath, "utf8"));
if (!config.mcpServers) {
config.mcpServers = {};
}
config.mcpServers["microsoft-todo"] = {
command: "npx",
args: ["microsoft-todo-mcp-server"],
env: {}
// No need for tokens in env anymore!
};
writeFileSync(claudeConfigPath, JSON.stringify(config, null, 2));
console.log("\n\u2705 Updated Claude Desktop configuration");
} catch (error) {
console.error("\n\u26A0\uFE0F Could not update Claude config automatically:", error);
}
}
setup().catch(console.error);
//# sourceMappingURL=setup.js.map