Files
proxmox/mcp-unifi/src/index.ts
defiQUG fbda1b4beb
Some checks failed
Deploy to Phoenix / deploy (push) Has been cancelled
docs: Ledger Live integration, contract deploy learnings, NEXT_STEPS updates
- ADD_CHAIN138_TO_LEDGER_LIVE: Ledger form done; public code review repo bis-innovations/LedgerLive; init/push commands
- CONTRACT_DEPLOYMENT_RUNBOOK: Chain 138 gas price 1 gwei, 36-addr check, TransactionMirror workaround
- CONTRACT_*: AddressMapper, MirrorManager deployed 2026-02-12; 36-address on-chain check
- NEXT_STEPS_FOR_YOU: Ledger done; steps completable now (no LAN); run-completable-tasks-from-anywhere
- MASTER_INDEX, OPERATOR_OPTIONAL, SMART_CONTRACTS_INVENTORY_SIMPLE: updates
- LEDGER_BLOCKCHAIN_INTEGRATION_COMPLETE: bis-innovations/LedgerLive reference

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-12 15:46:57 -08:00

111 lines
3.0 KiB
JavaScript

#!/usr/bin/env node
/**
* MCP Server for UniFi Controller
*
* Entry point for the Model Context Protocol server that provides
* tools for managing Ubiquiti UniFi/UDM Pro devices
*/
import { readFileSync } from 'fs';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';
import { homedir } from 'os';
import { UnifiServer } from './server/UnifiServer.js';
import { ApiMode } from 'unifi-api';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// Load environment variables from ~/.env file (standardized location)
const envPath = join(homedir(), '.env');
const envPathFallback = join(__dirname, '../.env');
function loadEnvFile(filePath: string): boolean {
try {
const envFile = readFileSync(filePath, 'utf8');
const envVars = envFile.split('\n').filter(
(line) => line.includes('=') && !line.trim().startsWith('#')
);
for (const line of envVars) {
const [key, ...values] = line.split('=');
// Validate key is a valid environment variable name
if (key && values.length > 0 && /^[A-Z_][A-Z0-9_]*$/.test(key.trim())) {
// Remove surrounding quotes if present and trim
let value = values.join('=').trim();
if (
(value.startsWith('"') && value.endsWith('"')) ||
(value.startsWith("'") && value.endsWith("'"))
) {
value = value.slice(1, -1);
}
process.env[key.trim()] = value;
}
}
return true;
} catch (error) {
return false;
}
}
// Try ~/.env first, then fallback to relative path
if (!loadEnvFile(envPath)) {
if (!loadEnvFile(envPathFallback)) {
console.error('Warning: Could not load .env file from ~/.env or ../.env');
}
}
// Get configuration from environment variables
const baseUrl = process.env.UNIFI_UDM_URL || 'https://192.168.1.1';
const apiMode = (process.env.UNIFI_API_MODE || 'private') as ApiMode;
const siteId = process.env.UNIFI_SITE_ID;
const verifySSL = process.env.UNIFI_VERIFY_SSL !== 'false';
let config: {
baseUrl: string;
apiMode: ApiMode;
siteId?: string;
verifySSL: boolean;
apiKey?: string;
username?: string;
password?: string;
};
if (apiMode === ApiMode.OFFICIAL) {
const apiKey = process.env.UNIFI_API_KEY;
if (!apiKey) {
console.error('Error: UNIFI_API_KEY must be set in environment variables for Official API mode');
process.exit(1);
}
config = {
baseUrl,
apiMode,
apiKey,
siteId,
verifySSL,
};
} else {
const username = process.env.UNIFI_USERNAME;
const password = process.env.UNIFI_PASSWORD;
if (!username || !password) {
console.error('Error: UNIFI_USERNAME and UNIFI_PASSWORD must be set in environment variables for Private API mode');
process.exit(1);
}
config = {
baseUrl,
apiMode,
username,
password,
siteId,
verifySSL,
};
}
// Create and run the server
const server = new UnifiServer(config);
server.run().catch((error) => {
console.error('Fatal error:', error);
process.exit(1);
});