Ctrl K
ComunidadGuías…

setup.js

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
#!/usr/bin/env node

/**
 * Follow Up Boss MCP Server - Setup Wizard
 *
 * Interactive setup that:
 * 1. Asks for your FUB API key
 * 2. Creates a .env file
 * 3. Tests the connection
 * 4. Shows next steps
 */

import { createInterface } from 'readline';
import { writeFileSync, existsSync } from 'fs';
import { resolve, dirname } from 'path';
import { fileURLToPath } from 'url';

const __dirname = dirname(fileURLToPath(import.meta.url));

const rl = createInterface({
  input: process.stdin,
  output: process.stdout,
});

function ask(question) {
  return new Promise((resolve) => {
    rl.question(question, (answer) => resolve(answer.trim()));
  });
}

async function testConnection(apiKey) {
  // Dynamic import to avoid issues if axios isn't installed yet
  const { default: axios } = await import('axios');

  const response = await axios.get('https://api.followupboss.com/v1/me', {
    auth: { username: apiKey, password: '' },
    headers: { 'Accept': 'application/json' },
    timeout: 10000,
  });

  return response.data;
}

async function main() {
  console.log('');
  console.log('===========================================');
  console.log('  Follow Up Boss MCP Server - Setup');
  console.log('===========================================');
  console.log('');
  console.log('This will set up your connection to Follow Up Boss.');
  console.log('You\'ll need your FUB API key.');
  console.log('');
  console.log('To find it: Log into FUB > Admin > Integrations > API Keys & Lead Email > Create API Key');
  console.log('');

  const apiKey = await ask('Enter your FUB API key: ');

  if (!apiKey) {
    console.log('\nNo API key entered. Setup cancelled.');
    rl.close();
    process.exit(1);
  }

  console.log('\nTesting connection...');

  try {
    const user = await testConnection(apiKey);
    const name = user.name || user.firstName || 'Unknown';
    const account = user.accountName || user.account?.name || '';

    console.log('');
    console.log('  Connected successfully!');
    if (name) console.log(`  User: ${name}`);
    if (account) console.log(`  Account: ${account}`);
    console.log('');
  } catch (error) {
    if (error.response?.status === 401) {
      console.log('\nInvalid API key. Please check your key and try again.');
      console.log('Find it at: FUB > Admin > Integrations > API Keys & Lead Email');
    } else if (error.code === 'ENOTFOUND' || error.code === 'ECONNREFUSED') {
      console.log('\nCould not connect to Follow Up Boss. Check your internet connection.');
    } else {
      console.log(`\nConnection failed: ${error.message}`);
    }
    rl.close();
    process.exit(1);
  }

  // Safe mode question
  console.log('Choose an installation mode:');
  console.log('');
  console.log('  1. Safe Mode (recommended)');
  console.log('     Read, create, and update your FUB data.');
  console.log('     Delete tools are DISABLED. Nothing can be deleted.');
  console.log('');
  console.log('  2. Full Access');
  console.log('     All 160 tools enabled, including delete operations.');
  console.log('     Use with caution -- AI can delete contacts, deals, etc.');
  console.log('');
  const modeChoice = await ask('Enter 1 or 2 (default: 1): ');
  const safeMode = modeChoice !== '2';

  if (safeMode) {
    console.log('\n  Safe Mode enabled. Delete tools will be disabled.');
  } else {
    console.log('\n  Full Access enabled. All tools including delete are active.');
  }
  console.log('');

  // Write .env file
  const envPath = resolve(__dirname, '.env');
  const envExists = existsSync(envPath);

  if (envExists) {
    const overwrite = await ask('.env file already exists. Overwrite? (y/n): ');
    if (overwrite.toLowerCase() !== 'y') {
      console.log('\nSetup complete (kept existing .env file).');
      rl.close();
      printNextSteps(safeMode);
      return;
    }
  }

  writeFileSync(envPath, `# Follow Up Boss API Key\nFUB_API_KEY=${apiKey}\n\n# Safe Mode: disable all delete tools (true/false)\nFUB_SAFE_MODE=${safeMode}\n`);
  console.log('Saved settings to .env file.');

  rl.close();
  printNextSteps(safeMode);
}

function printNextSteps(safeMode) {
  const fullPath = resolve(__dirname);

  const envBlock = { FUB_API_KEY: "your_api_key_here" };
  if (safeMode) envBlock.FUB_SAFE_MODE = "true";

  console.log('');
  console.log('===========================================');
  console.log('  Next Steps: Connect to Claude');
  console.log('===========================================');
  console.log('');
  console.log(`Mode: ${safeMode ? 'SAFE MODE (delete tools disabled)' : 'FULL ACCESS (all tools enabled)'}`);
  console.log('');
  console.log('OPTION 1: Claude Desktop');
  console.log('');
  console.log('Add this to your Claude Desktop config file:');
  console.log('');
  console.log('  Mac:   ~/Library/Application Support/Claude/claude_desktop_config.json');
  console.log('  Win:   %APPDATA%\\Claude\\claude_desktop_config.json');
  console.log('');
  console.log(JSON.stringify({
    mcpServers: {
      "followupboss": {
        command: "node",
        args: [`${fullPath}/index.js`],
        env: envBlock
      }
    }
  }, null, 2));
  console.log('');
  console.log('(Replace "your_api_key_here" with your actual API key,');
  console.log(' or remove the env block if you\'re using the .env file)');
  console.log('');
  console.log('OPTION 2: Claude Code');
  console.log('');
  console.log(`  claude mcp add followupboss -- node ${fullPath}/index.js`);
  console.log('');
  console.log('Then restart Claude and try asking:');
  console.log('  "Show me my recent leads in Follow Up Boss"');
  console.log('');
}

main().catch((err) => {
  console.error('Setup failed:', err.message);
  process.exit(1);
});