#!/usr/bin/env node
/**
* Interactive setup wizard for Obsidian MCP Server
* Uses @inquirer/prompts for better cross-platform compatibility
*/
import { input, password, select, confirm } from '@inquirer/prompts';
import { writeFileSync, existsSync, readFileSync } from 'fs';
import { join } from 'path';
async function runSetup(): Promise<boolean> {
console.log('');
console.log('╔══════════════════════════════════════════════════════════════╗');
console.log('║ Obsidian MCP Server - Setup Wizard ║');
console.log('╚══════════════════════════════════════════════════════════════╝');
console.log('');
console.log('This wizard will help you configure the MCP server.');
console.log('Press Ctrl+C at any time to cancel.');
console.log('');
const envPath = join(process.cwd(), '.env');
try {
// Check for existing .env
if (existsSync(envPath)) {
const existingEnv = readFileSync(envPath, 'utf-8');
const hasValidKey = existingEnv.includes('OBSIDIAN_API_KEY') &&
!existingEnv.includes('your-api-key') &&
!existingEnv.includes('your-api-key-here');
if (hasValidKey) {
const useExisting = await confirm({
message: 'An existing configuration was found. Use it?',
default: true,
});
if (useExisting) {
console.log('');
console.log('✓ Using existing configuration.');
console.log('');
return true;
}
}
}
// Step 1: API Key
console.log('\n▶ Step 1: Obsidian API Configuration\n');
const apiKey = await password({
message: 'Enter your Obsidian API Key:',
mask: '*',
validate: (value) => {
if (!value || value.trim() === '') {
return 'API Key is required. Find it in Obsidian: Settings → Community Plugins → Local REST API';
}
return true;
},
});
// Step 2: API URL
const apiUrl = await input({
message: 'Obsidian API URL:',
default: 'http://127.0.0.1:27123',
validate: (value) => {
if (!value.startsWith('http')) {
return 'URL must start with http:// or https://';
}
return true;
},
});
// Step 3: Transport Mode
console.log('\n▶ Step 2: Transport Mode\n');
const transport = await select({
message: 'Select transport mode:',
choices: [
{ name: 'stdio - For Claude Desktop and command-line tools', value: 'stdio' },
{ name: 'http - For Open WebUI and web-based clients (Streamable HTTP)', value: 'http' },
],
default: 'stdio',
});
// Step 4: Port (if HTTP)
let port = '3000';
if (transport === 'http') {
console.log('\n▶ Step 3: Server Configuration\n');
const portInput = await input({
message: 'Port for HTTP server:',
default: '3000',
validate: (value) => {
const num = parseInt(value);
if (isNaN(num) || num < 1 || num > 65535) {
return 'Please enter a valid port number (1-65535)';
}
return true;
},
});
port = portInput;
}
// Step 5: Debug Mode
const debug = await confirm({
message: 'Enable debug logging?',
default: false,
});
// Build .env content
const envContent = `# Obsidian MCP Server Configuration
# Generated by setup wizard
# Required: Your Obsidian Local REST API Key
OBSIDIAN_API_KEY=${apiKey.trim()}
# Optional: Obsidian REST API URL
OBSIDIAN_API_URL=${apiUrl.trim()}
# MCP Transport mode - 'stdio' or 'http'
MCP_TRANSPORT=${transport}
# Port for HTTP mode
MCP_PORT=${port}
# Enable debug logging
DEBUG=${debug}
`;
// Write .env file
writeFileSync(envPath, envContent);
// Success message
console.log('');
console.log('========================================');
console.log(' Configuration Saved! ✓');
console.log('========================================');
console.log('');
if (transport === 'http') {
console.log('Start the server:');
console.log(' npm run start:http');
console.log('');
console.log('Configure Open WebUI:');
console.log(` URL: http://localhost:${port}/mcp`);
console.log(' Type: MCP Streamable HTTP');
console.log(' Auth: None');
} else {
console.log('Start the server:');
console.log(' npm start');
console.log('');
console.log('Configure Claude Desktop:');
console.log(' Add to claude_desktop_config.json');
}
console.log('');
console.log('Re-run setup anytime: npm run setup');
console.log('');
return true;
} catch (error) {
if (error instanceof Error && error.message.includes('User force closed')) {
console.log('\n\nSetup cancelled by user.');
return false;
}
console.error('\nError during setup:', error);
return false;
}
}
// Always run when executed directly
runSetup().then((success) => {
process.exit(success ? 0 : 1);
});