Major configuration and tooling updates: Authentication Changes: - Remove username/password authentication support - Require PORTAINER_URL and PORTAINER_API_KEY (both mandatory) - Simplify PortainerConfig class and validation logic - Update all documentation to reflect API key requirement Multiple Runtime Support: - Add uvx support for running without installation - Add uv support with dedicated wrapper script - Add npx support with Node.js wrapper script - Maintain backward compatibility with direct Python execution Documentation Updates: - Comprehensive README.md with all execution methods - Detailed USAGE.md with step-by-step instructions - Updated .env.example with clear required vs optional sections - Enhanced docstrings in server.py and config.py Tooling Support: - package.json for npm/npx support with cross-platform wrapper - scripts/run-with-uv.py for uv integration - bin/portainer-core-mcp Node.js wrapper for npx - test_uvx.py for uvx functionality testing Configuration Improvements: - Clear separation of required vs optional environment variables - Better validation error messages - Simplified authentication flow - Enhanced project metadata in pyproject.toml 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
115 lines
3.0 KiB
JavaScript
Executable File
115 lines
3.0 KiB
JavaScript
Executable File
#!/usr/bin/env node
|
|
|
|
const { spawn } = require('child_process');
|
|
const path = require('path');
|
|
|
|
// Get the directory where this script is located
|
|
const scriptDir = path.dirname(__filename);
|
|
const runServerPath = path.join(scriptDir, '..', 'run_server.py');
|
|
|
|
// Check if Python is available
|
|
function checkPython() {
|
|
return new Promise((resolve, reject) => {
|
|
const pythonCmd = process.platform === 'win32' ? 'python' : 'python3';
|
|
const proc = spawn(pythonCmd, ['--version'], { stdio: 'pipe' });
|
|
|
|
proc.on('close', (code) => {
|
|
if (code === 0) {
|
|
resolve(pythonCmd);
|
|
} else {
|
|
// Try alternative python command
|
|
const altPythonCmd = 'python';
|
|
const altProc = spawn(altPythonCmd, ['--version'], { stdio: 'pipe' });
|
|
|
|
altProc.on('close', (altCode) => {
|
|
if (altCode === 0) {
|
|
resolve(altPythonCmd);
|
|
} else {
|
|
reject(new Error('Python is not installed or not in PATH'));
|
|
}
|
|
});
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
// Run the Python server
|
|
async function runServer() {
|
|
try {
|
|
const pythonCmd = await checkPython();
|
|
console.log('🚀 Starting Portainer Core MCP Server via npx...');
|
|
|
|
const proc = spawn(pythonCmd, [runServerPath], {
|
|
stdio: 'inherit',
|
|
cwd: path.dirname(runServerPath)
|
|
});
|
|
|
|
proc.on('error', (err) => {
|
|
console.error('❌ Failed to start server:', err.message);
|
|
process.exit(1);
|
|
});
|
|
|
|
proc.on('close', (code) => {
|
|
if (code !== 0) {
|
|
console.error(`❌ Server exited with code ${code}`);
|
|
process.exit(code);
|
|
}
|
|
});
|
|
|
|
// Handle signals
|
|
process.on('SIGINT', () => {
|
|
console.log('\n👋 Stopping server...');
|
|
proc.kill('SIGINT');
|
|
});
|
|
|
|
process.on('SIGTERM', () => {
|
|
console.log('\n👋 Stopping server...');
|
|
proc.kill('SIGTERM');
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error('❌ Error:', error.message);
|
|
console.error('💡 Please ensure Python 3.8+ is installed and in your PATH');
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
// Show help
|
|
function showHelp() {
|
|
console.log(`
|
|
Portainer Core MCP Server
|
|
|
|
Usage:
|
|
npx portainer-core-mcp [options]
|
|
|
|
Options:
|
|
-h, --help Show this help message
|
|
-v, --version Show version information
|
|
|
|
Environment Variables:
|
|
PORTAINER_URL Portainer instance URL (required)
|
|
PORTAINER_API_KEY Portainer API key (required)
|
|
LOG_LEVEL Logging level (default: INFO)
|
|
DEBUG Enable debug mode (default: false)
|
|
|
|
Examples:
|
|
npx portainer-core-mcp
|
|
PORTAINER_URL=https://portainer.example.com PORTAINER_API_KEY=your-key npx portainer-core-mcp
|
|
`);
|
|
}
|
|
|
|
// Main
|
|
const args = process.argv.slice(2);
|
|
|
|
if (args.includes('-h') || args.includes('--help')) {
|
|
showHelp();
|
|
process.exit(0);
|
|
}
|
|
|
|
if (args.includes('-v') || args.includes('--version')) {
|
|
const packageJson = require('../package.json');
|
|
console.log(`portainer-core-mcp v${packageJson.version}`);
|
|
process.exit(0);
|
|
}
|
|
|
|
runServer().catch(console.error); |