signoz-mcp-server
Version:
Model Context Protocol server for SigNoz observability platform
256 lines ⢠9.67 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const commander_1 = require("commander");
const chalk_1 = __importDefault(require("chalk"));
const ora_1 = __importDefault(require("ora"));
const inquirer_1 = __importDefault(require("inquirer"));
const fs_1 = require("fs");
const path_1 = require("path");
const os_1 = require("os");
const program = new commander_1.Command();
const CONFIG_DIR = (0, path_1.join)((0, os_1.homedir)(), '.signoz-mcp');
const CONFIG_FILE = (0, path_1.join)(CONFIG_DIR, 'config.json');
function ensureConfigDir() {
if (!(0, fs_1.existsSync)(CONFIG_DIR)) {
(0, fs_1.mkdirSync)(CONFIG_DIR, { recursive: true });
}
}
function saveConfig(config) {
ensureConfigDir();
(0, fs_1.writeFileSync)(CONFIG_FILE, JSON.stringify(config, null, 2));
}
function loadConfig() {
try {
if ((0, fs_1.existsSync)(CONFIG_FILE)) {
return JSON.parse(require('fs').readFileSync(CONFIG_FILE, 'utf8'));
}
}
catch (error) {
console.error(chalk_1.default.red('Error loading config:'), error);
}
return null;
}
async function validateSigNozConnection(url, token) {
const spinner = (0, ora_1.default)('Validating SigNoz connection...').start();
try {
const axios = require('axios');
const apiUrl = url.endsWith('/') ? url.slice(0, -1) : url;
const response = await axios.get(`${apiUrl}/api/v1/version`, {
headers: {
'SIGNOZ-API-KEY': token,
'Content-Type': 'application/json'
},
timeout: 10000
});
if (response.status === 200) {
spinner.succeed(chalk_1.default.green('ā
Connection validated successfully!'));
console.log(chalk_1.default.blue(`š SigNoz Version: ${response.data.version || 'Unknown'}`));
console.log(chalk_1.default.blue(`š¢ Enterprise: ${response.data.ee ? 'Yes' : 'No'}`));
return true;
}
}
catch (error) {
spinner.fail(chalk_1.default.red('ā Connection validation failed'));
if (error.response) {
console.error(chalk_1.default.red(`HTTP ${error.response.status}: ${error.response.statusText}`));
if (error.response.status === 401) {
console.error(chalk_1.default.yellow('š” Check your API token - it might be invalid or expired'));
}
else if (error.response.status === 404) {
console.error(chalk_1.default.yellow('š” Check your URL - the SigNoz API endpoint might be wrong'));
}
}
else if (error.code === 'ECONNREFUSED') {
console.error(chalk_1.default.yellow('š” Connection refused - check if SigNoz is running and accessible'));
}
else {
console.error(chalk_1.default.red(`Error: ${error.message}`));
}
return false;
}
return false;
}
function generateMcpConfig(config) {
return {
mcpServers: {
signoz: {
command: "npx",
args: ["signoz-mcp-server"],
env: {
SIGNOZ_URL: config.url,
SIGNOZ_TOKEN: config.token
}
}
}
};
}
program
.name('signoz-mcp')
.description('CLI tool to configure SigNoz MCP Server')
.version('1.0.0');
program
.command('configure')
.description('Configure SigNoz MCP Server connection')
.option('-u, --url <url>', 'SigNoz instance URL')
.option('-t, --token <token>', 'SigNoz API token')
.option('-n, --name <name>', 'Configuration name (optional)')
.option('--no-validate', 'Skip connection validation')
.action(async (options) => {
console.log(chalk_1.default.blue.bold('š SigNoz MCP Server Configuration\n'));
let { url, token, name } = options;
const validate = options.validate !== false;
// Interactive prompts if parameters not provided
if (!url || !token) {
const answers = await inquirer_1.default.prompt([
{
type: 'input',
name: 'url',
message: 'Enter your SigNoz instance URL:',
default: url || 'http://localhost:3301',
validate: (input) => {
try {
new URL(input);
return true;
}
catch {
return 'Please enter a valid URL (e.g., http://localhost:3301 or https://your-signoz.com)';
}
}
},
{
type: 'password',
name: 'token',
message: 'Enter your SigNoz API token:',
default: token,
validate: (input) => input.length > 0 || 'API token is required'
},
{
type: 'input',
name: 'name',
message: 'Configuration name (optional):',
default: name || 'default'
}
]);
url = answers.url;
token = answers.token;
name = answers.name;
}
// Normalize URL
url = url.replace(/\/+$/, ''); // Remove trailing slashes
const config = {
url,
token,
name: name || 'default',
description: `SigNoz instance at ${url}`
};
// Validate connection if requested
if (validate) {
const isValid = await validateSigNozConnection(url, token);
if (!isValid) {
console.log(chalk_1.default.yellow('\nā ļø Connection validation failed. You can still save the configuration.'));
const { proceed } = await inquirer_1.default.prompt([
{
type: 'confirm',
name: 'proceed',
message: 'Do you want to save the configuration anyway?',
default: false
}
]);
if (!proceed) {
console.log(chalk_1.default.red('Configuration cancelled.'));
process.exit(1);
}
}
}
// Save configuration
try {
saveConfig(config);
console.log(chalk_1.default.green('ā
Configuration saved successfully!'));
console.log(chalk_1.default.blue(`š Config location: ${CONFIG_FILE}`));
// Generate Claude Desktop config
const mcpConfig = generateMcpConfig(config);
console.log(chalk_1.default.yellow('\nš Add this to your Claude Desktop config:'));
console.log(chalk_1.default.gray(JSON.stringify(mcpConfig, null, 2)));
console.log(chalk_1.default.green('\nš Setup complete! You can now use the SigNoz MCP server in Claude.'));
}
catch (error) {
console.error(chalk_1.default.red('ā Failed to save configuration:'), error);
process.exit(1);
}
});
program
.command('test')
.description('Test SigNoz connection with saved configuration')
.action(async () => {
const config = loadConfig();
if (!config) {
console.error(chalk_1.default.red('ā No configuration found. Run "signoz-mcp configure" first.'));
process.exit(1);
}
console.log(chalk_1.default.blue(`š Testing connection to: ${config.url}`));
const isValid = await validateSigNozConnection(config.url, config.token);
if (isValid) {
console.log(chalk_1.default.green('\nā
Connection test successful!'));
}
else {
console.log(chalk_1.default.red('\nā Connection test failed.'));
process.exit(1);
}
});
program
.command('show-config')
.description('Display current configuration')
.action(() => {
const config = loadConfig();
if (!config) {
console.error(chalk_1.default.red('ā No configuration found. Run "signoz-mcp configure" first.'));
process.exit(1);
}
console.log(chalk_1.default.blue.bold('š Current SigNoz MCP Configuration:\n'));
console.log(chalk_1.default.gray('Name:'), config.name);
console.log(chalk_1.default.gray('URL:'), config.url);
console.log(chalk_1.default.gray('Token:'), config.token.replace(/./g, '*').slice(0, -4) + config.token.slice(-4));
console.log(chalk_1.default.gray('Description:'), config.description);
console.log(chalk_1.default.gray('Config file:'), CONFIG_FILE);
});
program
.command('reset')
.description('Reset configuration')
.action(async () => {
const { confirm } = await inquirer_1.default.prompt([
{
type: 'confirm',
name: 'confirm',
message: 'Are you sure you want to reset the configuration?',
default: false
}
]);
if (confirm) {
try {
if ((0, fs_1.existsSync)(CONFIG_FILE)) {
require('fs').unlinkSync(CONFIG_FILE);
console.log(chalk_1.default.green('ā
Configuration reset successfully!'));
}
else {
console.log(chalk_1.default.yellow('ā ļø No configuration found to reset.'));
}
}
catch (error) {
console.error(chalk_1.default.red('ā Failed to reset configuration:'), error);
process.exit(1);
}
}
});
// Handle the case when used as MCP server
if (process.argv.length === 2) {
// No arguments provided, start as MCP server
require('./index');
}
else {
program.parse();
}
//# sourceMappingURL=cli.js.map